From 588494cbce5ded85e84ec3ccc079f2cf4775afc6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 26 Sep 2013 16:09:45 -0400 Subject: [PATCH] webapp: Support storing encrypted git repositories on rsync.net. Does not yet support re-enabling such a repository though. This commit was sponsored by Jan Pieper. --- Assistant/Gpg.hs | 36 ++++++++++++ Assistant/MakeRemote.hs | 41 +++++++++---- Assistant/WebApp/Configurators/AWS.hs | 1 + Assistant/WebApp/Configurators/IA.hs | 1 + Assistant/WebApp/Configurators/Local.hs | 16 ++--- Assistant/WebApp/Configurators/Ssh.hs | 55 ++++++++++++++---- Assistant/WebApp/Configurators/WebDAV.hs | 1 + Assistant/WebApp/Form.hs | 11 +--- Assistant/WebApp/Gpg.hs | 27 ++++----- Assistant/WebApp/routes | 2 + debian/changelog | 1 + doc/assistant/rsync.net.encryption.png | Bin 0 -> 40504 bytes .../add.hamlet} | 8 +-- .../configurators/rsync.net/encrypt.hamlet | 43 ++++++++++++++ 14 files changed, 177 insertions(+), 66 deletions(-) create mode 100644 Assistant/Gpg.hs create mode 100644 doc/assistant/rsync.net.encryption.png rename templates/configurators/{addrsync.net.hamlet => rsync.net/add.hamlet} (82%) create mode 100644 templates/configurators/rsync.net/encrypt.hamlet diff --git a/Assistant/Gpg.hs b/Assistant/Gpg.hs new file mode 100644 index 0000000000..a55a0cab73 --- /dev/null +++ b/Assistant/Gpg.hs @@ -0,0 +1,36 @@ +{- git-annex assistant gpg stuff + - + - Copyright 2013 Joey Hess + - + - Licensed under the GNU AGPL version 3 or higher. + -} + +{-# LANGUAGE QuasiQuotes, TemplateHaskell, OverloadedStrings #-} + +module Assistant.Gpg where + +import Utility.Gpg +import Utility.UserInfo +import Types.Remote (RemoteConfigKey) + +import qualified Data.Map as M + +{- Generates a gpg user id that is not used by any existing secret key -} +newUserId :: IO UserId +newUserId = do + oldkeys <- secretKeys + username <- myUserName + let basekeyname = username ++ "'s git-annex encryption key" + return $ Prelude.head $ filter (\n -> M.null $ M.filter (== n) oldkeys) + ( basekeyname + : map (\n -> basekeyname ++ show n) ([2..] :: [Int]) + ) + +data EnableEncryption = HybridEncryption | SharedEncryption | NoEncryption + deriving (Eq) + +{- Generates Remote configuration for encryption. -} +configureEncryption :: EnableEncryption -> (RemoteConfigKey, String) +configureEncryption SharedEncryption = ("encryption", "shared") +configureEncryption NoEncryption = ("encryption", "none") +configureEncryption HybridEncryption = ("encryption", "hybrid") diff --git a/Assistant/MakeRemote.hs b/Assistant/MakeRemote.hs index 4b0a4c7d9f..8a93e359bd 100644 --- a/Assistant/MakeRemote.hs +++ b/Assistant/MakeRemote.hs @@ -14,6 +14,7 @@ import qualified Types.Remote as R import qualified Remote import Remote.List import qualified Remote.Rsync as Rsync +import qualified Remote.GCrypt as GCrypt import qualified Git import qualified Git.Command import qualified Command.InitRemote @@ -23,6 +24,8 @@ import Git.Remote import Config import Config.Cost import Creds +import Assistant.Gpg +import Utility.Gpg (KeyId) import qualified Data.Text as T import qualified Data.Map as M @@ -31,7 +34,8 @@ import qualified Data.Map as M makeSshRemote :: Bool -> SshData -> Maybe Cost -> Assistant Remote makeSshRemote forcersync sshdata mcost = do r <- liftAnnex $ - addRemote $ maker (sshRepoName sshdata) sshurl + addRemote $ maker (sshRepoName sshdata) + (sshUrl forcersync sshdata) liftAnnex $ maybe noop (setRemoteCost r) mcost syncRemote r return r @@ -40,17 +44,20 @@ makeSshRemote forcersync sshdata mcost = do maker | rsync = makeRsyncRemote | otherwise = makeGitRemote - sshurl = T.unpack $ T.concat $ - if rsync - then [u, h, T.pack ":", sshDirectory sshdata, T.pack "/"] - else [T.pack "ssh://", u, h, d, T.pack "/"] - where - u = maybe (T.pack "") (\v -> T.concat [v, T.pack "@"]) $ sshUserName sshdata - h = sshHostName sshdata - d - | T.pack "/" `T.isPrefixOf` sshDirectory sshdata = sshDirectory sshdata - | T.pack "~/" `T.isPrefixOf` sshDirectory sshdata = T.concat [T.pack "/", sshDirectory sshdata] - | otherwise = T.concat [T.pack "/~/", sshDirectory sshdata] + +{- Generates a ssh or rsync url from a SshData. -} +sshUrl :: Bool -> SshData -> String +sshUrl forcersync sshdata = T.unpack $ T.concat $ + if (forcersync || rsyncOnly sshdata) + then [u, h, T.pack ":", sshDirectory sshdata, T.pack "/"] + else [T.pack "ssh://", u, h, d, T.pack "/"] + where + u = maybe (T.pack "") (\v -> T.concat [v, T.pack "@"]) $ sshUserName sshdata + h = sshHostName sshdata + d + | T.pack "/" `T.isPrefixOf` sshDirectory sshdata = sshDirectory sshdata + | T.pack "~/" `T.isPrefixOf` sshDirectory sshdata = T.concat [T.pack "/", sshDirectory sshdata] + | otherwise = T.concat [T.pack "/~/", sshDirectory sshdata] {- Runs an action that returns a name of the remote, and finishes adding it. -} addRemote :: Annex RemoteName -> Annex Remote @@ -74,6 +81,16 @@ makeRsyncRemote name location = makeRemote name location $ const $ void $ , ("type", "rsync") ] +{- Inits a gcrypt special remote, and returns its name. -} +makeGCryptRemote :: RemoteName -> String -> KeyId -> Annex RemoteName +makeGCryptRemote remotename location keyid = + initSpecialRemote remotename GCrypt.remote $ M.fromList + [ ("type", "gcrypt") + , ("gitrepo", location) + , configureEncryption HybridEncryption + , ("keyid", keyid) + ] + type SpecialRemoteMaker = RemoteName -> RemoteType -> R.RemoteConfig -> Annex RemoteName {- Inits a new special remote. The name is used as a suggestion, but diff --git a/Assistant/WebApp/Configurators/AWS.hs b/Assistant/WebApp/Configurators/AWS.hs index bf39419527..de59240b45 100644 --- a/Assistant/WebApp/Configurators/AWS.hs +++ b/Assistant/WebApp/Configurators/AWS.hs @@ -24,6 +24,7 @@ import Types.Remote (RemoteConfig) import Types.StandardGroups import Logs.PreferredContent import Creds +import Assistant.Gpg import qualified Data.Text as T import qualified Data.Map as M diff --git a/Assistant/WebApp/Configurators/IA.hs b/Assistant/WebApp/Configurators/IA.hs index d0d60e25ae..a3120e01a1 100644 --- a/Assistant/WebApp/Configurators/IA.hs +++ b/Assistant/WebApp/Configurators/IA.hs @@ -24,6 +24,7 @@ import Logs.PreferredContent import Logs.Remote import qualified Utility.Url as Url import Creds +import Assistant.Gpg import qualified Data.Text as T import qualified Data.Map as M diff --git a/Assistant/WebApp/Configurators/Local.hs b/Assistant/WebApp/Configurators/Local.hs index 413f1242d8..316e64bb4f 100644 --- a/Assistant/WebApp/Configurators/Local.hs +++ b/Assistant/WebApp/Configurators/Local.hs @@ -276,17 +276,14 @@ getConfirmAddDriveR drive = ifM (liftIO $ probeRepoExists dir) setupDriveModal :: Widget setupDriveModal = $(widgetFile "configurators/adddrive/setupmodal") -genKeyModal :: Widget -genKeyModal = $(widgetFile "configurators/genkeymodal") - getGenKeyForDriveR :: RemovableDrive -> Handler Html -getGenKeyForDriveR drive = withNewSecretKey $ \key -> do +getGenKeyForDriveR drive = withNewSecretKey $ \keyid -> do {- Generating a key takes a long time, and - the removable drive may have been disconnected - in the meantime. Check that it is still mounted - before finishing. -} ifM (liftIO $ any (\d -> mountPoint d == mountPoint drive) <$> driveList) - ( getFinishAddDriveR drive (RepoKey key) + ( getFinishAddDriveR drive (RepoKey keyid) , getAddDriveR ) @@ -295,13 +292,8 @@ getFinishAddDriveR drive = go where {- Set up new gcrypt special remote. -} go (RepoKey keyid) = whenGcryptInstalled $ makewith $ const $ do - r <- liftAnnex $ addRemote $ - initSpecialRemote remotename GCrypt.remote $ M.fromList - [ ("type", "gcrypt") - , ("gitrepo", dir) - , configureEncryption HybridEncryption - , ("keyid", keyid) - ] + r <- liftAnnex $ addRemote $ + makeGCryptRemote remotename dir keyid return (Types.Remote.uuid r, r) go NoRepoKey = do pr <- liftAnnex $ inRepo $ Git.GCrypt.probeRepo dir diff --git a/Assistant/WebApp/Configurators/Ssh.hs b/Assistant/WebApp/Configurators/Ssh.hs index 945e2b55c6..1587d0c4cb 100644 --- a/Assistant/WebApp/Configurators/Ssh.hs +++ b/Assistant/WebApp/Configurators/Ssh.hs @@ -11,6 +11,7 @@ module Assistant.WebApp.Configurators.Ssh where import Assistant.WebApp.Common +import Assistant.WebApp.Gpg import Assistant.Ssh import Assistant.MakeRemote import Utility.Rsync (rsyncUrlIsShell) @@ -19,10 +20,13 @@ import Remote import Logs.PreferredContent import Types.StandardGroups import Utility.UserInfo +import Utility.Gpg +import Assistant.Sync import qualified Data.Text as T import qualified Data.Map as M import Network.Socket +import Data.Ord sshConfigurator :: Widget -> Handler Html sshConfigurator = page "Add a remote server" (Just Configuration) @@ -147,7 +151,7 @@ postEnableRsyncR u = do case result of FormSuccess sshinput' | isRsyncNet (inputHostname sshinput') -> - void $ liftH $ makeRsyncNet sshinput' reponame (const noop) + void $ liftH $ enableRsyncNet sshinput' reponame (const noop) | otherwise -> do s <- liftIO $ testServer sshinput' case s of @@ -320,19 +324,17 @@ postAddRsyncNetR = do ((result, form), enctype) <- runFormPost $ renderBootstrap $ sshInputAForm hostnamefield $ SshInput Nothing Nothing Nothing 22 - let showform status = page "Add a Rsync.net repository" (Just Configuration) $ - $(widgetFile "configurators/addrsync.net") + let showform status = inpage $ + $(widgetFile "configurators/rsync.net/add") case result of FormSuccess sshinput - | isRsyncNet (inputHostname sshinput) -> do - let reponame = genSshRepoName "rsync.net" - (maybe "" T.unpack $ inputDirectory sshinput) - makeRsyncNet sshinput reponame setupGroup + | isRsyncNet (inputHostname sshinput) -> prep sshinput | otherwise -> showform $ UnusableServer "That is not a rsync.net host name." _ -> showform UntestedServer where + inpage = page "Add a Rsync.net repository" (Just Configuration) hostnamefield = textField `withExpandableNote` ("Help", help) help = [whamlet|
@@ -342,9 +344,41 @@ postAddRsyncNetR = do The host name will be something like "usw-s001.rsync.net", and the # user name something like "7491" |] + prep sshinput = do + let reponame = genSshRepoName "rsync.net" + (maybe "" T.unpack $ inputDirectory sshinput) + prepRsyncNet sshinput reponame $ \sshdata -> inpage $ do + secretkeys <- sortBy (comparing snd) . M.toList + <$> liftIO secretKeys + $(widgetFile "configurators/rsync.net/encrypt") -makeRsyncNet :: SshInput -> String -> (Remote -> Handler ()) -> Handler Html -makeRsyncNet sshinput reponame setup = do +getMakeRsyncNetSharedR :: SshData -> Handler Html +getMakeRsyncNetSharedR sshdata = makeSshRepo True setupGroup sshdata + +{- Make a gcrypt special remote on rsync.net. -} +getMakeRsyncNetGCryptR :: SshData -> RepoKey -> Handler Html +getMakeRsyncNetGCryptR sshdata NoRepoKey = withNewSecretKey $ \keyid -> + getMakeRsyncNetGCryptR sshdata (RepoKey keyid) +getMakeRsyncNetGCryptR sshdata (RepoKey keyid) = do + sshSetup [sshhost, gitinit] [] $ do + r <- liftAnnex $ addRemote $ + makeGCryptRemote (sshRepoName sshdata) (sshUrl True sshdata) keyid + setupGroup r + liftAssistant $ syncRemote r + redirect $ EditNewCloudRepositoryR $ Remote.uuid r + where + sshhost = genSshHost (sshHostName sshdata) (sshUserName sshdata) + gitinit = "git init --bare " ++ T.unpack (sshDirectory sshdata) + +enableRsyncNet :: SshInput -> String -> (Remote -> Handler ()) -> Handler Html +enableRsyncNet sshinput reponame setup = + prepRsyncNet sshinput reponame $ \sshdata -> + makeSshRepo True setup sshdata + +{- Prepares rsync.net ssh key, and if successful, runs an action with + - its SshData. -} +prepRsyncNet :: SshInput -> String -> (SshData -> Handler Html) -> Handler Html +prepRsyncNet sshinput reponame a = do knownhost <- liftIO $ maybe (return False) knownHost (inputHostname sshinput) keypair <- liftIO $ genSshKeyPair sshdata <- liftIO $ setupSshKeyPair keypair $ @@ -371,8 +405,7 @@ makeRsyncNet sshinput reponame setup = do , genSshHost (sshHostName sshdata) (sshUserName sshdata) , remotecommand ] - sshSetup sshopts (sshPubKey keypair) $ - makeSshRepo True setup sshdata + sshSetup sshopts (sshPubKey keypair) $ a sshdata isRsyncNet :: Maybe Text -> Bool isRsyncNet Nothing = False diff --git a/Assistant/WebApp/Configurators/WebDAV.hs b/Assistant/WebApp/Configurators/WebDAV.hs index 027abdf78d..cf367bb315 100644 --- a/Assistant/WebApp/Configurators/WebDAV.hs +++ b/Assistant/WebApp/Configurators/WebDAV.hs @@ -20,6 +20,7 @@ import Types.Remote (RemoteConfig) import Types.StandardGroups import Logs.PreferredContent import Logs.Remote +import Assistant.Gpg import qualified Data.Map as M #endif diff --git a/Assistant/WebApp/Form.hs b/Assistant/WebApp/Form.hs index 31f7339f22..3446e4fdee 100644 --- a/Assistant/WebApp/Form.hs +++ b/Assistant/WebApp/Form.hs @@ -12,8 +12,8 @@ module Assistant.WebApp.Form where -import Types.Remote (RemoteConfigKey) import Assistant.WebApp.Types +import Assistant.Gpg import Yesod hiding (textField, passwordField) import Yesod.Form.Fields as F @@ -75,9 +75,6 @@ withExpandableNote field (toggle, note) = withNote field $ [whamlet| where ident = "toggle_" ++ toggle -data EnableEncryption = HybridEncryption | SharedEncryption | NoEncryption - deriving (Eq) - {- Adds a check box to an AForm to control encryption. -} #if MIN_VERSION_yesod(1,2,0) enableEncryptionField :: (RenderMessage site FormMessage) => AForm (HandlerT site IO) EnableEncryption @@ -91,9 +88,3 @@ enableEncryptionField = areq (selectFieldList choices) "Encryption" (Just Shared [ ("Encrypt all data", SharedEncryption) , ("Disable encryption", NoEncryption) ] - -{- Generates Remote configuration for encryption. -} -configureEncryption :: EnableEncryption -> (RemoteConfigKey, String) -configureEncryption SharedEncryption = ("encryption", "shared") -configureEncryption NoEncryption = ("encryption", "none") -configureEncryption HybridEncryption = ("encryption", "hybrid") diff --git a/Assistant/WebApp/Gpg.hs b/Assistant/WebApp/Gpg.hs index b64bfee6b9..cc733fdebc 100644 --- a/Assistant/WebApp/Gpg.hs +++ b/Assistant/WebApp/Gpg.hs @@ -10,8 +10,8 @@ module Assistant.WebApp.Gpg where import Assistant.WebApp.Common +import Assistant.Gpg import Utility.Gpg -import Utility.UserInfo import qualified Git.Command import qualified Git.Remote import qualified Annex.Branch @@ -31,16 +31,15 @@ gpgKeyDisplay keyid userid = [whamlet| key id #{keyid} |] -{- Generates a gpg user id that is not used by any existing secret key -} -newUserId :: IO UserId -newUserId = do - oldkeys <- secretKeys - username <- myUserName - let basekeyname = username ++ "'s git-annex encryption key" - return $ Prelude.head $ filter (\n -> M.null $ M.filter (== n) oldkeys) - ( basekeyname - : map (\n -> basekeyname ++ show n) ([2..] :: [Int]) - ) +genKeyModal :: Widget +genKeyModal = $(widgetFile "configurators/genkeymodal") + +whenGcryptInstalled :: Handler Html -> Handler Html +whenGcryptInstalled a = ifM (liftIO $ inPath "git-remote-gcrypt") + ( a + , page "Need git-remote-gcrypt" (Just Configuration) $ + $(widgetFile "configurators/needgcrypt") + ) withNewSecretKey :: (KeyId -> Handler Html) -> Handler Html withNewSecretKey use = do @@ -73,9 +72,3 @@ getGCryptRemoteName u repoloc = do void $ inRepo $ Git.Remote.remove tmpremote return mname -whenGcryptInstalled :: Handler Html -> Handler Html -whenGcryptInstalled a = ifM (liftIO $ inPath "git-remote-gcrypt") - ( a - , page "Need git-remote-gcrypt" (Just Configuration) $ - $(widgetFile "configurators/needgcrypt") - ) diff --git a/Assistant/WebApp/routes b/Assistant/WebApp/routes index 0b78e4f623..cab76ab6cc 100644 --- a/Assistant/WebApp/routes +++ b/Assistant/WebApp/routes @@ -45,6 +45,8 @@ /config/repository/add/ssh/make/git/#SshData MakeSshGitR GET /config/repository/add/ssh/make/rsync/#SshData MakeSshRsyncR GET /config/repository/add/cloud/rsync.net AddRsyncNetR GET POST +/config/repository/add/cloud/rsync.net/shared/#SshData MakeRsyncNetSharedR GET +/config/repository/add/cloud/rsync.net/gcrypt/#SshData/#RepoKey MakeRsyncNetGCryptR GET /config/repository/add/cloud/S3 AddS3R GET POST /config/repository/add/cloud/IA AddIAR GET POST /config/repository/add/cloud/glacier AddGlacierR GET POST diff --git a/debian/changelog b/debian/changelog index 5588923c26..7c05434e48 100644 --- a/debian/changelog +++ b/debian/changelog @@ -17,6 +17,7 @@ git-annex (4.20130921) UNRELEASED; urgency=low the user running the conversion. * add, import, assistant: Better preserve the mtime of symlinks, when when adding content that gets deduplicated. + * webapp: Support storing encrypted git repositories on rsync.net. -- Joey Hess Sun, 22 Sep 2013 19:42:29 -0400 diff --git a/doc/assistant/rsync.net.encryption.png b/doc/assistant/rsync.net.encryption.png new file mode 100644 index 0000000000000000000000000000000000000000..ec751d10d253ecd1a8abfb70afc79220844d96bc GIT binary patch literal 40504 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Í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 bUj$~7EPQmMqs(3qaGbWVJyCM}%Kd)=yn_n{ literal 0 HcmV?d00001 diff --git a/templates/configurators/addrsync.net.hamlet b/templates/configurators/rsync.net/add.hamlet similarity index 82% rename from templates/configurators/addrsync.net.hamlet rename to templates/configurators/rsync.net/add.hamlet index d190441179..5a3459187e 100644 --- a/templates/configurators/addrsync.net.hamlet +++ b/templates/configurators/rsync.net/add.hamlet @@ -27,14 +27,14 @@ ^{form} ^{webAppFormAuthToken}
-