diff options
Diffstat (limited to '')
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | doc/gpg.texi | 20 | ||||
-rw-r--r-- | g10/call-dirmngr.c | 4 | ||||
-rw-r--r-- | g10/gpg.c | 6 | ||||
-rw-r--r-- | g10/import.c | 2 | ||||
-rw-r--r-- | g10/keyserver-internal.h | 11 | ||||
-rw-r--r-- | g10/keyserver.c | 92 | ||||
-rw-r--r-- | g10/misc.c | 22 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | tools/gpgtar-extract.c | 5 | ||||
-rw-r--r-- | tools/gpgtar-list.c | 10 |
12 files changed, 135 insertions, 48 deletions
@@ -1,3 +1,11 @@ +Noteworthy changes in version 2.5.12 (unreleased) +------------------------------------------------- + + * gpgtar: Fix regression in end-of-archive detection. [T7757] + + Release-info: https://dev.gnupg.org/T7756 + + Noteworthy changes in version 2.5.11 (2025-07-30) ------------------------------------------------- diff --git a/configure.ac b/configure.ac index 023604b8a..eb9a0f1af 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ min_automake_version="1.16.3" m4_define([mym4_package],[gnupg]) m4_define([mym4_major], [2]) m4_define([mym4_minor], [5]) -m4_define([mym4_micro], [11]) +m4_define([mym4_micro], [12]) # To start a new development series, i.e a new major or minor number # you need to mark an arbitrary commit before the first beta release diff --git a/doc/gpg.texi b/doc/gpg.texi index 91bc73e8c..b0e7232a1 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -2167,10 +2167,6 @@ are available for all keyserver types, some common options are: are marked on the keyserver as disabled. Note that this option is not used with HKP keyservers. - @item auto-key-retrieve - This is an obsolete alias for the option @option{auto-key-retrieve}. - Please do not use it; it will be removed in future versions.. - @item honor-keyserver-url When using @option{--refresh-keys}, if the key in question has a preferred keyserver URL, then use that preferred keyserver to refresh the key @@ -2188,6 +2184,15 @@ are available for all keyserver types, some common options are: @item only-pubkeys Do not import secret keys. + @item update-before-send + Before sending a key to an LDAP server try to retrieve and merge + that key first. This is only done if the key is specified by + fingerprint. This is enabled by default. + + @item auto-key-retrieve + This is an obsolete alias for the option @option{auto-key-retrieve}. + Please do not use it; it will be removed in future versions. + @item timeout @itemx http-proxy=@var{value} @itemx verbose @@ -2200,9 +2205,10 @@ are available for all keyserver types, some common options are: @end table The default list of options is: "self-sigs-only, import-clean, -repair-keys, repair-pks-subkey-bug, export-attributes". However, if -the actual used source is an LDAP server "no-self-sigs-only" is -assumed unless "self-sigs-only" has been explicitly configured. +repair-keys, repair-pks-subkey-bug, export-attributes, +update-before-send". However, if the actual used source is an LDAP +server "no-self-sigs-only" is assumed unless "self-sigs-only" has been +explicitly configured. @item --completes-needed @var{n} diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index 12469d60a..c1644b886 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -449,7 +449,9 @@ ks_status_cb (void *opaque, const char *line) /* Run the "KEYSERVER" command to return the name of the used - keyserver at R_KEYSERVER. */ + * keyserver at R_KEYSERVER. This function returns the first + * keyserver; it should be extended to handle multiple keyservers or + * we disallow the use of several keyservers. */ gpg_error_t gpg_dirmngr_ks_list (ctrl_t ctrl, char **r_keyserver) { @@ -2518,7 +2518,7 @@ main (int argc, char **argv) | IMPORT_COLLAPSE_SUBKEYS | IMPORT_CLEAN); opt.keyserver_options.export_options = EXPORT_ATTRIBUTES; - opt.keyserver_options.options = 0; + opt.keyserver_options.options = KEYSERVER_UPDATE_BEFORE_SEND; opt.verify_options = (LIST_SHOW_UID_VALIDITY | VERIFY_SHOW_POLICY_URLS | VERIFY_SHOW_STD_NOTATIONS @@ -5072,9 +5072,9 @@ main (int argc, char **argv) for( ; argc; argc--, argv++ ) append_to_strlist2( &sl, *argv, utf8_strings ); if( cmd == aSendKeys ) - rc = keyserver_export (ctrl, sl ); + rc = keyserver_export (ctrl, sl, 0 ); else if( cmd == aRecvKeys ) - rc = keyserver_import (ctrl, sl ); + rc = keyserver_import (ctrl, sl, 0); else { export_stats_t stats = export_new_stats (); diff --git a/g10/import.c b/g10/import.c index 6e33ac976..1ee818d61 100644 --- a/g10/import.c +++ b/g10/import.c @@ -2234,7 +2234,7 @@ import_one_real (ctrl_t ctrl, log_error (_("key %s: public key not found: %s\n"), keystr(keyid), gpg_strerror (err)); } - else if (err && (opt.import_options&IMPORT_MERGE_ONLY) ) + else if (err && ((opt.import_options|options)&IMPORT_MERGE_ONLY) ) { if (opt.verbose && !silent ) log_info( _("key %s: new key - skipped\n"), keystr(keyid)); diff --git a/g10/keyserver-internal.h b/g10/keyserver-internal.h index cb2c005b4..9506fd015 100644 --- a/g10/keyserver-internal.h +++ b/g10/keyserver-internal.h @@ -25,8 +25,11 @@ #include "../common/types.h" /* Flags for the keyserver import functions. */ -#define KEYSERVER_IMPORT_FLAG_QUICK 1 -#define KEYSERVER_IMPORT_FLAG_LDAP 2 +#define KEYSERVER_IMPORT_FLAG_QUICK 1 /* Short time out. */ +#define KEYSERVER_IMPORT_FLAG_LDAP 2 /* Require LDAP server. */ +#define KEYSERVER_IMPORT_FLAG_SILENT 4 /* Do not print stats. */ +#define KEYSERVER_IMPORT_FLAG_ONLYFPR 8 /* Allow only fingerprint specs. */ +#define KEYSERVER_IMPORT_FLAG_UPDSEND 16 /* In updating before send. */ int parse_keyserver_options(char *options); void free_keyserver_spec(struct keyserver_spec *keyserver); @@ -35,8 +38,8 @@ struct keyserver_spec *parse_keyserver_uri (const char *string, int require_scheme); struct keyserver_spec *parse_preferred_keyserver(PKT_signature *sig); int keyserver_any_configured (ctrl_t ctrl); -int keyserver_export (ctrl_t ctrl, strlist_t users); -int keyserver_import (ctrl_t ctrl, strlist_t users); +gpg_error_t keyserver_export (ctrl_t ctrl, strlist_t users, int assume_new_key); +gpg_error_t keyserver_import (ctrl_t ctrl, strlist_t users, unsigned int flags); int keyserver_import_fpr (ctrl_t ctrl, const byte *fprint,size_t fprint_len, struct keyserver_spec *keyserver, unsigned int flags); diff --git a/g10/keyserver.c b/g10/keyserver.c index 069c541d2..bdfbde5c3 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -99,6 +99,8 @@ static struct parse_options keyserver_opts[]= N_("automatically retrieve keys when verifying signatures")}, {"honor-keyserver-url",KEYSERVER_HONOR_KEYSERVER_URL,NULL, N_("honor the preferred keyserver URL set on the key")}, + {"update-before-send", KEYSERVER_UPDATE_BEFORE_SEND,NULL, + N_("update a key before sending it")}, {NULL,0,NULL,NULL} }; @@ -107,7 +109,8 @@ static gpg_error_t keyserver_get (ctrl_t ctrl, struct keyserver_spec *override_keyserver, unsigned int flags, unsigned char **r_fpr, size_t *r_fprlen); -static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs); +static gpg_error_t keyserver_put (ctrl_t ctrl, strlist_t keyspecs, + int assume_new_key); /* Reasonable guess. The commonly used test key simon.josefsson.org @@ -790,8 +793,11 @@ search_line_handler (void *opaque, int special, char *line) -int -keyserver_export (ctrl_t ctrl, strlist_t users) +/* Send all keys specified by USERS to the configured keyserver. If + * ASSUME_NEW_KEY is true the KEYSERVER_UPDATE_BEFORE_SEND option will + * be ignored. */ +gpg_error_t +keyserver_export (ctrl_t ctrl, strlist_t users, int assume_new_key) { gpg_error_t err; strlist_t sl=NULL; @@ -815,7 +821,7 @@ keyserver_export (ctrl_t ctrl, strlist_t users) if(sl) { - rc = keyserver_put (ctrl, sl); + rc = keyserver_put (ctrl, sl, assume_new_key); free_strlist(sl); } @@ -898,23 +904,31 @@ keyserver_retrieval_screener (kbnode_t keyblock, void *opaque) } -int -keyserver_import (ctrl_t ctrl, strlist_t users) +/* Given a list of patterns in USERS, try to import those keys from + * the configured keyserver. */ +gpg_error_t +keyserver_import (ctrl_t ctrl, strlist_t users, unsigned int flags) { - gpg_error_t err; + gpg_error_t tmperr; + gpg_error_t err = 0; KEYDB_SEARCH_DESC *desc; int num=100,count=0; - int rc=0; /* Build a list of key ids */ - desc=xmalloc(sizeof(KEYDB_SEARCH_DESC)*num); + desc = xmalloc (sizeof(KEYDB_SEARCH_DESC)*num); for(;users;users=users->next) { - err = classify_user_id (users->d, &desc[count], 1); - if (err || (desc[count].mode != KEYDB_SEARCH_MODE_SHORT_KID - && desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID - && desc[count].mode != KEYDB_SEARCH_MODE_FPR)) + tmperr = classify_user_id (users->d, &desc[count], 1); + if (!tmperr && (flags & KEYSERVER_IMPORT_FLAG_ONLYFPR) + && desc[count].mode != KEYDB_SEARCH_MODE_FPR) + { + log_info (_("\"%s\" not a fingerprint: skipping\n"), users->d); + continue; + } + if (tmperr || (desc[count].mode != KEYDB_SEARCH_MODE_SHORT_KID + && desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID + && desc[count].mode != KEYDB_SEARCH_MODE_FPR)) { log_error (_("\"%s\" not a key ID: skipping\n"), users->d); continue; @@ -928,12 +942,12 @@ keyserver_import (ctrl_t ctrl, strlist_t users) } } - if(count>0) - rc = keyserver_get (ctrl, desc, count, NULL, 0, NULL, NULL); + if (count > 0) + err = keyserver_get (ctrl, desc, count, NULL, flags, NULL, NULL); - xfree(desc); + xfree (desc); - return rc; + return err; } @@ -1517,7 +1531,11 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, keyservers. */ /* For LDAP servers we reset IMPORT_SELF_SIGS_ONLY and - * IMPORT_CLEAN unless they have been set explicitly. */ + * IMPORT_CLEAN unless they have been set explicitly. We + * forcible clear them if that has been requested and also set + * the MERGE_ONLY option so that a --send-key can't be tricked + * into importing a key by means of the update-before-send + * keyserver option. */ options = (opt.keyserver_options.import_options | IMPORT_ONLY_PUBKEYS); if (source && (!strncmp (source, "ldap:", 5) || !strncmp (source, "ldaps:", 6))) @@ -1527,6 +1545,11 @@ keyserver_get_chunk (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, if (!opt.flags.expl_import_clean) options &= ~IMPORT_CLEAN; } + if ((flags & KEYSERVER_IMPORT_FLAG_UPDSEND)) + { + options &= ~(IMPORT_SELF_SIGS_ONLY | IMPORT_CLEAN); + options |= IMPORT_MERGE_ONLY; + } screenerarg.desc = desc; screenerarg.ndesc = *r_ndesc_used; @@ -1575,7 +1598,7 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, ndesc -= ndesc_used; } - if (any_good) + if (any_good && !(flags & KEYSERVER_IMPORT_FLAG_SILENT)) import_print_stats (stats_handle); import_release_stats_handle (stats_handle); @@ -1583,10 +1606,11 @@ keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc, } -/* Send all keys specified by KEYSPECS to the configured keyserver. */ +/* Send all keys specified by KEYSPECS to the configured keyserver. + * If ASSUME_NEW_KEY is true the KEYSERVER_UPDATE_BEFORE_SEND option + * will be ignored. */ static gpg_error_t -keyserver_put (ctrl_t ctrl, strlist_t keyspecs) - +keyserver_put (ctrl_t ctrl, strlist_t keyspecs, int assume_new_key) { gpg_error_t err; strlist_t kspec; @@ -1595,12 +1619,36 @@ keyserver_put (ctrl_t ctrl, strlist_t keyspecs) if (!keyspecs) return 0; /* Return success if the list is empty. */ + /* Get the name of the used keyservers. */ if (gpg_dirmngr_ks_list (ctrl, &ksurl)) { log_error (_("no keyserver known\n")); return gpg_error (GPG_ERR_NO_KEYSERVER); } + /* If the option is active, we first try to import the keys given by + * fingerprint from the keyserver. For example, if some PKI server + * has signed a key and the user has not yet imported that updated + * key, an upload would overwrite that key signature. This is only + * relevant for LDAP servers but not for the legacy HKP servers. */ + if ((opt.keyserver_options.options & KEYSERVER_UPDATE_BEFORE_SEND) + && !assume_new_key + && ksurl && (!strncmp (ksurl, "ldap:", 5) + || !strncmp (ksurl, "ldaps:", 6))) + { + err = keyserver_import (ctrl, keyspecs, (KEYSERVER_IMPORT_FLAG_UPDSEND + | KEYSERVER_IMPORT_FLAG_ONLYFPR + | KEYSERVER_IMPORT_FLAG_SILENT)); + if (err) + { + if (opt.verbose && gpg_err_code (err) != GPG_ERR_NO_DATA) + log_info (_("keyserver receive failed: %s\n"), + gpg_strerror (err)); + err = 0; + } + } + + /* Send key after key to the keyserver. */ for (kspec = keyspecs; kspec; kspec = kspec->next) { void *data; diff --git a/g10/misc.c b/g10/misc.c index c52091830..43be620e6 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1578,25 +1578,37 @@ parse_options(char *str,unsigned int *options, { char *tok; - if (str && (!strcmp (str, "help") || !strcmp (str, "full-help"))) + if (str && (!strcmp (str, "help") + || !strcmp (str, "full-help") || !strcmp (str, "fullhelp"))) { int i,maxlen=0; int full = *str == 'f'; + int set; /* Figure out the longest option name so we can line these up neatly. */ for(i=0;opts[i].name;i++) - if(opts[i].help && maxlen<strlen(opts[i].name)) + if((full || opts[i].help) && maxlen<strlen(opts[i].name)) maxlen=strlen(opts[i].name); for(i=0;opts[i].name;i++) if(opts[i].help) - es_printf("%s%*s%s\n",opts[i].name, - maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help)); + { + set = (*options & opts[i].bit); + es_printf("%s%*s%s%s%s%s\n",opts[i].name, + maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help), + set?" [":"", set? _("enabled"):"", set?"]":""); + } + if (full) for (i=0; opts[i].name; i++) if(!opts[i].help) - es_printf("%s\n",opts[i].name); + { + set = (*options & opts[i].bit); + es_printf("%s%*s%s%s%s\n",opts[i].name, + set? (maxlen+2-(int)strlen(opts[i].name)):0,"", + set?"[":"", set? _("enabled"):"", set?"]":""); + } g10_exit(0); } diff --git a/g10/options.h b/g10/options.h index 28fc2207a..c7f21086c 100644 --- a/g10/options.h +++ b/g10/options.h @@ -486,6 +486,7 @@ EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode; #define KEYSERVER_ADD_FAKE_V3 (1<<2) #define KEYSERVER_AUTO_KEY_RETRIEVE (1<<3) #define KEYSERVER_HONOR_KEYSERVER_URL (1<<4) +#define KEYSERVER_UPDATE_BEFORE_SEND (1<<5) #endif /*G10_OPTIONS_H*/ diff --git a/tools/gpgtar-extract.c b/tools/gpgtar-extract.c index 5ec22e8f7..d23ccc579 100644 --- a/tools/gpgtar-extract.c +++ b/tools/gpgtar-extract.c @@ -492,7 +492,8 @@ gpgtar_extract (const char *filename, int decrypt) #endif err = gpgrt_process_spawn (opt.gpg_program, argv, ((filename ? 0 : GPGRT_PROCESS_STDIN_KEEP) - | GPGRT_PROCESS_STDOUT_PIPE), act, &proc); + | GPGRT_PROCESS_STDOUT_PIPE + | GPGRT_PROCESS_STDERR_KEEP), act, &proc); gpgrt_spawn_actions_release (act); xfree (argv); if (err) @@ -525,6 +526,8 @@ gpgtar_extract (const char *filename, int decrypt) for (;;) { err = gpgtar_read_header (stream, tarinfo, &header, &extheader); + if (!err && !header) + break; /* End of archive. */ if (err || header == NULL) goto leave; diff --git a/tools/gpgtar-list.c b/tools/gpgtar-list.c index 07056575d..9f2eca318 100644 --- a/tools/gpgtar-list.c +++ b/tools/gpgtar-list.c @@ -527,7 +527,8 @@ gpgtar_list (const char *filename, int decrypt) #endif err = gpgrt_process_spawn (opt.gpg_program, argv, ((filename ? 0 : GPGRT_PROCESS_STDIN_KEEP) - | GPGRT_PROCESS_STDOUT_PIPE), act, &proc); + | GPGRT_PROCESS_STDOUT_PIPE + | GPGRT_PROCESS_STDERR_KEEP), act, &proc); gpgrt_spawn_actions_release (act); xfree (argv); if (err) @@ -559,6 +560,8 @@ gpgtar_list (const char *filename, int decrypt) for (;;) { err = read_header (stream, tarinfo, &header, &extheader); + if (!err && !header) + break; /* End of archive. */ if (err || header == NULL) goto leave; @@ -585,8 +588,9 @@ gpgtar_list (const char *filename, int decrypt) int exitcode; gpgrt_process_ctl (proc, GPGRT_PROCESS_GET_EXIT_ID, &exitcode); - log_error ("running %s failed (exitcode=%d): %s", - opt.gpg_program, exitcode, gpg_strerror (err)); + if (exitcode) + log_error ("running %s failed (exitcode=%d): %s", + opt.gpg_program, exitcode, gpg_strerror (err)); } gpgrt_process_release (proc); proc = NULL; |