diff options
Diffstat (limited to 'tools/gpg-wks-client.c')
-rw-r--r-- | tools/gpg-wks-client.c | 133 |
1 files changed, 103 insertions, 30 deletions
diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 3aa8f98..6f593ff 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -74,6 +74,8 @@ enum cmd_and_opt_values oWithColons, oBlacklist, oNoAutostart, + oAddRevocs, + oNoAddRevocs, oDummy }; @@ -100,9 +102,9 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_c (aRemoveKey, "remove-key", "remove a key from a directory"), ARGPARSE_c (aPrintWKDHash, "print-wkd-hash", - "Print the WKD identifier for the given user ids"), + "print the WKD identifier for the given user ids"), ARGPARSE_c (aPrintWKDURL, "print-wkd-url", - "Print the WKD URL for the given user id"), + "print the WKD URL for the given user id"), ARGPARSE_group (301, ("@\nOptions:\n ")), @@ -117,6 +119,8 @@ static ARGPARSE_OPTS opts[] = { ARGPARSE_s_n (oWithColons, "with-colons", "@"), ARGPARSE_s_s (oBlacklist, "blacklist", "@"), ARGPARSE_s_s (oDirectory, "directory", "@"), + ARGPARSE_s_n (oAddRevocs, "add-revocs", "add revocation certificates"), + ARGPARSE_s_n (oNoAddRevocs, "no-add-revocs", "do not add revocation certificates"), ARGPARSE_s_s (oFakeSubmissionAddr, "fake-submission-addr", "@"), @@ -154,7 +158,7 @@ static gpg_error_t proc_userid_from_stdin (gpg_error_t (*func)(const char *), const char *text); static gpg_error_t command_supported (char *userid); static gpg_error_t command_check (char *userid); -static gpg_error_t command_send (const char *fingerprint, const char *userid); +static gpg_error_t command_create (const char *fingerprint, const char *userid); static gpg_error_t encrypt_response (estream_t *r_output, estream_t input, const char *addrspec, const char *fingerprint); @@ -254,6 +258,12 @@ parse_arguments (ARGPARSE_ARGS *pargs, ARGPARSE_OPTS *popts) case oBlacklist: add_blacklist (pargs->r.ret_str); break; + case oAddRevocs: + opt.add_revocs = 1; + break; + case oNoAddRevocs: + opt.add_revocs = 0; + break; case aSupported: case aCreate: @@ -296,6 +306,8 @@ main (int argc, char **argv) assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); setup_libassuan_logging (&opt.debug, NULL); + opt.add_revocs = 1; /* Default add revocation certs. */ + /* Parse the command line. */ pargs.argc = &argc; pargs.argv = &argv; @@ -372,7 +384,7 @@ main (int argc, char **argv) case aCreate: if (argc != 2) wrong_args ("--create FINGERPRINT USER-ID"); - err = command_send (argv[0], argv[1]); + err = command_create (argv[0], argv[1]); if (err) log_error ("creating request failed: %s\n", gpg_strerror (err)); break; @@ -1090,6 +1102,9 @@ command_check (char *userid) log_info (" created: %s\n", asctimestamp (sl->created)); if (sl->mbox) log_info (" addr-spec: %s\n", sl->mbox); + if (sl->expired || sl->revoked) + log_info (" flags:%s%s\n", + sl->expired? " expired":"", sl->revoked?" revoked":""); } } if (!found) @@ -1112,7 +1127,7 @@ command_check (char *userid) /* Locate the key by fingerprint and userid and send a publication * request. */ static gpg_error_t -command_send (const char *fingerprint, const char *userid) +command_create (const char *fingerprint, const char *userid) { gpg_error_t err; KEYDB_SEARCH_DESC desc; @@ -1128,6 +1143,7 @@ command_send (const char *fingerprint, const char *userid) uidinfo_list_t uidlist = NULL; uidinfo_list_t uid, thisuid; time_t thistime; + int any; if (classify_user_id (fingerprint, &desc, 1) || !(desc.mode == KEYDB_SEARCH_MODE_FPR @@ -1145,7 +1161,7 @@ command_send (const char *fingerprint, const char *userid) err = gpg_error (GPG_ERR_INV_USER_ID); goto leave; } - err = wks_get_key (&key, fingerprint, addrspec, 0); + err = wks_get_key (&key, fingerprint, addrspec, 0, 1); if (err) goto leave; @@ -1189,12 +1205,20 @@ command_send (const char *fingerprint, const char *userid) } thistime = 0; thisuid = NULL; + any = 0; for (uid = uidlist; uid; uid = uid->next) { 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->expired) + { + if (opt.verbose) + log_info ("ignoring expired user id '%s'\n", uid->uid); + continue; + } + any = 1; if (uid->created > thistime) { thistime = uid->created; @@ -1203,6 +1227,14 @@ command_send (const char *fingerprint, const char *userid) } if (!thisuid) thisuid = uidlist; /* This is the case for a missing timestamp. */ + if (!any) + { + log_error ("public key %s has no mail address '%s'\n", + fingerprint, addrspec); + err = gpg_error (GPG_ERR_INV_USER_ID); + goto leave; + } + if (opt.verbose) log_info ("submitting key with user id '%s'\n", thisuid->uid); @@ -1213,7 +1245,7 @@ command_send (const char *fingerprint, const char *userid) estream_t newkey; es_rewind (key); - err = wks_filter_uid (&newkey, key, thisuid->uid, 0); + err = wks_filter_uid (&newkey, key, thisuid->uid, 1); if (err) { log_error ("error filtering key: %s\n", gpg_strerror (err)); @@ -1238,11 +1270,47 @@ command_send (const char *fingerprint, const char *userid) * the key again. */ es_fclose (key); key = NULL; - err = wks_get_key (&key, fingerprint, addrspec, 1); + err = wks_get_key (&key, fingerprint, addrspec, 1, 1); if (err) goto leave; } + if (opt.add_revocs) + { + if (es_fseek (key, 0, SEEK_END)) + { + err = gpg_error_from_syserror (); + log_error ("error seeking stream: %s\n", gpg_strerror (err)); + goto leave; + } + err = wks_find_add_revocs (key, addrspec); + if (err) + { + log_error ("error finding revocations for '%s': %s\n", + addrspec, gpg_strerror (err)); + goto leave; + } + } + + + /* Now put the armor around the key. */ + { + estream_t newkey; + + es_rewind (key); + err = wks_armor_key (&newkey, key, + no_encrypt? NULL + /* */ : ("Content-Type: application/pgp-keys\n" + "\n")); + if (err) + { + log_error ("error armoring key: %s\n", gpg_strerror (err)); + goto leave; + } + es_fclose (key); + key = newkey; + } + /* Hack to support posteo but let them disable this by setting the * new policy-version flag. */ if (policy->protocol_version < 3 @@ -1287,7 +1355,7 @@ command_send (const char *fingerprint, const char *userid) if (no_encrypt) { void *data; - size_t datalen, n; + size_t datalen; if (posteo_hack) { @@ -1312,16 +1380,7 @@ command_send (const char *fingerprint, const char *userid) goto leave; } key = NULL; - /* We need to skip over the first line which has a content-type - * header not needed here. */ - for (n=0; n < datalen ; n++) - if (((const char *)data)[n] == '\n') - { - n++; - break; - } - - err = mime_maker_add_body_data (mime, (char*)data + n, datalen - n); + err = mime_maker_add_body_data (mime, data, datalen); xfree (data); if (err) goto leave; @@ -1808,7 +1867,7 @@ domain_matches_mbox (const char *domain, const char *mbox) /* Core of mirror_one_key with the goal of mirroring just one uid. * UIDLIST is used to figure out whether the given MBOX occurs several - * times in UIDLIST and then to single out the newwest one. This is + * times in UIDLIST and then to single out the newest one. This is * so that for a key with * uid: Joe Someone <joe@example.org> * uid: Joe <joe@example.org> @@ -1849,24 +1908,36 @@ mirror_one_keys_userid (estream_t key, const char *mbox, uidinfo_list_t uidlist, err = gpg_error (GPG_ERR_NO_USER_ID); goto leave; } - /* FIXME: Consult blacklist. */ - - /* Only if we have more than one user id we bother to run the - * filter. In this case the result will be put into NEWKEY*/ + /* Always filter the key so that the result will be non-armored. */ es_rewind (key); - if (uidlist->next) + err = wks_filter_uid (&newkey, key, thisuid->uid, 1); + if (err) { - err = wks_filter_uid (&newkey, key, thisuid->uid, 0); + log_error ("error filtering key %s: %s\n", fpr, gpg_strerror (err)); + err = gpg_error (GPG_ERR_NO_PUBKEY); + goto leave; + } + + if (opt.add_revocs) + { + if (es_fseek (newkey, 0, SEEK_END)) + { + err = gpg_error_from_syserror (); + log_error ("error seeking stream: %s\n", gpg_strerror (err)); + goto leave; + } + err = wks_find_add_revocs (newkey, mbox); if (err) { - log_error ("error filtering key %s: %s\n", fpr, gpg_strerror (err)); - err = gpg_error (GPG_ERR_NO_PUBKEY); + log_error ("error finding revocations for '%s': %s\n", + mbox, gpg_strerror (err)); goto leave; } + es_rewind (newkey); } - err = wks_install_key_core (newkey? newkey : key, mbox); + err = wks_install_key_core (newkey, mbox); if (opt.verbose) log_info ("key %s published for '%s'\n", fpr, mbox); mirror_one_key_parm.nuids++; @@ -1905,7 +1976,9 @@ mirror_one_key (estream_t key) { if (!uid->mbox || (uid->flags & 1)) continue; /* No mail box or already processed. */ - if (!domain_matches_mbox (domain, uid->mbox)) + if (uid->expired) + continue; + if (*domain && !domain_matches_mbox (domain, uid->mbox)) continue; /* We don't want this one. */ if (is_in_blacklist (uid->mbox)) continue; |