diff options
author | 2016-12-28 15:55:54 -0400 | |
---|---|---|
committer | 2016-12-28 16:07:49 -0400 | |
commit | 357cbaff0221bc2371ebe357dbe2c57a373c11e1 (patch) | |
tree | a8c5a5860f48dd990404ca9ff937addf283247c1 | |
parent | 248a08d0b05d99b47f8a8f51ff4bde59d70c9c20 (diff) |
improve description of password prompting
Since the user does not know whether it will run su or sudo, indicate
whether the password prompt will be for root or the user's password,
when possible.
I assume that programs like gksu that can prompt for either depending on
system setup will make clear in their prompt what they're asking for.
-rw-r--r-- | Command/EnableTor.hs | 6 | ||||
-rw-r--r-- | Utility/Su.hs | 66 |
2 files changed, 57 insertions, 15 deletions
diff --git a/Command/EnableTor.hs b/Command/EnableTor.hs index 6f145413d..27e57d649 100644 --- a/Command/EnableTor.hs +++ b/Command/EnableTor.hs @@ -49,10 +49,12 @@ start os = do Just userid -> go uuid userid else do showStart "enable-tor" "" - showLongNote "Need root access to enable tor..." gitannex <- liftIO readProgramFile let ps = [Param (cmdname cmd), Param (show curruserid)] - ifM (liftIO $ runAsRoot gitannex ps) + sucommand <- liftIO $ mkSuCommand gitannex ps + maybe noop showLongNote + (describePasswordPrompt' sucommand) + ifM (liftIO $ runSuCommand sucommand) ( next $ next checkHiddenService , giveup $ unwords $ [ "Failed to run as root:" , gitannex ] ++ toCommand ps diff --git a/Utility/Su.hs b/Utility/Su.hs index 44a95c39f..b8df07dd3 100644 --- a/Utility/Su.hs +++ b/Utility/Su.hs @@ -12,18 +12,51 @@ import Utility.Env import System.Posix.Terminal --- Runs a command as root, fairly portably. +data WhosePassword + = RootPassword + | UserPassword + | SomePassword + -- ^ may be user or root; su program should indicate which + deriving (Show) + +data PasswordPrompt + = WillPromptPassword WhosePassword + | MayPromptPassword WhosePassword + | NoPromptPassword + deriving (Show) + +describePasswordPrompt :: PasswordPrompt -> Maybe String +describePasswordPrompt (WillPromptPassword whose) = Just $ + "You will be prompted for " ++ describeWhosePassword whose ++ " password" +describePasswordPrompt (MayPromptPassword whose) = Just $ + "You may be prompted for " ++ describeWhosePassword whose ++ " password" +describePasswordPrompt NoPromptPassword = Nothing + +describeWhosePassword :: WhosePassword -> String +describeWhosePassword RootPassword = "root's" +describeWhosePassword UserPassword = "your" +describeWhosePassword SomePassword = "a" + +data SuCommand = SuCommand PasswordPrompt String [CommandParam] + deriving (Show) + +describePasswordPrompt' :: Maybe SuCommand -> Maybe String +describePasswordPrompt' (Just (SuCommand p _ _)) = describePasswordPrompt p +describePasswordPrompt' Nothing = Nothing + +runSuCommand :: (Maybe SuCommand) -> IO Bool +runSuCommand (Just (SuCommand _ cmd ps)) = boolSystem cmd ps +runSuCommand Nothing = return False + +-- Generates a SuCommand that runs a command as root, fairly portably. -- -- Does not use sudo commands if something else is available, because -- the user may not be in sudoers and we couldn't differentiate between -- that and the command failing. Although, some commands like gksu -- decide based on the system's configuration whether sudo should be used. -runAsRoot :: String -> [CommandParam] -> IO Bool -runAsRoot cmd ps = go =<< firstM (inPath . fst) =<< selectcmds +mkSuCommand :: String -> [CommandParam] -> IO (Maybe SuCommand) +mkSuCommand cmd ps = firstM (\(SuCommand _ p _) -> inPath p) =<< selectcmds where - go Nothing = return False - go (Just (cmd', ps')) = boolSystem cmd' ps' - selectcmds = ifM (inx <||> (not <$> atconsole)) ( return (graphicalcmds ++ consolecmds) , return consolecmds @@ -34,20 +67,27 @@ runAsRoot cmd ps = go =<< firstM (inPath . fst) =<< selectcmds -- These will only work when the user is logged into a desktop. graphicalcmds = - [ ("gksu", [Param shellcmd]) - , ("kdesu", [Param shellcmd]) + [ SuCommand (MayPromptPassword SomePassword) "gksu" + [Param shellcmd] + , SuCommand (MayPromptPassword SomePassword) "kdesu" + [Param shellcmd] -- Available in Debian's menu package; knows about lots of -- ways to gain root. - , ("su-to-root", [Param "-X", Param "-c", Param shellcmd]) + , SuCommand (MayPromptPassword SomePassword) "su-to-root" + [Param "-X", Param "-c", Param shellcmd] -- OSX native way to run a command as root, prompts in GUI - , ("osascript", [Param "-e", Param ("do shell script \"" ++ shellcmd ++ "\" with administrator privileges")]) + , SuCommand (WillPromptPassword RootPassword) "osascript" + [Param "-e", Param ("do shell script \"" ++ shellcmd ++ "\" with administrator privileges")] ] -- These will only work when run in a console. consolecmds = - [ ("su", [Param "-c", Param shellcmd]) - , ("sudo", [Param cmd] ++ ps) - , ("su-to-root", [Param "-c", Param shellcmd]) + [ SuCommand (WillPromptPassword RootPassword) "su" + [Param "-c", Param shellcmd] + , SuCommand (MayPromptPassword UserPassword) "sudo" + ([Param cmd] ++ ps) + , SuCommand (MayPromptPassword SomePassword) "su-to-root" + [Param "-c", Param shellcmd] ] shellcmd = unwords $ map shellEscape (cmd:toCommand ps) |