* main.h, import.c (parse_import_options, fix_hkp_corruption, import_one,

delete_inv_parts), g10.c (main): New import-option
"repair-hkp-subkey-bug", which repairs as much as possible the HKP
mangling multiple subkeys bug.  It is on by default for keyserver
receives, and off by default for regular --import.

* main.h, import.c (import, import_one, delete_inv_parts), hkp.c
(hkp_ask_import), keyserver.c (keyserver_spawn): Use keyserver import
options when doing keyserver receives.
This commit is contained in:
David Shaw 2002-07-24 21:17:19 +00:00
parent d0c643a6c5
commit 553ac3f08c
6 changed files with 116 additions and 26 deletions

View File

@ -1,5 +1,15 @@
2002-07-24 David Shaw <dshaw@jabberwocky.com>
* main.h, import.c (parse_import_options, fix_hkp_corruption,
import_one, delete_inv_parts), g10.c (main): New import-option
"repair-hkp-subkey-bug", which repairs as much as possible the HKP
mangling multiple subkeys bug. It is on by default for keyserver
receives, and off by default for regular --import.
* main.h, import.c (import, import_one, delete_inv_parts), hkp.c
(hkp_ask_import), keyserver.c (keyserver_spawn): Use keyserver
import options when doing keyserver receives.
* options.h, exec.h, exec.c (set_exec_path, exec_write), g10.c
(main), keyserver.c (keyserver_spawn): If the user does not use
"exec-path", completely replace $PATH with GNUPG_LIBEXECDIR before

View File

@ -906,10 +906,12 @@ main( int argc, char **argv )
opt.pgp2_workarounds = 1;
opt.force_v3_sigs = 1;
opt.escape_from = 1;
opt.import_options=IMPORT_DEFAULT;
opt.export_options=EXPORT_DEFAULT;
opt.keyserver_options.import_options=IMPORT_DEFAULT;
opt.keyserver_options.export_options=EXPORT_DEFAULT;
opt.import_options=0;
opt.export_options=
EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
opt.keyserver_options.import_options=IMPORT_REPAIR_HKP_SUBKEY_BUG;
opt.keyserver_options.export_options=
EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
opt.keyserver_options.include_subkeys=1;
#if defined (__MINGW32__) || defined (__CYGWIN32__)
opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
@ -2027,7 +2029,8 @@ main( int argc, char **argv )
case aFastImport:
case aImport:
import_keys( argc? argv:NULL, argc, (cmd == aFastImport), NULL );
import_keys( argc? argv:NULL, argc, (cmd == aFastImport),
NULL, opt.import_options );
break;
case aExport:

View File

@ -98,7 +98,8 @@ hkp_ask_import( KEYDB_SEARCH_DESC *desc, void *stats_handle)
: g10_errstr(rc) );
}
else {
rc = import_keys_stream( hd.fp_read, 0, stats_handle);
rc = import_keys_stream( hd.fp_read, 0, stats_handle,
opt.keyserver_options.import_options);
http_close( &hd );
}

View File

