diff options
Diffstat (limited to 'KeyRing.hs')
-rw-r--r-- | KeyRing.hs | 185 |
1 files changed, 93 insertions, 92 deletions
@@ -80,7 +80,7 @@ home = HomeDir | |||
80 | data InputFile = HomeSec | 80 | data InputFile = HomeSec |
81 | | HomePub | 81 | | HomePub |
82 | | ArgFile FilePath | 82 | | ArgFile FilePath |
83 | | FileDesc Int | 83 | | FileDesc Posix.Fd |
84 | 84 | ||
85 | type UsageTag = String | 85 | type UsageTag = String |
86 | type Initializer = String | 86 | type Initializer = String |
@@ -1132,97 +1132,98 @@ runKeyRing keyring = do | |||
1132 | let (lked, map snd -> failed_locks) = partition (isJust . fst) lks | 1132 | let (lked, map snd -> failed_locks) = partition (isJust . fst) lks |
1133 | ret <- | 1133 | ret <- |
1134 | if not $ null failed_locks | 1134 | if not $ null failed_locks |
1135 | then return $ KikiResult (FailedToLock failed_locks) [] | 1135 | then return $ KikiResult (FailedToLock failed_locks) [] |
1136 | else do | 1136 | else do |
1137 | 1137 | ||
1138 | let doDecrypt = todo | 1138 | let doDecrypt = todo |
1139 | 1139 | ||
1140 | -- merge all keyrings, PEM files, and wallets | 1140 | |
1141 | bresult <- buildKeyDB secring pubring grip0 keyring | 1141 | -- merge all keyrings, PEM files, and wallets |
1142 | 1142 | bresult <- buildKeyDB secring pubring grip0 keyring | |
1143 | try' bresult $ \((db,grip,wk),report_imports) -> do | 1143 | |
1144 | 1144 | try' bresult $ \((db,grip,wk),report_imports) -> do | |
1145 | nonexistents <- | 1145 | |
1146 | filterM (fmap not . doesFileExist . fst) | 1146 | nonexistents <- |
1147 | $ do (f,t) <- Map.toList (kFiles keyring) | 1147 | filterM (fmap not . doesFileExist . fst) |
1148 | f <- resolveInputFile secring pubring f | 1148 | $ do (f,t) <- Map.toList (kFiles keyring) |
1149 | return (f,t) | 1149 | f <- resolveInputFile secring pubring f |
1150 | 1150 | return (f,t) | |
1151 | let (missing,notmissing) = partition (\(_,_,ns,_)->null (ns >>= snd)) $ do | 1151 | |
1152 | (fname,(rtyp,ftyp)) <- nonexistents | 1152 | let (missing,notmissing) = partition (\(_,_,ns,_)->null (ns >>= snd)) $ do |
1153 | guard $ isMutable rtyp | 1153 | (fname,(rtyp,ftyp)) <- nonexistents |
1154 | (topspec,subspec) <- fmap (parseSpec $ maybe "" id grip) | 1154 | guard $ isMutable rtyp |
1155 | $ getUsage ftyp | 1155 | (topspec,subspec) <- fmap (parseSpec $ maybe "" id grip) |
1156 | -- ms will contain duplicates if a top key has multiple matching | 1156 | $ getUsage ftyp |
1157 | -- subkeys. This is intentional. | 1157 | -- ms will contain duplicates if a top key has multiple matching |
1158 | let -- ms = map (keykey . fst) $ selectAll True (topspec,subspec) db | 1158 | -- subkeys. This is intentional. |
1159 | -- ms = filterMatches topspec $ Map.toList db | 1159 | let -- ms = map (keykey . fst) $ selectAll True (topspec,subspec) db |
1160 | ns = do | 1160 | -- ms = filterMatches topspec $ Map.toList db |
1161 | (kk,kd) <- filterMatches topspec $ Map.toList db | 1161 | ns = do |
1162 | return (kk , subkeysForExport subspec kd) | 1162 | (kk,kd) <- filterMatches topspec $ Map.toList db |
1163 | return (fname,subspec,ns,initializer rtyp) | 1163 | return (kk , subkeysForExport subspec kd) |
1164 | (exports0,ambiguous) = partition (\(_,_,ns,_)->null $ drop 1 $ (ns>>=snd)) | 1164 | return (fname,subspec,ns,initializer rtyp) |
1165 | notmissing | 1165 | (exports0,ambiguous) = partition (\(_,_,ns,_)->null $ drop 1 $ (ns>>=snd)) |
1166 | exports = map (\(f,subspec,ns,cmd) -> (f,subspec,ns >>= snd,cmd)) exports0 | 1166 | notmissing |
1167 | 1167 | exports = map (\(f,subspec,ns,cmd) -> (f,subspec,ns >>= snd,cmd)) exports0 | |
1168 | 1168 | ||
1169 | ambiguity (f,topspec,subspec,_) = do | 1169 | |
1170 | return $ KikiResult (AmbiguousKeySpec f) [] | 1170 | ambiguity (f,topspec,subspec,_) = do |
1171 | 1171 | return $ KikiResult (AmbiguousKeySpec f) [] | |
1172 | ifnotnull (x:xs) f g = f x | 1172 | |
1173 | ifnotnull _ f g = g | 1173 | ifnotnull (x:xs) f g = f x |
1174 | 1174 | ifnotnull _ f g = g | |
1175 | ifnotnull ambiguous ambiguity $ do | 1175 | |
1176 | 1176 | ifnotnull ambiguous ambiguity $ do | |
1177 | -- create nonexistent files via external commands | 1177 | |
1178 | externals_ret <- do | 1178 | -- create nonexistent files via external commands |
1179 | let cmds = mapMaybe getcmd missing | 1179 | externals_ret <- do |
1180 | where | 1180 | let cmds = mapMaybe getcmd missing |
1181 | getcmd (fname,subspec,ms,mcmd) = do | 1181 | where |
1182 | cmd <- mcmd | 1182 | getcmd (fname,subspec,ms,mcmd) = do |
1183 | return (fname,subspec,ms,cmd) | 1183 | cmd <- mcmd |
1184 | rs <- forM cmds $ \tup@(fname,subspec,ms,cmd) -> do | 1184 | return (fname,subspec,ms,cmd) |
1185 | e <- systemEnv [ ("file",fname) | 1185 | rs <- forM cmds $ \tup@(fname,subspec,ms,cmd) -> do |
1186 | , ("usage",maybe "" id subspec) ] | 1186 | e <- systemEnv [ ("file",fname) |
1187 | cmd | 1187 | , ("usage",maybe "" id subspec) ] |
1188 | case e of | 1188 | cmd |
1189 | ExitFailure num -> return (tup,FailedExternal num) | 1189 | case e of |
1190 | ExitSuccess -> return (tup,ExternallyGeneratedFile) | 1190 | ExitFailure num -> return (tup,FailedExternal num) |
1191 | 1191 | ExitSuccess -> return (tup,ExternallyGeneratedFile) | |
1192 | v <- foldM importPEMKey (KikiSuccess (db,[])) $ do | 1192 | |
1193 | ((f,subspec,ms,cmd),r) <- rs | 1193 | v <- foldM importPEMKey (KikiSuccess (db,[])) $ do |
1194 | guard $ case r of | 1194 | ((f,subspec,ms,cmd),r) <- rs |
1195 | ExternallyGeneratedFile -> True | 1195 | guard $ case r of |
1196 | _ -> False | 1196 | ExternallyGeneratedFile -> True |
1197 | return (f,subspec,map fst ms,cmd) | 1197 | _ -> False |
1198 | 1198 | return (f,subspec,map fst ms,cmd) | |
1199 | try v $ \(db,import_rs) -> do | 1199 | |
1200 | return $ KikiSuccess (db, map (\((f,_,_,_),r)->(f,r)) rs | 1200 | try v $ \(db,import_rs) -> do |
1201 | ++ import_rs) | 1201 | return $ KikiSuccess (db, map (\((f,_,_,_),r)->(f,r)) rs |
1202 | 1202 | ++ import_rs) | |
1203 | try' externals_ret $ \(db,report_externals) -> do | 1203 | |
1204 | 1204 | try' externals_ret $ \(db,report_externals) -> do | |
1205 | r <- writeWalletKeys keyring db wk | 1205 | |
1206 | try' r $ \report_wallets -> do | 1206 | r <- writeWalletKeys keyring db wk |
1207 | 1207 | try' r $ \report_wallets -> do | |
1208 | r <- writeRingKeys keyring db wk secring pubring | 1208 | |
1209 | try' r $ \report_rings -> do | 1209 | r <- writeRingKeys keyring db wk secring pubring |
1210 | 1210 | try' r $ \report_rings -> do | |
1211 | r <- writePEMKeys db exports | 1211 | |
1212 | try' r $ \report_pems -> do | 1212 | r <- writePEMKeys db exports |
1213 | 1213 | try' r $ \report_pems -> do | |
1214 | let rt = KeyRingRuntime | 1214 | |
1215 | { rtPubring = pubring | 1215 | let rt = KeyRingRuntime |
1216 | , rtSecring = secring | 1216 | { rtPubring = pubring |
1217 | , rtGrip = grip | 1217 | , rtSecring = secring |
1218 | , rtKeyDB = db | 1218 | , rtGrip = grip |
1219 | } | 1219 | , rtKeyDB = db |
1220 | return $ KikiResult (KikiSuccess rt) | 1220 | } |
1221 | $ concat [ report_imports | 1221 | return $ KikiResult (KikiSuccess rt) |
1222 | , report_externals | 1222 | $ concat [ report_imports |
1223 | , report_wallets | 1223 | , report_externals |
1224 | , report_rings | 1224 | , report_wallets |
1225 | , report_pems ] | 1225 | , report_rings |
1226 | , report_pems ] | ||
1226 | 1227 | ||
1227 | forM_ lked $ \(Just lk, fname) -> dotlock_release lk | 1228 | forM_ lked $ \(Just lk, fname) -> dotlock_release lk |
1228 | 1229 | ||