summaryrefslogtreecommitdiff
path: root/kiki.hs
diff options
context:
space:
mode:
authorJames Crayne <jim.crayne@gmail.com>2014-04-26 19:37:59 -0400
committerJames Crayne <jim.crayne@gmail.com>2014-04-26 19:37:59 -0400
commit278e30eb03b821c9ce9502eb3879ef728367dde8 (patch)
treeab1b4e557b1caa8479a9ab2b41e925bf80b8f2bb /kiki.hs
parentbd6992f90dea2425190efa048eafdda27ac84456 (diff)
show command
Diffstat (limited to 'kiki.hs')
-rw-r--r--kiki.hs340
1 files changed, 208 insertions, 132 deletions
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)
461 461
462kiki_usage bSecret cmd = putStr $ 462kiki_usage bSecret cmd = putStr $
463 case cmd of 463 case cmd of
464 "sync-secret" -> unlines 464 "show" -> unlines $
465 ["kiki show [options...]"
466 ,""
467 ," show displays infomration about keys stored in the data files which resides in"
468 ," the home directory (see --homedir)."
469 ,""
470 ," The files pubring.gpg and subring.gpg in the directory specified by the "
471 ," --homedir option are implicitly included in the keyring set."
472 ,""
473 ," Subkeys that are imported with kiki are given an annotation \"usage@\" which"
474 ," indicates what the key is for. This tag can be used as a SPEC to select a"
475 ," particular key. Master keys may be specified by using fingerprints or by"
476 ," specifying a substring of an associated UID."
477 ,"Options: "
478 ] ++ commonOptions ++
479 [" --working"
480 ," Show fingerprints for the working key (which will be used to"
481 ," make signatures) and all its subkeys and UID."
482 ,""
483 ," --key SPEC"
484 ," Show fingerprints for the specified key and all its subkeys"
485 ," and UID."
486 ,""
487 ," --all Show fingerprints and UIDs and usage tags for all known keys."
488 ,""
489 ," --whose-key"
490 ," Shows the fingerprint and UIDs of the key that owns the one that"
491 ," is input on stdin in ssh-rsa format."
492 ,""
493 ," --pem SPEC"
494 ," Outputs the PKCS #8 public key corresponding to SPEC."
495 ,""
496 ," --ssh SPEC"
497 ," Outputs the ssh-rsa blob for the specified public key."
498 ,""
499 ," --wip SPEC"
500 ," Outputs the secret crypto-coin key in Wallet Input Format."
501 ,""
502 ," --help Shows this help screen."
503 ,""
504 ] ++ keyspec
505 "sync-secret" -> unlines $
465 ["kiki sync-secret [options...]" 506 ["kiki sync-secret [options...]"
466 ,"" 507 ,""
467 ," sync-secret merges a set of key files into a combined database and then" 508 ," sync-secret merges a set of key files into a combined database and then"
@@ -475,8 +516,8 @@ kiki_usage bSecret cmd = putStr $
475 ," indicates what the key is for. This tag can be used as a SPEC to select a" 516 ," indicates what the key is for. This tag can be used as a SPEC to select a"
476 ," particular key. Master keys may be specified by using fingerprints or by" 517 ," particular key. Master keys may be specified by using fingerprints or by"
477 ," specifying a substring of an associated UID." 518 ," specifying a substring of an associated UID."
478 ] 519 ] ++ syncflags ++ keyspec
479 "import-secret" -> unlines 520 "import-secret" -> unlines $
480 ["kiki import-secret [options...]" 521 ["kiki import-secret [options...]"
481 ,"" 522 ,""
482 ," import-secret uses a set of key files to update your keyring. It does not" 523 ," import-secret uses a set of key files to update your keyring. It does not"
@@ -489,130 +530,108 @@ kiki_usage bSecret cmd = putStr $
489 ," indicates what the key is for. This tag can be used as a SPEC to select a" 530 ," indicates what the key is for. This tag can be used as a SPEC to select a"
490 ," particular key. Master keys may be specified by using fingerprints or by" 531 ," particular key. Master keys may be specified by using fingerprints or by"
491 ," specifying a substring of an associated UID." 532 ," specifying a substring of an associated UID."
492 ] 533 ] ++ syncflags ++ keyspec
493 ++ unlines 534 where
494 ["" 535 commonOptions :: [String]
495 ,"Flags:" 536 commonOptions =
496 ," --homedir DIR" 537 [" --homedir DIR"
497 ," Where to find the the files secring.gpg and pubring.gpg. The " 538 ," Where to find the the files secring.gpg and pubring.gpg. The "
498 ," default location is taken from the environment variable " 539 ," default location is taken from the environment variable "
499 ," GNUPGHOME." 540 ," GNUPGHOME."
500 ,"" 541 ,""
501 ," --passphrase-fd N" 542 ," --passphrase-fd N"
502 ," Read passphrase from the given file descriptor." 543 ," Read passphrase from the given file descriptor."
503 ,"" 544 ,""
504 ," --import Add master keys to pubring.gpg. Without this option, only UID" 545 ]
505 ," and subkey data is updated. " 546 syncflags :: [String]
506 ,"" 547 syncflags =
507 ," --import-if-authentic" 548 [""
508 ," Add signed master keys to pubring.gpg. Like --import except that" 549 ,"Flags:"] ++ commonOptions ++
509 ," only keys with signatures from the working key (--show-wk) are" 550 [" --import Add master keys to pubring.gpg. Without this option, only UID"
510 ," imported." 551 ," and subkey data is updated. "
511 ,"" 552 ,""
512 ," --autosign Sign all cross-certified tor-style UIDs." 553 ," --import-if-authentic"
513 ," A tor-style UID is of the form:" 554 ," Add signed master keys to pubring.gpg. Like --import except that"
514 ," Anonymous <root@HOSTNAME.onion>" 555 ," only keys with signatures from the working key (--show-wk) are"
515 ," It is considered cross certified if there exists a cross-certified" 556 ," imported."
516 ," 'tor' subkey corresponding to the address HOSTNAME.onion." 557 ,""
517 ,"" 558 ," --autosign Sign all cross-certified tor-style UIDs."
518 ,"Merging:" 559 ," A tor-style UID is of the form:"
519 ," --keyrings FILE FILE..." 560 ," Anonymous <root@HOSTNAME.onion>"
520 ," Provide keyring files other than the implicit secring.gpg and" 561 ," It is considered cross certified if there exists a cross-certified"
521 ," pubring.gpg in the --homedir. This option is implicit unless" 562 ," 'tor' subkey corresponding to the address HOSTNAME.onion."
522 ," --keypairs or --wallets is used." 563 ,""
523 ,""] 564 ,"Merging:"
524 ++ do 565 ," --keyrings FILE FILE..."
525 guard bSecret 566 ," Provide keyring files other than the implicit secring.gpg and"
526 unlines 567 ," pubring.gpg in the --homedir. This option is implicit unless"
527 [" --wallets FILE FILE..." 568 ," --keypairs or --wallets is used."
528 ," Provide wallet files with secret crypto-coin keys in Wallet" 569 ,""]
529 ," Import Format. The keys will be treated as subkeys of your" 570 ++ do
530 ," current working key (the one shown by --show-wk)." 571 guard bSecret
531 ,"" 572 return $ unlines
532 ," --keypairs KEYSPEC KEYSPEC..." 573 [" --wallets FILE FILE..."
533 ," A keypair is a secret key coupled with it's corresponding public" 574 ," Provide wallet files with secret crypto-coin keys in Wallet"
534 ," key, both of which are ordinarily stored in a single file in pem" 575 ," Import Format. The keys will be treated as subkeys of your"
535 ," format. Users incognisant of the fact that the public key (which" 576 ," current working key (the one shown by --show-wk)."
536 ," is also stored separately) is in this file, often think of it as" 577 ,""
537 ," their secret key file." 578 ," --keypairs KEYSPEC KEYSPEC..."
538 ,"" 579 ," A keypair is a secret key coupled with it's corresponding public"
539 ," Each KEYSPEC specifies that a key should match the content and" 580 ," key, both of which are ordinarily stored in a single file in pem"
540 ," timestamp of an external PKCS #1 private RSA key file." 581 ," format. Users incognisant of the fact that the public key (which"
541 ," " 582 ," is also stored separately) is in this file, often think of it as"
542 ," KEYSPEC ::= SPEC=FILE{CMD} " 583 ," their secret key file."
543 ,"" 584 ,""
544 ," The form of SPEC is documented below. If there is only one master" 585 ," Each KEYSPEC specifies that a key should match the content and"
545 ," key in your keyring and only one key is used for each purpose, then" 586 ," timestamp of an external PKCS #1 private RSA key file."
546 ," it is possible for SPEC in this case to merely be a tag which offers" 587 ," "
547 ," information about what this key is used for, for example, any of" 588 ," KEYSPEC ::= SPEC=FILE{CMD} "
548 ," `tor', `ssh-client', `ssh-host', or `strongswan' will do." 589 ,""
549 ,"" 590 ," The form of SPEC is documented below. If there is only one master"
550 ," If neither SPEC or FILE match any keys, then the CMD will be " 591 ," key in your keyring and only one key is used for each purpose, then"
551 ," executed in order to create the FILE." 592 ," it is possible for SPEC in this case to merely be a tag which offers"
552 ,""] 593 ," information about what this key is used for, for example, any of"
553{- ,"Output:" 594 ," `tor', `ssh-client', `ssh-host', or `strongswan' will do."
554 ," --show-wk Show fingerprints for the working key (which will be used to" 595 ,""
555 ," make signatures) and all its subkeys and UID." 596 ," If neither SPEC or FILE match any keys, then the CMD will be "
556 ,"" 597 ," executed in order to create the FILE."
557 ," --show-key SPEC" 598 ,""]
558 ," Show fingerprints for the specified key and all its subkeys" 599 keyspec = -- unlines $
559 ," and UID." 600 ["Specifying keys on the kiki command line:"
560 ,"" 601 ,""
561 ," --show-all Show fingerprints and UIDs and usage tags for all known keys." 602 ," SPEC ::= MASTER/SUBKEY"
562 ,"" 603 ,""
563 ," --show-whose-key" 604 ," SPEC indicates a specific key in the keyring, in it's longest incarnation,"
564 ," Shows the fingerprint and UIDs of the key that owns the one that" 605 ," it is of the form MASTER/SUBKEY where MASTER and SUBKEY are documented below."
565 ," is input on stdin in ssh-rsa format." 606 ," If kiki can infer the key unambiguously, either via the command in question or"
566 ,"" 607 ," the contents of the keyring, then it is permissable to ommit either MASTER or"
567 ," --show-pem SPEC" 608 ," SUBKEY, in which case the slash may also be ommitted unless it is used via its"
568 ," Outputs the PKCS #8 public key corresponding to SPEC." 609 ," position to indicate whether a SUBKEY or MASTER is intended."
569 ,"" 610 ,""
570 ," --show-ssh SPEC" 611 ," MASTER may be any of"
571 ," Outputs the ssh-rsa blob for the specified public key." 612 ," * The tail end of a fingerprint prefixed by 'fp:'"
572 ,"" 613 ," * A sub-string of a user id (without slashes) prefixed by 'u:'"
573 ," --show-wip SPEC" 614 ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)"
574 ," Outputs the secret crypto-coin key in Wallet Input Format." 615 ," * A sub-string of a user id (without slashes, the prefix 'u:' is optional)"
575 ,"" 616 ,""
576 ," --help Shows this help screen." 617 ," SUBKEY may be any of"
577 ,"" 618 ," * The tail end of a fingerprint prefixed by 'fp:'"
578 -} 619 ," * An exact match of a usage tag prefixed by 't:'"
579 ++ 620 ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)"
580 unlines 621 ," * An exact match of a usage tag (The prefix 't:' is optional)"
581 ["Specifying keys on the kiki command line:" 622 ,""
582 ,"" 623 ," In parsing the spec, kiki will attempt to match the string to one of the"
583 ," SPEC ::= MASTER/SUBKEY" 624 ," above formats, in the order presented."
584 ,"" 625 ,""
585 ," SPEC indicates a specific key in the keyring, in it's longest incarnation," 626 ," Examples of valid SPEC strings:"
586 ," it is of the form MASTER/SUBKEY where MASTER and SUBKEY are documented below." 627 ,""
587 ," If kiki can infer the key unambiguously, either via the command in question or" 628 ," fp:4A39F/tor"
588 ," the contents of the keyring, then it is permissable to ommit either MASTER or" 629 ," u:joe/tor"
589 ," SUBKEY, in which case the slash may also be ommitted unless it is used via its" 630 ," u:joe/t:tor"
590 ," position to indicate whether a SUBKEY or MASTER is intended." 631 ," u:joe/fp:4abf30"
591 ,"" 632 ," joe/tor"
592 ," MASTER may be any of" 633 ," 5E24CD442AA6965D2012E62A905C24185D5379C2"
593 ," * The tail end of a fingerprint prefixed by 'fp:'" 634 ]
594 ," * A sub-string of a user id (without slashes) prefixed by 'u:'"
595 ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)"
596 ," * A sub-string of a user id (without slashes, the prefix 'u:' is optional)"
597 ,""
598 ," SUBKEY may be any of"
599 ," * The tail end of a fingerprint prefixed by 'fp:'"
600 ," * An exact match of a usage tag prefixed by 't:'"
601 ," * 40 characters of hexidecimal (kiki will assume this to be a fingerprint)"
602 ," * An exact match of a usage tag (The prefix 't:' is optional)"
603 ,""
604 ," In parsing the spec, kiki will attempt to match the string to one of the"
605 ," above formats, in the order presented."
606 ,""
607 ," Examples of valid SPEC strings:"
608 ,""
609 ," fp:4A39F/tor"
610 ," u:joe/tor"
611 ," u:joe/t:tor"
612 ," u:joe/fp:4abf30"
613 ," joe/tor"
614 ," 5E24CD442AA6965D2012E62A905C24185D5379C2"
615 ]
616 635
617doAutosign rt kd@(KeyData k ksigs umap submap) = ops 636doAutosign rt kd@(KeyData k ksigs umap submap) = ops
618 where 637 where
@@ -651,13 +670,15 @@ processArgs sargspec polyVariadicArgs defaultPoly args_raw = (sargs,margs)
651 trail = drop 1 trail1 670 trail = drop 1 trail1
652 commonArgSpec = [ ("--homedir",1) 671 commonArgSpec = [ ("--homedir",1)
653 , ("--passphrase-fd",1) 672 , ("--passphrase-fd",1)
673 , ("--help",0)
654 ] 674 ]
675 sargspec' = commonArgSpec ++ sargspec
655 (sargs,margs) = 676 (sargs,margs) =
656 (sargs, foldl' (\m (k:xs)->Map.alter (appendArgs k xs) k m) 677 (sargs, foldl' (\m (k:xs)->Map.alter (appendArgs k xs) k m)
657 Map.empty 678 Map.empty
658 gargs) 679 gargs)
659 where (sargs,vargs) = partitionStaticArguments (commonArgSpec ++ sargspec) args 680 where (sargs,vargs) = partitionStaticArguments sargspec' args
660 argspec = map fst sargspec ++ polyVariadicArgs 681 argspec = map fst sargspec' ++ polyVariadicArgs
661 args' = if map (take 1) (take 1 vargs) == ["-"] 682 args' = if map (take 1) (take 1 vargs) == ["-"]
662 then vargs 683 then vargs
663 else defaultPoly:vargs 684 else defaultPoly:vargs
@@ -705,7 +726,6 @@ sync bExport bImport bSecret cmdarg args_raw = do
705 , ("--show-pem",1) 726 , ("--show-pem",1)
706 , ("--show-ssh",1) 727 , ("--show-ssh",1)
707 , ("--show-wip",1) -} 728 , ("--show-wip",1) -}
708 , ("--help",0)
709 ] 729 ]
710 polyVariadicArgs = ["--keyrings" 730 polyVariadicArgs = ["--keyrings"
711 ,"--hosts" ] 731 ,"--hosts" ]
@@ -833,7 +853,63 @@ kiki "help" args = forM_ args $ \arg -> case lookup arg commands of
833 Nothing -> putStrLn $ "No help available for commmand '" ++ arg ++ "'." 853 Nothing -> putStrLn $ "No help available for commmand '" ++ arg ++ "'."
834 _ -> kiki arg ["--help"] 854 _ -> kiki arg ["--help"]
835 855
836kiki "show" args = return () 856kiki "show" args = do
857 let (sargs,margs) = processArgs sargspec polyVariadicArgs "--show" args
858 sargspec = [ ("--working",0) --("--show-wk",0)
859 , ("--all",0) --("--show-all",0)
860 , ("--whose-key",0)
861 , ("--key",1)
862 , ("--pem",1)
863 , ("--ssh",1)
864 , ("--wip",1)
865 ]
866 polyVariadicArgs = ["--show"]
867 let cap = parseCommonArgs margs
868 homespec = cap_homespec cap
869 passfd = cap_passfd cap
870 pems = []
871 rings = []
872 hosts = []
873 walts = []
874 kikiOp = KeyRingOperation
875 { kFiles = Map.fromList $
876 [ ( HomeSec, (ConstRef, KeyRingFile passfd) )
877 , ( HomePub, (ConstRef, KeyRingFile Nothing) )
878 ]
879 ++ rings
880 ++ pems
881 ++ walts
882 ++ hosts
883 , kImports = Map.empty
884 , kManip = noManip
885 , homeSpec = homespec
886 }
887
888 (\f -> maybe f (const $ kiki_usage False "show") $ Map.lookup "--help" margs) $ do
889 KikiResult rt report <- runKeyRing kikiOp
890
891 input_key <- maybe (return Nothing)
892 (const $ fmap (Just . readPublicKey) Char8.getContents)
893 $ Map.lookup "--whose-key" margs
894
895 case rt of
896 KikiSuccess rt -> do -- interpret --show-* commands.
897 let grip = rtGrip rt
898 let shspec = Map.fromList [("--working", const $ show_wk (rtSecring rt) grip)
899 ,("--all",const show_all)
900 ,("--whose-key", const $ show_whose_key input_key)
901 ,("--key",\[x] -> show_key x $ fromMaybe "" grip)
902 ,("--pem",\[x] -> show_pem x $ fromMaybe "" grip)
903 ,("--ssh",\[x] -> show_ssh x $ fromMaybe "" grip)
904 ,("--wip",\[x] -> show_wip x $ fromMaybe "" grip)
905 ]
906 shargs = mapMaybe (\(x:xs) -> (,xs) <$> Map.lookup x shspec) sargs
907
908 forM_ shargs $ \(cmd,args) -> cmd args (rtKeyDB rt)
909 err -> putStrLn $ errorString err
910
911 forM_ report $ \(fname,act) -> do
912 putStrLn $ fname ++ ": " ++ reportString act
837 913
838commands :: [(String,String)] 914commands :: [(String,String)]
839commands = 915commands =
@@ -859,4 +935,4 @@ main = do
859 cmd : args | cmd `elem` map fst commands 935 cmd : args | cmd `elem` map fst commands
860 -> kiki cmd args 936 -> kiki cmd args
861 937
862 _ -> kiki "help" args_raw 938 _ -> kiki "help" [] --args_raw