Allow controlling whether login credentials for S3 and webdav are committed to the repository, by setting embedcreds=yes|no when running initremote.
This commit is contained in:
parent
f7a7ec4ebf
commit
9221e62d87
9 changed files with 108 additions and 62 deletions
51
Creds.hs
51
Creds.hs
|
@ -12,7 +12,7 @@ import Annex.Perms
|
||||||
import Utility.FileMode
|
import Utility.FileMode
|
||||||
import Crypto
|
import Crypto
|
||||||
import Types.Remote (RemoteConfig, RemoteConfigKey)
|
import Types.Remote (RemoteConfig, RemoteConfigKey)
|
||||||
import Remote.Helper.Encryptable (remoteCipher, isTrustedCipher)
|
import Remote.Helper.Encryptable (remoteCipher, embedCreds)
|
||||||
|
|
||||||
import System.Environment
|
import System.Environment
|
||||||
import System.Posix.Env (setEnv)
|
import System.Posix.Env (setEnv)
|
||||||
|
@ -31,26 +31,32 @@ data CredPairStorage = CredPairStorage
|
||||||
, credPairRemoteKey :: Maybe RemoteConfigKey
|
, credPairRemoteKey :: Maybe RemoteConfigKey
|
||||||
}
|
}
|
||||||
|
|
||||||
{- Stores creds in a remote's configuration, if the remote is encrypted
|
{- Stores creds in a remote's configuration, if the remote allows
|
||||||
- with a GPG key. Otherwise, caches them locally. -}
|
- that. Otherwise, caches them locally. -}
|
||||||
setRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex RemoteConfig
|
setRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex RemoteConfig
|
||||||
setRemoteCredPair c storage = go =<< getRemoteCredPair c storage
|
setRemoteCredPair c storage = go =<< getRemoteCredPair c storage
|
||||||
where
|
where
|
||||||
go (Just creds) = do
|
go (Just creds)
|
||||||
mcipher <- remoteCipher c
|
| embedCreds c = case credPairRemoteKey storage of
|
||||||
case (mcipher, credPairRemoteKey storage) of
|
Nothing -> localcache creds
|
||||||
(Just cipher, Just key) | isTrustedCipher c -> do
|
Just key -> storeconfig creds key =<< remoteCipher c
|
||||||
s <- liftIO $ encrypt cipher
|
| otherwise = localcache creds
|
||||||
(feedBytes $ L.pack $ encodeCredPair creds)
|
|
||||||
(readBytes $ return . L.unpack)
|
|
||||||
return $ M.insert key (toB64 s) c
|
|
||||||
_ -> do
|
|
||||||
writeCacheCredPair creds storage
|
|
||||||
return c
|
|
||||||
go Nothing = return c
|
go Nothing = return c
|
||||||
|
|
||||||
|
localcache creds = do
|
||||||
|
writeCacheCredPair creds storage
|
||||||
|
return c
|
||||||
|
|
||||||
|
storeconfig creds key (Just cipher) = do
|
||||||
|
s <- liftIO $ encrypt cipher
|
||||||
|
(feedBytes $ L.pack $ encodeCredPair creds)
|
||||||
|
(readBytes $ return . L.unpack)
|
||||||
|
return $ M.insert key (toB64 s) c
|
||||||
|
storeconfig creds key Nothing =
|
||||||
|
return $ M.insert key (toB64 $ encodeCredPair creds) c
|
||||||
|
|
||||||
{- Gets a remote's credpair, from the environment if set, otherwise
|
{- Gets a remote's credpair, from the environment if set, otherwise
|
||||||
- from the cache in gitAnnexCredsDir, or failing that, from the encrypted
|
- from the cache in gitAnnexCredsDir, or failing that, from the
|
||||||
- value in RemoteConfig. -}
|
- value in RemoteConfig. -}
|
||||||
getRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)
|
getRemoteCredPair :: RemoteConfig -> CredPairStorage -> Annex (Maybe CredPair)
|
||||||
getRemoteCredPair c storage = maybe fromcache (return . Just) =<< fromenv
|
getRemoteCredPair c storage = maybe fromcache (return . Just) =<< fromenv
|
||||||
|
@ -61,17 +67,20 @@ getRemoteCredPair c storage = maybe fromcache (return . Just) =<< fromenv
|
||||||
Just key -> do
|
Just key -> do
|
||||||
mcipher <- remoteCipher c
|
mcipher <- remoteCipher c
|
||||||
case (M.lookup key c, mcipher) of
|
case (M.lookup key c, mcipher) of
|
||||||
|
(Nothing, _) -> return Nothing
|
||||||
(Just enccreds, Just cipher) -> do
|
(Just enccreds, Just cipher) -> do
|
||||||
creds <- liftIO $ decrypt cipher
|
creds <- liftIO $ decrypt cipher
|
||||||
(feedBytes $ L.pack $ fromB64 enccreds)
|
(feedBytes $ L.pack $ fromB64 enccreds)
|
||||||
(readBytes $ return . L.unpack)
|
(readBytes $ return . L.unpack)
|
||||||
case decodeCredPair creds of
|
fromcreds creds
|
||||||
Just credpair -> do
|
(Just bcreds, Nothing) ->
|
||||||
writeCacheCredPair credpair storage
|
fromcreds $ fromB64 bcreds
|
||||||
return $ Just credpair
|
|
||||||
_ -> do error $ "bad " ++ key
|
|
||||||
_ -> return Nothing
|
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
|
fromcreds creds = case decodeCredPair creds of
|
||||||
|
Just credpair -> do
|
||||||
|
writeCacheCredPair credpair storage
|
||||||
|
return $ Just credpair
|
||||||
|
_ -> do error $ "bad creds"
|
||||||
|
|
||||||
{- Gets a CredPair from the environment. -}
|
{- Gets a CredPair from the environment. -}
|
||||||
getEnvCredPair :: CredPairStorage -> IO (Maybe CredPair)
|
getEnvCredPair :: CredPairStorage -> IO (Maybe CredPair)
|
||||||
|
|
|
@ -87,10 +87,20 @@ remoteCipher c = go $ extractCipher c
|
||||||
Annex.changeState (\s -> s { Annex.ciphers = M.insert encipher cipher cache })
|
Annex.changeState (\s -> s { Annex.ciphers = M.insert encipher cipher cache })
|
||||||
return $ Just cipher
|
return $ Just cipher
|
||||||
|
|
||||||
{- Checks if there is a trusted (non-shared) cipher. -}
|
{- Checks if the remote's config allows storing creds in the remote's config.
|
||||||
isTrustedCipher :: RemoteConfig -> Bool
|
-
|
||||||
isTrustedCipher c =
|
- embedcreds=yes allows this, and embedcreds=no prevents it.
|
||||||
isJust (M.lookup "cipherkeys" c) && isJust (M.lookup "cipher" c)
|
-
|
||||||
|
- If not set, the default is to only store creds when it's surely safe:
|
||||||
|
- When gpg encryption is used, in which case the creds will be encrypted
|
||||||
|
- using it. Not when a shared cipher is used.
|
||||||
|
-}
|
||||||
|
embedCreds :: RemoteConfig -> Bool
|
||||||
|
embedCreds c
|
||||||
|
| M.lookup "embedcreds" c == Just "yes" = True
|
||||||
|
| M.lookup "embedcreds" c == Just "no" = False
|
||||||
|
| isJust (M.lookup "cipherkeys" c) && isJust (M.lookup "cipher" c) = True
|
||||||
|
| otherwise = False
|
||||||
|
|
||||||
{- Gets encryption Cipher, and encrypted version of Key. -}
|
{- Gets encryption Cipher, and encrypted version of Key. -}
|
||||||
cipherKey :: Maybe RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))
|
cipherKey :: Maybe RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))
|
||||||
|
|
3
debian/changelog
vendored
3
debian/changelog
vendored
|
@ -13,6 +13,9 @@ git-annex (3.20121113) UNRELEASED; urgency=low
|
||||||
* directory special remote: Made more efficient and robust.
|
* directory special remote: Made more efficient and robust.
|
||||||
* Bugfix: directory special remote could loop forever storing a key
|
* Bugfix: directory special remote could loop forever storing a key
|
||||||
when a too small chunksize was configured.
|
when a too small chunksize was configured.
|
||||||
|
* Allow controlling whether login credentials for S3 and webdav are
|
||||||
|
committed to the repository, by setting embedcreds=yes|no when running
|
||||||
|
initremote.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Tue, 13 Nov 2012 13:17:07 -0400
|
-- Joey Hess <joeyh@debian.org> Tue, 13 Nov 2012 13:17:07 -0400
|
||||||
|
|
||||||
|
|
|
@ -8,21 +8,29 @@ See [[tips/using_Amazon_S3]] and
|
||||||
|
|
||||||
The standard environment variables `AWS_ACCESS_KEY_ID` and
|
The standard environment variables `AWS_ACCESS_KEY_ID` and
|
||||||
`AWS_SECRET_ACCESS_KEY` are used to supply login credentials
|
`AWS_SECRET_ACCESS_KEY` are used to supply login credentials
|
||||||
for Amazon. When encryption is enabled, they are stored in encrypted form
|
for Amazon. You need to set these only when running
|
||||||
by `git annex initremote`. Without encryption, they are stored in a
|
`git annex initremote`, as they will be cached in a file only you
|
||||||
file only you can read inside the local git repository. So you do not
|
can read inside the local git repository.
|
||||||
need to keep the environment variables set after the initial
|
|
||||||
initalization of the remote.
|
|
||||||
|
|
||||||
A number of parameters can be passed to `git annex initremote` to configure
|
A number of parameters can be passed to `git annex initremote` to configure
|
||||||
the S3 remote.
|
the S3 remote.
|
||||||
|
|
||||||
* `encryption` - Required. Either "none" to disable encryption
|
* `encryption` - Required. Either "none" to disable encryption (not recommended),
|
||||||
(not recommended),
|
|
||||||
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
||||||
key that will be given access to the remote. Note that additional gpg
|
key that will be given access to the remote, or "shared" which allows
|
||||||
keys can be given access to a remote by rerunning initremote with
|
every clone of the repository to access the encrypted data (use with caution).
|
||||||
the new key id. See [[encryption]].
|
|
||||||
|
Note that additional gpg keys can be given access to a remote by
|
||||||
|
rerunning initremote with the new key id. See [[encryption]].
|
||||||
|
|
||||||
|
* `embedcreds` - Optional. Set to "yes" embed the login credentials inside
|
||||||
|
the git repository, which allows other clones to also access them. This is
|
||||||
|
the default when gpg encryption is enabled; the credentials are stored
|
||||||
|
encrypted and only those with the repository's keys can access them.
|
||||||
|
|
||||||
|
It is not the default when using shared encryption, or no encryption.
|
||||||
|
Think carefully about who can access your repository before using
|
||||||
|
embedcreds without gpg encryption.
|
||||||
|
|
||||||
* `datacenter` - Defaults to "US". Other values include "EU",
|
* `datacenter` - Defaults to "US". Other values include "EU",
|
||||||
"us-west-1", and "ap-southeast-1".
|
"us-west-1", and "ap-southeast-1".
|
||||||
|
|
|
@ -22,9 +22,11 @@ These parameters can be passed to `git annex initremote` to configure bup:
|
||||||
* `encryption` - Required. Either "none" to disable encryption of content
|
* `encryption` - Required. Either "none" to disable encryption of content
|
||||||
stored in bup (ssh will still be used to transport it securely),
|
stored in bup (ssh will still be used to transport it securely),
|
||||||
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
||||||
key that will be given access to the remote. Note that additional gpg
|
key that will be given access to the remote, or "shared" which allows
|
||||||
keys can be given access to a remote by rerunning initremote with
|
every clone of the repository to access the encrypted data (use with caution).
|
||||||
the new key id. See [[encryption]].
|
|
||||||
|
Note that additional gpg keys can be given access to a remote by
|
||||||
|
rerunning initremote with the new key id. See [[encryption]].
|
||||||
|
|
||||||
* `buprepo` - Required. This is passed to `bup` as the `--remote`
|
* `buprepo` - Required. This is passed to `bup` as the `--remote`
|
||||||
to use to store data. To create the repository,`bup init` will be run.
|
to use to store data. To create the repository,`bup init` will be run.
|
||||||
|
|
|
@ -10,12 +10,14 @@ the drive's mountpoint as a directory remote.
|
||||||
These parameters can be passed to `git annex initremote` to configure the
|
These parameters can be passed to `git annex initremote` to configure the
|
||||||
remote:
|
remote:
|
||||||
|
|
||||||
* `encryption` - Required. Either "none" to disable encryption of content
|
* `encryption` - Required. Either "none" to disable encryption,
|
||||||
stored in the directory,
|
|
||||||
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
||||||
key that will be given access to the remote. Note that additional gpg
|
key that will be given access to the remote, or "shared" which allows
|
||||||
keys can be given access to a remote by rerunning initremote with
|
every clone of the repository to decrypt the encrypted data.
|
||||||
the new key id. See [[encryption]].
|
|
||||||
|
Note that additional gpg keys can be given access to a remote by
|
||||||
|
rerunning initremote with the new key id. See [[encryption]].
|
||||||
|
|
||||||
* `chunksize` - Avoid storing files larger than the specified size in the
|
* `chunksize` - Avoid storing files larger than the specified size in the
|
||||||
directory. For use on directories on mount points that have file size
|
directory. For use on directories on mount points that have file size
|
||||||
limitations. The default is to never chunk files.
|
limitations. The default is to never chunk files.
|
||||||
|
|
|
@ -25,11 +25,13 @@ Can you spot the potential data loss bugs in the above simple example?
|
||||||
|
|
||||||
These parameters can be passed to `git annex initremote`:
|
These parameters can be passed to `git annex initremote`:
|
||||||
|
|
||||||
* `encryption` - Required. Either "none" to disable encryption of content,
|
* `encryption` - Required. Either "none" to disable encryption,
|
||||||
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
||||||
key that will be given access to the remote. Note that additional gpg
|
key that will be given access to the remote, or "shared" which allows
|
||||||
keys can be given access to a remote by rerunning initremote with
|
every clone of the repository to access the encrypted data.
|
||||||
the new key id. See [[encryption]].
|
|
||||||
|
Note that additional gpg keys can be given access to a remote by
|
||||||
|
rerunning initremote with the new key id. See [[encryption]].
|
||||||
|
|
||||||
* `hooktype` - Required. This specifies a collection of hooks to use for
|
* `hooktype` - Required. This specifies a collection of hooks to use for
|
||||||
this remote.
|
this remote.
|
||||||
|
|
|
@ -15,11 +15,13 @@ Or for using rsync over SSH
|
||||||
These parameters can be passed to `git annex initremote` to configure rsync:
|
These parameters can be passed to `git annex initremote` to configure rsync:
|
||||||
|
|
||||||
* `encryption` - Required. Either "none" to disable encryption of content
|
* `encryption` - Required. Either "none" to disable encryption of content
|
||||||
stored in rsync,
|
stored on the remote rsync server,
|
||||||
or a value that can be looked up (using `gpg -k`) to find a gpg encryption
|
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
||||||
key that will be given access to the remote. Note that additional gpg
|
key that will be given access to the remote, or "shared" which allows
|
||||||
keys can be given access to a remote by rerunning initremote with
|
every clone of the repository to decrypt the encrypted data.
|
||||||
the new key id. See [[encryption]].
|
|
||||||
|
Note that additional gpg keys can be given access to a remote by
|
||||||
|
rerunning initremote with the new key id. See [[encryption]].
|
||||||
|
|
||||||
* `rsyncurl` - Required. This is the url or `hostname:/directory` to
|
* `rsyncurl` - Required. This is the url or `hostname:/directory` to
|
||||||
pass to rsync to tell it where to store content.
|
pass to rsync to tell it where to store content.
|
||||||
|
|
|
@ -3,21 +3,29 @@ This special remote type stores file contents in a WebDAV server.
|
||||||
## configuration
|
## configuration
|
||||||
|
|
||||||
The environment variables `WEBDAV_USERNAME` and `WEBDAV_PASSWORD` are used
|
The environment variables `WEBDAV_USERNAME` and `WEBDAV_PASSWORD` are used
|
||||||
to supply login credentials. When encryption is enabled, they are stored in
|
to supply login credentials. You need to set these only when running
|
||||||
encrypted form by `git annex initremote`. Without encryption, they are
|
`git annex initremote`, as they will be cached in a file only you
|
||||||
stored in a file only you can read inside the local git repository. So you
|
can read inside the local git repository.
|
||||||
do not need to keep the environment variables set after the initial
|
|
||||||
initalization of the remote.
|
|
||||||
|
|
||||||
A number of parameters can be passed to `git annex initremote` to configure
|
A number of parameters can be passed to `git annex initremote` to configure
|
||||||
the webdav remote.
|
the webdav remote.
|
||||||
|
|
||||||
* `encryption` - Required. Either "none" to disable encryption
|
* `encryption` - Required. Either "none" to disable encryption (not recommended),
|
||||||
(not recommended),
|
|
||||||
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
or a value that can be looked up (using gpg -k) to find a gpg encryption
|
||||||
key that will be given access to the remote. Note that additional gpg
|
key that will be given access to the remote, or "shared" which allows
|
||||||
keys can be given access to a remote by rerunning initremote with
|
every clone of the repository to access the encrypted data (use with caution).
|
||||||
the new key id. See [[encryption]].
|
|
||||||
|
Note that additional gpg keys can be given access to a remote by
|
||||||
|
rerunning initremote with the new key id. See [[encryption]].
|
||||||
|
|
||||||
|
* `embedcreds` - Optional. Set to "yes" embed the login credentials inside
|
||||||
|
the git repository, which allows other clones to also access them. This is
|
||||||
|
the default when gpg encryption is enabled; the credentials are stored
|
||||||
|
encrypted and only those with the repository's keys can access them.
|
||||||
|
|
||||||
|
It is not the default when using shared encryption, or no encryption.
|
||||||
|
Think carefully about who can access your repository before using
|
||||||
|
embedcreds without gpg encryption.
|
||||||
|
|
||||||
* `url` - Required. The URL to the WebDAV directory where files will be
|
* `url` - Required. The URL to the WebDAV directory where files will be
|
||||||
stored. This can be a subdirectory of a larger WebDAV repository, and will
|
stored. This can be a subdirectory of a larger WebDAV repository, and will
|
||||||
|
|
Loading…
Add table
Reference in a new issue