g10: Support armored keyrings in gpgv.
[gnupg.git] / g10 / gpg.c
index 5c2a6c8..bb5e847 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,7 +1,7 @@
 /* gpg.c - The GnuPG utility (main for gpg)
  * Copyright (C) 1998-2011 Free Software Foundation, Inc.
- * Copyright (C) 1997-2014 Werner Koch
- * Copyright (C) 2015 g10 Code GmbH
+ * Copyright (C) 1997-2016 Werner Koch
+ * Copyright (C) 2015-2016 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -141,6 +141,7 @@ enum cmd_and_opt_values
     aExport,
     aExportSecret,
     aExportSecretSub,
+    aExportSshKey,
     aCheckKeys,
     aGenRevoke,
     aDesigRevoke,
@@ -453,6 +454,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ),
   ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ),
   ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ),
+  ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ),
   ARGPARSE_c (aImport, "import", N_("import/merge keys")),
   ARGPARSE_c (aFastImport, "fast-import", "@"),
 #ifdef ENABLE_CARD_SUPPORT
@@ -484,7 +486,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aGenRandom,"gen-random", "@" ),
   ARGPARSE_c (aServer,   "server",  N_("run in server mode")),
   ARGPARSE_c (aTOFUPolicy, "tofu-policy",
-             N_("|VALUE|set the TOFU policy for a key (good, unknown, bad, ask, auto)")),
+             N_("|VALUE|set the TOFU policy for a key")),
 
   ARGPARSE_group (301, N_("@\nOptions:\n ")),
 
@@ -679,7 +681,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
   ARGPARSE_s_i (oDefCertLevel, "default-cert-check-level", "@"), /* old */
+#ifndef NO_TRUST_MODELS
   ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"),
+#endif
   ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
   ARGPARSE_s_s (oTOFUDefaultPolicy, "tofu-default-policy", "@"),
   ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"),
@@ -2101,299 +2105,6 @@ get_default_configname (void)
   return configname;
 }
 
