72
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										72
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -88,6 +88,15 @@ version = "2.8.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" | checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "block-buffer" | ||||||
|  | version = "0.10.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" | ||||||
|  | dependencies = [ | ||||||
|  |  "generic-array", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "bumpalo" | name = "bumpalo" | ||||||
| version = "3.17.0" | version = "3.17.0" | ||||||
| @@ -240,6 +249,16 @@ version = "0.8.21" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "crypto-common" | ||||||
|  | version = "0.1.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" | ||||||
|  | dependencies = [ | ||||||
|  |  "generic-array", | ||||||
|  |  "typenum", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "deranged" | name = "deranged" | ||||||
| version = "0.3.11" | version = "0.3.11" | ||||||
| @@ -255,6 +274,16 @@ version = "0.1.13" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" | checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "digest" | ||||||
|  | version = "0.10.7" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" | ||||||
|  | dependencies = [ | ||||||
|  |  "block-buffer", | ||||||
|  |  "crypto-common", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "dns-lookup" | name = "dns-lookup" | ||||||
| version = "2.0.4" | version = "2.0.4" | ||||||
| @@ -295,6 +324,16 @@ version = "2.3.0" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "generic-array" | ||||||
|  | version = "0.14.7" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" | ||||||
|  | dependencies = [ | ||||||
|  |  "typenum", | ||||||
|  |  "version_check", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "getrandom" | name = "getrandom" | ||||||
| version = "0.3.1" | version = "0.3.1" | ||||||
| @@ -404,6 +443,16 @@ version = "0.4.25" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" | checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "md-5" | ||||||
|  | version = "0.10.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" | ||||||
|  | dependencies = [ | ||||||
|  |  "cfg-if", | ||||||
|  |  "digest", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "memchr" | name = "memchr" | ||||||
| version = "2.7.4" | version = "2.7.4" | ||||||
| @@ -916,6 +965,12 @@ dependencies = [ | |||||||
|  "time-core", |  "time-core", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "typenum" | ||||||
|  | version = "1.18.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "unicode-ident" | name = "unicode-ident" | ||||||
| version = "1.0.16" | version = "1.0.16" | ||||||
| @@ -975,6 +1030,7 @@ dependencies = [ | |||||||
|  "uu_lscpu", |  "uu_lscpu", | ||||||
|  "uu_lslocks", |  "uu_lslocks", | ||||||
|  "uu_lsmem", |  "uu_lsmem", | ||||||
|  |  "uu_mcookie", | ||||||
|  "uu_mesg", |  "uu_mesg", | ||||||
|  "uu_mountpoint", |  "uu_mountpoint", | ||||||
|  "uu_renice", |  "uu_renice", | ||||||
| @@ -1068,6 +1124,16 @@ dependencies = [ | |||||||
|  "uucore", |  "uucore", | ||||||
| ] | ] | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "uu_mcookie" | ||||||
|  | version = "0.0.1" | ||||||
|  | dependencies = [ | ||||||
|  |  "clap", | ||||||
|  |  "md-5", | ||||||
|  |  "rand 0.9.0", | ||||||
|  |  "uucore", | ||||||
|  | ] | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "uu_mesg" | name = "uu_mesg" | ||||||
| version = "0.0.1" | version = "0.0.1" | ||||||
| @@ -1149,6 +1215,12 @@ version = "0.0.30" | |||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
| checksum = "0bb6d972f580f8223cb7052d8580aea2b7061e368cf476de32ea9457b19459ed" | checksum = "0bb6d972f580f8223cb7052d8580aea2b7061e368cf476de32ea9457b19459ed" | ||||||
|  |  | ||||||
|  | [[package]] | ||||||
|  | name = "version_check" | ||||||
|  | version = "0.9.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" | ||||||
|  |  | ||||||
| [[package]] | [[package]] | ||||||
| name = "wasi" | name = "wasi" | ||||||
| version = "0.13.3+wasi-0.2.2" | version = "0.13.3+wasi-0.2.2" | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ feat_common_core = [ | |||||||
|   "lscpu", |   "lscpu", | ||||||
|   "lslocks", |   "lslocks", | ||||||
|   "lsmem", |   "lsmem", | ||||||
|  |   "mcookie", | ||||||
|   "mesg", |   "mesg", | ||||||
|   "mountpoint", |   "mountpoint", | ||||||
|   "renice", |   "renice", | ||||||
| @@ -48,6 +49,7 @@ clap_mangen = "0.2" | |||||||
| dns-lookup = "2.0.4" | dns-lookup = "2.0.4" | ||||||
| libc = "0.2.152" | libc = "0.2.152" | ||||||
| linux-raw-sys = { version = "0.9.0", features = ["ioctl"] } | linux-raw-sys = { version = "0.9.0", features = ["ioctl"] } | ||||||
|  | md-5 = "0.10.6" | ||||||
| nix = { version = "0.29", default-features = false } | nix = { version = "0.29", default-features = false } | ||||||
| phf = "0.11.2" | phf = "0.11.2" | ||||||
| phf_codegen = "0.11.2" | phf_codegen = "0.11.2" | ||||||
| @@ -81,6 +83,7 @@ last = { optional = true, version = "0.0.1", package = "uu_last", path = "src/uu | |||||||
| lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" } | lscpu = { optional = true, version = "0.0.1", package = "uu_lscpu", path = "src/uu/lscpu" } | ||||||
| lslocks = { optional = true, version = "0.0.1", package = "uu_lslocks", path = "src/uu/lslocks" } | lslocks = { optional = true, version = "0.0.1", package = "uu_lslocks", path = "src/uu/lslocks" } | ||||||
| lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/uu/lsmem" } | lsmem = { optional = true, version = "0.0.1", package = "uu_lsmem", path = "src/uu/lsmem" } | ||||||
|  | mcookie = { optional = true, version = "0.0.1", package = "uu_mcookie", path = "src/uu/mcookie" } | ||||||
| mesg = { optional = true, version = "0.0.1", package = "uu_mesg", path = "src/uu/mesg" } | mesg = { optional = true, version = "0.0.1", package = "uu_mesg", path = "src/uu/mesg" } | ||||||
| mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" } | mountpoint = { optional = true, version = "0.0.1", package = "uu_mountpoint", path = "src/uu/mountpoint" } | ||||||
| renice = { optional = true, version = "0.0.1", package = "uu_renice", path = "src/uu/renice" } | renice = { optional = true, version = "0.0.1", package = "uu_renice", path = "src/uu/renice" } | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								src/uu/mcookie/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/uu/mcookie/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | [package] | ||||||
|  | name = "uu_mcookie" | ||||||
|  | version = "0.0.1" | ||||||
|  | edition = "2021" | ||||||
|  |  | ||||||
|  | [lib] | ||||||
|  | path = "src/mcookie.rs" | ||||||
|  |  | ||||||
|  | [[bin]] | ||||||
|  | name = "mcookie" | ||||||
|  | path = "src/main.rs" | ||||||
|  |  | ||||||
|  | [dependencies] | ||||||
|  | uucore = { workspace = true } | ||||||
|  | clap = { workspace = true } | ||||||
|  | md-5 = { workspace = true } | ||||||
|  | rand = { workspace = true } | ||||||
							
								
								
									
										7
									
								
								src/uu/mcookie/mcookie.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/uu/mcookie/mcookie.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | |||||||
|  | # mcookie | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | mcookie [OPTION]... | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Generate magic cookies for xauth. | ||||||
							
								
								
									
										1
									
								
								src/uu/mcookie/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/uu/mcookie/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | uucore::bin!(uu_mcookie); | ||||||
							
								
								
									
										111
									
								
								src/uu/mcookie/src/mcookie.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/uu/mcookie/src/mcookie.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | // This file is part of the uutils util-linux package. | ||||||
|  | // | ||||||
|  | // For the full copyright and license information, please view the LICENSE | ||||||
|  | // file that was distributed with this source code. | ||||||
|  |  | ||||||
|  | use std::{fs::File, io::Read}; | ||||||
|  |  | ||||||
|  | use clap::{crate_version, Arg, ArgAction, Command}; | ||||||
|  | use md5::{Digest, Md5}; | ||||||
|  | use rand::RngCore; | ||||||
|  | use uucore::{error::UResult, format_usage, help_about, help_usage}; | ||||||
|  |  | ||||||
|  | mod options { | ||||||
|  |     pub const FILE: &str = "file"; | ||||||
|  |     pub const MAX_SIZE: &str = "max-size"; | ||||||
|  |     pub const VERBOSE: &str = "verbose"; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ABOUT: &str = help_about!("mcookie.md"); | ||||||
|  | const USAGE: &str = help_usage!("mcookie.md"); | ||||||
|  |  | ||||||
|  | #[uucore::main] | ||||||
|  | pub fn uumain(args: impl uucore::Args) -> UResult<()> { | ||||||
|  |     let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?; | ||||||
|  |  | ||||||
|  |     let verbose = matches.get_flag(options::VERBOSE); | ||||||
|  |  | ||||||
|  |     let seed_files: Vec<&str> = matches | ||||||
|  |         .get_many::<String>(options::FILE) | ||||||
|  |         .unwrap_or_default() | ||||||
|  |         .map(|v| v.as_str()) | ||||||
|  |         .collect(); | ||||||
|  |  | ||||||
|  |     // TODO: Parse max size from human-readable strings (KiB, MiB, GiB etc.) | ||||||
|  |     let max_size = matches | ||||||
|  |         .get_one::<String>(options::MAX_SIZE) | ||||||
|  |         .map(|v| v.parse::<u64>().expect("Failed to parse max-size value")); | ||||||
|  |  | ||||||
|  |     let mut hasher = Md5::new(); | ||||||
|  |  | ||||||
|  |     for file in seed_files { | ||||||
|  |         let mut f = File::open(file)?; | ||||||
|  |         let mut buffer: Vec<u8> = Vec::new(); | ||||||
|  |  | ||||||
|  |         if let Some(max_bytes) = &max_size { | ||||||
|  |             let mut handle = f.take(*max_bytes); | ||||||
|  |             handle.read_to_end(&mut buffer)?; | ||||||
|  |         } else { | ||||||
|  |             f.read_to_end(&mut buffer)?; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if verbose { | ||||||
|  |             eprintln!("Got {} bytes from {}", buffer.len(), file); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         hasher.update(&buffer); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const RANDOM_BYTES: usize = 128; | ||||||
|  |     let mut rng = rand::rng(); | ||||||
|  |     let mut rand_bytes = [0u8; RANDOM_BYTES]; | ||||||
|  |     rng.fill_bytes(&mut rand_bytes); | ||||||
|  |  | ||||||
|  |     hasher.update(rand_bytes); | ||||||
|  |  | ||||||
|  |     if verbose { | ||||||
|  |         eprintln!("Got {} bytes from randomness source", RANDOM_BYTES); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     let result = hasher.finalize(); | ||||||
|  |     let output = result | ||||||
|  |         .iter() | ||||||
|  |         .map(|byte| format!("{:02x}", byte)) | ||||||
|  |         .collect::<Vec<_>>() | ||||||
|  |         .join(""); | ||||||
|  |  | ||||||
|  |     println!("{}", output); | ||||||
|  |  | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn uu_app() -> Command { | ||||||
|  |     Command::new(uucore::util_name()) | ||||||
|  |         .version(crate_version!()) | ||||||
|  |         .about(ABOUT) | ||||||
|  |         .override_usage(format_usage(USAGE)) | ||||||
|  |         .infer_long_args(true) | ||||||
|  |         .arg( | ||||||
|  |             Arg::new(options::FILE) | ||||||
|  |                 .short('f') | ||||||
|  |                 .long("file") | ||||||
|  |                 .value_name("file") | ||||||
|  |                 .action(ArgAction::Append) | ||||||
|  |                 .help("use file as a cookie seed"), | ||||||
|  |         ) | ||||||
|  |         .arg( | ||||||
|  |             Arg::new(options::MAX_SIZE) | ||||||
|  |                 .short('m') | ||||||
|  |                 .long("max-size") | ||||||
|  |                 .value_name("num") | ||||||
|  |                 .action(ArgAction::Set) | ||||||
|  |                 .help("limit how much is read from seed files"), | ||||||
|  |         ) | ||||||
|  |         .arg( | ||||||
|  |             Arg::new(options::VERBOSE) | ||||||
|  |                 .short('v') | ||||||
|  |                 .long("verbose") | ||||||
|  |                 .action(ArgAction::SetTrue) | ||||||
|  |                 .help("explain what is being done"), | ||||||
|  |         ) | ||||||
|  | } | ||||||
							
								
								
									
										65
									
								
								tests/by-util/test_mcookie.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								tests/by-util/test_mcookie.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | |||||||
|  | // This file is part of the uutils util-linux package. | ||||||
|  | // | ||||||
|  | // For the full copyright and license information, please view the LICENSE | ||||||
|  | // file that was distributed with this source code. | ||||||
|  |  | ||||||
|  | use std::io::Write; | ||||||
|  |  | ||||||
|  | use tempfile::{NamedTempFile, TempDir}; | ||||||
|  |  | ||||||
|  | use crate::common::util::TestScenario; | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_invalid_arg() { | ||||||
|  |     new_ucmd!().arg("--definitely-invalid").fails().code_is(1); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_basic_usage() { | ||||||
|  |     let res = new_ucmd!().succeeds(); | ||||||
|  |  | ||||||
|  |     let stdout = res.no_stderr().stdout_str(); | ||||||
|  |  | ||||||
|  |     // Expect 32 hex characters for the MD5 hash (after trimming the newline) | ||||||
|  |     assert_eq!(stdout.trim_end().len(), 32); | ||||||
|  |     assert!(stdout.trim_end().chars().all(|c| c.is_ascii_hexdigit())); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_verbose() { | ||||||
|  |     let res = new_ucmd!().arg("--verbose").succeeds(); | ||||||
|  |     res.stderr_contains("Got 128 bytes from randomness source"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[test] | ||||||
|  | fn test_seed_files_and_max_size() { | ||||||
|  |     let mut file1 = NamedTempFile::new().unwrap(); | ||||||
|  |     const CONTENT1: &str = "Some seed data"; | ||||||
|  |     file1.write_all(CONTENT1.as_bytes()).unwrap(); | ||||||
|  |  | ||||||
|  |     let mut file2 = NamedTempFile::new().unwrap(); | ||||||
|  |     const CONTENT2: [u8; 2048] = [1; 2048]; | ||||||
|  |     file2.write_all(&CONTENT2).unwrap(); | ||||||
|  |  | ||||||
|  |     let res = new_ucmd!() | ||||||
|  |         .arg("--verbose") | ||||||
|  |         .arg("-f") | ||||||
|  |         .arg(file1.path()) | ||||||
|  |         .arg("-f") | ||||||
|  |         .arg(file2.path()) | ||||||
|  |         .arg("-m") | ||||||
|  |         .arg("1337") | ||||||
|  |         .succeeds(); | ||||||
|  |  | ||||||
|  |     res.stderr_contains(format!( | ||||||
|  |         "Got {} bytes from {}", | ||||||
|  |         CONTENT1.len(), | ||||||
|  |         file1.path().to_str().unwrap() | ||||||
|  |     )); | ||||||
|  |  | ||||||
|  |     // Ensure we only read up to the limit of bytes, despite the file being bigger | ||||||
|  |     res.stderr_contains(format!( | ||||||
|  |         "Got 1337 bytes from {}", | ||||||
|  |         file2.path().to_str().unwrap() | ||||||
|  |     )); | ||||||
|  | } | ||||||
| @@ -56,3 +56,7 @@ mod test_dmesg; | |||||||
| #[cfg(feature = "fsfreeze")] | #[cfg(feature = "fsfreeze")] | ||||||
| #[path = "by-util/test_fsfreeze.rs"] | #[path = "by-util/test_fsfreeze.rs"] | ||||||
| mod test_fsfreeze; | mod test_fsfreeze; | ||||||
|  |  | ||||||
|  | #[cfg(feature = "mcookie")] | ||||||
|  | #[path = "by-util/test_mcookie.rs"] | ||||||
|  | mod test_mcookie; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sylvestre Ledru
					Sylvestre Ledru