deal with ssh key expiry

Not a perfect solution, but good enough, few users will wait 10 minutes in
the middle and see it expire, I hope.
This commit is contained in:
Joey Hess 2014-05-15 15:15:19 -04:00
parent f651cbd572
commit dc72ea4ab5
3 changed files with 41 additions and 13 deletions

View file

@ -26,6 +26,7 @@ import qualified Remote.GCrypt as GCrypt
import Annex.UUID import Annex.UUID
import Logs.UUID import Logs.UUID
import Assistant.RemoteControl import Assistant.RemoteControl
import Types.Creds
import Assistant.CredPairCache import Assistant.CredPairCache
import Config.Files import Config.Files
import Utility.Tmp import Utility.Tmp
@ -318,11 +319,22 @@ sshSetup :: SshInput -> [String] -> Maybe String -> Handler Html -> Handler Html
sshSetup sshinput opts input a = do sshSetup sshinput opts input a = do
(transcript, ok) <- liftAssistant $ sshAuthTranscript sshinput opts input (transcript, ok) <- liftAssistant $ sshAuthTranscript sshinput opts input
if ok if ok
then a then do
else showSshErr transcript liftAssistant $ expireCachedCred $ getLogin sshinput
a
else sshErr sshinput transcript
showSshErr :: String -> Handler Html sshErr :: SshInput -> String -> Handler Html
showSshErr msg = sshConfigurator $ sshErr sshinput msg
| inputAuthMethod sshinput == CachedPassword =
ifM (liftAssistant $ isNothing <$> getCachedCred (getLogin sshinput))
( sshConfigurator $
$(widgetFile "configurators/ssh/expiredpassword")
, showerr
)
| otherwise = showerr
where
showerr = sshConfigurator $
$(widgetFile "configurators/ssh/error") $(widgetFile "configurators/ssh/error")
{- Runs a ssh command, returning a transcript of its output. {- Runs a ssh command, returning a transcript of its output.
@ -345,7 +357,7 @@ sshAuthTranscript sshinput opts input = case inputAuthMethod sshinput of
cacheCred (login, geti inputPassword) (Seconds $ 60 * 10) cacheCred (login, geti inputPassword) (Seconds $ 60 * 10)
setupAskPass setupAskPass
where where
login = geti inputUsername ++ "@" ++ geti inputHostname login = getLogin sshinput
geti f = maybe "" T.unpack (f sshinput) geti f = maybe "" T.unpack (f sshinput)
go extraopts env = processTranscript' "ssh" (extraopts ++ opts) env $ go extraopts env = processTranscript' "ssh" (extraopts ++ opts) env $
@ -374,6 +386,11 @@ sshAuthTranscript sshinput opts input = case inputAuthMethod sshinput of
passwordprompts :: Int -> String passwordprompts :: Int -> String
passwordprompts = sshOpt "NumberOfPasswordPrompts" . show passwordprompts = sshOpt "NumberOfPasswordPrompts" . show
getLogin :: SshInput -> Login
getLogin sshinput = geti inputUsername ++ "@" ++ geti inputHostname
where
geti f = maybe "" T.unpack (f sshinput)
{- The UUID will be NoUUID when the repository does not already exist, {- The UUID will be NoUUID when the repository does not already exist,
- or was not a git-annex repository before. -} - or was not a git-annex repository before. -}
getConfirmSshR :: SshData -> UUID -> Handler Html getConfirmSshR :: SshData -> UUID -> Handler Html

View file

@ -21,8 +21,8 @@ can be pretty sure noone is sniffing the (localhost) connection.
cause the webapp to read the password and forward it on. Also, set cause the webapp to read the password and forward it on. Also, set
DISPLAY to ensure that ssh runs the program. **done** DISPLAY to ensure that ssh runs the program. **done**
Looking at ssh.exe, I think this will even work on windows; it contains the Looking at ssh.exe, I think this will even work on Windows; it contains the
code to run ssh-askpass. code to run ssh-askpass. (It does work on Windows!)
### securely handling the password ### securely handling the password
@ -31,7 +31,10 @@ code to run ssh-askpass.
is being accessed remotely, absolutely: require https. is being accessed remotely, absolutely: require https.
* Use hs-securemem to store password. * Use hs-securemem to store password.
* Avoid storing password for long. Erase it after webapp setup of remote * Avoid storing password for long. Erase it after webapp setup of remote
is complete. Time out after 10 minutes and erase it. is complete. Time out after 10 minutes and erase it. **done**
* If the user is slow, the cached ssh key can exire before they finish.
This results in ssh being given no password, and failing. The UI
now detects this and suggests the user retry. **done**
* Prompt using a html field name that does not trigger web browser password * Prompt using a html field name that does not trigger web browser password
saving if possible. saving if possible.
@ -58,7 +61,3 @@ if the shim cannot requst an arbitrary password prompt.
* test on OSX * test on OSX
* test on Android * test on Android
* If the user is slow, the cached ssh key can exire before they finish.
Currently this results in ssh being given no password, and failing.
Either avoid time-based expiry (manually expiring when done, and how
to detect if they gave up?) or notice this and give a sensible error.

View file

@ -0,0 +1,12 @@
<div .col-sm-9>
<div .content-box>
<h2>
<span .glyphicon .glyphicon-warning-sign>
\ Failed to make repository
<p>
The password you entered has expired. Suggest you go back, #
re-enter the password, and try again.
<p>
Transcript:
<pre>
#{msg}