summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Command/EnableTor.hs6
-rw-r--r--Utility/Su.hs66
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)