From 278e30eb03b821c9ce9502eb3879ef728367dde8 Mon Sep 17 00:00:00 2001 From: James Crayne Date: Sat, 26 Apr 2014 19:37:59 -0400 Subject: show command --- kiki.hs | 340 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 208 insertions(+), 132 deletions(-) (limited to 'kiki.hs') diff --git a/kiki.hs b/kiki.hs index b3fa330..f5716f0 100644 --- a/kiki.hs +++ b/kiki.hs @@ -461,7 +461,48 @@ whoseKey rsakey db = filter matchkey (Map.elems db) kiki_usage bSecret cmd = putStr $ case cmd of - "sync-secret" -> unlines + "show" -> unlines $ + ["kiki show [options...]" + ,"" + ," show displays infomration about keys stored in the data files which resides in" + ," the home directory (see --homedir)." + ,"" + ," The files pubring.gpg and subring.gpg in the directory specified by the " + ," --homedir option are implicitly included in the keyring set." + ,"" + ," Subkeys that are imported with kiki are given an annotation \"usage@\" which" + ," indicates what the key is for. This tag can be used as a SPEC to select a" + ," particular key. Master keys may be specified by using fingerprints or by" + ," specifying a substring of an associated UID." + ,"Options: " + ] ++ commonOptions ++ + [" --working" + ," Show fingerprints for the working key (which will be used to" + ," make signatures) and all its subkeys and UID." + ,"" + ," --key SPEC" + ," Show fingerprints for the specified key and all its subkeys" + ," and UID." + ,"" + ," --all Show fingerprints and UIDs and usage tags for all known keys." + ,"" + ," --whose-key" + ," Shows the fingerprint and UIDs of the key that owns the one that" + ," is input on stdin in ssh-rsa format." + ,"" + ," --pem SPEC" + ," Outputs the PKCS #8 public key corresponding to SPEC." + ,"" + ," --ssh SPEC" + ," Outputs the ssh-rsa blob for the specified public key." + ,"" + ," --wip SPEC" + ," Outputs the secret crypto-coin key in Wallet Input Format." + ,"" + ," --help Shows this help screen." + ,"" + ] ++ keyspec + "sync-secret" -> unlines $ ["kiki sync-secret [options...]" ,"" ," sync-secret merges a set of key files into a combined database and then" @@ -475,8 +516,8 @@ kiki_usage bSecret cmd = putStr $ ," indicates what the key is for. This tag can be used as a SPEC to select a" ," particular key. Master keys may be specified by using fingerprints or by" ," specifying a substring of an associated UID." - ] - "import-secret" -> unlines + ] ++ syncflags ++ keyspec + "import-secret" -> unlines $ ["kiki import-secret [options...]" ,"" ," import-secret uses a set of key files to update your keyring. It does not" @@ -489,130 +530,108 @@ kiki_usage bSecret cmd = putStr $ ," indicates what the key is for. This tag can be used as a SPEC to select a" ," particular key. Master keys may be specified by using fingerprints or by" ," specifying a substring of an associated UID." - ] - ++ unlines - ["" - ,"Flags:" - ," --homedir DIR" - ," Where to find the the files secring.gpg and pubring.gpg. The " - ," default location is taken from the environment variable " - ," GNUPGHOME." - ,"" - ," --passphrase-fd N" - ," Read passphrase from the given file descriptor." - ,"" - ," --import Add master keys to pubring.gpg. Without this option, only UID" - ," and subkey data is updated. " - ,"" - ," --import-if-authentic" - ," Add signed master keys to pubring.gpg. Like --import except that" - ," only keys with signatures from the working key (--show-wk) are" - ," imported." - ,"" - ," --autosign Sign all cross-certified tor-style UIDs." - ," A tor-style UID is of the form:" - ," Anonymous " - ," It is considered cross certified if there exists a cross-certified" - ," 'tor' subkey corresponding to the address HOSTNAME.onion." - ,"" - ,"Merging:" - ," --keyrings FILE FILE..." - ," Provide keyring files other than the implicit secring.gpg and" - ," pubring.gpg in the --homedir. This option is implicit unless" - ," --keypairs or --wallets is used." - ,""] - ++ do - guard bSecret - unlines - [" --wallets FILE FILE..." - ," Provide wallet files with secret crypto-coin keys in Wallet" - ," Import Format. The keys will be treated as subkeys of your" - ," current working key (the one shown by --show-wk)." - ,"" - ," --keypairs KEYSPEC KEYSPEC..." - ," A keypair is a secret key coupled with it's corresponding public" - ," key, both of which are ordinarily stored in a single file in pem" - ," format. Users incognisant of the fact that the public key (which" - ," is also stored separately) is in this file, often think of it as" - ," their secret key file." - ,"" - ," Each KEYSPEC specifies that a key should match the content and" - ," timestamp of an external PKCS #1 private RSA key file." - ," " - ," KEYSPEC ::= SPEC=FILE{CMD} " - ,"" - ," The form of SPEC is documented below. If there is only one master" - ," key in your keyring and only one key is used for each purpose, then" - ," it is possible for SPEC in this case to merely be a tag which offers" - ," information about what this key is used for, for example, any of" - ," `tor', `ssh-client', `ssh-host', or `strongswan' will do." - ,"" - ," If neither SPEC or FILE match any keys, then the CMD will be " - ," executed in order to create the FILE." - ,""] -{- ,"Output:" - ," --show-wk Show fingerprints for the working key (which will be used to" - ," make signatures) and all its subkeys and UID." - ,"" - ," --show-key SPEC" - ," Show fingerprints for the specified key and all its subkeys" - ," and UID." - ,"" - ," --show-all Show fingerprints and UIDs and usage tags for all known keys." - ,"" - ," --show-whose-key" - ," Shows the fingerprint and UIDs of the key that owns the one that" - ," is input on stdin in ssh-rsa format." - ,"" - ," --show-pem SPEC" - ," Outputs the PKCS #8 public key corresponding to SPEC." - ,"" - ," --show-ssh SPEC" - ," Outputs the ssh-rsa blob for the specified public key." - ,"" - ," --show-wip SPEC" - ," Outputs the secret crypto-coin key in Wallet Input Format." - ,"" - ," --help Shows this help screen." - ,"" - -} - ++ - unlines - ["Specifying keys on the kiki command line:" - ,"" - ," SPEC ::= MASTER/SUBKEY" - ,"" - ," SPEC indicates a specific key in the keyring, in it's longest incarnation," - ," it is of the form MASTER/SUBKEY where MASTER and SUBKEY are documented below." - ," If kiki can infer the key unambiguously, either via the command in question or" - ," the contents of the keyring, then it is permissable to ommit either MASTER or" - ," SUBKEY, in which case the slash may also be ommitted unless it is used via its" - ," position to indicate whether a SUBKEY or MASTER is intended." - ,"" - ," MASTER may be any of" - ," * The tail end of a fingerprint prefixed by 'fp:'" - ," * A sub-string of a user id (without slashes) prefixed by 'u:'" - ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)" - ," * A sub-string of a user id (without slashes, the prefix 'u:' is optional)" - ,"" - ," SUBKEY may be any of" - ," * The tail end of a fingerprint prefixed by 'fp:'" - ," * An exact match of a usage tag prefixed by 't:'" - ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)" - ," * An exact match of a usage tag (The prefix 't:' is optional)" - ,"" - ," In parsing the spec, kiki will attempt to match the string to one of the" - ," above formats, in the order presented." - ,"" - ," Examples of valid SPEC strings:" - ,"" - ," fp:4A39F/tor" - ," u:joe/tor" - ," u:joe/t:tor" - ," u:joe/fp:4abf30" - ," joe/tor" - ," 5E24CD442AA6965D2012E62A905C24185D5379C2" - ] + ] ++ syncflags ++ keyspec + where + commonOptions :: [String] + commonOptions = + [" --homedir DIR" + ," Where to find the the files secring.gpg and pubring.gpg. The " + ," default location is taken from the environment variable " + ," GNUPGHOME." + ,"" + ," --passphrase-fd N" + ," Read passphrase from the given file descriptor." + ,"" + ] + syncflags :: [String] + syncflags = + ["" + ,"Flags:"] ++ commonOptions ++ + [" --import Add master keys to pubring.gpg. Without this option, only UID" + ," and subkey data is updated. " + ,"" + ," --import-if-authentic" + ," Add signed master keys to pubring.gpg. Like --import except that" + ," only keys with signatures from the working key (--show-wk) are" + ," imported." + ,"" + ," --autosign Sign all cross-certified tor-style UIDs." + ," A tor-style UID is of the form:" + ," Anonymous " + ," It is considered cross certified if there exists a cross-certified" + ," 'tor' subkey corresponding to the address HOSTNAME.onion." + ,"" + ,"Merging:" + ," --keyrings FILE FILE..." + ," Provide keyring files other than the implicit secring.gpg and" + ," pubring.gpg in the --homedir. This option is implicit unless" + ," --keypairs or --wallets is used." + ,""] + ++ do + guard bSecret + return $ unlines + [" --wallets FILE FILE..." + ," Provide wallet files with secret crypto-coin keys in Wallet" + ," Import Format. The keys will be treated as subkeys of your" + ," current working key (the one shown by --show-wk)." + ,"" + ," --keypairs KEYSPEC KEYSPEC..." + ," A keypair is a secret key coupled with it's corresponding public" + ," key, both of which are ordinarily stored in a single file in pem" + ," format. Users incognisant of the fact that the public key (which" + ," is also stored separately) is in this file, often think of it as" + ," their secret key file." + ,"" + ," Each KEYSPEC specifies that a key should match the content and" + ," timestamp of an external PKCS #1 private RSA key file." + ," " + ," KEYSPEC ::= SPEC=FILE{CMD} " + ,"" + ," The form of SPEC is documented below. If there is only one master" + ," key in your keyring and only one key is used for each purpose, then" + ," it is possible for SPEC in this case to merely be a tag which offers" + ," information about what this key is used for, for example, any of" + ," `tor', `ssh-client', `ssh-host', or `strongswan' will do." + ,"" + ," If neither SPEC or FILE match any keys, then the CMD will be " + ," executed in order to create the FILE." + ,""] + keyspec = -- unlines $ + ["Specifying keys on the kiki command line:" + ,"" + ," SPEC ::= MASTER/SUBKEY" + ,"" + ," SPEC indicates a specific key in the keyring, in it's longest incarnation," + ," it is of the form MASTER/SUBKEY where MASTER and SUBKEY are documented below." + ," If kiki can infer the key unambiguously, either via the command in question or" + ," the contents of the keyring, then it is permissable to ommit either MASTER or" + ," SUBKEY, in which case the slash may also be ommitted unless it is used via its" + ," position to indicate whether a SUBKEY or MASTER is intended." + ,"" + ," MASTER may be any of" + ," * The tail end of a fingerprint prefixed by 'fp:'" + ," * A sub-string of a user id (without slashes) prefixed by 'u:'" + ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)" + ," * A sub-string of a user id (without slashes, the prefix 'u:' is optional)" + ,"" + ," SUBKEY may be any of" + ," * The tail end of a fingerprint prefixed by 'fp:'" + ," * An exact match of a usage tag prefixed by 't:'" + ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)" + ," * An exact match of a usage tag (The prefix 't:' is optional)" + ,"" + ," In parsing the spec, kiki will attempt to match the string to one of the" + ," above formats, in the order presented." + ,"" + ," Examples of valid SPEC strings:" + ,"" + ," fp:4A39F/tor" + ," u:joe/tor" + ," u:joe/t:tor" + ," u:joe/fp:4abf30" + ," joe/tor" + ," 5E24CD442AA6965D2012E62A905C24185D5379C2" + ] doAutosign rt kd@(KeyData k ksigs umap submap) = ops where @@ -651,13 +670,15 @@ processArgs sargspec polyVariadicArgs defaultPoly args_raw = (sargs,margs) trail = drop 1 trail1 commonArgSpec = [ ("--homedir",1) , ("--passphrase-fd",1) + , ("--help",0) ] + sargspec' = commonArgSpec ++ sargspec (sargs,margs) = (sargs, foldl' (\m (k:xs)->Map.alter (appendArgs k xs) k m) Map.empty gargs) - where (sargs,vargs) = partitionStaticArguments (commonArgSpec ++ sargspec) args - argspec = map fst sargspec ++ polyVariadicArgs + where (sargs,vargs) = partitionStaticArguments sargspec' args + argspec = map fst sargspec' ++ polyVariadicArgs args' = if map (take 1) (take 1 vargs) == ["-"] then vargs else defaultPoly:vargs @@ -705,7 +726,6 @@ sync bExport bImport bSecret cmdarg args_raw = do , ("--show-pem",1) , ("--show-ssh",1) , ("--show-wip",1) -} - , ("--help",0) ] polyVariadicArgs = ["--keyrings" ,"--hosts" ] @@ -833,7 +853,63 @@ kiki "help" args = forM_ args $ \arg -> case lookup arg commands of Nothing -> putStrLn $ "No help available for commmand '" ++ arg ++ "'." _ -> kiki arg ["--help"] -kiki "show" args = return () +kiki "show" args = do + let (sargs,margs) = processArgs sargspec polyVariadicArgs "--show" args + sargspec = [ ("--working",0) --("--show-wk",0) + , ("--all",0) --("--show-all",0) + , ("--whose-key",0) + , ("--key",1) + , ("--pem",1) + , ("--ssh",1) + , ("--wip",1) + ] + polyVariadicArgs = ["--show"] + let cap = parseCommonArgs margs + homespec = cap_homespec cap + passfd = cap_passfd cap + pems = [] + rings = [] + hosts = [] + walts = [] + kikiOp = KeyRingOperation + { kFiles = Map.fromList $ + [ ( HomeSec, (ConstRef, KeyRingFile passfd) ) + , ( HomePub, (ConstRef, KeyRingFile Nothing) ) + ] + ++ rings + ++ pems + ++ walts + ++ hosts + , kImports = Map.empty + , kManip = noManip + , homeSpec = homespec + } + + (\f -> maybe f (const $ kiki_usage False "show") $ Map.lookup "--help" margs) $ do + KikiResult rt report <- runKeyRing kikiOp + + input_key <- maybe (return Nothing) + (const $ fmap (Just . readPublicKey) Char8.getContents) + $ Map.lookup "--whose-key" margs + + case rt of + KikiSuccess rt -> do -- interpret --show-* commands. + let grip = rtGrip rt + let shspec = Map.fromList [("--working", const $ show_wk (rtSecring rt) grip) + ,("--all",const show_all) + ,("--whose-key", const $ show_whose_key input_key) + ,("--key",\[x] -> show_key x $ fromMaybe "" grip) + ,("--pem",\[x] -> show_pem x $ fromMaybe "" grip) + ,("--ssh",\[x] -> show_ssh x $ fromMaybe "" grip) + ,("--wip",\[x] -> show_wip x $ fromMaybe "" grip) + ] + shargs = mapMaybe (\(x:xs) -> (,xs) <$> Map.lookup x shspec) sargs + + forM_ shargs $ \(cmd,args) -> cmd args (rtKeyDB rt) + err -> putStrLn $ errorString err + + forM_ report $ \(fname,act) -> do + putStrLn $ fname ++ ": " ++ reportString act commands :: [(String,String)] commands = @@ -859,4 +935,4 @@ main = do cmd : args | cmd `elem` map fst commands -> kiki cmd args - _ -> kiki "help" args_raw + _ -> kiki "help" [] --args_raw -- cgit v1.2.3