wks: Allow reading of --install-key arguments from stdin.
authorWerner Koch <wk@gnupg.org>
Tue, 4 Dec 2018 14:27:19 +0000 (15:27 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 4 Dec 2018 14:31:41 +0000 (15:31 +0100)
* tools/wks-util.c (install_key_from_spec_file): New.
(wks_cmd_install_key): Call it.
* tools/gpg-wks-client.c (main): Allow --install-key w/o arguments.
* tools/gpg-wks-server.c (main): Ditto.

Signed-off-by: Werner Koch <wk@gnupg.org>
doc/wks.texi
tools/gpg-wks-client.c
tools/gpg-wks-server.c
tools/wks-util.c

index 021fe5b..a0b2a34 100644 (file)
@@ -95,8 +95,11 @@ local directory (see option @option{-C}) reflecting the structure of a
 WKD.  The arguments are a file with the keyblock and the user-id to
 install.  If the first argument resembles a fingerprint the key is
 taken from the current keyring; to force the use of a file, prefix the
-first argument with "./".  The command @option{--remove-key} removes a
-key from that directory, its only argument is a user-id.
+first argument with "./".  If no arguments are given the parameters
+are read from stdin; the expected format are lines with the
+fingerprint and the mailbox separated by a space.  The command
+@option{--remove-key} removes a key from that directory, its only
+argument is a user-id.
 
 @command{gpg-wks-client} is not commonly invoked directly and thus it
 is not installed in the bin directory.  Here is an example how it can
@@ -280,7 +283,9 @@ The command @option{--install-key} manually installs a key into the
 WKD.  The arguments are a file with the keyblock and the user-id to
 install.  If the first argument resembles a fingerprint the key is
 taken from the current keyring; to force the use of a file, prefix the
-first argument with "./".
+first argument with "./".  If no arguments are given the parameters
+are read from stdin; the expected format are lines with the
+fingerprint and the mailbox separated by a space.
 
 The command @option{--remove-key} uninstalls a key from the WKD.  The
 process returns success in this case; to also print a diagnostic, use
index 5535a68..0dee1a2 100644 (file)
@@ -363,9 +363,12 @@ main (int argc, char **argv)
       break;
 
     case aInstallKey:
-      if (argc != 2)
-        wrong_args ("--install-key FILE|FINGERPRINT USER-ID");
-      err = wks_cmd_install_key (*argv, argv[1]);
+      if (!argc)
+        err = wks_cmd_install_key (NULL, NULL);
+      else if (argc == 2)
+        err = wks_cmd_install_key (*argv, argv[1]);
+      else
+        wrong_args ("--install-key [FILE|FINGERPRINT USER-ID]");
       break;
 
     case aRemoveKey:
index eae93b3..1a0ba8f 100644 (file)
@@ -381,9 +381,12 @@ main (int argc, char **argv)
       break;
 
     case aInstallKey:
-      if (argc != 2)
-        wrong_args ("--install-key FILE USER-ID");
-      err = wks_cmd_install_key (*argv, argv[1]);
+      if (!argc)
+        err = wks_cmd_install_key (NULL, NULL);
+      else if (argc == 2)
+        err = wks_cmd_install_key (*argv, argv[1]);
+      else
+        wrong_args ("--install-key [FILE|FINGERPRINT USER-ID]");
       break;
 
     case aRemoveKey:
index c0ea06a..73cced9 100644 (file)
@@ -855,8 +855,65 @@ wks_compute_hu_fname (char **r_fname, const char *addrspec)
 }
 
 
+
+/* Helper form wks_cmd_install_key.  */
+static gpg_error_t
+install_key_from_spec_file (const char *fname)
+{
+  gpg_error_t err;
+  estream_t fp;
+  char *line = NULL;
+  size_t linelen = 0;
+  char *fields[2];
+  unsigned int lnr = 0;
+
+  if (!fname || !strcmp (fname, ""))
+    fp = es_stdin;
+  else
+    fp = es_fopen (fname, "rb");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error reading '%s': %s\n", fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  while (es_getline (&line, &linelen, fp) >= 0)
+    {
+      lnr++;
+      trim_spaces (line);
+      log_debug ("got line='%s'\n", line);
+      if (!*line ||  *line == '#')
+        continue;
+      if (split_fields (line, fields, DIM(fields)) < 2)
+        {
+          log_error ("error reading '%s': syntax error at line %u\n",
+                     fname, lnr);
+          continue;
+        }
+      err = wks_cmd_install_key (fields[0], fields[1]);
+      if (err)
+        goto leave;
+    }
+  if (es_ferror (fp))
+    {
+      err = gpg_error_from_syserror ();
+      log_error ("error reading '%s': %s\n", fname, gpg_strerror (err));
+      goto leave;
+    }
+
+ leave:
+  if (fp != es_stdin)
+    es_fclose (fp);
+  es_free (line);
+  return err;
+}
+
+
 /* Install a single key into the WKD by reading FNAME and extracting
- * USERID.  */
+ * USERID.  If USERID is NULL FNAME is expected to be a list of fpr
+ * mbox lines and for each line the respective key will be
+ * installed.  */
 gpg_error_t
 wks_cmd_install_key (const char *fname, const char *userid)
 {
@@ -871,6 +928,9 @@ wks_cmd_install_key (const char *fname, const char *userid)
   char *huname = NULL;
   int any;
 
+  if (!userid)
+    return install_key_from_spec_file (fname);
+
   addrspec = mailbox_from_userid (userid, 0);
   if (!addrspec)
     {