diff --git a/Propellor.hs b/Propellor.hs index 71f552d..2b7f978 100644 --- a/Propellor.hs +++ b/Propellor.hs @@ -19,8 +19,6 @@ getProperties :: HostName -> [Property] getProperties hostname@"clam.kitenet.net" = [ cleanCloudAtCost hostname , standardSystem Apt.Unstable - , User.hasPassword "root" - , User.hasPassword "joey" -- Clam is a tor bridge. , Tor.isBridge , Apt.installed ["docker.io"] @@ -44,19 +42,19 @@ standardSystem suite = propertyList "standard system" , Apt.installed ["etckeeper"] , Apt.installed ["ssh"] , GitHome.installedFor "root" + , User.hasSomePassword "root" -- Harden the system, but only once root's authorized_keys -- is safely in place. , check (Ssh.hasAuthorizedKeys "root") $ Ssh.passwordAuthentication False - , check (Ssh.hasAuthorizedKeys "root") $ - User.lockedPassword "root" - , Apt.installed ["vim"] , User.sshAccountFor "joey" , Apt.installed ["sudo"] -- nopasswd because no password is set up for joey. , "sudoer joey" ==> "/etc/sudoers" `File.containsLine` "joey ALL=(ALL:ALL) NOPASSWD:ALL" + , User.hasSomePassword "joey" , GitHome.installedFor "joey" + , Apt.installed ["vim", "screen"] -- I use postfix, or no MTA. , Apt.removed ["exim4"] `onChange` Apt.autoRemove ] diff --git a/Property/User.hs b/Property/User.hs index 661a6f8..6bdff2e 100644 --- a/Property/User.hs +++ b/Property/User.hs @@ -22,6 +22,12 @@ nuked user _ = check (isJust <$> homedir user) $ cmdProperty "userdel" ] `describe` ("nuked user " ++ user) +{- Only ensures that the user has some password set. It may or may + - not be the password from the PrivData. -} +hasSomePassword :: UserName -> Property +hasSomePassword user = check ((/= HasPassword) <$> getPasswordStatus user) $ + hasPassword user + hasPassword :: UserName -> Property hasPassword user = Property (user ++ " has password") $ withPrivData (Password user) $ \password -> makeChange $ @@ -37,11 +43,19 @@ lockedPassword user = check (not <$> isLockedPassword user) $ cmdProperty "passw ] `describe` ("locked " ++ user ++ " password") -isLockedPassword :: UserName -> IO Bool -isLockedPassword user = parse . words <$> readProcess "passwd" ["-S", user] +data PasswordStatus = NoPassword | LockedPassword | HasPassword + deriving (Eq) + +getPasswordStatus :: UserName -> IO PasswordStatus +getPasswordStatus user = parse . words <$> readProcess "passwd" ["-S", user] where - parse (_:"L":_) = True - parse _ = False + parse (_:"L":_) = LockedPassword + parse (_:"NP":_) = NoPassword + parse (_:"P":_) = HasPassword + parse _ = NoPassword + +isLockedPassword :: UserName -> IO Bool +isLockedPassword user = (== LockedPassword) <$> getPasswordStatus user homedir :: UserName -> IO (Maybe FilePath) homedir user = catchMaybeIO $ homeDirectory <$> getUserEntryForName user