-
-static gpg_error_t
-check_user_ids (strlist_t *sp,
-                int warn_possibly_ambiguous,
-                int error_if_not_found)
-{
-  strlist_t s = *sp;
-  strlist_t s2 = NULL;
-  strlist_t t;
-
-  gpg_error_t rc = 0;
-  gpg_error_t err;
-
-  KEYDB_HANDLE hd = NULL;
-
-  char fingerprint_formatted[MAX_FORMATTED_FINGERPRINT_LEN + 1];
-
-  /* A quick check to avoid allocating a new strlist if we can skip
-     all keys.  Handles also the case of !SP.  See below for details.  */
-  for (t = s; t && (!(t->flags & PK_LIST_CONFIG)
-                    && !(t->flags & PK_LIST_ENCRYPT_TO)); t = t->next)
-    ;
-  if (!t)
-    return 0;
-
-  for (t = s; t; t = t->next)
-    {
-      const char *option;
-
-      KEYDB_SEARCH_DESC desc;
-      KBNODE kb;
-      PKT_public_key *pk;
-      char fingerprint_bin[MAX_FINGERPRINT_LEN];
-      size_t fingerprint_bin_len = sizeof (fingerprint_bin);
-      /* We also potentially need a ! at the end.  */
-      char fingerprint[2 * MAX_FINGERPRINT_LEN + 1 + 1];
-      int added = 0;
-      int dups = 0;
-      int ambiguous = 0;
-
-      /* If the key has been given on the command line and it has not
-         been given by one of the encrypt-to options, we skip the
-         checks.  The reason is that the actual key selection code
-         does its own checks and provides proper status message to the
-         caller to detect the wrong keys.  */
-      if (!(t->flags & PK_LIST_CONFIG) && !(t->flags & PK_LIST_ENCRYPT_TO))
-        {
-          add_to_strlist (&s2, t->d);
-          s2->flags = t->flags;
-          continue;
-        }
-
-      switch (t->flags >> PK_LIST_SHIFT)
-        {
-        case oDefaultKey: option = "--default-key"; break;
-        case oEncryptTo: option = "--encrypt-to"; break;
-        case oHiddenEncryptTo: option = "--hidden-encrypt-to"; break;
-        case oEncryptToDefaultKey: option = "--encrypt-to-default-key"; break;
-        case oRecipient: option = "--recipient"; break;
-        case oHiddenRecipient: option = "--hidden-recipient"; break;
-        case oLocalUser: option = "--local-user"; break;
-        default:
-          log_bug ("Unsupport option: %d\n", (t->flags >> PK_LIST_SHIFT));
-        }
-
-      if (DBG_LOOKUP)
-        {
-          log_debug ("\n");
-          log_debug ("%s: Checking %s=%s\n", __func__, option, t->d);
-        }
-
-      err = classify_user_id (t->d, &desc, 1);
-      if (err)
-        {
-          if (! rc)
-            rc = err;
-
-          log_error (_("key \"%s\" not found: %s\n"),
-                       t->d, gpg_strerror (err));
-          if (!opt.quiet)
-            log_info (_("(check argument of option '%s')\n"), option);
-          continue;
-        }
-
-      if (warn_possibly_ambiguous
-          && ! (desc.mode == KEYDB_SEARCH_MODE_LONG_KID
-                || desc.mode == KEYDB_SEARCH_MODE_FPR16
-                || desc.mode == KEYDB_SEARCH_MODE_FPR20
-                || desc.mode == KEYDB_SEARCH_MODE_FPR))
-        log_info (_("Warning: value '%s' for option '%s'"
-                    " should be a long key ID or a fingerprint\n"),
-                  t->d, option);
-
-      if (! hd)
-        {
-          hd = keydb_new ();
-          if (!hd)
-            {
-              rc = gpg_error_from_syserror ();
-              break;
-            }
-        }
-      else
-        keydb_search_reset (hd);
-
-      err = keydb_search (hd, &desc, 1, NULL);
-      if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
-        {
-          if (DBG_LOOKUP)
-            log_debug ("%s: '%s' not found.\n", __func__, t->d);
-
-          if (error_if_not_found)
-            {
-              if (! rc)
-                rc = err;
-
-              log_error (_("key \"%s\" not found\n"), t->d);
-              if (!opt.quiet)
-                log_info (_("(check argument of option '%s')\n"), option);
-            }
-          continue;
-        }
-      if (err)
-        {
-          if (! rc)
-            rc = err;
-
-          log_error (_("key \"%s\" not found: %s\n"), t->d, gpg_strerror (err));
-          break;
-        }
-
-      err = keydb_get_keyblock (hd, &kb);
-      if (err)
-        {
-          if (! rc)
-            rc = err;
-
-          log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
-          continue;
-        }
-
-      pk = kb->pkt->pkt.public_key;
-      if ((desc.mode == KEYDB_SEARCH_MODE_SHORT_KID
-           || desc.mode == KEYDB_SEARCH_MODE_LONG_KID
-           || desc.mode == KEYDB_SEARCH_MODE_FPR16
-           || desc.mode == KEYDB_SEARCH_MODE_FPR20)
-          && strchr (t->d, '!'))
-        /* Exact search.  In this case we want to set FINGERPRINT not
-           to the primary key, but the key (primary or sub) that
-           matched the search criteria.  Note: there will always be
-           exactly one match.  */
-        {
-          kbnode_t n = kb;
-          PKT_public_key *match = NULL;
-          int i;
-
-          do
-            {
-              if ((n->flag & 1))
-                /* The matched node.  */
-                {
-                  assert (! match);
-                  match = n->pkt->pkt.public_key;
-                }
-            }
-          while ((n = find_next_kbnode (n, PKT_PUBLIC_SUBKEY)));
-          assert (match);
-
-          fingerprint_from_pk (match, fingerprint_bin, &fingerprint_bin_len);
-          assert (fingerprint_bin_len == sizeof (fingerprint_bin));
-          bin2hex (fingerprint_bin, MAX_FINGERPRINT_LEN, fingerprint);
-
-          i = strlen (fingerprint);
-          fingerprint[i] = '!';
-          fingerprint[i + 1] = '\0';
-
-          add_to_strlist (&s2, fingerprint);
-          added = 1;
-        }
-
-      /* We need the primary key's fingerprint to detect dups so
-         always format it.  */
-      fingerprint_from_pk (pk, fingerprint_bin, &fingerprint_bin_len);
-      assert (fingerprint_bin_len == sizeof (fingerprint_bin));
-      bin2hex (fingerprint_bin, MAX_FINGERPRINT_LEN, fingerprint);
-
-      if (! added)
-        add_to_strlist (&s2, fingerprint);
-      s2->flags = s->flags;
-
-      release_kbnode (kb);
-
-      /* Continue the search.  */
-      if (DBG_LOOKUP)
-        log_debug ("%s: Checking if %s='%s' is ambiguous or there are dups\n",
-                   __func__, option, t->d);
-      while (1)
-        {
-          char fingerprint_bin2[MAX_FINGERPRINT_LEN];
-          size_t fingerprint_bin2_len = sizeof (fingerprint_bin2);
-          char fingerprint2[2 * MAX_FINGERPRINT_LEN + 1];
-
-          err = keydb_search (hd, &desc, 1, NULL);
-          if (gpg_err_code (err) == GPG_ERR_NOT_FOUND
-              || gpg_err_code (err) == GPG_ERR_EOF)
-            /* Not found => not ambiguous.   */
-            break;
-          else if (err)
-            /* An error (other than "not found").  */
-            {
-              log_error (_("error searching the keyring: %s\n"),
-                         gpg_strerror (err));
-              if (! rc)
-                rc = err;
-
-              break;
-            }
-
-          /* Another result!  */
-
-          err = keydb_get_keyblock (hd, &kb);
-          if (err)
-            {
-              log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
-              if (! rc)
-                rc = err;
-            }
-          else
-            {
-              pk = kb->pkt->pkt.public_key;
-              fingerprint_from_pk (pk, fingerprint_bin2, &fingerprint_bin2_len);
-              assert (fingerprint_bin2_len == sizeof (fingerprint_bin2));
-              bin2hex (fingerprint_bin2, MAX_FINGERPRINT_LEN, fingerprint2);
-
-              if (strcmp (fingerprint, fingerprint2) == 0)
-                dups ++;
-              else
-                {
-                  ambiguous ++;
-
-                  if (! rc)
-                    rc = GPG_ERR_AMBIGUOUS_NAME;
-
-                  if (ambiguous == 1)
-                    {
-                      /* TRANSLATORS: The %s prints a key
-                         specification which for example has been
-                         given at the command line.  Lines with
-                         fingerprints are printed after this
-                         message.  */
-                      log_error (_("key specification '%s' is ambiguous\n"),
-                                 t->d);
-                      if (!opt.quiet)
-                        log_info (_("(check argument of option '%s')\n"),
-                                  option);
-
-                      log_info (_("'%s' matches at least:\n"), t->d);
-                      log_info ("  %s\n",
-                                format_hexfingerprint
-                                 (fingerprint,
-                                  fingerprint_formatted,
-                                  sizeof fingerprint_formatted));
-                    }
-
-                  log_info ("  %s\n",
-                            format_hexfingerprint
-                             (fingerprint2,
-                              fingerprint_formatted,
-                              sizeof fingerprint_formatted));
-                }
-
-              release_kbnode (kb);
-            }
-        }
-
-      if (dups)
-        log_info (_("Warning: %s appears in the keyring %d times.\n"),
-                  format_hexfingerprint (fingerprint,
-                                         fingerprint_formatted,
-                                         sizeof fingerprint_formatted),
-                  1 + dups);
-    }
-
-  strlist_rev (&s2);
-
-  keydb_release (hd);
-
-  free_strlist (s);
-  *sp = s2;
-  return rc;
-}
-
-
 int
 main (int argc, char **argv)
 {
@@ -2517,7 +2228,8 @@ main (int argc, char **argv)
                           | VERIFY_SHOW_POLICY_URLS
                           | VERIFY_SHOW_STD_NOTATIONS
                           | VERIFY_SHOW_KEYSERVER_URLS);
