diff options
author | Werner Koch <wk@gnupg.org> | 2016-12-08 16:11:42 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2016-12-08 16:59:12 +0100 |
commit | c3138decd77d788906885b638b344d0d1faf32c0 (patch) | |
tree | ed9f6158e35282b441a3b138a1d8166072803b73 /tools/wks-util.c | |
parent | gpgscm: Generalize 'for-each-p'. (diff) | |
download | gnupg2-c3138decd77d788906885b638b344d0d1faf32c0.tar.xz gnupg2-c3138decd77d788906885b638b344d0d1faf32c0.zip |
tools: Move a function from gpg-wks-server to wks-util.c.
* tools/gpg-wks-server.c (list_key_status_cb): Remove.
(list_key): Move to ...
* tools/wks-util.c (wks_list_key): here and rename. Add new args
R_FPR and R_MBOXES and remove the CTX.
(list_key_status_cb): New.
* tools/wks-util.c: Include ccparray.h, exectool.h, and mbox-util.h.
* tools/gpg-wks-server.c (process_new_key): Replace list_key by
wks_list_key.
(check_and_publish): Ditto.
Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to '')
-rw-r--r-- | tools/wks-util.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/tools/wks-util.c b/tools/wks-util.c index 1b47612bd..f4f44f6b2 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -23,11 +23,190 @@ #include <string.h> #include "util.h" +#include "ccparray.h" +#include "exectool.h" +#include "mbox-util.h" #include "mime-maker.h" #include "send-mail.h" #include "gpg-wks.h" + +/* Helper for wks_list_key. */ +static void +list_key_status_cb (void *opaque, const char *keyword, char *args) +{ + (void)opaque; + + if (DBG_CRYPTO) + log_debug ("gpg status: %s %s\n", keyword, args); +} + + +/* Run gpg on KEY and store the primary fingerprint at R_FPR and the + * list of mailboxes at R_MBOXES. Returns 0 on success; on error NULL + * is stored at R_FPR and R_MBOXES and an error code is returned. */ +gpg_error_t +wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes) +{ + gpg_error_t err; + ccparray_t ccp; + const char **argv; + estream_t listing; + char *line = NULL; + size_t length_of_line = 0; + size_t maxlen; + ssize_t len; + char **fields = NULL; + int nfields; + int lnr; + char *mbox = NULL; + char *fpr = NULL; + strlist_t mboxes = NULL; + + *r_fpr = NULL; + *r_mboxes = NULL; + + /* Open a memory stream. */ + listing = es_fopenmem (0, "w+b"); + if (!listing) + { + err = gpg_error_from_syserror (); + log_error ("error allocating memory buffer: %s\n", gpg_strerror (err)); + return err; + } + + ccparray_init (&ccp, 0); + + ccparray_put (&ccp, "--no-options"); + if (!opt.verbose) + ccparray_put (&ccp, "--quiet"); + else if (opt.verbose > 1) + ccparray_put (&ccp, "--verbose"); + ccparray_put (&ccp, "--batch"); + ccparray_put (&ccp, "--status-fd=2"); + ccparray_put (&ccp, "--always-trust"); + ccparray_put (&ccp, "--with-colons"); + ccparray_put (&ccp, "--dry-run"); + ccparray_put (&ccp, "--import-options=import-minimal,import-show"); + ccparray_put (&ccp, "--import"); + + ccparray_put (&ccp, NULL); + argv = ccparray_get (&ccp, NULL); + if (!argv) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = gnupg_exec_tool_stream (opt.gpg_program, argv, key, + NULL, listing, + list_key_status_cb, NULL); + if (err) + { + log_error ("import failed: %s\n", gpg_strerror (err)); + goto leave; + } + + es_rewind (listing); + lnr = 0; + maxlen = 2048; /* Set limit. */ + while ((len = es_read_line (listing, &line, &length_of_line, &maxlen)) > 0) + { + lnr++; + if (!maxlen) + { + log_error ("received line too long\n"); + err = gpg_error (GPG_ERR_LINE_TOO_LONG); + goto leave; + } + /* Strip newline and carriage return, if present. */ + while (len > 0 + && (line[len - 1] == '\n' || line[len - 1] == '\r')) + line[--len] = '\0'; + /* log_debug ("line '%s'\n", line); */ + + xfree (fields); + fields = strtokenize (line, ":"); + if (!fields) + { + err = gpg_error_from_syserror (); + log_error ("strtokenize failed: %s\n", gpg_strerror (err)); + goto leave; + } + for (nfields = 0; fields[nfields]; nfields++) + ; + if (!nfields) + { + err = gpg_error (GPG_ERR_INV_ENGINE); + goto leave; + } + if (!strcmp (fields[0], "sec")) + { + /* gpg may return "sec" as the first record - but we do not + * accept secret keys. */ + err = gpg_error (GPG_ERR_NO_PUBKEY); + goto leave; + } + if (lnr == 1 && strcmp (fields[0], "pub")) + { + /* First record is not a public key. */ + err = gpg_error (GPG_ERR_INV_ENGINE); + goto leave; + } + if (lnr > 1 && !strcmp (fields[0], "pub")) + { + /* More than one public key. */ + err = gpg_error (GPG_ERR_TOO_MANY); + goto leave; + } + if (!strcmp (fields[0], "sub") || !strcmp (fields[0], "ssb")) + break; /* We can stop parsing here. */ + + if (!strcmp (fields[0], "fpr") && nfields > 9 && !fpr) + { + fpr = xtrystrdup (fields[9]); + if (!fpr) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + else if (!strcmp (fields[0], "uid") && nfields > 9) + { + /* Fixme: Unescape fields[9] */ + xfree (mbox); + mbox = mailbox_from_userid (fields[9]); + if (mbox && !append_to_strlist_try (&mboxes, mbox)) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + } + if (len < 0 || es_ferror (listing)) + { + err = gpg_error_from_syserror (); + log_error ("error reading memory stream\n"); + goto leave; + } + + *r_fpr = fpr; + fpr = NULL; + *r_mboxes = mboxes; + mboxes = NULL; + + leave: + xfree (fpr); + xfree (mboxes); + xfree (mbox); + xfree (fields); + es_free (line); + xfree (argv); + es_fclose (listing); + return err; +} + + /* Helper to write mail to the output(s). */ gpg_error_t wks_send_mime (mime_maker_t mime) |