diff options
author | joe <joe@jerkface.net> | 2014-04-29 19:10:01 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2014-04-29 19:10:01 -0400 |
commit | f3c14cb7693bab7a4dee8dae390088feee5a92b0 (patch) | |
tree | 5837601cfe6f6c6164e1e86853d379961d7299bc | |
parent | fb8a8cbe57562a4de1b3a022fff34bca2d2db5ab (diff) |
combined secring/pubring paths into an InputFileContext structure.
-rw-r--r-- | KeyRing.hs | 105 |
1 files changed, 56 insertions, 49 deletions
@@ -247,22 +247,22 @@ data KeyRingOperation = KeyRingOperation | |||
247 | , homeSpec :: Maybe String | 247 | , homeSpec :: Maybe String |
248 | } | 248 | } |
249 | 249 | ||
250 | resolveInputFile :: FilePath -> FilePath -> InputFile -> [FilePath] | 250 | resolveInputFile :: InputFileContext -> InputFile -> [FilePath] |
251 | resolveInputFile secring pubring = resolve | 251 | resolveInputFile 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 | ||
259 | filesToLock :: | 259 | filesToLock :: |
260 | KeyRingOperation -> FilePath -> FilePath -> [FilePath] | 260 | KeyRingOperation -> InputFileContext -> [FilePath] |
261 | filesToLock k secring pubring = do | 261 | filesToLock 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 | ||
831 | data InputFileContext = InputFileContext | ||
832 | { homesecPath :: FilePath | ||
833 | , homepubPath :: FilePath | ||
834 | } | ||
835 | |||
836 | |||
837 | readInputFileS :: InputFileContext -> InputFile -> IO S.ByteString | ||
838 | readInputFileS ctx (FileDesc fd) = fdToHandle fd >>= S.hGetContents | ||
839 | readInputFileS ctx inp = do | ||
840 | let fname = resolveInputFile ctx inp | ||
841 | fmap S.concat $ mapM S.readFile fname | ||
831 | 842 | ||
832 | cachedContents :: FilePath -> FilePath -> InputFile -> IO (IO S.ByteString) | 843 | cachedContents :: InputFileContext -> InputFile -> IO (IO S.ByteString) |
833 | cachedContents secring pubring fd = do | 844 | cachedContents 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 | |||
851 | importPEMKey :: | 857 | importPEMKey :: |
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 | ||
866 | mergeHostFiles :: KeyRingOperation -> KeyDB | 872 | mergeHostFiles :: 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)])) |
878 | mergeHostFiles krd db secring pubring = do | 882 | mergeHostFiles 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 | ||
926 | writeHostsFiles | 930 | writeHostsFiles |
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)] |
936 | writeHostsFiles krd secring pubring (hostdbs0,hostdbs,u1,gpgnames,outgoing_names) = do | 938 | writeHostsFiles 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 | ||
966 | buildKeyDB :: (MappedPacket -> IO (KikiCondition Packet)) | 968 | buildKeyDB :: (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)])) |
979 | buildKeyDB doDecrypt secring pubring grip0 keyring = do | 981 | buildKeyDB 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 | ||
1536 | makeMemoizingDecrypter :: KeyRingOperation -> FilePath -> FilePath | 1539 | makeMemoizingDecrypter :: KeyRingOperation -> InputFileContext |
1537 | -> IO (MappedPacket -> IO (KikiCondition Packet)) | 1540 | -> IO (MappedPacket -> IO (KikiCondition Packet)) |
1538 | makeMemoizingDecrypter operation secring pubring = do | 1541 | makeMemoizingDecrypter 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 | ||
1631 | initializeMissingPEMFiles :: | 1634 | initializeMissingPEMFiles :: |
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)])) |
1641 | initializeMissingPEMFiles operation secring pubring grip decrypt db = do | 1644 | initializeMissingPEMFiles 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 |