change s3 creds caching
Rather than store decrypted creds in the environment, store them in the creds cache file. This way, a single git-annex can have multiple S3 remotes using different creds.
This commit is contained in:
parent
e4bf74a965
commit
f18a53eec0
1 changed files with 42 additions and 33 deletions
75
Remote/S3.hs
75
Remote/S3.hs
|
@ -5,7 +5,7 @@
|
||||||
- Licensed under the GNU GPL version 3 or higher.
|
- Licensed under the GNU GPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module Remote.S3 (remote) where
|
module Remote.S3 (remote, s3SetCredsEnv) where
|
||||||
|
|
||||||
import Network.AWS.AWSConnection
|
import Network.AWS.AWSConnection
|
||||||
import Network.AWS.S3Object
|
import Network.AWS.S3Object
|
||||||
|
@ -274,42 +274,39 @@ s3Connection c u = do
|
||||||
[(p, _)] -> p
|
[(p, _)] -> p
|
||||||
_ -> error $ "bad S3 port value: " ++ s
|
_ -> error $ "bad S3 port value: " ++ s
|
||||||
|
|
||||||
{- S3 creds come from the environment if set.
|
{- S3 creds come from the environment if set, otherwise from the cache
|
||||||
- Otherwise, might be stored encrypted in the remote's config, or
|
- in gitAnnexCredsDir, or failing that, might be stored encrypted in
|
||||||
- locally in gitAnnexCredsDir. -}
|
- the remote's config. -}
|
||||||
s3GetCreds :: RemoteConfig -> UUID -> Annex (Maybe (String, String))
|
s3GetCreds :: RemoteConfig -> UUID -> Annex (Maybe (String, String))
|
||||||
s3GetCreds c u = maybe fromconfig (return . Just) =<< liftIO getenv
|
s3GetCreds c u = maybe fromcache (return . Just) =<< liftIO getenv
|
||||||
where
|
where
|
||||||
getenv = liftM2 (,)
|
getenv = liftM2 (,)
|
||||||
<$> get s3AccessKey
|
<$> get s3AccessKey
|
||||||
<*> get s3SecretKey
|
<*> get s3SecretKey
|
||||||
where
|
where
|
||||||
get = catchMaybeIO . getEnv
|
get = catchMaybeIO . getEnv
|
||||||
cache (ak, sk) = do
|
fromcache = do
|
||||||
setEnv s3AccessKey ak True
|
|
||||||
setEnv s3SecretKey sk True
|
|
||||||
return $ Just (ak, sk)
|
|
||||||
fromconfig = do
|
|
||||||
mcipher <- remoteCipher c
|
|
||||||
case (M.lookup "s3creds" c, mcipher) of
|
|
||||||
(Just s3creds, Just cipher) ->
|
|
||||||
liftIO $ decrypt s3creds cipher
|
|
||||||
_ -> fromcredsfile
|
|
||||||
fromcredsfile = do
|
|
||||||
d <- fromRepo gitAnnexCredsDir
|
d <- fromRepo gitAnnexCredsDir
|
||||||
let f = d </> fromUUID u
|
let f = d </> fromUUID u
|
||||||
v <- liftIO $ catchMaybeIO $ readFile f
|
v <- liftIO $ catchMaybeIO $ readFile f
|
||||||
case lines <$> v of
|
case lines <$> v of
|
||||||
Just (ak:sk:[]) -> liftIO $ cache (ak, sk)
|
Just (ak:sk:[]) -> return $ Just (ak, sk)
|
||||||
|
_ -> fromconfig
|
||||||
|
fromconfig = do
|
||||||
|
mcipher <- remoteCipher c
|
||||||
|
case (M.lookup "s3creds" c, mcipher) of
|
||||||
|
(Just s3creds, Just cipher) -> do
|
||||||
|
creds <- liftIO $ decrypt s3creds cipher
|
||||||
|
case creds of
|
||||||
|
[ak, sk] -> do
|
||||||
|
s3CacheCreds (ak, sk) u
|
||||||
|
return $ Just (ak, sk)
|
||||||
|
_ -> do error "bad s3creds"
|
||||||
_ -> return Nothing
|
_ -> return Nothing
|
||||||
decrypt s3creds cipher = do
|
decrypt s3creds cipher = lines <$>
|
||||||
creds <- lines <$>
|
withDecryptedContent cipher
|
||||||
withDecryptedContent cipher
|
(return $ L.pack $ fromB64 s3creds)
|
||||||
(return $ L.pack $ fromB64 s3creds)
|
(return . L.unpack)
|
||||||
(return . L.unpack)
|
|
||||||
case creds of
|
|
||||||
[ak, sk] -> cache (ak, sk)
|
|
||||||
_ -> do error "bad s3creds"
|
|
||||||
|
|
||||||
{- Stores S3 creds encrypted in the remote's config if possible to do so
|
{- Stores S3 creds encrypted in the remote's config if possible to do so
|
||||||
- securely, and otherwise locally in gitAnnexCredsDir. -}
|
- securely, and otherwise locally in gitAnnexCredsDir. -}
|
||||||
|
@ -326,17 +323,29 @@ s3SetCreds c u = do
|
||||||
(return . L.unpack)
|
(return . L.unpack)
|
||||||
return $ M.insert "s3creds" (toB64 s) c
|
return $ M.insert "s3creds" (toB64 s) c
|
||||||
_ -> do
|
_ -> do
|
||||||
d <- fromRepo gitAnnexCredsDir
|
s3CacheCreds (ak, sk) u
|
||||||
createAnnexDirectory d
|
|
||||||
let f = d </> fromUUID u
|
|
||||||
h <- liftIO $ openFile f WriteMode
|
|
||||||
liftIO $ modifyFileMode f $ removeModes
|
|
||||||
[groupReadMode, otherReadMode]
|
|
||||||
liftIO $ hPutStr h $ unlines [ak, sk]
|
|
||||||
liftIO $ hClose h
|
|
||||||
return c
|
return c
|
||||||
_ -> return c
|
_ -> return c
|
||||||
|
|
||||||
|
{- The S3 creds are cached in gitAnnexCredsDir. -}
|
||||||
|
s3CacheCreds :: (String, String) -> UUID -> Annex ()
|
||||||
|
s3CacheCreds (ak, sk) u = do
|
||||||
|
d <- fromRepo gitAnnexCredsDir
|
||||||
|
createAnnexDirectory d
|
||||||
|
liftIO $ do
|
||||||
|
let f = d </> fromUUID u
|
||||||
|
h <- openFile f WriteMode
|
||||||
|
modifyFileMode f $ removeModes
|
||||||
|
[groupReadMode, otherReadMode]
|
||||||
|
hPutStr h $ unlines [ak, sk]
|
||||||
|
hClose h
|
||||||
|
|
||||||
|
{- Sets the S3 creds in the environment. -}
|
||||||
|
s3SetCredsEnv :: (String, String) -> IO ()
|
||||||
|
s3SetCredsEnv (ak, sk) = do
|
||||||
|
setEnv s3AccessKey ak True
|
||||||
|
setEnv s3SecretKey sk True
|
||||||
|
|
||||||
s3AccessKey :: String
|
s3AccessKey :: String
|
||||||
s3AccessKey = "AWS_ACCESS_KEY_ID"
|
s3AccessKey = "AWS_ACCESS_KEY_ID"
|
||||||
s3SecretKey :: String
|
s3SecretKey :: String
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue