From 475107dff365673f9038126f99b20a11760f6192 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Thu, 9 Jun 2005 02:53:18 +0000 Subject: [PATCH] * trustdb.c (clean_uids_from_key), keyedit.c (menu_clean_uids_from_key): Tweak algorithm to preserve the last selfsig which helps prevent uid resurrections. --- g10/ChangeLog | 4 ++++ g10/keyedit.c | 40 ++++++++++++++++++++++------------------ g10/trustdb.c | 24 +++++++++--------------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 2f8b61754..48a6e6eda 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,9 @@ 2005-06-08 David Shaw + * trustdb.c (clean_uids_from_key), keyedit.c + (menu_clean_uids_from_key): Tweak algorithm to preserve the last + selfsig which helps prevent uid resurrections. + * getkey.c (fixup_uidnode, merge_selfsigs_main): Handle both expired and revoked uids in fixup_uidnode(). No need to special case in merge_selfsigs_main(). This also means that an expired diff --git a/g10/keyedit.c b/g10/keyedit.c index 70c5c5b57..46603d1bc 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1435,7 +1435,8 @@ static struct { "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") }, { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") }, { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") }, - { "clean", cmdCLEAN , KEYEDIT_NOT_SK, NULL }, + { "clean", cmdCLEAN , KEYEDIT_NOT_SK, + N_("clean unusable parts from key") }, { NULL, cmdNONE, 0, NULL } }; @@ -2150,19 +2151,16 @@ keyedit_menu( const char *username, STRLIST locusr, redisplay=modified=menu_clean_uids_from_key(keyblock); else if(ascii_strcasecmp(arg_string,"subkeys")==0) redisplay=modified=menu_clean_subkeys_from_key(keyblock); - else if(ascii_strcasecmp(arg_string,"all")==0) - { - modified=menu_clean_sigs_from_uids(keyblock); - modified+=menu_clean_uids_from_key(keyblock); - modified+=menu_clean_subkeys_from_key(keyblock); - redisplay=modified; - } else tty_printf("Unable to clean `%s'\n",arg_string); } else - tty_printf("Please specify item to clean: `sigs'," - " `uids', `subkeys', or `all'\n"); + { + modified=menu_clean_sigs_from_uids(keyblock); + modified+=menu_clean_uids_from_key(keyblock); + modified+=menu_clean_subkeys_from_key(keyblock); + redisplay=modified; + } } break; @@ -3187,34 +3185,40 @@ menu_clean_sigs_from_uids(KBNODE keyblock) static int menu_clean_uids_from_key(KBNODE keyblock) { - KBNODE node; int modified=clean_uids_from_key(keyblock,0); if(modified) { + KBNODE node,uidnode=NULL; + for(node=keyblock->next;node;node=node->next) { - if(node->pkt->pkttype==PKT_USER_ID && is_deleted_kbnode(node)) + if(node->pkt->pkttype==PKT_USER_ID) + uidnode=node; + else if(uidnode && node->pkt->pkttype==PKT_SIGNATURE + && is_deleted_kbnode(node)) { const char *reason; - char *user=utf8_to_native(node->pkt->pkt.user_id->name, - node->pkt->pkt.user_id->len,0); + char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name, + uidnode->pkt->pkt.user_id->len,0); - if(node->pkt->pkt.user_id->is_revoked) + if(uidnode->pkt->pkt.user_id->is_revoked) reason=_("revoked"); - else if(node->pkt->pkt.user_id->is_expired) + else if(uidnode->pkt->pkt.user_id->is_expired) reason=_("expired"); else reason=_("invalid"); - tty_printf("User ID \"%s\" removed: %s\n",user,reason); + tty_printf("User ID \"%s\" compacted: %s\n",user,reason); + + uidnode=NULL; m_free(user); } } } else - tty_printf("No user IDs are removable.\n"); + tty_printf("No user IDs are compactable.\n"); return modified; } diff --git a/g10/trustdb.c b/g10/trustdb.c index d0f6dd83b..19dcb0a1c 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1641,30 +1641,23 @@ clean_sigs_from_uid(KBNODE keyblock,KBNODE uidnode,int noisy) and is not expired. Note that this does not take into account whether the uid has a trust path to it - just whether the keyholder themselves has certified the uid. Returns how many user IDs were - removed. */ + removed. To "remove" a user ID, we simply remove ALL signatures + except the self-sig that caused the user ID to be remove-worthy. + We don't actually remove the user ID packet itself since it might + be ressurected in a later merge. */ int clean_uids_from_key(KBNODE keyblock,int noisy) { - int uidcount=0,delete_until_next=0,deleted=0; + int delete_until_next=0,deleted=0; KBNODE node; assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY); merge_keys_and_selfsig(keyblock); - /* First count how many user IDs we have. We need to be careful - that we don't delete them all as some keys could actually have NO - valid user IDs. 2440 requires at least 1 user ID packet, valid - or not. */ for(node=keyblock->next; node && node->pkt->pkttype!=PKT_PUBLIC_SUBKEY; node=node->next) - if(node->pkt->pkttype==PKT_USER_ID) - uidcount++; - - for(node=keyblock->next; - node && node->pkt->pkttype!=PKT_PUBLIC_SUBKEY && uidcount>deleted+1; - node=node->next) { if(node->pkt->pkttype==PKT_USER_ID) { @@ -1693,7 +1686,7 @@ clean_uids_from_key(KBNODE keyblock,int noisy) else reason=_("invalid"); - log_info("removing user ID \"%s\" from key %s: %s\n", + log_info("compacting user ID \"%s\" on key %s: %s\n", user,keystr(keyblock->pkt->pkt.public_key->keyid), reason); @@ -1701,8 +1694,9 @@ clean_uids_from_key(KBNODE keyblock,int noisy) } } } - - if(delete_until_next) + else if(node->pkt->pkttype==PKT_SIGNATURE + && delete_until_next + && !node->pkt->pkt.signature->flags.chosen_selfsig) delete_kbnode(node); }