From 4fc681f78b2e659d3db3da99fe7c640416fb3b43 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 15 Sep 2016 00:26:33 -0400 Subject: Change format of ~/.keysafe/backup.log Allow deserializing SecretKeySource so we can later know what gpg keys are backed up. Converted KeyId to Text as JSON can't handle ByteString. --- BackupRecord.hs | 4 ++-- Benchmark.hs | 6 ++++-- CHANGELOG | 1 + CmdLine.hs | 3 ++- Gpg.hs | 5 +++-- Serialization.hs | 5 +++-- Types.hs | 14 +++++++++++--- UI/Readline.hs | 3 ++- UI/Zenity.hs | 5 +++-- 9 files changed, 31 insertions(+), 15 deletions(-) diff --git a/BackupRecord.hs b/BackupRecord.hs index 39e07fa..6d150e1 100644 --- a/BackupRecord.hs +++ b/BackupRecord.hs @@ -34,7 +34,7 @@ import qualified Data.ByteString.Lazy as B data BackupRecord = BackupRecord { backupDate :: POSIXTime , backupServers :: [HostName] - , secretKeySource :: String + , secretKeySource :: SecretKeySource , passwordEntropy :: Int } deriving (Show, Generic) @@ -46,7 +46,7 @@ mkBackupRecord :: [Server] -> SecretKeySource -> Entropy UnknownPassword -> IO B mkBackupRecord servers sks (Entropy n) = BackupRecord <$> getPOSIXTime <*> pure (map serverName servers) - <*> pure (show sks) + <*> pure sks <*> pure n backupRecordFile :: IO FilePath diff --git a/Benchmark.hs b/Benchmark.hs index c121e17..66436fe 100644 --- a/Benchmark.hs +++ b/Benchmark.hs @@ -14,6 +14,7 @@ import HTTP.ProofOfWork import Cost import Serialization () import qualified Data.ByteString.UTF8 as BU8 +import qualified Data.Text as T import qualified Crypto.Argon2 as Argon2 import Data.Time.Clock import Control.DeepSeq @@ -41,10 +42,11 @@ benchmarkExpensiveHash' rounds tunables@(UseArgon2 _ hashopts) expected = do forM_ [1..rounds] $ \n -> do -- Must vary the data being hashed to avoid laziness -- caching hash results. - let base = BU8.fromString (show n) + let base = T.pack (show n) + let baseb = BU8.fromString (show n) let ExpensiveHash _ t = expensiveHash tunables (Salt (GpgKey (KeyId (base <> "dummy")))) - (base <> "himom") + (baseb <> "himom") t `deepseq` return () end <- getCurrentTime let diff = floor (end `diffUTCTime` start) :: Integer diff --git a/CHANGELOG b/CHANGELOG index e4862ff..ef53ce9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ keysafe (0.20160915) UNRELEASED; urgency=medium proof of work. * Make rate limiter adapt to ongoing load more quickly -- every 15 minutes instead of every 60. + * Change format of ~/.keysafe/backup.log -- Joey Hess Wed, 14 Sep 2016 20:19:43 -0400 diff --git a/CmdLine.hs b/CmdLine.hs index a41a759..686fcb5 100644 --- a/CmdLine.hs +++ b/CmdLine.hs @@ -12,6 +12,7 @@ import Tunables import qualified Gpg import Options.Applicative import qualified Data.ByteString.UTF8 as BU8 +import qualified Data.Text as T import System.Directory import Network.Wai.Handler.Warp (Port) @@ -79,7 +80,7 @@ parse = CmdLine ( long "test" <> help "Run test suite." ) - gpgswitch = GpgKey . KeyId . BU8.fromString <$> strOption + gpgswitch = GpgKey . KeyId . T.pack <$> strOption ( long "gpgkeyid" <> metavar "KEYID" <> help "Specify keyid of gpg key to back up or restore. (When this option is used to back up a key, it must also be used at restore time.)" diff --git a/Gpg.hs b/Gpg.hs index 4522cfb..c752059 100644 --- a/Gpg.hs +++ b/Gpg.hs @@ -15,6 +15,7 @@ import System.IO import System.Exit import qualified Data.ByteString as B import qualified Data.ByteString.UTF8 as BU8 +import qualified Data.Text as T -- | Pick gpg secret key to back up. -- @@ -51,7 +52,7 @@ listSecretKeys = map mk . parse . lines <$> readProcess "gpg" extract c (Just keyid) rest extract c k (_:rest) = extract c k rest - mk (userid, keyid) = (Name (BU8.fromString userid), KeyId (BU8.fromString keyid)) + mk (userid, keyid) = (Name (BU8.fromString userid), KeyId (T.pack keyid)) getSecretKey :: KeyId -> IO SecretKey getSecretKey (KeyId kid) = do @@ -63,7 +64,7 @@ getSecretKey (KeyId kid) = do ExitSuccess -> return secretkey _ -> error "gpg --export-secret-key failed" where - ps = ["--batch", "--export-secret-key", BU8.toString kid] + ps = ["--batch", "--export-secret-key", T.unpack kid] writeSecretKey :: SecretKey -> IO () writeSecretKey (SecretKey b) = do diff --git a/Serialization.hs b/Serialization.hs index eb6394c..9803d71 100644 --- a/Serialization.hs +++ b/Serialization.hs @@ -12,6 +12,7 @@ import Types import Raaz.Core.Encode import qualified Data.ByteString as B import qualified Data.ByteString.UTF8 as BU8 +import qualified Data.Text as T import Data.Monoid import Data.Word @@ -19,7 +20,7 @@ import Data.Word -- For example "gpg C910D9222512E3C7", or "file path". instance Encodable SecretKeySource where toByteString (GpgKey (KeyId b)) = - "gpg" <> B.singleton sepChar <> b + "gpg" <> B.singleton sepChar <> BU8.fromString (T.unpack b) toByteString (KeyFile f) = "file" <> B.singleton sepChar <> BU8.fromString f fromByteString b = case B.break (== sepChar) b of @@ -28,7 +29,7 @@ instance Encodable SecretKeySource where | otherwise -> let i = B.drop 1 rest in case t of - "gpg" -> Just $ GpgKey (KeyId i) + "gpg" -> Just $ GpgKey (KeyId (T.pack (BU8.toString i))) "file" -> Just $ KeyFile (BU8.toString i) _ -> Nothing diff --git a/Types.hs b/Types.hs index 2ab5d6c..c065da3 100644 --- a/Types.hs +++ b/Types.hs @@ -9,9 +9,11 @@ module Types where import Types.Cost import qualified Data.ByteString as B +import qualified Data.Text as T import Data.String import Control.DeepSeq import GHC.Generics (Generic) +import Data.Aeson -- | keysafe stores secret keys. newtype SecretKey = SecretKey B.ByteString @@ -53,11 +55,17 @@ newtype Name = Name B.ByteString -- | Source of the secret key stored in keysafe. data SecretKeySource = GpgKey KeyId | KeyFile FilePath - deriving (Show) + deriving (Show, Generic) + +instance ToJSON SecretKeySource +instance FromJSON SecretKeySource -- | The keyid is any value that is unique to a private key, and can be -- looked up somehow without knowing the private key. -- -- A gpg keyid is the obvious example. -data KeyId = KeyId B.ByteString - deriving (Show) +data KeyId = KeyId T.Text + deriving (Show, Generic) + +instance ToJSON KeyId +instance FromJSON KeyId diff --git a/UI/Readline.hs b/UI/Readline.hs index 0f852ea..7f19f67 100644 --- a/UI/Readline.hs +++ b/UI/Readline.hs @@ -17,6 +17,7 @@ import Data.Char import Text.Read import Control.Monad import qualified Data.ByteString.UTF8 as BU8 +import qualified Data.Text as T readlineUI :: UI readlineUI = UI @@ -129,7 +130,7 @@ myPromptKeyId title desc l = do putStrLn desc putStrLn "" forM_ nl $ \(n, ((Name name), (KeyId kid))) -> - putStrLn $ show n ++ ".\t" ++ BU8.toString name ++ " (keyid " ++ BU8.toString kid ++ ")" + putStrLn $ show n ++ ".\t" ++ BU8.toString name ++ " (keyid " ++ T.unpack kid ++ ")" prompt where nl = zip [1 :: Integer ..] l diff --git a/UI/Zenity.hs b/UI/Zenity.hs index 943be14..74810d9 100644 --- a/UI/Zenity.hs +++ b/UI/Zenity.hs @@ -15,6 +15,7 @@ import System.FilePath import System.Directory import System.Exit import qualified Data.ByteString.UTF8 as BU8 +import qualified Data.Text as T zenityUI :: UI zenityUI = UI @@ -122,12 +123,12 @@ myPromptKeyId title desc l = do , "--print-column", "ALL" , "--separator", "\BEL" , "--width", "500" - ] ++ concatMap (\(Name n, KeyId kid) -> [BU8.toString n, BU8.toString kid]) l + ] ++ concatMap (\(Name n, KeyId kid) -> [BU8.toString n, T.unpack kid]) l (ret, ok) <- waitZenity h if ok then do let (_n, _:kid) = break (== '\BEL') ret - return $ Just (KeyId (BU8.fromString kid)) + return $ Just (KeyId (T.pack kid)) else return Nothing myWithProgress :: Title -> Desc -> ((Percent -> IO ()) -> IO a) -> IO a -- cgit v1.2.3