summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-09-18 15:37:21 +0200
committerWerner Koch <wk@gnupg.org>2017-09-18 15:41:51 +0200
commit50c8b6c88f5d9f4b6c4e9c03aee31fe29afa94b8 (patch)
tree7767ecb19f9540c311a61fe9a75412681fed9674
parentwks: Send only the newest UID to the server. (diff)
downloadgnupg2-50c8b6c88f5d9f4b6c4e9c03aee31fe29afa94b8.tar.xz
gnupg2-50c8b6c88f5d9f4b6c4e9c03aee31fe29afa94b8.zip
wks: Create a new user id if provider wants mailbox-only.
* tools/gpg-wks-client.c (get_key): Add arg 'exact'. (add_user_id): New. (command_send): Create new user id. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--doc/wks.texi4
-rw-r--r--tools/gpg-wks-client.c77
2 files changed, 72 insertions, 9 deletions
diff --git a/doc/wks.texi b/doc/wks.texi
index f9b1a0c14..029dbf0c0 100644
--- a/doc/wks.texi
+++ b/doc/wks.texi
@@ -78,7 +78,9 @@ the command is a properly formatted mail with all standard headers.
This mail can be fed to @command{sendmail(8)} or any other tool to
actually send that mail. If @command{sendmail(8)} is installed the
option @option{--send} can be used to directly send the created
-request.
+request. If the provider request a 'mailbox-only' user id and no such
+user id is found, @command{gpg-wks-client} will try an additional user
+id.
The @option{--receive} and @option{--read} commands are used to
process confirmation mails as send from the service provider. The
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c
index 37b75606b..73a8a1f43 100644
--- a/tools/gpg-wks-client.c
+++ b/tools/gpg-wks-client.c
@@ -348,10 +348,13 @@ get_key_status_cb (void *opaque, const char *keyword, char *args)
/* Get a key by fingerprint from gpg's keyring and make sure that the
- * mail address ADDRSPEC is included in the key. The key is returned
- * as a new memory stream at R_KEY. */
+ * mail address ADDRSPEC is included in the key. If EXACT is set the
+ * returned user id must match Addrspec exactly and not just in the
+ * addr-spec (mailbox) part. The key is returned as a new memory
+ * stream at R_KEY. */
static gpg_error_t
-get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
+get_key (estream_t *r_key, const char *fingerprint, const char *addrspec,
+ int exact)
{
gpg_error_t err;
ccparray_t ccp;
@@ -376,7 +379,7 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
es_fputs ("Content-Type: application/pgp-keys\n"
"\n", key);
- filterexp = es_bsprintf ("keep-uid=mbox = %s", addrspec);
+ filterexp = es_bsprintf ("keep-uid=%s=%s", exact? "uid":"mbox", addrspec);
if (!filterexp)
{
err = gpg_error_from_syserror ();
@@ -435,6 +438,49 @@ get_key (estream_t *r_key, const char *fingerprint, const char *addrspec)
}
+/* Add the user id UID to the key identified by FINGERPRINT. */
+static gpg_error_t
+add_user_id (const char *fingerprint, const char *uid)
+{
+ gpg_error_t err;
+ ccparray_t ccp;
+ const char **argv = NULL;
+
+ 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, "--always-trust");
+ ccparray_put (&ccp, "--quick-add-uid");
+ ccparray_put (&ccp, fingerprint);
+ ccparray_put (&ccp, uid);
+
+ 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, NULL,
+ NULL, NULL,
+ NULL, NULL);
+ if (err)
+ {
+ log_error ("adding user id failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ leave:
+ xfree (argv);
+ return err;
+}
+
+
struct decrypt_stream_parm_s
{
@@ -721,7 +767,7 @@ command_send (const char *fingerprint, const char *userid)
err = gpg_error (GPG_ERR_INV_USER_ID);
goto leave;
}
- err = get_key (&key, fingerprint, addrspec);
+ err = get_key (&key, fingerprint, addrspec, 0);
if (err)
goto leave;
@@ -786,6 +832,9 @@ command_send (const char *fingerprint, const char *userid)
{
if (!uid->mbox)
continue; /* Should not happen anyway. */
+ if (policy.mailbox_only
+ && ascii_strcasecmp (uid->uid, uid->mbox))
+ continue; /* UID has more than just the mailbox. */
if (uid->created > thistime)
{
thistime = uid->created;
@@ -793,7 +842,7 @@ command_send (const char *fingerprint, const char *userid)
}
}
if (!thisuid)
- thisuid = uid; /* This is the case for a missing timestamp. */
+ thisuid = uidlist; /* This is the case for a missing timestamp. */
if (opt.verbose)
log_info ("submitting key with user id '%s'\n", thisuid->uid);
@@ -816,10 +865,22 @@ command_send (const char *fingerprint, const char *userid)
}
if (policy.mailbox_only
- && ascii_strcasecmp (userid, addrspec))
+ && (!thisuid->mbox || ascii_strcasecmp (thisuid->uid, thisuid->mbox)))
{
log_info ("Warning: policy requires 'mailbox-only'"
- " - creating new user id'\n");
+ " - adding user id '%s'\n", addrspec);
+ err = add_user_id (fingerprint, addrspec);
+ if (err)
+ goto leave;
+
+ /* Need to get the key again. This time we request filtering
+ * for the full user id, so that we do not need check and filter
+ * the key again. */
+ es_fclose (key);
+ key = NULL;
+ err = get_key (&key, fingerprint, addrspec, 1);
+ if (err)
+ goto leave;
}
/* Hack to support posteo but let them disable this by setting the