* trustdb.c (clean_uids_from_key), keyedit.c
authorDavid Shaw <dshaw@jabberwocky.com>
Thu, 9 Jun 2005 02:53:18 +0000 (02:53 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Thu, 9 Jun 2005 02:53:18 +0000 (02:53 +0000)
(menu_clean_uids_from_key): Tweak algorithm to preserve the last
selfsig which helps prevent uid resurrections.

g10/ChangeLog
g10/keyedit.c
g10/trustdb.c

index 2f8b617..48a6e6e 100644 (file)
@@ -1,5 +1,9 @@
 2005-06-08  David Shaw  <dshaw@jabberwocky.com>
 
+       * 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
index 70c5c5b..46603d1 100644 (file)
@@ -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;
 }
index d0f6dd8..19dcb0a 100644 (file)
@@ -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);
     }