diff --git a/src/passwd.rs b/src/passwd.rs index 0285894..d55e2da 100644 --- a/src/passwd.rs +++ b/src/passwd.rs @@ -23,7 +23,7 @@ use std::fmt::{self, Display}; #[derive(Debug, PartialEq, Eq)] pub struct Username<'a> { /// The username value - username: &'a str, + pub(crate) username: &'a str, } impl Display for Username<'_> { @@ -54,17 +54,32 @@ impl<'a> TryFrom<&'a str> for Username<'a> { } #[derive(Debug, PartialEq, Eq)] -pub struct Password<'a> { - password: &'a str, +pub enum Password<'a> { + Encrypted(EncryptedPassword<'a>), + Shadow(crate::shadow::Shadow<'a>), } impl Display for Password<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Password::Encrypted(EncryptedPassword { password }) => write!(f, "{}", password,), + Password::Shadow(_) => write!(f, "x"), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct EncryptedPassword<'a> { + pub(crate) password: &'a str, +} + +impl Display for EncryptedPassword<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.password,) } } -impl<'a> TryFrom<&'a str> for Password<'a> { +impl<'a> TryFrom<&'a str> for EncryptedPassword<'a> { type Error = UserLibError; fn try_from(source: &'a str) -> std::result::Result { if source == "x" { @@ -343,7 +358,9 @@ impl<'a> Passwd<'a> { if elements.len() == 7 { Ok(Passwd { username: Username::try_from(*elements.get(0).unwrap())?, - password: Password::try_from(*elements.get(1).unwrap())?, + password: Password::Encrypted(EncryptedPassword::try_from( + *elements.get(1).unwrap(), + )?), uid: Uid::try_from(*elements.get(2).unwrap())?, gid: Gid::try_from(*elements.get(3).unwrap())?, gecos: Gecos::try_from(*elements.get(4).unwrap())?, @@ -360,7 +377,10 @@ impl<'a> Passwd<'a> { } #[must_use] pub const fn get_password(&self) -> &'a str { - self.password.password + match self.password { + Password::Encrypted(EncryptedPassword { password }) => password, + Password::Shadow(crate::shadow::Shadow { ref password, .. }) => password.password, + } } #[must_use] pub const fn get_uid(&self) -> u32 { @@ -390,9 +410,9 @@ impl Default for Passwd<'_> { username: Username { username: "defaultuser", }, - password: Password { + password: Password::Encrypted(EncryptedPassword { password: "notencrypted", - }, + }), uid: Uid { uid: 1001 }, gid: Gid { gid: 1001 }, gecos: Gecos::Simple { diff --git a/src/shadow.rs b/src/shadow.rs index 97b5975..329666b 100644 --- a/src/shadow.rs +++ b/src/shadow.rs @@ -18,15 +18,26 @@ use std::fmt::{self, Debug, Display}; /// A record(line) in the user database `/etc/shadow` found in most linux systems. #[derive(Debug, PartialEq, Eq)] pub struct Shadow<'a> { - username: passwd::Username<'a>, /* Username. */ - password: passwd::Password<'a>, /* Hashed passphrase */ - last_change: Option, /* User ID. */ - earliest_change: Option, /* Group ID. */ - latest_change: Option, /* Real name. */ - warn_period: Option, /* Home directory. */ - deactivated: Option, /* Shell program. */ - deactivated_since: Option, /* Shell program. */ - extensions: Option, /* Shell program. */ + username: passwd::Username<'a>, /* Username. */ + pub(crate) password: passwd::EncryptedPassword<'a>, /* Hashed passphrase */ + last_change: Option, /* User ID. */ + earliest_change: Option, /* Group ID. */ + latest_change: Option, /* Real name. */ + warn_period: Option, /* Home directory. */ + deactivated: Option, /* Shell program. */ + deactivated_since: Option, /* Shell program. */ + extensions: Option, /* Shell program. */ +} + +impl<'a> Shadow<'a> { + #[must_use] + pub const fn get_username(&self) -> &'a str { + self.username.username + } + #[must_use] + pub const fn get_password(&self) -> &'a str { + self.password.password + } } impl<'a> Display for Shadow<'a> { @@ -72,10 +83,10 @@ impl<'a> Shadow<'a> { /// /// # Example /// ``` - /// let pwd = adduser::shadow::Shadow::new_from_string( + /// let shad = adduser::shadow::Shadow::new_from_string( /// "test:!!$6$/RotIe4VZzzAun4W$7YUONvru1rDnllN5TvrnOMsWUD5wSDUPAD6t6/Xwsr/0QOuWF3HcfAhypRkGa8G1B9qqWV5kZSnCb8GKMN9N61:18260:0:99999:7:::" /// ).unwrap(); - /// + /// assert_eq!(shad.get_username(), "test"); /// ``` /// /// # Errors @@ -87,7 +98,7 @@ impl<'a> Shadow<'a> { let extra = elements.get(8).unwrap(); Ok(Shadow { username: passwd::Username::try_from(*elements.get(0).unwrap())?, - password: passwd::Password::try_from(*elements.get(1).unwrap())?, + password: passwd::EncryptedPassword::try_from(*elements.get(1).unwrap())?, last_change: date_since_epoch(elements.get(2).unwrap()), earliest_change: date_since_epoch(elements.get(3).unwrap()), latest_change: date_since_epoch(elements.get(4).unwrap()),