isUnmodifiedCheap,
verifyKeyContentPostRetrieval,
verifyKeyContent,
- VerifyConfig(..),
+ VerifyConfig,
+ VerifyConfigA(..),
Verification(..),
unVerified,
withTmpWorkDir,
import Annex.ReplaceFile
import Annex.AdjustedBranch (adjustedBranchRefresh)
import Messages.Progress
-import Types.Remote (RetrievalSecurityPolicy(..))
+import Types.Remote (RetrievalSecurityPolicy(..), VerifyConfigA(..))
import Types.NumCopies
import Types.Key
import Types.Transfer
Just StallDetectionDisabled -> go Nothing
Just sd -> runTransferrer sd r key f d Download witness
where
- go sd = getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) key f $ \dest ->
+ go sd = getViaTmp (Remote.retrievalSecurityPolicy r) vc key f $ \dest ->
download' (Remote.uuid r) key f sd d (go' dest) witness
go' dest p = verifiedAction $
- Remote.retrieveKeyFile r key f (fromRawFilePath dest) p
+ Remote.retrieveKeyFile r key f (fromRawFilePath dest) p vc
+ vc = Remote.RemoteVerify r
-- Download, not supporting canceling detected stalls.
download' :: Observable v => UUID -> Key -> AssociatedFile -> Maybe StallDetection -> RetryDecider -> (MeterUpdate -> Annex v) -> NotifyWitness -> Annex v
{-# LANGUAGE CPP #-}
module Annex.Verify (
- VerifyConfig(..),
shouldVerify,
verifyKeyContentPostRetrieval,
verifyKeyContent,
import Annex.Common
import qualified Annex
import qualified Types.Remote
+import Types.Remote (VerifyConfigA(..))
import qualified Types.Backend
import Types.Backend (IncrementalVerifier(..))
import qualified Backend
import qualified System.FilePath.ByteString as P
#endif
-data VerifyConfig = AlwaysVerify | NoVerify | RemoteVerify Remote | DefaultVerify
-
shouldVerify :: VerifyConfig -> Annex Bool
shouldVerify AlwaysVerify = return True
shouldVerify NoVerify = return False
-- should use to download it.
setTempUrl urlkey loguri
let downloader = \dest p ->
- fst <$> Remote.verifiedAction (Remote.retrieveKeyFile r urlkey af dest p)
+ fst <$> Remote.verifiedAction
+ (Remote.retrieveKeyFile r urlkey af dest p (RemoteVerify r))
ret <- downloadWith canadd addunlockedmatcher downloader urlkey (Remote.uuid r) loguri file
removeTempUrl urlkey
return ret
)
, return Nothing
)
- getfile' tmp = Remote.retrieveKeyFile remote key (AssociatedFile Nothing) (fromRawFilePath tmp) dummymeter
+ getfile' tmp = Remote.retrieveKeyFile remote key (AssociatedFile Nothing) (fromRawFilePath tmp) dummymeter (RemoteVerify remote)
dummymeter _ = noop
getcheap tmp = case Remote.retrieveKeyFileCheap remote of
Just a -> isRight <$> tryNonAsync (a key afile (fromRawFilePath tmp))
Nothing -> return True
Just verifier -> verifier k (serializeKey' k)
get r k = logStatusAfter k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) $ \dest ->
- tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate) >>= \case
+ tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate (RemoteVerify r)) >>= \case
Right v -> return (True, v)
Left _ -> return (False, UnVerified)
store r k = Remote.storeKey r k (AssociatedFile Nothing) nullMeterUpdate
Remote.checkPresent r k
, check (== Right False) "retrieveKeyFile" $ \r k ->
logStatusAfter k $ getViaTmp (Remote.retrievalSecurityPolicy r) (RemoteVerify r) k (AssociatedFile Nothing) $ \dest ->
- tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate) >>= \case
+ tryNonAsync (Remote.retrieveKeyFile r k (AssociatedFile Nothing) (fromRawFilePath dest) nullMeterUpdate (RemoteVerify r)) >>= \case
Right v -> return (True, v)
Left _ -> return (False, UnVerified)
, check (== Right False) "retrieveKeyFileCheap" $ \r k -> case Remote.retrieveKeyFileCheap r of
fromPerform :: Key -> AssociatedFile -> Remote -> CommandPerform
fromPerform key file remote = go Upload file $
download' (uuid remote) key file Nothing stdRetry $ \p ->
- logStatusAfter key $ getViaTmp (retrievalSecurityPolicy remote) (RemoteVerify remote) key file $ \t ->
- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p) >>= \case
+ logStatusAfter key $ getViaTmp (retrievalSecurityPolicy remote) vc key file $ \t ->
+ tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p vc) >>= \case
Right v -> return (True, v)
Left e -> do
warning (show e)
return (False, UnVerified)
+ where
+ vc = RemoteVerify remote
go :: Direction -> AssociatedFile -> (NotifyWitness -> Annex Bool) -> CommandPerform
go direction file a = notifyTransfer direction file a >>= liftIO . exitBool
| otherwise = notifyTransfer direction file $
download' (Remote.uuid remote) key file Nothing stdRetry $ \p ->
logStatusAfter key $ getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key file $ \t -> do
- r <- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p) >>= \case
+ r <- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p (RemoteVerify remote)) >>= \case
Left e -> do
warning (show e)
return (False, UnVerified)
-- and for retrying, and updating location log,
-- and stall canceling.
let go p = getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key file $ \t -> do
- Remote.verifiedAction (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p)
+ Remote.verifiedAction (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p (RemoteVerify remote))
in download' (Remote.uuid remote) key file Nothing noRetry go
noNotification
runner (AssistantUploadRequest _ key (TransferAssociatedFile file)) remote =
notifyTransfer Download file $
download' (Remote.uuid remote) key file Nothing stdRetry $ \p ->
logStatusAfter key $ getViaTmp (Remote.retrievalSecurityPolicy remote) (RemoteVerify remote) key file $ \t -> do
- r <- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p) >>= \case
+ r <- tryNonAsync (Remote.retrieveKeyFile remote key file (fromRawFilePath t) p (RemoteVerify remote)) >>= \case
Left e -> do
warning (show e)
return (False, UnVerified)
, remoteStateHandle = rs
}
-downloadKey :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-downloadKey key _file dest p = do
+downloadKey :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+downloadKey key _file dest p _ = do
get . map (torrentUrlNum . fst . getDownloader) =<< getBitTorrentUrls key
-- While bittorrent verifies the hash in the torrent file,
-- the torrent file itself is downloaded without verification,
failedlock = giveup "can't lock content"
{- Tries to copy a key's content from a remote's annex to a file. -}
-copyFromRemote :: Remote -> State -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
+copyFromRemote :: Remote -> State -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
copyFromRemote = copyFromRemote' False
-copyFromRemote' :: Bool -> Remote -> State -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-copyFromRemote' forcersync r st key file dest meterupdate = do
+copyFromRemote' :: Bool -> Remote -> State -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+copyFromRemote' forcersync r st key file dest meterupdate vc = do
repo <- getRepo r
- copyFromRemote'' repo forcersync r st key file dest meterupdate
+ copyFromRemote'' repo forcersync r st key file dest meterupdate vc
-copyFromRemote'' :: Git.Repo -> Bool -> Remote -> State -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-copyFromRemote'' repo forcersync r st@(State connpool _ _ _ _) key file dest meterupdate
+copyFromRemote'' :: Git.Repo -> Bool -> Remote -> State -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+copyFromRemote'' repo forcersync r st@(State connpool _ _ _ _) key file dest meterupdate vc
| Git.repoIsHttp repo = do
gc <- Annex.getGitConfig
ok <- Url.withUrlOptionsPromptingCreds $
let checksuccess = check >>= \case
Just err -> giveup err
Nothing -> return True
- let verify = Annex.Content.RemoteVerify r
copier <- mkFileCopier hardlink st
(ok, v) <- runTransfer (Transfer Download u (fromKey id key))
file Nothing stdRetry $ \p ->
metered (Just (combineMeterUpdate p meterupdate)) key $ \_ p' ->
- copier object dest key p' checksuccess verify
+ copier object dest key p' checksuccess vc
if ok
then return v
else giveup "failed to retrieve content from remote"
then return v
else giveup "failed to retrieve content from remote"
else P2PHelper.retrieve
- (Annex.Content.RemoteVerify r)
(\p -> Ssh.runProto r connpool (return (False, UnVerified)) (fallback p))
- key file dest meterupdate
+ key file dest meterupdate vc
| otherwise = giveup "copying from non-ssh, non-http remote not supported"
where
fallback p = unVerified $ feedprogressback $ \p' -> do
res <- onLocalFast st $ ifM (Annex.Content.inAnnex key)
( return True
, runTransfer (Transfer Download u (fromKey id key)) file Nothing stdRetry $ \p -> do
- let verify = Annex.Content.RemoteVerify r
+ let verify = RemoteVerify r
copier <- mkFileCopier hardlink st
let rsp = RetrievalAllKeysSecure
let checksuccess = liftIO checkio >>= \case
, lockContent = if versioned
then lockContent r
else Nothing
- , retrieveKeyFile = \k af dest p ->
+ , retrieveKeyFile = \k af dest p vc ->
if isimport
- then supportversionedretrieve k af dest p $
+ then supportversionedretrieve k af dest p vc $
retrieveKeyFileFromImport dbv ciddbv k af dest p
else if isexport
- then supportversionedretrieve k af dest p $
+ then supportversionedretrieve k af dest p vc $
retrieveKeyFileFromExport dbv k af dest p
- else retrieveKeyFile r k af dest p
+ else retrieveKeyFile r k af dest p vc
, retrieveKeyFileCheap = if versioned
then retrieveKeyFileCheap r
else Nothing
-- versionedExport remotes have a key/value store, so can use
-- the usual retrieveKeyFile, rather than an import/export
-- variant. However, fall back to that if retrieveKeyFile fails.
- supportversionedretrieve k af dest p a
+ supportversionedretrieve k af dest p vc a
| versionedExport (exportActions r) =
- retrieveKeyFile r k af dest p
+ retrieveKeyFile r k af dest p vc
`catchNonAsync` const a
| otherwise = a
addHooks' r starthook stophook = r'
where
r' = r
- { storeKey = \k f p -> wrapper $ storeKey r k f p
- , retrieveKeyFile = \k f d p -> wrapper $ retrieveKeyFile r k f d p
+ { storeKey = \k f p ->
+ wrapper $ storeKey r k f p
+ , retrieveKeyFile = \k f d p vc ->
+ wrapper $ retrieveKeyFile r k f d p vc
, retrieveKeyFileCheap = case retrieveKeyFileCheap r of
Just a -> Just $ \k af f -> wrapper $ a k af f
Nothing -> Nothing
Just False -> giveup "Transfer failed"
Nothing -> remoteUnavail
-retrieve :: VerifyConfig -> (MeterUpdate -> ProtoRunner (Bool, Verification)) -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-retrieve verifyconfig runner k af dest p = do
+retrieve :: (MeterUpdate -> ProtoRunner (Bool, Verification)) -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+retrieve runner k af dest p verifyconfig = do
iv <- startVerifyKeyContentIncrementally verifyconfig k
metered (Just p) k $ \m p' ->
runner p' (P2P.get dest k iv af m p') >>= \case
-}
storeKeyDummy :: Key -> AssociatedFile -> MeterUpdate -> Annex ()
storeKeyDummy _ _ _ = error "missing storeKey implementation"
-retrieveKeyFileDummy :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-retrieveKeyFileDummy _ _ _ _ = error "missing retrieveKeyFile implementation"
+retrieveKeyFileDummy :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+retrieveKeyFileDummy _ _ _ _ _ = error "missing retrieveKeyFile implementation"
removeKeyDummy :: Key -> Annex ()
removeKeyDummy _ = error "missing removeKey implementation"
checkPresentDummy :: Key -> Annex Bool
where
encr = baser
{ storeKey = \k _f p -> cip >>= storeKeyGen k p
- , retrieveKeyFile = \k _f d p -> cip >>= retrieveKeyFileGen k d p
+ , retrieveKeyFile = \k _f d p vc -> cip >>= retrieveKeyFileGen k d p vc
, retrieveKeyFileCheap = case retrieveKeyFileCheap baser of
Nothing -> Nothing
Just a
enck = maybe id snd enc
-- call retriever to get chunks; decrypt them; stream to dest file
- retrieveKeyFileGen k dest p enc =
+ retrieveKeyFileGen k dest p vc enc =
displayprogress p k Nothing $ \p' ->
- retrieveChunks retriever
- (uuid baser)
- (RemoteVerify baser)
+ retrieveChunks retriever (uuid baser) vc
chunkconfig enck k dest p' enc encr
where
enck = maybe id snd enc
gitConfigSpecialRemote u c' [("httpalso", "true")]
return (c', u)
-downloadKey :: Maybe URLString -> LearnedLayout -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-downloadKey baseurl ll key _af dest p = do
+downloadKey :: Maybe URLString -> LearnedLayout -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+downloadKey baseurl ll key _af dest p _vc = do
downloadAction dest p key (keyUrlAction baseurl ll key)
return UnVerified
import Annex.Common
import qualified Annex
import qualified P2P.Protocol as P2P
-import qualified Annex.Content
import P2P.Address
import P2P.Annex
import P2P.IO
, cost = cst
, name = Git.repoDescribe r
, storeKey = store (const protorunner)
- , retrieveKeyFile = retrieve (Annex.Content.RemoteVerify this) (const protorunner)
+ , retrieveKeyFile = retrieve (const protorunner)
, retrieveKeyFileCheap = Nothing
, retrievalSecurityPolicy = RetrievalAllKeysSecure
, removeKey = remove protorunner
(giveup "tahoe failed to store content")
(\cap -> storeCapability rs k cap)
-retrieve :: RemoteStateHandle -> TahoeHandle -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-retrieve rs hdl k _f d _p = do
+retrieve :: RemoteStateHandle -> TahoeHandle -> Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+retrieve rs hdl k _f d _p _ = do
go =<< getCapability rs k
-- Tahoe verifies the content it retrieves using cryptographically
-- secure methods.
, remoteStateHandle = rs
}
-downloadKey :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> Annex Verification
-downloadKey key _af dest p = do
+downloadKey :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfig -> Annex Verification
+downloadKey key _af dest p _ = do
get =<< getWebUrls key
return UnVerified
where
RemoteGitConfig(..),
Remote,
RemoteType,
+ VerifyConfig,
) where
import Annex
type Backend = BackendA Annex
type Remote = RemoteA Annex
type RemoteType = RemoteTypeA Annex
+type VerifyConfig = VerifyConfigA Annex
, RemoteStateHandle
, SetupStage(..)
, Availability(..)
+ , VerifyConfigA(..)
, Verification(..)
, unVerified
, RetrievalSecurityPolicy(..)
-- (The MeterUpdate does not need to be used if it writes
-- sequentially to the file.)
-- Throws exception on failure.
- , retrieveKeyFile :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> a Verification
+ , retrieveKeyFile :: Key -> AssociatedFile -> FilePath -> MeterUpdate -> VerifyConfigA a -> a Verification
-- Retrieves a key's contents to a tmp file, if it can be done cheaply.
-- It's ok to create a symlink or hardlink.
-- Throws exception on failure.
instance ToUUID (RemoteA a) where
toUUID = uuid
+data VerifyConfigA a
+ = AlwaysVerify
+ | NoVerify
+ | RemoteVerify (RemoteA a)
+ | DefaultVerify
+
data Verification
= UnVerified
-- ^ Content was not verified during transfer, but is probably