mirror of
https://github.com/ouch-org/ouch.git
synced 2025-07-19 16:10:53 +00:00
improve code structure
This commit is contained in:
parent
1aa6bad460
commit
a6b3e96df5
@ -5,6 +5,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
|
use crate::utils::landlock;
|
||||||
|
|
||||||
#[cfg(not(feature = "bzip3"))]
|
#[cfg(not(feature = "bzip3"))]
|
||||||
use crate::archive;
|
use crate::archive;
|
||||||
@ -316,6 +317,10 @@ fn execute_decompression(
|
|||||||
is_output_dir_provided: bool,
|
is_output_dir_provided: bool,
|
||||||
is_smart_unpack: bool,
|
is_smart_unpack: bool,
|
||||||
) -> crate::Result<ControlFlow<(), usize>> {
|
) -> crate::Result<ControlFlow<(), usize>> {
|
||||||
|
|
||||||
|
// init landlock sandbox to restrict file system write access to output_dir
|
||||||
|
landlock::init_sandbox(output_dir);
|
||||||
|
|
||||||
if is_smart_unpack {
|
if is_smart_unpack {
|
||||||
return smart_unpack(unpack_fn, output_dir, output_file_path, question_policy);
|
return smart_unpack(unpack_fn, output_dir, output_file_path, question_policy);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use fs_err as fs;
|
use fs_err as fs;
|
||||||
|
use crate::utils::landlock;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
archive,
|
archive,
|
||||||
@ -23,6 +24,11 @@ pub fn list_archive_contents(
|
|||||||
question_policy: QuestionPolicy,
|
question_policy: QuestionPolicy,
|
||||||
password: Option<&[u8]>,
|
password: Option<&[u8]>,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
|
|
||||||
|
// Initialize landlock sandbox with empty write path
|
||||||
|
// This allows only read access to the filesystem
|
||||||
|
//landlock::init_sandbox(None);
|
||||||
|
|
||||||
let reader = fs::File::open(archive_path)?;
|
let reader = fs::File::open(archive_path)?;
|
||||||
|
|
||||||
// Zip archives are special, because they require io::Seek, so it requires it's logic separated
|
// Zip archives are special, because they require io::Seek, so it requires it's logic separated
|
||||||
|
36
src/main.rs
36
src/main.rs
@ -7,10 +7,8 @@ pub mod error;
|
|||||||
pub mod extension;
|
pub mod extension;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
//pub mod sandbox;
|
|
||||||
|
|
||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use cli::CliArgs;
|
use cli::CliArgs;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
@ -50,9 +48,9 @@ fn run() -> Result<()> {
|
|||||||
let (args, skip_questions_positively, file_visibility_policy) = CliArgs::parse_and_validate_args()?;
|
let (args, skip_questions_positively, file_visibility_policy) = CliArgs::parse_and_validate_args()?;
|
||||||
|
|
||||||
// Get the output dir if specified, else use current dir
|
// Get the output dir if specified, else use current dir
|
||||||
let working_dir = args.output_dir
|
//let working_dir = args.output_dir
|
||||||
.clone()
|
// .clone()
|
||||||
.unwrap_or_else(|| env::current_dir().unwrap_or_default());
|
// .unwrap_or_else(|| env::current_dir().unwrap_or_default());
|
||||||
|
|
||||||
// restrict filesystem access to working_dir;
|
// restrict filesystem access to working_dir;
|
||||||
// 1. working_dir is either the output_dir specified by the -d option or
|
// 1. working_dir is either the output_dir specified by the -d option or
|
||||||
@ -68,33 +66,7 @@ fn run() -> Result<()> {
|
|||||||
// directory requires LANDLOCK_ACCESS_FS_MAKE_DIR
|
// directory requires LANDLOCK_ACCESS_FS_MAKE_DIR
|
||||||
|
|
||||||
// expects either the .tmp-ouch-XXXXXX path or the specified output directory (-d option)
|
// expects either the .tmp-ouch-XXXXXX path or the specified output directory (-d option)
|
||||||
init_sandbox(&working_dir);
|
//utils::landlock::init_sandbox(&working_dir);
|
||||||
|
|
||||||
commands::run(args, skip_questions_positively, file_visibility_policy)
|
commands::run(args, skip_questions_positively, file_visibility_policy)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_sandbox(allowed_dir: &Path) {
|
|
||||||
|
|
||||||
if std::env::var("CI").is_ok() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if utils::landlock::is_landlock_supported() {
|
|
||||||
|
|
||||||
let path_str = allowed_dir.to_str().expect("Cannot convert path");
|
|
||||||
match utils::landlock::restrict_paths(&[path_str]) {
|
|
||||||
Ok(status) => {
|
|
||||||
//check
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
//log warning
|
|
||||||
std::process::exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// warn!("Landlock is NOT supported on this platform or kernel (<5.19).");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -7,6 +7,11 @@ use landlock::{
|
|||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// The status code returned from `ouch` on error
|
||||||
|
pub const EXIT_FAILURE: i32 = libc::EXIT_FAILURE;
|
||||||
|
|
||||||
/// Returns true if Landlock is supported by the running kernel (Linux kernel >= 5.19).
|
/// Returns true if Landlock is supported by the running kernel (Linux kernel >= 5.19).
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
pub fn is_landlock_supported() -> bool {
|
pub fn is_landlock_supported() -> bool {
|
||||||
@ -43,24 +48,58 @@ pub enum MyRestrictError {
|
|||||||
///
|
///
|
||||||
/// The Landlock ABI is set to v2 for compatibility with Linux 5.19+.
|
/// The Landlock ABI is set to v2 for compatibility with Linux 5.19+.
|
||||||
/// All hierarchies are given full access, but root ("/") is read-only.
|
/// All hierarchies are given full access, but root ("/") is read-only.
|
||||||
pub fn restrict_paths(hierarchies: &[&str]) -> Result<RestrictionStatus, MyRestrictError> {
|
fn restrict_paths(hierarchies: &[&str]) -> Result<RestrictionStatus, MyRestrictError> {
|
||||||
// The Landlock ABI should be incremented (and tested) regularly.
|
// The Landlock ABI should be incremented (and tested) regularly.
|
||||||
// ABI set to 2 in compatibility with linux 5.19 and higher
|
// ABI set to 2 in compatibility with linux 5.19 and higher
|
||||||
let abi = ABI::V2;
|
let abi = ABI::V2;
|
||||||
let access_all = AccessFs::from_all(abi);
|
let access_all = AccessFs::from_all(abi);
|
||||||
let access_read = AccessFs::from_read(abi);
|
let access_read = AccessFs::from_read(abi);
|
||||||
|
|
||||||
Ok(Ruleset::default()
|
|
||||||
|
let mut ruleset = Ruleset::default()
|
||||||
.handle_access(access_all)?
|
.handle_access(access_all)?
|
||||||
.create()?
|
.create()?
|
||||||
// Read-only access to / (entire filesystem).
|
// Read-only access to / (entire filesystem).
|
||||||
.add_rules(landlock::path_beneath_rules(&["/"], access_read))?
|
.add_rules(landlock::path_beneath_rules(&["/"], access_read))?;
|
||||||
.add_rules(
|
|
||||||
|
// Add write permissions to specified directory of provided
|
||||||
|
if !hierarchies.is_empty() {
|
||||||
|
ruleset = ruleset.add_rules(
|
||||||
hierarchies
|
hierarchies
|
||||||
.iter()
|
.iter()
|
||||||
.map::<Result<_, MyRestrictError>, _>(|p| {
|
.map::<Result<_, MyRestrictError>, _>(|p| {
|
||||||
Ok(PathBeneath::new(PathFd::new(p)?, access_all))
|
Ok(PathBeneath::new(PathFd::new(p)?, access_all))
|
||||||
}),
|
}),
|
||||||
)?
|
)?;
|
||||||
.restrict_self()?)
|
}
|
||||||
|
|
||||||
|
Ok(ruleset.restrict_self()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn init_sandbox(allowed_dir: &Path) {
|
||||||
|
|
||||||
|
if std::env::var("CI").is_ok() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if is_landlock_supported() {
|
||||||
|
|
||||||
|
let path_str = allowed_dir.to_str().expect("Cannot convert path");
|
||||||
|
|
||||||
|
match restrict_paths(&[path_str]) {
|
||||||
|
Ok(status) => {
|
||||||
|
//check
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
//log warning
|
||||||
|
std::process::exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// warn!("Landlock is NOT supported on this platform or kernel (<5.19).");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user