Fix caching of decrypted ciphers, which failed when drop had to check multiple different encrypted special remotes.

This commit is contained in:
Joey Hess 2011-12-08 16:01:46 -04:00
parent 2568beee07
commit e3f1568e0f
5 changed files with 27 additions and 12 deletions

View file

@ -36,6 +36,7 @@ import Types.BranchState
import Types.TrustLevel
import Types.UUID
import qualified Utility.Matcher
import qualified Data.Map as M
-- git-annex's monad
newtype Annex a = Annex { runAnnex :: StateT AnnexState IO a }
@ -70,7 +71,7 @@ data AnnexState = AnnexState
, limit :: Either [Utility.Matcher.Token (FilePath -> Annex Bool)] (Utility.Matcher.Matcher (FilePath -> Annex Bool))
, forcetrust :: [(UUID, TrustLevel)]
, trustmap :: Maybe TrustMap
, cipher :: Maybe Cipher
, ciphers :: M.Map EncryptedCipher Cipher
}
newState :: Git.Repo -> AnnexState
@ -93,7 +94,7 @@ newState gitrepo = AnnexState
, limit = Left []
, forcetrust = []
, trustmap = Nothing
, cipher = Nothing
, ciphers = M.empty
}
{- Create and returns an Annex state object for the specified git repo. -}

View file

@ -61,19 +61,22 @@ encryptableRemote c storeKeyEncrypted retrieveKeyFileEncrypted r =
withkey a k = cip k >>= maybe (a k) (a . snd)
cip = cipherKey c
{- Gets encryption Cipher. The decrypted Cipher is cached in the Annex
{- Gets encryption Cipher. The decrypted Ciphers are cached in the Annex
- state. -}
remoteCipher :: RemoteConfig -> Annex (Maybe Cipher)
remoteCipher c = maybe expensive cached =<< Annex.getState Annex.cipher
remoteCipher c = go $ extractCipher c
where
cached cipher = return $ Just cipher
expensive = case extractCipher c of
Nothing -> return Nothing
Just encipher -> do
showNote "gpg"
cipher <- liftIO $ decryptCipher c encipher
Annex.changeState (\s -> s { Annex.cipher = Just cipher })
return $ Just cipher
go Nothing = return Nothing
go (Just encipher) = do
cache <- Annex.getState Annex.ciphers
case M.lookup encipher cache of
Just cipher -> return $ Just cipher
Nothing -> decrypt encipher cache
decrypt encipher cache = do
showNote "gpg"
cipher <- liftIO $ decryptCipher c encipher
Annex.changeState (\s -> s { Annex.ciphers = M.insert encipher cipher cache })
return $ Just cipher
{- Gets encryption Cipher, and encrypted version of Key. -}
cipherKey :: Maybe RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))

View file

@ -11,5 +11,7 @@ module Types.Crypto where
newtype Cipher = Cipher String
data EncryptedCipher = EncryptedCipher String KeyIds
deriving (Ord, Eq)
newtype KeyIds = KeyIds [String]
deriving (Ord, Eq)

2
debian/changelog vendored
View file

@ -5,6 +5,8 @@ git-annex (3.20111204) UNRELEASED; urgency=low
* Prevent key names from containing newlines.
* add: If interrupted, add can leave files converted to symlinks but not
yet added to git. Running the add again will now clean up this situtation.
* Fix caching of decrypted ciphers, which failed when drop had to check
multiple different encrypted special remotes.
-- Joey Hess <joeyh@debian.org> Sun, 04 Dec 2011 12:22:37 -0400

View file

@ -92,3 +92,10 @@ git annex copy --to remoteserver -d tools/md5_sha1_utility.exe
> Running: sh ["-c","rsync --quiet 'REMOVED_HOST:annex/work/1F/PQ/'\"'\"'GPGHMACSHA1--ff075e57f649300c5698e346be74fb6e22d70e35/GPGHMACSHA1--ff075e57f649300c5698e346be74fb6e22d70e35'\"'\"'' 2>/dev/null"]
And yes, only the hash *annex copy* is checking for exists on the remote side. --[[gebi]]
> Ok, this is due to too aggressive caching of the decrypted cipher
> for a remote. When dopping, it decrypts localserver's cipher,
> caches it, and then when checking remoteserver it says hey,
> here's an already decrypted cipher -- it must be the right one!
>
> Problem reproduced here, and fixed. [[done]] --[[Joey]]