From b6fd60dfa1709f162c25eb72cf8c45d0ab9bf34f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 4 Dec 2018 15:27:19 +0100 Subject: [PATCH] wks: Allow reading of --install-key arguments from stdin. * 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 (cherry picked from commit ba46a359b9d6549b74ec8401ea39bad434d87564) --- doc/wks.texi | 11 ++++++-- tools/gpg-wks-client.c | 9 ++++-- tools/gpg-wks-server.c | 9 ++++-- tools/wks-util.c | 62 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 81 insertions(+), 10 deletions(-) diff --git a/doc/wks.texi b/doc/wks.texi index caae3fd62..d6798b1ab 100644 --- a/doc/wks.texi +++ b/doc/wks.texi @@ -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 diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 2adfcfad2..c8ff16651 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -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: diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c index eae93b374..1a0ba8f4f 100644 --- a/tools/gpg-wks-server.c +++ b/tools/gpg-wks-server.c @@ -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: diff --git a/tools/wks-util.c b/tools/wks-util.c index fe06e361f..cc755fd5c 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -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); if (!addrspec) {