Skip to content

Commit 2924653

Browse files
committed
lidi-clients: option to chroot lidi-receive-file (requires CAP_SYS_CHROOT)
1 parent b161b0b commit 2924653

5 files changed

Lines changed: 51 additions & 4 deletions

File tree

.github/workflows/release.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ jobs:
2828
run: rustup update
2929

3030
- name: Build release
31-
run: just release
31+
run: |
32+
just release
33+
just grant_chroot_receive_file
3234
3335
- name: Gather artifacts
3436
run: |

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

justfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ release_tcp_mmsg:
77
release_tls_native:
88
cargo build --release --no-default-features --features from-tls,to-tls,tls,receive-native,send-native
99

10+
grant_chroot_receive_file:
11+
sudo setcap cap_sys_chroot=pe target/release/lidi-receive-file
12+
1013
clean:
1114
cargo clean
1215

lidi-clients/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ version = "0"
2323
optional = true
2424
default-features = false
2525

26+
[dependencies.libc]
27+
version = "0"
28+
default-features = false
29+
features = [ "std" ]
30+
2631
[dependencies.log]
2732
version = "0"
2833
default-features = false

lidi-clients/src/bin/lidi-receive-file.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clap::Parser;
2-
use std::{net, path};
2+
use std::{net, os::unix::ffi::OsStrExt, path};
33

44
#[derive(clap::Args)]
55
#[group(required = true, multiple = false)]
@@ -54,10 +54,12 @@ struct Args {
5454
help = "Exits after receiving max_files files"
5555
)]
5656
max_files: usize,
57-
#[clap(long, value_name = "overwrite", help = "Overwrite existing files")]
57+
#[clap(long, help = "Overwrite existing files")]
5858
overwrite: bool,
5959
#[clap(flatten)]
6060
tls: lidi_clients::Tls,
61+
#[clap(long, help = "Chroot in output directory before receiving files")]
62+
chroot: bool,
6163
#[clap(default_value = ".", help = "Output directory")]
6264
output_directory: path::PathBuf,
6365
}
@@ -94,7 +96,41 @@ fn main() {
9496
tls: args.tls,
9597
};
9698

97-
if let Err(e) = lidi_clients::file::receive::receive_files(&config, &args.output_directory) {
99+
let output_directory = if args.chroot {
100+
let mut bytes_output_directory = Vec::from(args.output_directory.as_os_str().as_bytes());
101+
bytes_output_directory.push(0);
102+
103+
let c_output_directory = match std::ffi::CString::from_vec_with_nul(bytes_output_directory)
104+
{
105+
Ok(res) => res,
106+
Err(e) => {
107+
log::error!(
108+
"failed to convert output directory to C string {}: {e}",
109+
args.output_directory.display()
110+
);
111+
std::process::exit(1);
112+
}
113+
};
114+
115+
if unsafe { libc::chroot(c_output_directory.as_ptr()) } != 0 {
116+
let err_str =
117+
unsafe { std::ffi::CStr::from_ptr(libc::strerror(*libc::__errno_location())) }
118+
.to_string_lossy();
119+
log::error!(
120+
"failed to chroot in {}: {err_str}",
121+
args.output_directory.display()
122+
);
123+
std::process::exit(1);
124+
}
125+
126+
log::info!("chrooted in {}", args.output_directory.display());
127+
128+
path::PathBuf::from("/")
129+
} else {
130+
args.output_directory
131+
};
132+
133+
if let Err(e) = lidi_clients::file::receive::receive_files(&config, &output_directory) {
98134
log::error!("{e}");
99135
}
100136
}

0 commit comments

Comments
 (0)