@ -55,19 +55,20 @@ struct stats_s {
static int import( IOBUF inp, int fast, const char* fname,
struct stats_s *stats );
struct stats_s *stats, unsigned int options );
static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root );
static void revocation_present(KBNODE keyblock);
static void remove_bad_stuff (KBNODE keyblock);
static int import_one( const char *fname, KBNODE keyblock, int fast,
struct stats_s *stats);
struct stats_s *stats, unsigned int options);
static int import_secret_one( const char *fname, KBNODE keyblock,
struct stats_s *stats );
static int import_revoke_cert( const char *fname, KBNODE node,
struct stats_s *stats);
static int chk_self_sigs( const char *fname, KBNODE keyblock,
PKT_public_key *pk, u32 *keyid );
static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid );
static int delete_inv_parts( const char *fname, KBNODE keyblock,
u32 *keyid, unsigned int options );
static int merge_blocks( const char *fname, KBNODE keyblock_orig,
KBNODE keyblock, u32 *keyid,
int *n_uids, int *n_sigs, int *n_subk );
@ -93,6 +94,7 @@ parse_import_options(char *str,unsigned int *options)
} import_opts[]=
{
{"allow-local-sigs",IMPORT_ALLOW_LOCAL_SIGS},
{"repair-hkp-subkey-bug",IMPORT_REPAIR_HKP_SUBKEY_BUG},
{NULL,0}
};
@ -170,7 +172,8 @@ import_release_stats_handle (void *p)
*
*/
void
import_keys( char **fnames, int nnames, int fast, void *stats_handle )
import_keys( char **fnames, int nnames, int fast,
void *stats_handle, unsigned int options )
{
int i;
struct stats_s *stats = stats_handle;
@ -189,7 +192,7 @@ import_keys( char **fnames, int nnames, int fast, void *stats_handle )
if( !inp )
log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
else {
int rc = import( inp, fast, fname, stats );
int rc = import( inp, fast, fname, stats, options );
iobuf_close(inp);
if( rc )
log_error("import from `%s' failed: %s\n", fname,
@ -206,7 +209,8 @@ import_keys( char **fnames, int nnames, int fast, void *stats_handle )
}
int
import_keys_stream( IOBUF inp, int fast, void *stats_handle )
import_keys_stream( IOBUF inp, int fast,
void *stats_handle, unsigned int options )
{
int rc = 0;
struct stats_s *stats = stats_handle;
@ -214,7 +218,7 @@ import_keys_stream( IOBUF inp, int fast, void *stats_handle )
if (!stats)
stats = import_new_stats_handle ();
rc = import( inp, fast, "[stream]", stats);
rc = import( inp, fast, "[stream]", stats, options);
if (!stats_handle) {
import_print_stats (stats);
import_release_stats_handle (stats);
@ -224,7 +228,8 @@ import_keys_stream( IOBUF inp, int fast, void *stats_handle )
}
static int
import( IOBUF inp, int fast, const char* fname, struct stats_s *stats )
import( IOBUF inp, int fast, const char* fname,
struct stats_s *stats, unsigned int options )
{
PACKET *pending_pkt = NULL;
KBNODE keyblock;
@ -241,7 +246,7 @@ import( IOBUF inp, int fast, const char* fname, struct stats_s *stats )
while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
remove_bad_stuff (keyblock);
if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
rc = import_one( fname, keyblock, fast, stats );
rc = import_one( fname, keyblock, fast, stats, options );
else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
rc = import_secret_one( fname, keyblock, stats );
else if( keyblock->pkt->pkttype == PKT_SIGNATURE
@ -440,6 +445,70 @@ remove_bad_stuff (KBNODE keyblock)
}
}
/* Walk through the subkeys on a pk to find if we have the HKP
disease: multiple subkeys with their binding sigs stripped, and the
sig for the first subkey placed after the last subkey. That is,
instead of "pk uid sig sub1 bind1 sub2 bind2 sub3 bind3" we have
"pk uid sig sub1 sub2 sub3 bind1". We can't do anything about sub2
and sub3, as they are already lost, but we can try and rescue sub1
by reordering the keyblock so that it reads "pk uid sig sub1 bind1
sub2 sub3". Returns TRUE if the keyblock was modified. */
static int
fix_hkp_corruption(KBNODE keyblock)
{
int changed=0,keycount=0;
KBNODE node,last=NULL,sknode=NULL;
/* First determine if we have the problem at all. Look for 2 or
more subkeys in a row, followed by a single binding sig. */
for(node=keyblock;node;last=node,node=node->next)
{
if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
{
keycount++;
if(!sknode)
sknode=node;
}
else if(node->pkt->pkttype==PKT_SIGNATURE &&
node->pkt->pkt.signature->sig_class==0x18 &&
keycount>=2 && node->next==NULL)
{
/* We might have the problem, as this key has two subkeys in
a row without any intervening packets. */
/* Sanity check */
if(last==NULL)
break;
/* Temporarily attach node to sknode. */
node->next=sknode->next;
sknode->next=node;
last->next=NULL;
if(check_key_signature(keyblock,node,NULL))
{
/* Not a match, so undo the changes. */
sknode->next=node->next;
last->next=node;
node->next=NULL;
break;
}
else
{
sknode->flag |= 1; /* Mark it good so we don't need to
check it again */
changed=1;
break;
}
}
else
keycount=0;
}
return changed;
}
/* Clean the subkeys on a pk so that they each have at most 1 binding
sig and at most 1 revocation sig. This works based solely on the
timestamps like the rest of gpg. If the standard does get
@ -538,7 +607,7 @@ clean_subkeys(KBNODE keyblock,u32 *keyid)
*/
static int
import_one( const char *fname, KBNODE keyblock, int fast,
struct stats_s *stats )
struct stats_s *stats, unsigned int options )
{
PKT_public_key *pk;
PKT_public_key *pk_orig;
@ -574,6 +643,11 @@ import_one( const char *fname, KBNODE keyblock, int fast,
}
clear_kbnode_flags( keyblock );
if((options&IMPORT_REPAIR_HKP_SUBKEY_BUG) && fix_hkp_corruption(keyblock))
log_info(_("key %08lX: HKP subkey corruption repaired\n"),
(ulong)keyid[1]);
rc = chk_self_sigs( fname, keyblock , pk, keyid );
if( rc )
return rc== -1? 0:rc;
@ -591,7 +665,7 @@ import_one( const char *fname, KBNODE keyblock, int fast,
m_free(user);
}
if( !delete_inv_parts( fname, keyblock, keyid ) ) {
if( !delete_inv_parts( fname, keyblock, keyid, options ) ) {
if( !opt.quiet ) {
log_info( _("key %08lX: no valid user IDs\n"),
(ulong)keyid[1]);
@ -1033,7 +1107,8 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
* returns: true if at least one valid user-id is left over.
*/
static int
delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
delete_inv_parts( const char *fname, KBNODE keyblock,
u32 *keyid, unsigned int options)
{
KBNODE node;
int nvalid=0, uid_seen=0, subkey_seen=0;
@ -1086,7 +1161,7 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
delete_kbnode( node ); /* build_packet() can't handle this */
else if( node->pkt->pkttype == PKT_SIGNATURE &&
!node->pkt->pkt.signature->flags.exportable &&
!(opt.import_options&IMPORT_ALLOW_LOCAL_SIGS) &&
!(options&IMPORT_ALLOW_LOCAL_SIGS) &&
seckey_available( node->pkt->pkt.signature->keyid ) ) {
/* here we violate the rfc a bit by still allowing
* to import non-exportable signature when we have the

View File

@ -598,7 +598,8 @@ keyserver_spawn(int action,STRLIST list,
do this could be to continue parsing this line-by-line and
make a temp iobuf for each key. */
import_keys_stream(spawn->fromchild,0,stats_handle);
import_keys_stream(spawn->fromchild,0,stats_handle,
opt.keyserver_options.import_options);
import_print_stats(stats_handle);
import_release_stats_handle(stats_handle);

View File

@ -150,13 +150,14 @@ KBNODE make_comment_node( const char *s );
KBNODE make_mpi_comment_node( const char *s, MPI a );
/*-- import.c --*/
/* 1, 4, and 8 are reserved so they match the EXPORT_* flags below */
#define IMPORT_ALLOW_LOCAL_SIGS 2
#define IMPORT_DEFAULT 0
#define IMPORT_ALLOW_LOCAL_SIGS 1
#define IMPORT_REPAIR_HKP_SUBKEY_BUG 2
int parse_import_options(char *str,unsigned int *options);
void import_keys( char **fnames, int nnames, int fast, void *stats_hd );
int import_keys_stream( IOBUF inp, int fast, void *stats_hd );
void import_keys( char **fnames, int nnames, int fast,
void *stats_hd, unsigned int options );
int import_keys_stream( IOBUF inp, int fast,
void *stats_hd, unsigned int options );
void *import_new_stats_handle (void);
void import_release_stats_handle (void *p);
void import_print_stats (void *hd);
@ -168,7 +169,6 @@ int collapse_uids( KBNODE *keyblock );
#define EXPORT_INCLUDE_LOCAL_SIGS 2
#define EXPORT_INCLUDE_ATTRIBUTES 4
#define EXPORT_INCLUDE_SENSITIVE_REVKEYS 8
#define EXPORT_DEFAULT (1|4)
int parse_export_options(char *str,unsigned int *options);
int export_pubkeys( STRLIST users, unsigned int options );