diff --git a/doc/gpg.texi b/doc/gpg.texi index 988835d22..2cb20f4c7 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2471,6 +2471,10 @@ The available properties are: created. The second is the same but given as an ISO string, e.g. "2016-08-17". (drop-subkey) + @item fpr + The hexified fingerprint of the current subkey or primary key. + (drop-subkey) + @item primary Boolean indicating whether the user id is the primary one. (keep-uid) diff --git a/g10/export.c b/g10/export.c index 052e16717..a76a7da84 100644 --- a/g10/export.c +++ b/g10/export.c @@ -73,6 +73,17 @@ static recsel_expr_t export_keep_uid; static recsel_expr_t export_drop_subkey; +/* An object used for a linked list to implement the + * push_export_filter/pop_export_filters functions. */ +struct export_filter_attic_s +{ + struct export_filter_attic_s *next; + recsel_expr_t export_keep_uid; + recsel_expr_t export_drop_subkey; +}; +static struct export_filter_attic_s *export_filter_attic; + + /* Local prototypes. */ static int do_export (ctrl_t ctrl, strlist_t users, int secret, @@ -198,6 +209,41 @@ parse_and_set_export_filter (const char *string) } +/* Push the current export filters onto a stack so that new export + * filters can be defined which will be active until the next + * pop_export_filters or another push_export_filters. */ +void +push_export_filters (void) +{ + struct export_filter_attic_s *item; + + item = xcalloc (1, sizeof *item); + item->export_keep_uid = export_keep_uid; + export_keep_uid = NULL; + item->export_drop_subkey = export_drop_subkey; + export_drop_subkey = NULL; + item->next = export_filter_attic; + export_filter_attic = item; +} + + +/* Revert the last push_export_filters. */ +void +pop_export_filters (void) +{ + struct export_filter_attic_s *item; + + item = export_filter_attic; + if (!item) + BUG (); /* No corresponding push. */ + export_filter_attic = item->next; + cleanup_export_globals (); + export_keep_uid = item->export_keep_uid; + export_drop_subkey = item->export_drop_subkey; +} + + + /* Create a new export stats object initialized to zero. On error returns NULL and sets ERRNO. */ export_stats_t @@ -292,10 +338,12 @@ export_secsubkeys (ctrl_t ctrl, strlist_t users, unsigned int options, /* * Export a single key into a memory buffer. STATS is either an - * export stats object for update or NULL. + * export stats object for update or NULL. If PREFIX is not NULL + * PREFIXLEN bytes from PREFIX are prepended to the R_DATA. */ gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, + const void *prefix, size_t prefixlen, export_stats_t stats, kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) { @@ -313,6 +361,8 @@ export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, return gpg_error_from_syserror (); iobuf = iobuf_temp (); + if (prefix && prefixlen) + iobuf_write (iobuf, prefix, prefixlen); err = do_export_stream (ctrl, iobuf, helplist, 0, r_keyblock, options, stats, &any); if (!err && !any) diff --git a/g10/gpgv.c b/g10/gpgv.c index 5ddc2a67c..ae37fa340 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -715,12 +715,15 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid, gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, + const void *prefix, size_t prefixlen, export_stats_t stats, kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) { (void)ctrl; (void)keyspec; (void)options; + (void)prefix; + (void)prefixlen; (void)stats; *r_keyblock = NULL; diff --git a/g10/import.c b/g10/import.c index ab825085e..77c05c1f1 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1478,6 +1478,11 @@ impex_filter_getval (void *cookie, const char *propname) (pk->pubkey_usage & PUBKEY_USAGE_UNKNOWN)?"?":""); result = numbuf; } + else if (!strcmp (propname, "fpr")) + { + hexfingerprint (pk, parm->hexfpr, sizeof parm->hexfpr); + result = parm->hexfpr; + } else result = NULL; } diff --git a/g10/keyserver.c b/g10/keyserver.c index 4d4a3ded8..bae604d10 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1806,7 +1806,7 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs) err = export_pubkey_buffer (ctrl, kspec->d, opt.keyserver_options.export_options, - NULL, + NULL, 0, NULL, &keyblock, &data, &datalen); if (err) log_error (_("skipped \"%s\": %s\n"), kspec->d, gpg_strerror (err)); diff --git a/g10/main.h b/g10/main.h index 704eb339f..3b44b16c6 100644 --- a/g10/main.h +++ b/g10/main.h @@ -390,6 +390,7 @@ struct impex_filter_parm_s { ctrl_t ctrl; kbnode_t node; + char hexfpr[2*MAX_FINGERPRINT_LEN + 1]; }; const char *impex_filter_getval (void *cookie, const char *propname); @@ -413,6 +414,8 @@ void export_print_stats (export_stats_t stats); int parse_export_options(char *str,unsigned int *options,int noisy); gpg_error_t parse_and_set_export_filter (const char *string); +void push_export_filters (void); +void pop_export_filters (void); int exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, kbnode_t node); @@ -425,6 +428,7 @@ int export_secsubkeys (ctrl_t ctrl, strlist_t users, unsigned int options, gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, + const void *prefix, size_t prefixlen, export_stats_t stats, kbnode_t *r_keyblock, void **r_data, size_t *r_datalen); diff --git a/g10/test-stubs.c b/g10/test-stubs.c index d5b6d4f02..ffff83d06 100644 --- a/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -471,12 +471,15 @@ gpg_dirmngr_get_pka (ctrl_t ctrl, const char *userid, gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, unsigned int options, + const void *prefix, size_t prefixlen, export_stats_t stats, kbnode_t *r_keyblock, void **r_data, size_t *r_datalen) { (void)ctrl; (void)keyspec; (void)options; + (void)prefix; + (void)prefixlen; (void)stats; *r_keyblock = NULL;