better probing for gcrypt repositories using new --check option
Now can tell if a repo uses gcrypt or not, and whether it's decryptable with the current gpg keys. This closes the hole that undecryptable gcrypt repos could have before been combined into the repo in encrypted mode.
This commit is contained in:
parent
b847d24992
commit
e8e209f4e5
5 changed files with 35 additions and 32 deletions
|
@ -307,24 +307,21 @@ getFinishAddDriveR drive = go
|
||||||
, page "Encrypt repository" (Just Configuration) $
|
, page "Encrypt repository" (Just Configuration) $
|
||||||
$(widgetFile "configurators/needgcrypt")
|
$(widgetFile "configurators/needgcrypt")
|
||||||
)
|
)
|
||||||
{- Either making a new unencrypted repo, or combining with
|
|
||||||
- an existing unencrypted repo, or combining with an existing
|
|
||||||
- gcrypt special remot, or some other existing gcrypt repo. -}
|
|
||||||
go NoRepoKey = do
|
go NoRepoKey = do
|
||||||
mu <- liftIO $ probeGCryptRemoteUUID dir
|
pr <- liftAnnex $ inRepo $ Git.GCrypt.probeRepo dir
|
||||||
case mu of
|
case pr of
|
||||||
Just u -> enablegcryptremote u
|
Git.GCrypt.Decryptable -> do
|
||||||
Nothing ->
|
mu <- liftIO $ probeGCryptRemoteUUID dir
|
||||||
ifM (liftAnnex $ inRepo $ Git.GCrypt.probeGCryptRepo dir)
|
case mu of
|
||||||
( error "The drive contains a gcrypt repository that is not a git-annex special remote. This is not supported."
|
Just u -> enablegcryptremote u
|
||||||
, makeunencrypted
|
Nothing -> error "The drive contains a gcrypt repository that is not a git-annex special remote. This is not supported."
|
||||||
)
|
Git.GCrypt.NotDecryptable ->
|
||||||
{- Sync the git-annex branch from the gcrypt repo, in order to
|
error $ "The drive contains a git repository that is encrypted with a GnuPG key that you do not have."
|
||||||
- make sure we know how the special remote should be set up. -}
|
Git.GCrypt.NotEncrypted -> makeunencrypted
|
||||||
enablegcryptremote u = do
|
enablegcryptremote u = do
|
||||||
mname <- liftAnnex $ getGCryptRemoteName u dir
|
mname <- liftAnnex $ getGCryptRemoteName u dir
|
||||||
case mname of
|
case mname of
|
||||||
Nothing -> error $ "Unable to use the gcrypt remote at " ++ dir ++ ". Perhaps it is encrypted using a GnuPG key that you do not have?"
|
Nothing -> error $ "Cannot find configuration for the gcrypt remote at " ++ dir
|
||||||
Just name -> makewith $ const $ do
|
Just name -> makewith $ const $ do
|
||||||
r <- liftAnnex $ addRemote $
|
r <- liftAnnex $ addRemote $
|
||||||
enableSpecialRemote name GCrypt.remote $ M.fromList
|
enableSpecialRemote name GCrypt.remote $ M.fromList
|
||||||
|
|
|
@ -32,8 +32,8 @@ isEncrypted _ = False
|
||||||
- Throws an exception if an url is invalid or the repo does not use
|
- Throws an exception if an url is invalid or the repo does not use
|
||||||
- gcrypt.
|
- gcrypt.
|
||||||
-}
|
-}
|
||||||
encryptedRepo :: Repo -> Repo -> IO Repo
|
encryptedRemote :: Repo -> Repo -> IO Repo
|
||||||
encryptedRepo baserepo = go
|
encryptedRemote baserepo = go
|
||||||
where
|
where
|
||||||
go Repo { location = Url url }
|
go Repo { location = Url url }
|
||||||
| urlPrefix `isPrefixOf` u =
|
| urlPrefix `isPrefixOf` u =
|
||||||
|
@ -45,20 +45,26 @@ encryptedRepo baserepo = go
|
||||||
go _ = notencrypted
|
go _ = notencrypted
|
||||||
notencrypted = error "not a gcrypt encrypted repository"
|
notencrypted = error "not a gcrypt encrypted repository"
|
||||||
|
|
||||||
{- Checks if the git repo at a location is a gcrypt repo that
|
data ProbeResult = Decryptable | NotDecryptable | NotEncrypted
|
||||||
- we can decrypt. This works by trying to fetch from the repo
|
|
||||||
- at the location, into the baserepo.
|
{- Checks if the git repo at a location uses gcrypt.
|
||||||
-
|
-
|
||||||
- Returns false if the git repo is not using gcrypt, or if it is using
|
- Rather expensive -- many need to fetch the entire repo contents.
|
||||||
- gcrypt but cannot be decrypted. We do not try to detect gcrypt
|
- (Which is fine if the repo is going to be added as a remote..)
|
||||||
- repos that cannot be decrypted, because gcrypt may change in the future
|
|
||||||
- to avoid easy fingerprinting of gcrypt repos.
|
|
||||||
-}
|
-}
|
||||||
probeGCryptRepo :: FilePath -> Repo -> IO Bool
|
probeRepo :: String -> Repo -> IO ProbeResult
|
||||||
probeGCryptRepo dir baserepo = catchBoolIO $ Command.runBool
|
probeRepo loc baserepo = do
|
||||||
[ Param "fetch"
|
let p = proc "git" $ toCommand $ Command.gitCommandLine
|
||||||
, Param $ urlPrefix ++ dir
|
[ Param "remote-gcrypt"
|
||||||
] baserepo
|
, Param "--check"
|
||||||
|
, Param loc
|
||||||
|
] baserepo
|
||||||
|
(_, _, _, pid) <- createProcess p
|
||||||
|
code <- waitForProcess pid
|
||||||
|
return $ case code of
|
||||||
|
ExitSuccess -> Decryptable
|
||||||
|
ExitFailure 1 -> NotDecryptable
|
||||||
|
ExitFailure _ -> NotEncrypted
|
||||||
|
|
||||||
type RemoteName = String
|
type RemoteName = String
|
||||||
type GCryptId = String
|
type GCryptId = String
|
||||||
|
|
|
@ -50,7 +50,7 @@ gen :: Git.Repo -> UUID -> RemoteConfig -> RemoteGitConfig -> Annex (Maybe Remot
|
||||||
gen gcryptr u c gc = do
|
gen gcryptr u c gc = do
|
||||||
g <- gitRepo
|
g <- gitRepo
|
||||||
-- get underlying git repo with real path, not gcrypt path
|
-- get underlying git repo with real path, not gcrypt path
|
||||||
r <- liftIO $ Git.GCrypt.encryptedRepo g gcryptr
|
r <- liftIO $ Git.GCrypt.encryptedRemote g gcryptr
|
||||||
let r' = r { Git.remoteName = Git.remoteName gcryptr }
|
let r' = r { Git.remoteName = Git.remoteName gcryptr }
|
||||||
(mgcryptid, r'') <- liftIO $ getGCryptId r'
|
(mgcryptid, r'') <- liftIO $ getGCryptId r'
|
||||||
-- doublecheck that local cache matches underlying repo's gcrypt-id
|
-- doublecheck that local cache matches underlying repo's gcrypt-id
|
||||||
|
|
|
@ -128,7 +128,7 @@ repoAvail r
|
||||||
| Git.GCrypt.isEncrypted r = do
|
| Git.GCrypt.isEncrypted r = do
|
||||||
g <- gitRepo
|
g <- gitRepo
|
||||||
liftIO $ do
|
liftIO $ do
|
||||||
er <- Git.GCrypt.encryptedRepo g r
|
er <- Git.GCrypt.encryptedRemote g r
|
||||||
if Git.repoIsLocal er || Git.repoIsLocalUnknown er
|
if Git.repoIsLocal er || Git.repoIsLocalUnknown er
|
||||||
then catchBoolIO $
|
then catchBoolIO $
|
||||||
void (Git.Config.read er) >> return True
|
void (Git.Config.read er) >> return True
|
||||||
|
|
2
debian/control
vendored
2
debian/control
vendored
|
@ -72,7 +72,7 @@ Depends: ${misc:Depends}, ${shlibs:Depends},
|
||||||
wget,
|
wget,
|
||||||
curl,
|
curl,
|
||||||
openssh-client (>= 1:5.6p1)
|
openssh-client (>= 1:5.6p1)
|
||||||
Recommends: lsof, gnupg, bind9-host, ssh-askpass, quvi, git-remote-gcrypt
|
Recommends: lsof, gnupg, bind9-host, ssh-askpass, quvi, git-remote-gcrypt (>= 0.20130908-4)
|
||||||
Suggests: graphviz, bup, libnss-mdns
|
Suggests: graphviz, bup, libnss-mdns
|
||||||
Description: manage files with git, without checking their contents into git
|
Description: manage files with git, without checking their contents into git
|
||||||
git-annex allows managing files with git, without checking the file
|
git-annex allows managing files with git, without checking the file
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue