diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-08-11 20:44:07 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-08-11 20:44:07 -0400 |
commit | a3834e558cf6ae04826b44e65a02ee22286f7952 (patch) | |
tree | 571159729a9392579aa993e3f3da8dd58745c0b3 | |
parent | ab3594dacb0461ae5e253544f65c3e3d50eb721d (diff) | |
download | keysafe-a3834e558cf6ae04826b44e65a02ee22286f7952.tar.gz |
write via temp file
avoids short reads, and also if a backup program came along while the write
was happening, avoids short backups
-rw-r--r-- | Storage.hs | 3 | ||||
-rw-r--r-- | Storage/LocalFiles.hs | 8 | ||||
-rw-r--r-- | keysafe.hs | 1 |
3 files changed, 10 insertions, 2 deletions
@@ -11,7 +11,8 @@ data Storage = Storage { storeShard :: StorableObjectIdent -> Shard -> IO StoreResult , retrieveShard :: ShardNum -> StorableObjectIdent -> IO RetrieveResult , obscureShards :: IO ObscureResult - -- ^ run after making some changes, to avoid correlation attacks + -- ^ run after making some calls to storeShard/retrieveShard, + -- to avoid correlation attacks } data StoreResult = StoreSuccess | StoreFailure String diff --git a/Storage/LocalFiles.hs b/Storage/LocalFiles.hs index 083a74e..b81ecbe 100644 --- a/Storage/LocalFiles.hs +++ b/Storage/LocalFiles.hs @@ -34,11 +34,14 @@ store :: StorableObjectIdent -> Shard -> IO StoreResult store i s = onError (StoreFailure . show) $ do dir <- shardDir createDirectoryIfMissing True dir - fd <- openFd (dir </> shardFile i) WriteOnly (Just 0o666) + let dest = dir </> shardFile i + let tmp = dest ++ ".tmp" + fd <- openFd tmp WriteOnly (Just 0o666) (defaultFileFlags { exclusive = True } ) h <- fdToHandle fd B.hPut h (toByteString s) hClose h + renameFile tmp dest return StoreSuccess retrieve :: ShardNum -> StorableObjectIdent -> IO RetrieveResult @@ -56,6 +59,9 @@ retrieve n i = onError (RetrieveFailure . show) $ do -- There is no way to set the ctime to the epoch, but setting the other -- times does at least set it to the current time, which makes all -- currently stored files look alike. +-- +-- Note that the contents of shards is never changed, so it's ok to set the +-- mtime to the epoch; backup programs won't be confused. obscure :: IO ObscureResult obscure = onError (ObscureFailure . show) $ do dir <- shardDir @@ -45,6 +45,7 @@ retrievedemo = do let l = drop 1 $ zip [1..] (getIdents sis) shards <- map (\(RetrieveSuccess s) -> s) <$> mapM (uncurry (retrieveShard localFiles)) l + _ <- obscureShards localFiles let esk = combineShards tunables shards kek <- genKeyEncryptionKey tunables name password -- TODO: need to solve the encryption puzzle |