From ce6e96bd20e8a93bf826771b492286c794837bc9 Mon Sep 17 00:00:00 2001 From: MggMuggins Date: Thu, 26 Jul 2018 14:58:14 -0500 Subject: [PATCH] Major Refactor; Create passwd hashes Maybe some of the refactoring things I did don't make much sense, but I did them. The goal was to get rid of those macros (because macro definitions are really hard to read). I replaced two of them with very similar functions, and rearranged the `install` function. The installer now generates password hashes from the password entered by the user or listed in the toml file. This value is NO LONGER the password hash. The example configs have been changed to reflect this. --- config/default.toml | 3 +- config/minimal.toml | 3 +- src/lib.rs | 100 ++++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/config/default.toml b/config/default.toml index 470349cef8..ce7f54d13f 100644 --- a/config/default.toml +++ b/config/default.toml @@ -59,8 +59,7 @@ uutils = {} # User settings [users.root] -# Password is set to "password" -password = "$argon2i$m=4096,t=10,p=1$Tnc4UVV0N00$ML9LIOujd3nmAfkAwEcSTMPqakWUF0OUiLWrIy0nGLk" +password = "password" uid = 0 gid = 0 name = "root" diff --git a/config/minimal.toml b/config/minimal.toml index dba20f5d48..54e41b317e 100644 --- a/config/minimal.toml +++ b/config/minimal.toml @@ -17,8 +17,7 @@ userutils = {} # User settings [users.root] -# Password is set to "password" -password = "$argon2i$m=4096,t=10,p=1$Tnc4UVV0N00$ML9LIOujd3nmAfkAwEcSTMPqakWUF0OUiLWrIy0nGLk" +password = "password" uid = 0 gid = 0 name = "root" diff --git a/src/lib.rs b/src/lib.rs index 6a2c50df78..a34ae1de48 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,7 @@ type Result = std::result::Result; const REMOTE: &'static str = "https://static.redox-os.org/pkg"; const TARGET: &'static str = "x86_64-unknown-redox"; +const SYSROOT: &'static str = "SYSROOT"; /// Converts a password to a serialized argon2rs hash, understandable /// by redox_users. If the password is blank, the hash is blank. @@ -120,12 +121,42 @@ fn install_packages>(config: &Config, dest: &str, cookbook: Option } } -pub fn install, S: AsRef>(config: Config, output: P, cookbook: Option) -> Result<()> { - let output = output.as_ref(); - println!("Install {:#?} to {}", config, output.display()); - +pub fn install, S: AsRef>(config: Config, output_dir: P, cookbook: Option) -> Result<()> { + + /// Creates a directory relative to the output directory + fn create_dir_relative>(path: P) -> Result<()> { + let root = env::var(SYSROOT)?; + let target_dir = Path::new(&root) + .join(path.as_ref()); + println!("Create directory {}", target_dir.display()); + fs::create_dir_all(&target_dir)?; + Ok(()) + } + + /// Creates a file relative to the output directory + fn create_file_relative>(path: P, data: &[u8], is_symlink: bool) -> Result<()> { + let root = env::var(SYSROOT)?; + let target_file = Path::new(&root) + .join(path.as_ref()); + + if let Some(parent) = target_file.parent() { + println!("Create file parent {}", parent.display()); + fs::create_dir_all(parent)?; + } + + if is_symlink { + println!("Create symlink {}", target_file.display()); + symlink(&OsStr::from_bytes(data), &target_file)?; + } else { + println!("Create file {}", target_file.display()); + let mut file = fs::File::create(&target_file)?; + file.write_all(data)?; + } + Ok(()) + } + let mut context = liner::Context::new(); - + macro_rules! prompt { ($dst:expr, $def:expr, $($arg:tt)*) => (if config.general.prompt { match unwrap_or_prompt($dst, &mut context, &format!($($arg)*)) { @@ -141,48 +172,27 @@ pub fn install, S: AsRef>(config: Config, output: P, cookboo }) } + // Using an env var here to communicate the root dir to the functions + // instead of passing it as a param + env::set_var(SYSROOT, output_dir.as_ref().as_os_str()); + + let output_dir = output_dir.as_ref(); + println!("Install {:#?} to {}", config, output_dir.display()); + // TODO: Mount disk if output is a file - let sysroot = output.to_owned(); + let output_dir = output_dir.to_owned(); - macro_rules! dir { - ($path:expr) => {{ - let mut path = sysroot.clone(); - path.push($path); - println!("Create directory {}", path.display()); - fs::create_dir_all(&path)?; - }}; - } + create_dir_relative("")?; - macro_rules! file { - ($path:expr, $data:expr, $symlink:expr) => {{ - let mut path = sysroot.clone(); - path.push($path); - if let Some(parent) = path.parent() { - println!("Create file parent {}", parent.display()); - fs::create_dir_all(parent)?; - } - if $symlink { - println!("Create symlink {}", path.display()); - symlink(&OsStr::from_bytes($data), &path)?; - } else { - println!("Create file {}", path.display()); - let mut file = fs::File::create(&path)?; - file.write_all($data)?; - } - }}; - } - - dir!(""); - - install_packages(&config, sysroot.to_str().unwrap(), cookbook); + install_packages(&config, output_dir.to_str().unwrap(), cookbook); for file in config.files { - file!(file.path.trim_matches('/'), file.data.as_bytes(), file.symlink); + create_file_relative(file.path.trim_matches('/'), file.data.as_bytes(), file.symlink)?; } let mut passwd = String::new(); let mut next_uid = 1000; - + for (username, user) in config.users { // plaintext let password = if let Some(password) = user.password { @@ -203,7 +213,7 @@ pub fn install, S: AsRef>(config: Config, output: P, cookboo let gid = user.gid.unwrap_or(uid); - let name = prompt!(user.name, username.clone(), "{}: name [{}]: ", username, username)?; + let name = prompt!(user.name, username.clone(), "{}: name (GECOS) [{}]: ", username, username)?; let home = prompt!(user.home, format!("/home/{}", username), "{}: home [/home/{}]: ", username, username)?; let shell = prompt!(user.shell, "/bin/ion".to_string(), "{}: shell [/bin/ion]: ", username)?; @@ -215,15 +225,15 @@ pub fn install, S: AsRef>(config: Config, output: P, cookboo println!("\tHome: {}", home); println!("\tShell: {}", shell); - dir!(home.trim_matches('/')); - + create_dir_relative(home.trim_matches('/'))?; + let password = hash_password(&password)?; - + passwd.push_str(&format!("{};{};{};{};{};file:{};file:{}\n", username, password, uid, gid, name, home, shell)); } - - if ! passwd.is_empty() { - file!("etc/passwd", passwd.as_bytes(), false); + + if !passwd.is_empty() { + create_file_relative("etc/passwd", passwd.as_bytes(), false)?; } Ok(())