diff --git a/Cargo.lock b/Cargo.lock index 9a04220..f5a3eef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,9 +29,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" @@ -321,18 +321,18 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.26" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "shlex", ] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "cfg_aliases" @@ -499,9 +499,9 @@ checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" [[package]] name = "enumflags2" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ "enumflags2_derive", "serde", @@ -509,9 +509,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", @@ -735,7 +735,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -773,9 +773,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -1056,9 +1056,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" dependencies = [ "jiff-static", "log", @@ -1069,9 +1069,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", @@ -1096,9 +1096,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.172" +version = "0.2.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" +checksum = "d8cfeafaffdbc32176b64fb251369d52ea9f0a8fbc6f8759edffef7b525d64bb" [[package]] name = "libsystemd" @@ -1160,9 +1160,9 @@ checksum = "670fdfda89751bc4a84ac13eaa63e205cf0fd22b4c9a5fbfa085b63c1f1d3a30" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memoffset" @@ -1173,17 +1173,11 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "miniz_oxide" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -1195,7 +1189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "windows-sys 0.59.0", ] @@ -1647,9 +1641,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.19" +version = "0.12.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" +checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813" dependencies = [ "base64", "bytes", @@ -1661,12 +1655,9 @@ dependencies = [ "hyper-rustls", "hyper-tls", "hyper-util", - "ipnet", "js-sys", "log", - "mime", "native-tls", - "once_cell", "percent-encoding", "pin-project-lite", "quinn", @@ -1706,9 +1697,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] name = "rustc-hash" @@ -2011,9 +2002,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.101" +version = "2.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" +checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" dependencies = [ "proc-macro2", "quote", @@ -2395,9 +2386,9 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" @@ -2614,9 +2605,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index e2d6eeb..d5f1f2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,8 @@ edition = "2024" resolver = "3" [features] -unstable = [] +capabilities = ["dep:caps"] +unstable = ["capabilities"] [dependencies] derive-new = "0.7.0" @@ -17,6 +18,7 @@ toml = "0.8" [dependencies.caps] version = "0.5.5" default-features = false +optional = true [dependencies.libc] version = "0.2" diff --git a/src/main.rs b/src/main.rs index cc62b0e..7eedb9c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,8 @@ pub(crate) mod process; pub(crate) mod types; pub(crate) mod utils; +#[cfg(feature = "capabilities")] +use crate::utils::check_permissions; use crate::{ consts::*, prelude::*, @@ -28,7 +30,6 @@ use crate::{ SubCommand, }, }, - utils::check_permissions, }; use acme2_eab::Directory; use async_scoped::TokioScope; @@ -241,6 +242,7 @@ async fn schema_generator() -> Result<(), Error> { fn main() { log_init(); let args = Arguments::parse(); + #[cfg(feature = "capabilities")] if args.subcommands.is_none() && !check_permissions() { error!( "This program needs the capability to change the ownership and the permissions of files. this can be done via adding the capability via `capsh --caps=\"cap_chown+ep cap_fowner+ep\" --shell=racme -- racme.toml`, systemd service setting AmbientCapabilities or running as root(not recommended)" diff --git a/src/process/mod.rs b/src/process/mod.rs index 5eb156b..7fdf6f2 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -1,20 +1,21 @@ +#[cfg(feature = "capabilities")] +use std::os::{ + fd::AsFd, + unix::fs::fchown, +}; use std::{ collections::{ HashMap, HashSet, }, fs::Permissions, - os::{ - fd::AsFd, - unix::fs::{ - PermissionsExt as _, - fchown, - }, - }, + os::unix::fs::PermissionsExt as _, path::PathBuf, sync::Arc, }; +#[cfg(feature = "capabilities")] +use crate::utils::get_uid_gid; use crate::{ consts::{ ATTEMPTS, @@ -37,7 +38,6 @@ use crate::{ }, utils::{ gen_key, - get_uid_gid, prefix_emails, }, }; @@ -218,6 +218,7 @@ pub async fn site(args: ProcessorArgs<'_>) { }; cert_renew = true; } + #[cfg(feature = "capabilities")] let (uid, gid) = get_uid_gid(args.owner(), args.group()); let mut private_key; // Private key block @@ -245,6 +246,7 @@ pub async fn site(args: ProcessorArgs<'_>) { if write_pkey { let pkey = private_key.private_key_to_pem_pkcs8().unwrap(); let mut file = match_error!(with_mode_write(0o640).open(private_key_file.clone()).await=>Err(error)->"Failed to write new private key: {error}"); + #[cfg(feature = "capabilities")] if let Err(error) = fchown(file.as_fd(), uid, gid) { error!("Failed to change owner of the new privatekey: {error}"); return; @@ -339,12 +341,14 @@ pub async fn site(args: ProcessorArgs<'_>) { let mut pubkey_file = match_error!(with_mode_write(0o644).open(pubkey_filename).await=>Err(error)-> "Failed to open the file for the publickey: {error}"); match_error!(pubkey_file.write_all(&certs[0].to_pem().unwrap()).await=>Err(error)-> "Failed to write the publickey: {error}"); + #[cfg(feature = "capabilities")] if let Err(error) = fchown(pubkey_file.as_fd(), uid, gid) { error!("Failed to change owner of the new publickey: {error}"); return; } let mut fullchain = match_error!(with_mode_write(0o644).open(directory.join("fullchain.pem")).await=>Err(error)-> "failed to open the fullchain.pem: {error}"); + #[cfg(feature = "capabilities")] if let Err(error) = fchown(fullchain.as_fd(), uid, gid) { error!("Failed to change owner of the new file with the complete chain: {error}"); return; @@ -353,6 +357,7 @@ pub async fn site(args: ProcessorArgs<'_>) { let _ = fullchain.write_all(&cert.to_pem().unwrap()).await; } let mut bundle = match_error!(with_mode_write(0o640).open(directory.join("bundle.pem")).await=>Err(error)-> "failed to open the bundle.pem: {error}"); + #[cfg(feature = "capabilities")] if let Err(error) = fchown(bundle.as_fd(), uid, gid) { error!("Failed to change owner of the new bundle: {error}"); return; diff --git a/src/types/config.rs b/src/types/config.rs index a74d55c..ae09ee4 100644 --- a/src/types/config.rs +++ b/src/types/config.rs @@ -166,9 +166,11 @@ pub struct SiteConfig { /// Owner of the Certificate and private key #[serde(default)] + #[cfg(feature = "capabilities")] pub owner: String, /// Group of the Certificate and private key #[serde(default)] + #[cfg(feature = "capabilities")] pub group: String, } diff --git a/src/types/structs.rs b/src/types/structs.rs index e033722..7aa953a 100644 --- a/src/types/structs.rs +++ b/src/types/structs.rs @@ -86,8 +86,10 @@ impl<'a: 'b, 'b> ProcessorArgs<'a> { attr_function!(pub challenge_dir => Option); + #[cfg(feature = "capabilities")] attr_function!(pub owner site => String); + #[cfg(feature = "capabilities")] attr_function!(pub group site => String); attr_function!(pub client => Client); diff --git a/src/utils.rs b/src/utils.rs index 94ec9fe..ed1c346 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -17,6 +17,7 @@ use crate::{ structs::Error, }, }; +#[cfg(feature = "capabilities")] use caps::{ CapSet, has_cap, @@ -38,6 +39,7 @@ use openssl::{ }, }; +#[cfg(feature = "capabilities")] const CAPABILITY_SET: CapSet = CapSet::Permitted; pub fn prefix_emails(input: Vec) -> Vec { @@ -107,6 +109,7 @@ pub fn string_to_cn(name: String) -> X509Name { builder.build() } +#[cfg(feature = "capabilities")] pub fn check_permissions() -> bool { let caps = has_cap(None, CAPABILITY_SET, caps::Capability::CAP_CHOWN).unwrap_or(false) && has_cap(None, CAPABILITY_SET, caps::Capability::CAP_FOWNER).unwrap_or(false);