diff --git a/g10/export.c b/g10/export.c index 606f4eb22..ddd94cf05 100644 --- a/g10/export.c +++ b/g10/export.c @@ -2250,8 +2250,8 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, keydb_release (kdbhd); if (err || !keyblock_out) release_kbnode( keyblock ); - if( !*any ) - log_info(_("WARNING: nothing exported\n")); + if( !*any && !opt.quiet) + log_info (_("WARNING: nothing exported\n")); return err; } diff --git a/tools/gpg-wks-client.c b/tools/gpg-wks-client.c index 45c14bc55..2139011e0 100644 --- a/tools/gpg-wks-client.c +++ b/tools/gpg-wks-client.c @@ -1095,6 +1095,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) @@ -1133,6 +1136,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 @@ -1194,12 +1198,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; @@ -1208,6 +1220,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); @@ -1949,6 +1969,8 @@ mirror_one_key (estream_t key) { if (!uid->mbox || (uid->flags & 1)) continue; /* No mail box or already processed. */ + if (uid->expired) + continue; if (!domain_matches_mbox (domain, uid->mbox)) continue; /* We don't want this one. */ if (is_in_blacklist (uid->mbox)) diff --git a/tools/gpg-wks.h b/tools/gpg-wks.h index 59a0aca74..a7c17ca52 100644 --- a/tools/gpg-wks.h +++ b/tools/gpg-wks.h @@ -81,6 +81,8 @@ struct uidinfo_list_s time_t created; /* Time the userid was created. */ char *mbox; /* NULL or the malloced mailbox from UID. */ unsigned int flags; /* These flags are cleared on creation. */ + unsigned int expired:1; + unsigned int revoked:1; char uid[1]; }; typedef struct uidinfo_list_s *uidinfo_list_t; diff --git a/tools/wks-util.c b/tools/wks-util.c index 91a4a7da8..2e8541491 100644 --- a/tools/wks-util.c +++ b/tools/wks-util.c @@ -101,7 +101,8 @@ wks_write_status (int no, const char *format, ...) * updated. C-style escaping is removed from UID. On error ERRNO is * set and NULL returned. */ static uidinfo_list_t -append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created) +append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created, + int expired, int revoked) { uidinfo_list_t r, sl; char *plainuid; @@ -121,6 +122,8 @@ append_to_uidinfo_list (uidinfo_list_t *list, const char *uid, time_t created) sl->created = created; sl->flags = 0; sl->mbox = mailbox_from_userid (plainuid); + sl->expired = !!expired; + sl->revoked = !!revoked; sl->next = NULL; if (!*list) *list = sl; @@ -296,6 +299,22 @@ key_status_cb (void *opaque, const char *keyword, char *args) } +/* Parse field 1 and set revoked and expired on return. */ +static void +set_expired_revoked (const char *string, int *expired, int *revoked) +{ + *expired = *revoked = 0; + /* Look at letters and stop at the first digit. */ + for ( ;*string && !digitp (string); string++) + { + if (*string == 'e') + *expired = 1; + else if (*string == 'r') + *revoked = 1; + } +} + + /* 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. @@ -316,6 +335,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) int lnr; char *fpr = NULL; uidinfo_list_t mboxes = NULL; + int expired, revoked; if (r_fpr) *r_fpr = NULL; @@ -364,6 +384,7 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) es_rewind (listing); lnr = 0; + expired = revoked = 0; maxlen = 2048; /* Set limit. */ while ((len = es_read_line (listing, &line, &length_of_line, &maxlen)) > 0) { @@ -408,12 +429,20 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) err = gpg_error (GPG_ERR_INV_ENGINE); goto leave; } - if (lnr > 1 && !strcmp (fields[0], "pub")) + if (!strcmp (fields[0], "pub")) { - /* More than one public key. */ - err = gpg_error (GPG_ERR_TOO_MANY); - goto leave; + if (lnr > 1) + { + /* More than one public key. */ + err = gpg_error (GPG_ERR_TOO_MANY); + goto leave; + } + if (nfields > 1) + set_expired_revoked (fields[1], &expired, &revoked); + else + expired = revoked = 0; } + if (!strcmp (fields[0], "sub") || !strcmp (fields[0], "ssb")) break; /* We can stop parsing here. */ @@ -428,8 +457,13 @@ wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes) } else if (!strcmp (fields[0], "uid") && nfields > 9) { + int uidexpired, uidrevoked; + + set_expired_revoked (fields[1], &uidexpired, &uidrevoked); if (!append_to_uidinfo_list (&mboxes, fields[9], - parse_timestamp (fields[5], NULL))) + parse_timestamp (fields[5], NULL), + expired || uidexpired, + revoked || uidrevoked)) { err = gpg_error_from_syserror (); goto leave; @@ -1280,6 +1314,12 @@ wks_cmd_install_key (const char *fname, const char *userid) continue; /* Should not happen anyway. */ if (ascii_strcasecmp (uid->mbox, addrspec)) continue; /* Not the requested addrspec. */ + if (uid->expired) + { + if (opt.verbose) + log_info ("ignoring expired user id '%s'\n", uid->uid); + continue; + } any = 1; if (uid->created > thistime) {