summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tools/gpg-wks-server.c170
-rw-r--r--tools/gpg-wks.h1
-rw-r--r--tools/wks-util.c179
3 files changed, 186 insertions, 164 deletions
diff --git a/tools/gpg-wks-server.c b/tools/gpg-wks-server.c
index fd65b40c6..1a918587c 100644
--- a/tools/gpg-wks-server.c
+++ b/tools/gpg-wks-server.c
@@ -348,168 +348,6 @@ main (int argc, char **argv)
}
-
-static void
-list_key_status_cb (void *opaque, const char *keyword, char *args)
-{
- server_ctx_t ctx = opaque;
- (void)ctx;
- if (DBG_CRYPTO)
- log_debug ("gpg status: %s %s\n", keyword, args);
-}
-
-
-static gpg_error_t
-list_key (server_ctx_t ctx, estream_t key)
-{
- 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;
-
- /* We store our results in the context - clear it first. */
- xfree (ctx->fpr);
- ctx->fpr = NULL;
- free_strlist (ctx->mboxes);
- ctx->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, ctx);
- 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 && !ctx->fpr)
- {
- ctx->fpr = xtrystrdup (fields[9]);
- if (!ctx->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 (&ctx->mboxes, mbox))
- {
- err = gpg_error_from_syserror ();
- goto leave;
- }
- }
- }
- if (len < 0 || es_ferror (listing))
- log_error ("error reading memory stream\n");
-
- leave:
- xfree (mbox);
- xfree (fields);
- es_free (line);
- xfree (argv);
- es_fclose (listing);
- return err;
-}
-
-
/* Take the key in KEYFILE and write it to OUTFILE in binary encoding.
* If ADDRSPEC is given only matching user IDs are included in the
* output. */
@@ -1216,7 +1054,9 @@ process_new_key (server_ctx_t ctx, estream_t key)
struct policy_flags_s policybuf;
/* First figure out the user id from the key. */
- err = list_key (ctx, key);
+ xfree (ctx->fpr);
+ free_strlist (ctx->mboxes);
+ err = wks_list_key (key, &ctx->fpr, &ctx->mboxes);
if (err)
goto leave;
if (!ctx->fpr)
@@ -1457,7 +1297,9 @@ check_and_publish (server_ctx_t ctx, const char *address, const char *nonce)
}
/* We need to get the fingerprint from the key. */
- err = list_key (ctx, key);
+ xfree (ctx->fpr);
+ free_strlist (ctx->mboxes);
+ err = wks_list_key (key, &ctx->fpr, &ctx->mboxes);
if (err)
goto leave;
if (!ctx->fpr)
diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h
index f7cccb32c..7f347eb3e 100644
--- a/tools/gpg-wks.h
+++ b/tools/gpg-wks.h
@@ -65,6 +65,7 @@ typedef struct policy_flags_s *policy_flags_t;
/*-- wks-util.c --*/
+gpg_error_t wks_list_key (estream_t key, char **r_fpr, strlist_t *r_mboxes);
gpg_error_t wks_send_mime (mime_maker_t mime);
gpg_error_t wks_parse_policy (policy_flags_t flags, estream_t stream,
int ignore_unknown);
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)