diff --git a/g10/ChangeLog b/g10/ChangeLog index 0075f66b1..4e456a19a 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,15 @@ 2005-11-11 David Shaw + * trustdb.h, trustdb.c (clean_key): New function to handle key + cleaning from one convenient place. + + * options.h, import.c (parse_import_options, + clean_sigs_from_all_uids, import_one): Reduce clean options to + two: clean and minimize. + + * parse-packet.c (setup_user_id): Remove. + (parse_user_id, parse_attribute): Just use xmalloc_clear instead. + * trustdb.c (clean_uid_from_key, clean_uids_from_key): Significantly simpler implementation. diff --git a/g10/import.c b/g10/import.c index 17cc38f00..52118ec7a 100644 --- a/g10/import.c +++ b/g10/import.c @@ -101,15 +101,14 @@ parse_import_options(char *str,unsigned int *options,int noisy) N_("create a public key when importing a secret key")}, {"merge-only",IMPORT_MERGE_ONLY,NULL, N_("only accept updates to existing keys")}, - {"import-clean",IMPORT_CLEAN_SIGS|IMPORT_CLEAN_UIDS,NULL, - N_("all import-clean-* options from above")}, - {"import-clean-sigs",IMPORT_CLEAN_SIGS,NULL, - N_("remove unusable signatures after import")}, - {"import-clean-uids",IMPORT_CLEAN_UIDS,NULL, - N_("remove unusable user IDs after import")}, - {"import-minimal", - IMPORT_MINIMAL|IMPORT_CLEAN_SIGS|IMPORT_CLEAN_UIDS,NULL, + {"import-clean",IMPORT_CLEAN,NULL, + N_("remove unusable user IDs and signatures after import")}, + {"import-clean-sigs",0,NULL,NULL}, + {"import-clean-uids",0,NULL,NULL}, + {"import-minimal",IMPORT_MINIMAL|IMPORT_CLEAN,NULL, N_("remove unusable user IDs and all signatures after import")}, + /* Alias */ + {"import-minimize",IMPORT_MINIMAL|IMPORT_CLEAN,NULL,NULL}, /* Aliases for backward compatibility */ {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL,NULL}, {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL,NULL}, @@ -669,20 +668,6 @@ check_prefs(KBNODE keyblock) } } -static int -clean_sigs_from_all_uids(KBNODE keyblock,int self_only) -{ - KBNODE uidnode; - int deleted=0; - - for(uidnode=keyblock->next;uidnode;uidnode=uidnode->next) - if(uidnode->pkt->pkttype==PKT_USER_ID) - deleted+=clean_sigs_from_uid(keyblock,uidnode,opt.verbose,self_only); - - return deleted; -} - - /**************** * Try to import one keyblock. Return an error only in serious cases, but * never for an invalid keyblock. It uses log_error to increase the @@ -748,11 +733,8 @@ import_one( const char *fname, KBNODE keyblock, that we have to clean later. This has no practical impact on the end result, but does result in less logging which might confuse the user. */ - if(options&IMPORT_CLEAN_SIGS) - clean_sigs_from_all_uids(keyblock,options&IMPORT_MINIMAL); - - if(options&IMPORT_CLEAN_UIDS) - clean_uids_from_key(keyblock,opt.verbose); + if(options&IMPORT_CLEAN) + clean_key(keyblock,opt.verbose,options&IMPORT_MINIMAL,NULL,NULL); clear_kbnode_flags( keyblock ); @@ -901,12 +883,9 @@ import_one( const char *fname, KBNODE keyblock, goto leave; } - if(options&IMPORT_CLEAN_SIGS) - n_sigs_cleaned=clean_sigs_from_all_uids(keyblock_orig, - options&IMPORT_MINIMAL); - - if(options&IMPORT_CLEAN_UIDS) - n_uids_cleaned=clean_uids_from_key(keyblock_orig,opt.verbose); + if(options&IMPORT_CLEAN) + clean_key(keyblock_orig,opt.verbose,options&IMPORT_MINIMAL, + &n_uids_cleaned,&n_sigs_cleaned); if( n_uids || n_sigs || n_subk || n_sigs_cleaned || n_uids_cleaned) { mod_key = 1; diff --git a/g10/options.h b/g10/options.h index 181f658ca..20544b9a6 100644 --- a/g10/options.h +++ b/g10/options.h @@ -266,8 +266,7 @@ struct { #define IMPORT_SK2PK (1<<3) #define IMPORT_MERGE_ONLY (1<<4) #define IMPORT_MINIMAL (1<<5) -#define IMPORT_CLEAN_SIGS (1<<6) -#define IMPORT_CLEAN_UIDS (1<<7) +#define IMPORT_CLEAN (1<<6) #define EXPORT_LOCAL_SIGS (1<<0) #define EXPORT_ATTRIBUTES (1<<1) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index e5523beca..b67ad7f82 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1966,32 +1966,15 @@ parse_attribute_subpkts(PKT_user_id *uid) return count; } -static void setup_user_id(PACKET *packet) -{ - packet->pkt.user_id->ref = 1; - packet->pkt.user_id->attribs = NULL; - packet->pkt.user_id->attrib_data = NULL; - packet->pkt.user_id->attrib_len = 0; - packet->pkt.user_id->is_primary = 0; - packet->pkt.user_id->is_revoked = 0; - packet->pkt.user_id->is_expired = 0; - packet->pkt.user_id->expiredate = 0; - packet->pkt.user_id->created = 0; - packet->pkt.user_id->help_key_usage = 0; - packet->pkt.user_id->help_key_expire = 0; - packet->pkt.user_id->prefs = NULL; - packet->pkt.user_id->namehash = NULL; -} static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) { byte *p; - packet->pkt.user_id = xmalloc(sizeof *packet->pkt.user_id + pktlen); + packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen); packet->pkt.user_id->len = pktlen; - - setup_user_id(packet); + packet->pkt.user_id->ref=1; p = packet->pkt.user_id->name; for( ; pktlen; pktlen--, p++ ) @@ -2052,13 +2035,12 @@ parse_attribute( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) byte *p; #define EXTRA_UID_NAME_SPACE 71 - packet->pkt.user_id = xmalloc(sizeof *packet->pkt.user_id - + EXTRA_UID_NAME_SPACE); - - setup_user_id(packet); - + packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + + EXTRA_UID_NAME_SPACE); + packet->pkt.user_id->ref=1; packet->pkt.user_id->attrib_data = xmalloc(pktlen); packet->pkt.user_id->attrib_len = pktlen; + p = packet->pkt.user_id->attrib_data; for( ; pktlen; pktlen--, p++ ) *p = iobuf_get_noeof(inp); diff --git a/g10/trustdb.c b/g10/trustdb.c index bfd35a971..dd45e959f 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1668,23 +1668,27 @@ clean_uid_from_key(KBNODE keyblock,KBNODE uidnode,int noisy) { KBNODE node; PKT_user_id *uid=uidnode->pkt->pkt.user_id; + int deleted=0; assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY); assert(uidnode->pkt->pkttype==PKT_USER_ID); - /* Skip valid user IDs, and non-self-signed user IDs if - --allow-non-selfsigned-uid is set. */ - if(uid->created || (!uid->is_expired && !uid->is_revoked - && opt.allow_non_selfsigned_uid)) + /* Skip valid user IDs, compacted user IDs, and non-self-signed user + IDs if --allow-non-selfsigned-uid is set. */ + if(uid->created || uid->flags.compacted + || (!uid->is_expired && !uid->is_revoked + && opt.allow_non_selfsigned_uid)) return 0; for(node=uidnode->next; node && node->pkt->pkttype==PKT_SIGNATURE; node=node->next) if(!node->pkt->pkt.signature->flags.chosen_selfsig) - delete_kbnode(node); - - uid->flags.compacted=1; + { + delete_kbnode(node); + deleted=1; + uidnode->pkt->pkt.user_id->flags.compacted=1; + } if(noisy) { @@ -1705,7 +1709,7 @@ clean_uid_from_key(KBNODE keyblock,KBNODE uidnode,int noisy) xfree(user); } - return 1; + return deleted; } int @@ -1725,6 +1729,34 @@ clean_uids_from_key(KBNODE keyblock,int noisy) return deleted; } +void +clean_key(KBNODE keyblock,int noisy,int self_only, + int *uids_cleaned,int *sigs_cleaned) +{ + KBNODE uidnode; + int dummy; + + if(!uids_cleaned) + uids_cleaned=&dummy; + + if(!sigs_cleaned) + sigs_cleaned=&dummy; + + merge_keys_and_selfsig(keyblock); + + for(uidnode=keyblock->next; + uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY; + uidnode=uidnode->next) + if(uidnode->pkt->pkttype==PKT_USER_ID) + { + /* Do clean_uid_from_key first since if it fires off, we don't + have to bother with the other */ + *uids_cleaned+=clean_uid_from_key(keyblock,uidnode,noisy); + if(!uidnode->pkt->pkt.user_id->flags.compacted) + *sigs_cleaned+=clean_sigs_from_uid(keyblock,uidnode,noisy,self_only); + } +} + /* Used by validate_one_keyblock to confirm a regexp within a trust signature. Returns 1 for match, and 0 for no match or regex error. */ diff --git a/g10/trustdb.h b/g10/trustdb.h index e75e7f83c..8e6a842e7 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -84,6 +84,8 @@ int clear_ownertrusts (PKT_public_key *pk); int clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy,int self_only); int clean_uids_from_key(KBNODE keyblock,int noisy); +void clean_key(KBNODE keyblock,int noisy,int self_only, + int *uids_cleaned,int *sigs_cleaned); /*-- tdbdump.c --*/ void list_trustdb(const char *username);