From d32f2dc10ee6a782b2dd5c9c8f045db91f0b5de5 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 24 Oct 2016 13:12:58 -0600 Subject: [PATCH] Correctly use salt --- Cargo.toml | 4 ++++ src/bin/getty.rs | 4 +--- src/bin/login.rs | 4 +--- src/bin/passwd.rs | 10 ++++++++++ src/bin/su.rs | 6 ++---- src/bin/sudo.rs | 4 ++-- src/lib.rs | 23 ++++++++++++++--------- 7 files changed, 34 insertions(+), 21 deletions(-) create mode 100644 src/bin/passwd.rs diff --git a/Cargo.toml b/Cargo.toml index 62867eb325..74eb187f24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,10 @@ path = "src/bin/id.rs" name = "login" path = "src/bin/login.rs" +[[bin]] +name = "passwd" +path = "src/bin/passwd.rs" + [[bin]] name = "su" path = "src/bin/su.rs" diff --git a/src/bin/getty.rs b/src/bin/getty.rs index 866c5e78fe..c8be30c075 100644 --- a/src/bin/getty.rs +++ b/src/bin/getty.rs @@ -17,8 +17,6 @@ pub fn main() { let _ = syscall::open(&tty, syscall::flag::O_RDWR); let _ = syscall::open(&tty, syscall::flag::O_RDWR); - env::set_current_dir("file:").unwrap(); - env::set_var("TTY", &tty); { let mut path = [0; 4096]; @@ -37,7 +35,7 @@ pub fn main() { loop { //stdout.write(b"\x1Bc").unwrap(); let _ = stdout.flush(); - match Command::new("file:bin/login").spawn() { + match Command::new("login").spawn() { Ok(mut child) => match child.wait() { Ok(_status) => (), //println!("getty: waited for login: {:?}", status.code()), Err(err) => panic!("getty: failed to wait for login: {}", err) diff --git a/src/bin/login.rs b/src/bin/login.rs index 202f2be30c..0dd585c09b 100644 --- a/src/bin/login.rs +++ b/src/bin/login.rs @@ -48,11 +48,9 @@ pub fn main() { stdout.write(b"\n").unwrap(); let _ = stdout.flush(); - let password_hash = Passwd::encode(&password); - for line in passwd_string.lines() { if let Ok(passwd) = Passwd::parse(line) { - if user == passwd.user && password_hash == passwd.hash { + if user == passwd.user && passwd.verify(&password) { passwd_option = Some(passwd); break; } diff --git a/src/bin/passwd.rs b/src/bin/passwd.rs new file mode 100644 index 0000000000..ebc472de1e --- /dev/null +++ b/src/bin/passwd.rs @@ -0,0 +1,10 @@ +extern crate termion; +extern crate userutils; + +use std::env; + +fn main() { + let passwd = env::args().nth(1).unwrap(); + let salt = env::args().nth(2).unwrap(); + println!("{}", userutils::Passwd::encode(&passwd, &salt)); +} diff --git a/src/bin/su.rs b/src/bin/su.rs index 0f76db9e42..87a540f3b1 100644 --- a/src/bin/su.rs +++ b/src/bin/su.rs @@ -26,7 +26,7 @@ pub fn main() { let uid = syscall::getuid().unwrap(); let mut passwd_string = String::new(); - File::open("file:etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap(); + File::open("/etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap(); let mut passwd_option = None; for line in passwd_string.lines() { @@ -46,11 +46,9 @@ pub fn main() { stdout.write(b"\n").unwrap(); let _ = stdout.flush(); - let password_hash = Passwd::encode(&password); - for line in passwd_string.lines() { if let Ok(passwd) = Passwd::parse(line) { - if user == passwd.user && password_hash == passwd.hash { + if user == passwd.user && passwd.verify(&password) { passwd_option = Some(passwd); break; } diff --git a/src/bin/sudo.rs b/src/bin/sudo.rs index 60a134bcb2..471a574b5e 100644 --- a/src/bin/sudo.rs +++ b/src/bin/sudo.rs @@ -17,7 +17,7 @@ pub fn main() { if uid != 0 { let mut passwd_string = String::new(); - File::open("file:etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap(); + File::open("/etc/passwd").unwrap().read_to_string(&mut passwd_string).unwrap(); let mut passwd_option = None; for line in passwd_string.lines() { @@ -32,7 +32,7 @@ pub fn main() { let passwd = passwd_option.expect("sudo: user not found in passwd"); let mut group_string = String::new(); - File::open("file:etc/group").unwrap().read_to_string(&mut group_string).unwrap(); + File::open("/etc/group").unwrap().read_to_string(&mut group_string).unwrap(); let mut group_option = None; for line in group_string.lines() { diff --git a/src/lib.rs b/src/lib.rs index c59780b7f2..f4c40f7009 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,8 @@ extern crate argon2rs; +use argon2rs::verifier::Encoded; +use argon2rs::{Argon2, Variant}; + pub struct Passwd<'a> { pub user: &'a str, pub hash: &'a str, @@ -11,15 +14,6 @@ pub struct Passwd<'a> { } impl<'a> Passwd<'a> { - //TODO: SALT - pub fn encode(password: &str) -> String { - let mut encoded = String::new(); - for b in argon2rs::argon2i_simple(password, "saltsalt").iter() { - encoded.push_str(&format!("{:X}", b)); - } - encoded - } - pub fn parse(line: &'a str) -> Result, ()> { let mut parts = line.split(';'); @@ -41,6 +35,17 @@ impl<'a> Passwd<'a> { shell: shell }) } + + pub fn encode(password: &str, salt: &str) -> String { + let a2 = Argon2::new(10, 1, 4096, Variant::Argon2i).unwrap(); + let e = Encoded::new(a2, password.as_bytes(), salt.as_bytes(), &[], &[]); + String::from_utf8(e.to_u8()).unwrap() + } + + pub fn verify(&self, password: &str) -> bool { + let e = Encoded::from_u8(self.hash.as_bytes()).unwrap(); + e.verify(password.as_bytes()) + } } pub struct Group<'a> {