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.TrustLevel
import Types.UUID import Types.UUID
import qualified Utility.Matcher import qualified Utility.Matcher
import qualified Data.Map as M
-- git-annex's monad -- git-annex's monad
newtype Annex a = Annex { runAnnex :: StateT AnnexState IO a } 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)) , limit :: Either [Utility.Matcher.Token (FilePath -> Annex Bool)] (Utility.Matcher.Matcher (FilePath -> Annex Bool))
, forcetrust :: [(UUID, TrustLevel)] , forcetrust :: [(UUID, TrustLevel)]
, trustmap :: Maybe TrustMap , trustmap :: Maybe TrustMap
, cipher :: Maybe Cipher , ciphers :: M.Map EncryptedCipher Cipher
} }
newState :: Git.Repo -> AnnexState newState :: Git.Repo -> AnnexState
@ -93,7 +94,7 @@ newState gitrepo = AnnexState
, limit = Left [] , limit = Left []
, forcetrust = [] , forcetrust = []
, trustmap = Nothing , trustmap = Nothing
, cipher = Nothing , ciphers = M.empty
} }
{- Create and returns an Annex state object for the specified git repo. -} {- 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) withkey a k = cip k >>= maybe (a k) (a . snd)
cip = cipherKey c 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. -} - state. -}
remoteCipher :: RemoteConfig -> Annex (Maybe Cipher) remoteCipher :: RemoteConfig -> Annex (Maybe Cipher)
remoteCipher c = maybe expensive cached =<< Annex.getState Annex.cipher remoteCipher c = go $ extractCipher c
where where
cached cipher = return $ Just cipher go Nothing = return Nothing
expensive = case extractCipher c of go (Just encipher) = do
Nothing -> return Nothing cache <- Annex.getState Annex.ciphers
Just encipher -> do case M.lookup encipher cache of
showNote "gpg" Just cipher -> return $ Just cipher
cipher <- liftIO $ decryptCipher c encipher Nothing -> decrypt encipher cache
Annex.changeState (\s -> s { Annex.cipher = Just cipher }) decrypt encipher cache = do
return $ Just cipher 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. -} {- Gets encryption Cipher, and encrypted version of Key. -}
cipherKey :: Maybe RemoteConfig -> Key -> Annex (Maybe (Cipher, Key)) cipherKey :: Maybe RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))

View file

@ -11,5 +11,7 @@ module Types.Crypto where
newtype Cipher = Cipher String newtype Cipher = Cipher String
data EncryptedCipher = EncryptedCipher String KeyIds data EncryptedCipher = EncryptedCipher String KeyIds
deriving (Ord, Eq)
newtype KeyIds = KeyIds [String] 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. * Prevent key names from containing newlines.
* add: If interrupted, add can leave files converted to symlinks but not * 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. 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 -- 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"] > 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]] 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]]