summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-04-29 19:10:01 -0400
committerjoe <joe@jerkface.net>2014-04-29 19:10:01 -0400
commitf3c14cb7693bab7a4dee8dae390088feee5a92b0 (patch)
tree5837601cfe6f6c6164e1e86853d379961d7299bc
parentfb8a8cbe57562a4de1b3a022fff34bca2d2db5ab (diff)
combined secring/pubring paths into an InputFileContext structure.
-rw-r--r--KeyRing.hs105
1 files changed, 56 insertions, 49 deletions
diff --git a/KeyRing.hs b/KeyRing.hs
index d057cd4..85f2944 100644
--- a/KeyRing.hs
+++ b/KeyRing.hs
@@ -247,22 +247,22 @@ data KeyRingOperation = KeyRingOperation
247 , homeSpec :: Maybe String 247 , homeSpec :: Maybe String
248 } 248 }
249 249
250resolveInputFile :: FilePath -> FilePath -> InputFile -> [FilePath] 250resolveInputFile :: InputFileContext -> InputFile -> [FilePath]
251resolveInputFile secring pubring = resolve 251resolveInputFile ctx = resolve
252 where 252 where
253 resolve HomeSec = return secring 253 resolve HomeSec = return (homesecPath ctx)
254 resolve HomePub = return pubring 254 resolve HomePub = return (homepubPath ctx)
255 resolve (ArgFile f) = return f 255 resolve (ArgFile f) = return f
256 resolve _ = [] 256 resolve _ = []
257 257
258 258
259filesToLock :: 259filesToLock ::
260 KeyRingOperation -> FilePath -> FilePath -> [FilePath] 260 KeyRingOperation -> InputFileContext -> [FilePath]
261filesToLock k secring pubring = do 261filesToLock k ctx = do
262 (f,stream) <- Map.toList (kFiles k) 262 (f,stream) <- Map.toList (kFiles k)
263 case fill stream of 263 case fill stream of
264 KF_None -> [] 264 KF_None -> []
265 _ -> resolveInputFile secring pubring f 265 _ -> resolveInputFile ctx f
266 266
267 267
268-- kret :: a -> KeyRingOperation a 268-- kret :: a -> KeyRingOperation a
@@ -828,9 +828,20 @@ seek_key (KeyUidMatch pat) ps
828 uidStr _ = "" 828 uidStr _ = ""
829 829
830 830
831data InputFileContext = InputFileContext
832 { homesecPath :: FilePath
833 , homepubPath :: FilePath
834 }
835
836
837readInputFileS :: InputFileContext -> InputFile -> IO S.ByteString
838readInputFileS ctx (FileDesc fd) = fdToHandle fd >>= S.hGetContents
839readInputFileS ctx inp = do
840 let fname = resolveInputFile ctx inp
841 fmap S.concat $ mapM S.readFile fname
831 842
832cachedContents :: FilePath -> FilePath -> InputFile -> IO (IO S.ByteString) 843cachedContents :: InputFileContext -> InputFile -> IO (IO S.ByteString)
833cachedContents secring pubring fd = do 844cachedContents ctx fd = do
834 ref <- newIORef Nothing 845 ref <- newIORef Nothing
835 return $ get ref fd 846 return $ get ref fd
836 where 847 where
@@ -839,15 +850,10 @@ cachedContents secring pubring fd = do
839 get ref fd = do 850 get ref fd = do
840 pw <- readIORef ref 851 pw <- readIORef ref
841 flip (flip maybe return) pw $ do 852 flip (flip maybe return) pw $ do
842 pw <- fmap trimCR $ getContents fd 853 pw <- fmap trimCR $ readInputFileS ctx fd
843 writeIORef ref (Just pw) 854 writeIORef ref (Just pw)
844 return pw 855 return pw
845 856
846 getContents (FileDesc fd) = fdToHandle fd >>= S.hGetContents
847 getContents inp = do
848 let fname = resolveInputFile secring pubring inp
849 fmap S.concat $ mapM S.readFile fname
850
851importPEMKey :: 857importPEMKey ::
852 (MappedPacket -> IO (KikiCondition Packet)) 858 (MappedPacket -> IO (KikiCondition Packet))
853 -> KikiCondition 859 -> KikiCondition
@@ -863,9 +869,7 @@ importPEMKey doDecrypt db' tup = do
863 return $ KikiSuccess (db'', report0 ++ report) 869 return $ KikiSuccess (db'', report0 ++ report)
864 870
865 871
866mergeHostFiles :: KeyRingOperation -> KeyDB 872mergeHostFiles :: KeyRingOperation -> KeyDB -> InputFileContext
867 -> FilePath
868 -> FilePath
869 -> IO 873 -> IO
870 (KikiCondition 874 (KikiCondition
871 ( ( Map.Map [Char8.ByteString] KeyData 875 ( ( Map.Map [Char8.ByteString] KeyData
@@ -875,14 +879,14 @@ mergeHostFiles :: KeyRingOperation -> KeyDB
875 , [(SockAddr, ([Char8.ByteString], [Char8.ByteString]))] 879 , [(SockAddr, ([Char8.ByteString], [Char8.ByteString]))]
876 , [SockAddr])) 880 , [SockAddr]))
877 , [(FilePath,KikiReportAction)])) 881 , [(FilePath,KikiReportAction)]))
878mergeHostFiles krd db secring pubring = do 882mergeHostFiles krd db ctx = do
879 let hns = files ishosts 883 let hns = files ishosts
880 ishosts Hosts = True 884 ishosts Hosts = True
881 ishosts _ = False 885 ishosts _ = False
882 files istyp = do 886 files istyp = do
883 (f,stream) <- Map.toList (kFiles krd) 887 (f,stream) <- Map.toList (kFiles krd)
884 guard (istyp $ typ stream) 888 guard (istyp $ typ stream)
885 resolveInputFile secring pubring f 889 resolveInputFile ctx f
886 890
887 hostdbs0 <- mapM (fmap Hosts.decode . L.readFile) hns 891 hostdbs0 <- mapM (fmap Hosts.decode . L.readFile) hns
888 892
@@ -924,16 +928,14 @@ mergeHostFiles krd db secring pubring = do
924 return $ KikiSuccess ((db',(hostdbs0,hostdbs,u1,gpgnames,outgoing_names)),[]) 928 return $ KikiSuccess ((db',(hostdbs0,hostdbs,u1,gpgnames,outgoing_names)),[])
925 929
926writeHostsFiles 930writeHostsFiles
927 :: KeyRingOperation 931 :: KeyRingOperation -> InputFileContext
928 -> [Char]
929 -> [Char]
930 -> ([Hosts.Hosts], 932 -> ([Hosts.Hosts],
931 [Hosts.Hosts], 933 [Hosts.Hosts],
932 Hosts.Hosts, 934 Hosts.Hosts,
933 [(SockAddr, (t1, [Char8.ByteString]))], 935 [(SockAddr, (t1, [Char8.ByteString]))],
934 [SockAddr]) 936 [SockAddr])
935 -> IO [(FilePath, KikiReportAction)] 937 -> IO [(FilePath, KikiReportAction)]
936writeHostsFiles krd secring pubring (hostdbs0,hostdbs,u1,gpgnames,outgoing_names) = do 938writeHostsFiles krd ctx (hostdbs0,hostdbs,u1,gpgnames,outgoing_names) = do
937 let hns = files isMutableHosts 939 let hns = files isMutableHosts
938 isMutableHosts (fill -> KF_None) = False 940 isMutableHosts (fill -> KF_None) = False
939 isMutableHosts (typ -> Hosts) = True 941 isMutableHosts (typ -> Hosts) = True
@@ -941,7 +943,7 @@ writeHostsFiles krd secring pubring (hostdbs0,hostdbs,u1,gpgnames,outgoing_names
941 files istyp = do 943 files istyp = do
942 (f,stream) <- Map.toList (kFiles krd) 944 (f,stream) <- Map.toList (kFiles krd)
943 guard (istyp stream) 945 guard (istyp stream)
944 resolveInputFile secring pubring f 946 resolveInputFile ctx f
945 947
946 -- 3. add hostnames from gpg for addresses not in U 948 -- 3. add hostnames from gpg for addresses not in U
947 let u = foldl' f u1 ans 949 let u = foldl' f u1 ans
@@ -964,7 +966,7 @@ writeHostsFiles krd secring pubring (hostdbs0,hostdbs,u1,gpgnames,outgoing_names
964 966
965 967
966buildKeyDB :: (MappedPacket -> IO (KikiCondition Packet)) 968buildKeyDB :: (MappedPacket -> IO (KikiCondition Packet))
967 -> FilePath -> FilePath -> Maybe String -> KeyRingOperation 969 -> InputFileContext -> Maybe String -> KeyRingOperation
968 -> IO (KikiCondition ((KeyDB 970 -> IO (KikiCondition ((KeyDB
969 ,Maybe String 971 ,Maybe String
970 ,Maybe MappedPacket 972 ,Maybe MappedPacket
@@ -976,17 +978,17 @@ buildKeyDB :: (MappedPacket -> IO (KikiCondition Packet))
976 ,Map.Map FilePath Access 978 ,Map.Map FilePath Access
977 ) 979 )
978 ,[(FilePath,KikiReportAction)])) 980 ,[(FilePath,KikiReportAction)]))
979buildKeyDB doDecrypt secring pubring grip0 keyring = do 981buildKeyDB doDecrypt ctx grip0 keyring = do
980 let 982 let
981 files isring = do 983 files isring = do
982 (f,stream) <- Map.toList (kFiles keyring) 984 (f,stream) <- Map.toList (kFiles keyring)
983 guard (isring $ typ stream) 985 guard (isring $ typ stream)
984 resolveInputFile secring pubring f 986 resolveInputFile ctx f
985 987
986 filesAccs isring = do 988 filesAccs isring = do
987 (f,stream) <- Map.toList (kFiles keyring) 989 (f,stream) <- Map.toList (kFiles keyring)
988 guard (isring $ typ stream) 990 guard (isring $ typ stream)
989 n <- resolveInputFile secring pubring f 991 n <- resolveInputFile ctx f
990 return (n, access stream) 992 return (n, access stream)
991 993
992 readp (n,acc) = fmap readp0 $ readPacketsFromFile n 994 readp (n,acc) = fmap readp0 $ readPacketsFromFile n
@@ -1020,8 +1022,8 @@ buildKeyDB doDecrypt secring pubring grip0 keyring = do
1020 where 1022 where
1021 fstkey = listToMaybe $ mapMaybe isSecringKey ms 1023 fstkey = listToMaybe $ mapMaybe isSecringKey ms
1022 where isSecringKey ((fn,_),Message ps) 1024 where isSecringKey ((fn,_),Message ps)
1023 | fn==secring = listToMaybe ps 1025 | fn==homesecPath ctx = listToMaybe ps
1024 isSecringKey _ = Nothing 1026 isSecringKey _ = Nothing
1025 db_rings = foldl' (\db ((fname,_),ps) -> merge db fname ps) Map.empty ms 1027 db_rings = foldl' (\db ((fname,_),ps) -> merge db fname ps) Map.empty ms
1026 1028
1027 wk = listToMaybe $ do 1029 wk = listToMaybe $ do
@@ -1049,7 +1051,7 @@ buildKeyDB doDecrypt secring pubring grip0 keyring = do
1049 let pems = do 1051 let pems = do
1050 (n,stream) <- Map.toList $ kFiles keyring 1052 (n,stream) <- Map.toList $ kFiles keyring
1051 grip <- maybeToList grip 1053 grip <- maybeToList grip
1052 n <- resolveInputFile secring pubring n 1054 n <- resolveInputFile ctx n
1053 guard $ spillable stream && ispem (typ stream) 1055 guard $ spillable stream && ispem (typ stream)
1054 let us = mapMaybe usageFromFilter [fill stream,spill stream] 1056 let us = mapMaybe usageFromFilter [fill stream,spill stream]
1055 usage <- take 1 us 1057 usage <- take 1 us
@@ -1063,7 +1065,7 @@ buildKeyDB doDecrypt secring pubring grip0 keyring = do
1063 db <- foldM (importPEMKey doDecrypt) (KikiSuccess (db,[])) imports 1065 db <- foldM (importPEMKey doDecrypt) (KikiSuccess (db,[])) imports
1064 try db $ \(db,reportPEMs) -> do 1066 try db $ \(db,reportPEMs) -> do
1065 1067
1066 r <- mergeHostFiles keyring db secring pubring 1068 r <- mergeHostFiles keyring db ctx
1067 try r $ \((db,hs),reportHosts) -> do 1069 try r $ \((db,hs),reportHosts) -> do
1068 1070
1069 return $ KikiSuccess ( (db, grip, mwk, hs, accs), reportWallets ++ reportPEMs ) 1071 return $ KikiSuccess ( (db, grip, mwk, hs, accs), reportWallets ++ reportPEMs )
@@ -1289,7 +1291,7 @@ writeWalletKeys krd db wk = do
1289 files pred = do 1291 files pred = do
1290 (f,stream) <- Map.toList (kFiles krd) 1292 (f,stream) <- Map.toList (kFiles krd)
1291 guard (pred stream) 1293 guard (pred stream)
1292 resolveInputFile "" "" f 1294 resolveInputFile (InputFileContext "" "") f
1293 let writeWallet report n = do 1295 let writeWallet report n = do
1294 let cs' = do 1296 let cs' = do
1295 (nw,mp) <- cs 1297 (nw,mp) <- cs
@@ -1370,11 +1372,12 @@ writeRingKeys krd rt {- db wk secring pubring -} = do
1370 db = rtKeyDB rt 1372 db = rtKeyDB rt
1371 secring = rtSecring rt 1373 secring = rtSecring rt
1372 pubring = rtPubring rt 1374 pubring = rtPubring rt
1375 ctx = InputFileContext secring pubring
1373 let s = do 1376 let s = do
1374 (f,f0,stream) <- do 1377 (f,f0,stream) <- do
1375 (f0,stream) <- Map.toList (kFiles krd) 1378 (f0,stream) <- Map.toList (kFiles krd)
1376 guard (isring $ typ stream) 1379 guard (isring $ typ stream)
1377 f <- resolveInputFile secring pubring f0 1380 f <- resolveInputFile ctx f0
1378 return (f,f0,stream) 1381 return (f,f0,stream)
1379 let x = do 1382 let x = do
1380 let wantedForFill :: Access -> KeyFilter -> KeyData -> Maybe Bool 1383 let wantedForFill :: Access -> KeyFilter -> KeyData -> Maybe Bool
@@ -1533,15 +1536,15 @@ writePEMKeys doDecrypt db exports = do
1533 try pun $ \pun -> do 1536 try pun $ \pun -> do
1534 return $ KikiSuccess (fname,pun) 1537 return $ KikiSuccess (fname,pun)
1535 1538
1536makeMemoizingDecrypter :: KeyRingOperation -> FilePath -> FilePath 1539makeMemoizingDecrypter :: KeyRingOperation -> InputFileContext
1537 -> IO (MappedPacket -> IO (KikiCondition Packet)) 1540 -> IO (MappedPacket -> IO (KikiCondition Packet))
1538makeMemoizingDecrypter operation secring pubring = do 1541makeMemoizingDecrypter operation ctx = do
1539 pws <- 1542 pws <-
1540 -- TODO: head will throw an exception if a File Descriptor operation 1543 -- TODO: head will throw an exception if a File Descriptor operation
1541 -- file is present. We probably should change OriginMap to use InputFile 1544 -- file is present. We probably should change OriginMap to use InputFile
1542 -- instead of FilePath. 1545 -- instead of FilePath.
1543 Traversable.mapM (cachedContents secring pubring . fromJust . pwfile . typ) 1546 Traversable.mapM (cachedContents ctx . fromJust . pwfile . typ)
1544 (Map.mapKeys (head . resolveInputFile secring pubring) 1547 (Map.mapKeys (head . resolveInputFile ctx)
1545 $ Map.filter (isJust . pwfile . typ) $ kFiles operation) 1548 $ Map.filter (isJust . pwfile . typ) $ kFiles operation)
1546 unkeysRef <- newIORef Map.empty 1549 unkeysRef <- newIORef Map.empty
1547 return $ doDecrypt unkeysRef pws 1550 return $ doDecrypt unkeysRef pws
@@ -1630,7 +1633,7 @@ performManipulations doDecrypt operation rt wk = do
1630 1633
1631initializeMissingPEMFiles :: 1634initializeMissingPEMFiles ::
1632 KeyRingOperation 1635 KeyRingOperation
1633 -> FilePath -> FilePath -> Maybe String 1636 -> InputFileContext -> Maybe String
1634 -> (MappedPacket -> IO (KikiCondition Packet)) 1637 -> (MappedPacket -> IO (KikiCondition Packet))
1635 -> KeyDB 1638 -> KeyDB
1636 -> IO (KikiCondition ( (KeyDB,[( FilePath 1639 -> IO (KikiCondition ( (KeyDB,[( FilePath
@@ -1638,11 +1641,11 @@ initializeMissingPEMFiles ::
1638 , [MappedPacket] 1641 , [MappedPacket]
1639 , Maybe Initializer)]) 1642 , Maybe Initializer)])
1640 , [(FilePath,KikiReportAction)])) 1643 , [(FilePath,KikiReportAction)]))
1641initializeMissingPEMFiles operation secring pubring grip decrypt db = do 1644initializeMissingPEMFiles operation ctx grip decrypt db = do
1642 nonexistents <- 1645 nonexistents <-
1643 filterM (fmap not . doesFileExist . fst) 1646 filterM (fmap not . doesFileExist . fst)
1644 $ do (f,t) <- Map.toList (kFiles operation) 1647 $ do (f,t) <- Map.toList (kFiles operation)
1645 f <- resolveInputFile secring pubring f 1648 f <- resolveInputFile ctx f
1646 return (f,t) 1649 return (f,t)
1647 1650
1648 let (missing,notmissing) = partition (\(_,_,ns,_)->null (ns >>= snd)) $ do 1651 let (missing,notmissing) = partition (\(_,_,ns,_)->null (ns >>= snd)) $ do
@@ -1715,7 +1718,10 @@ runKeyRing operation = do
1715 Left e -> return $ KikiResult e [] 1718 Left e -> return $ KikiResult e []
1716 Right wkun -> body wkun 1719 Right wkun -> body wkun
1717 try' homedir $ \(homedir,secring,pubring,grip0) -> do 1720 try' homedir $ \(homedir,secring,pubring,grip0) -> do
1718 let tolocks = filesToLock operation secring pubring 1721 let ctx = InputFileContext secring pubring
1722 tolocks = filesToLock operation ctx
1723 secring <- return Nothing
1724 pubring <- return Nothing
1719 lks <- forM tolocks $ \f -> do 1725 lks <- forM tolocks $ \f -> do
1720 lk <- dotlock_create f 0 1726 lk <- dotlock_create f 0
1721 v <- flip (maybe $ return Nothing) lk $ \lk -> do 1727 v <- flip (maybe $ return Nothing) lk $ \lk -> do
@@ -1732,21 +1738,22 @@ runKeyRing operation = do
1732 -- memoizing decrypter 1738 -- memoizing decrypter
1733 -- TODO: Unspilled keyrings should be usable for decrypting 1739 -- TODO: Unspilled keyrings should be usable for decrypting
1734 -- and signing. 1740 -- and signing.
1735 decrypt <- makeMemoizingDecrypter operation secring pubring 1741 decrypt <- makeMemoizingDecrypter operation ctx
1736 1742
1737 -- merge all keyrings, PEM files, and wallets 1743 -- merge all keyrings, PEM files, and wallets
1738 bresult <- buildKeyDB decrypt secring pubring grip0 operation 1744 bresult <- buildKeyDB decrypt ctx grip0 operation
1739 try' bresult $ \((db,grip,wk,hs,accs),report_imports) -> do 1745 try' bresult $ \((db,grip,wk,hs,accs),report_imports) -> do
1740 1746
1741 externals_ret <- initializeMissingPEMFiles operation 1747 externals_ret <- initializeMissingPEMFiles operation
1742 secring pubring grip 1748 ctx
1749 grip
1743 decrypt 1750 decrypt
1744 db 1751 db
1745 try' externals_ret $ \((db,exports),report_externals) -> do 1752 try' externals_ret $ \((db,exports),report_externals) -> do
1746 1753
1747 let rt = KeyRingRuntime 1754 let rt = KeyRingRuntime
1748 { rtPubring = pubring 1755 { rtPubring = homepubPath ctx
1749 , rtSecring = secring 1756 , rtSecring = homesecPath ctx
1750 , rtGrip = grip 1757 , rtGrip = grip
1751 , rtWorkingKey = fmap packet wk 1758 , rtWorkingKey = fmap packet wk
1752 , rtKeyDB = db 1759 , rtKeyDB = db
@@ -1768,7 +1775,7 @@ runKeyRing operation = do
1768 r <- writePEMKeys decrypt (rtKeyDB rt) exports 1775 r <- writePEMKeys decrypt (rtKeyDB rt) exports
1769 try' r $ \report_pems -> do 1776 try' r $ \report_pems -> do
1770 1777
1771 import_hosts <- writeHostsFiles operation secring pubring hs 1778 import_hosts <- writeHostsFiles operation ctx hs
1772 1779
1773 return $ KikiResult (KikiSuccess rt) 1780 return $ KikiResult (KikiSuccess rt)
1774 $ concat [ report_imports 1781 $ concat [ report_imports