gpg: New import option "import-export".
authorWerner Koch <wk@gnupg.org>
Fri, 24 Jun 2016 11:11:37 +0000 (13:11 +0200)
committerWerner Koch <wk@gnupg.org>
Fri, 24 Jun 2016 11:11:37 +0000 (13:11 +0200)
* g10/import.c (parse_import_options): Add option "import-export".
(write_keyblock_to_output): New.
(import_one): Implement option.
--

We are now in the import export business.

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/gpg.texi
g10/import.c
g10/options.h

index 15f58f4..b8fda96 100644 (file)
@@ -2185,6 +2185,11 @@ opposite meaning. The options are:
   This can be combined with the option @option{--dry-run} to only look
   at keys.
 
+  @item import-export
+  Run the entire import code but instead of storing the key to the
+  local keyring write it to the output.  This option can be used to
+  remove all invalid parts from a key without the need to store it.
+
   @item merge-only
   During import, allow key updates to existing keys, but do not allow
   any new keys to be imported. Defaults to no.
index c4992be..b6bc0f2 100644 (file)
@@ -124,6 +124,9 @@ parse_import_options(char *str,unsigned int *options,int noisy)
       {"import-minimal",IMPORT_MINIMAL|IMPORT_CLEAN,NULL,
        N_("remove as much as possible from key after import")},
 
+      {"import-export", IMPORT_EXPORT, NULL,
+       N_("run import filters and export key immediately")},
+
       /* Aliases for backward compatibility */
       {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL},
       {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL},
@@ -764,6 +767,62 @@ fix_bad_direct_key_sigs (kbnode_t keyblock, u32 *keyid)
 }
 
 
+/* Write the keyblock either to stdin or to the file set with
+ * the --output option.  */
+static gpg_error_t
+write_keyblock_to_output (kbnode_t keyblock)
+{
+  gpg_error_t err;
+  const char *fname;
+  iobuf_t out;
+  kbnode_t node;
+  armor_filter_context_t *afx = NULL;
+
+  fname = opt.outfile? opt.outfile : "-";
+  if (is_secured_filename (fname) )
+    return gpg_error (GPG_ERR_EPERM);
+
+  out = iobuf_create (fname, 0);
+  if (!out)
+    {
+      err = gpg_error_from_syserror ();
+      log_error(_("can't create '%s': %s\n"), fname, gpg_strerror (err));
+      return err;
+    }
+  if (opt.verbose)
+    log_info (_("writing to '%s'\n"), iobuf_get_fname_nonnull (out));
+
+  if (opt.armor)
+    {
+      afx = new_armor_context ();
+      afx->what = 1;
+      push_armor_filter (afx, out);
+    }
+
+  for (node = keyblock; node; node = node->next)
+    {
+      if (!is_deleted_kbnode (node))
+       {
+         err = build_packet (out, node->pkt);
+         if (err)
+           {
+             log_error ("build_packet(%d) failed: %s\n",
+                        node->pkt->pkttype, gpg_strerror (err) );
+             goto leave;
+           }
+       }
+    }
+
+ leave:
+  if (err)
+    iobuf_cancel (out);
+  else
+    iobuf_close (out);
+  release_armor_context (afx);
+  return err;
+}
+
+
 static void
 print_import_ok (PKT_public_key *pk, unsigned int reason)
 {
@@ -952,6 +1011,7 @@ import_one (ctrl_t ctrl,
   int non_self = 0;
   size_t an;
   char pkstrbuf[PUBKEY_STRING_SIZE];
+  int merge_keys_done = 0;
 
   /* Get the key and print some info about it. */
   node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
@@ -1056,16 +1116,32 @@ import_one (ctrl_t ctrl,
   /* Get rid of deleted nodes.  */
   commit_kbnode (&keyblock);
 
-  /* Show the key in the form it is merged or inserted. */
-  if ((options & IMPORT_SHOW))
+  /* Show the key in the form it is merged or inserted.  We skip this
+   * if "import-export" is also active without --armor or the output
+   * file has explicily been given. */
+  if ((options & IMPORT_SHOW)
+      && !((options & IMPORT_EXPORT) && !opt.armor && !opt.outfile))
     {
       merge_keys_and_selfsig (keyblock);
+      merge_keys_done = 1;
       /* Note that we do not want to show the validity because the key
        * has not yet imported.  */
       list_keyblock_direct (ctrl, keyblock, 0, 0, 1, 1);
       es_fflush (es_stdout);
     }
 
+  /* Write the keyblock to the output and do not actually import.  */
+  if ((options & IMPORT_EXPORT))
+    {
+      if (!merge_keys_done)
+        {
+          merge_keys_and_selfsig (keyblock);
+          merge_keys_done = 1;
+        }
+      rc = write_keyblock_to_output (keyblock);
+      goto leave;
+    }
+
   if (opt.dry_run)
     goto leave;
 
index 58cf1f9..4279bd6 100644 (file)
@@ -340,6 +340,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
 #define IMPORT_CLEAN                     (1<<6)
 #define IMPORT_NO_SECKEY                 (1<<7)
 #define IMPORT_KEEP_OWNERTTRUST          (1<<8)
+#define IMPORT_EXPORT                    (1<<9)
 
 #define EXPORT_LOCAL_SIGS                (1<<0)
 #define EXPORT_ATTRIBUTES                (1<<1)