-    opt.list_options   = LIST_SHOW_UID_VALIDITY;
+    opt.list_options   = (LIST_SHOW_UID_VALIDITY
+                          | LIST_SHOW_USAGE);
 #ifdef NO_TRUST_MODELS
     opt.trust_model = TM_ALWAYS;
 #else
@@ -2693,6 +2405,7 @@ main (int argc, char **argv)
          case aListSigs:
          case aExportSecret:
          case aExportSecretSub:
+         case aExportSshKey:
          case aSym:
          case aClearsign:
          case aGenRevoke:
@@ -2898,6 +2611,8 @@ main (int argc, char **argv)
          case oDefaultKey:
             sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str);
             sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
             break;
          case oDefRecipient:
             if( *pargs.r.ret_str )
@@ -3101,7 +2816,7 @@ main (int argc, char **argv)
               sl->flags |= PK_LIST_CONFIG;
            break;
           case oEncryptToDefaultKey:
-            opt.encrypt_to_default_key = 1;
+            opt.encrypt_to_default_key = configfp ? 2 : 1;
             break;
          case oRecipient: /* store the recipient */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
@@ -4071,37 +3786,6 @@ main (int argc, char **argv)
         break;
       }
 
-    {
-      int have_def_secret_key = opt.def_secret_key != NULL;
-
-      rc = check_user_ids (&locusr, 1, 1);
-      if (rc)
-        g10_exit (1);
-      rc = check_user_ids (&remusr, 0, 1);
-      if (rc)
-        g10_exit (1);
-      rc = check_user_ids (&opt.def_secret_key, 1, 0);
-      if (rc)
-        g10_exit (1);
-
-      if (opt.encrypt_to_default_key)
-        {
-          const char *default_key = parse_def_secret_key (ctrl);
-          if (default_key)
-            {
-              sl = add_to_strlist2 (&remusr, default_key, utf8_strings);
-              sl->flags = ((oEncryptToDefaultKey << PK_LIST_SHIFT)
-                           | PK_LIST_ENCRYPT_TO);
-            }
-          else if (have_def_secret_key)
-            log_info (_("option '%s' given, but no valid default keys given\n"),
-                      "--encrypt-to-default-key");
-          else
-            log_info (_("option '%s' given, but option '%s' not given\n"),
-                      "--encrypt-to-default-key", "--default-key");
-        }
-    }
-
     /* The command dispatcher.  */
     switch( cmd )
       {
@@ -4263,7 +3947,6 @@ main (int argc, char **argv)
        break;
 
       case aVerify:
-        rc = 0;
        if (multifile)
          {
            if ((rc = verify_files (ctrl, argc, argv)))
@@ -4507,6 +4190,17 @@ main (int argc, char **argv)
        free_strlist(sl);
        break;
 
+      case aExportSshKey:
+        if (argc != 1)
+          wrong_args ("--export-ssh-key <user-id>");
+        rc = export_ssh_key (ctrl, argv[0]);
+        if (rc)
+          {
+            write_status_failure ("export-ssh-key", rc);
+            log_error (_("export as ssh key failed: %s\n"), gpg_strerror (rc));
+          }
+       break;
+
      case aSearchKeys:
        sl = NULL;
        for (; argc; argc--, argv++)
@@ -4591,7 +4285,7 @@ main (int argc, char **argv)
       case aDeArmor:
        if( argc > 1 )
            wrong_args("--dearmor [file]");
-       rc = dearmor_file( argc? *argv: NULL );
+       rc = dearmor_file( argc? *argv: NULL, -1 );
        if( rc )
           {
             write_status_failure ("dearmor", rc);