mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
* trustdb.h, trustdb.c (mark_usable_uid_certs): Add flags for the
no-pubkey and chosen revocation cases. (clean_uid): New function to clean a user ID of unusable (as defined by mark_usable_uid_certs) certs. * keyedit.c (keyedit_menu, menu_clean_uids): Call it here for new "clean" command that removes unusable sigs from a key.
This commit is contained in:
parent
be90f3cacb
commit
f02fe1dafb
@ -1,5 +1,13 @@
|
|||||||
2005-04-24 David Shaw <dshaw@jabberwocky.com>
|
2005-04-24 David Shaw <dshaw@jabberwocky.com>
|
||||||
|
|
||||||
|
* trustdb.h, trustdb.c (mark_usable_uid_certs): Add flags for the
|
||||||
|
no-pubkey and chosen revocation cases.
|
||||||
|
(clean_uid): New function to clean a user ID of unusable (as
|
||||||
|
defined by mark_usable_uid_certs) certs.
|
||||||
|
|
||||||
|
* keyedit.c (keyedit_menu, menu_clean_uids): Call it here for new
|
||||||
|
"clean" command that removes unusable sigs from a key.
|
||||||
|
|
||||||
* trustdb.h, keyedit.c (keyedit_menu, menu_select_uid_namehash):
|
* trustdb.h, keyedit.c (keyedit_menu, menu_select_uid_namehash):
|
||||||
Allow specifying user ID via the namehash from --with-colons
|
Allow specifying user ID via the namehash from --with-colons
|
||||||
--fixed-list-mode --list-keys. Suggested by Peter Palfrader.
|
--fixed-list-mode --list-keys. Suggested by Peter Palfrader.
|
||||||
|
@ -53,6 +53,7 @@ static void show_key_and_fingerprint( KBNODE keyblock );
|
|||||||
static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
|
static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
|
||||||
static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||||
static int menu_delsig( KBNODE pub_keyblock );
|
static int menu_delsig( KBNODE pub_keyblock );
|
||||||
|
static int menu_clean_uids(KBNODE keyblock);
|
||||||
static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
|
||||||
static int menu_addrevoker( KBNODE pub_keyblock,
|
static int menu_addrevoker( KBNODE pub_keyblock,
|
||||||
KBNODE sec_keyblock, int sensitive );
|
KBNODE sec_keyblock, int sensitive );
|
||||||
@ -1327,7 +1328,7 @@ enum cmdids
|
|||||||
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
|
cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
|
||||||
cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
|
cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
|
||||||
cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
|
cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
|
||||||
cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdNOP
|
cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, cmdNOP
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct
|
static struct
|
||||||
@ -1426,6 +1427,7 @@ static struct
|
|||||||
{ "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
|
{ "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
|
||||||
{ "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
|
{ "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
|
||||||
{ "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
|
{ "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
|
||||||
|
{ "clean", cmdCLEAN , KEYEDIT_NOT_SK, NULL },
|
||||||
{ NULL, cmdNONE, 0, NULL }
|
{ NULL, cmdNONE, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1952,7 +1954,7 @@ keyedit_menu( const char *username, STRLIST locusr,
|
|||||||
{
|
{
|
||||||
int sensitive=0;
|
int sensitive=0;
|
||||||
|
|
||||||
if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
|
if(ascii_strcasecmp(arg_string,"sensitive")==0)
|
||||||
sensitive=1;
|
sensitive=1;
|
||||||
if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
|
if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
|
||||||
redisplay = 1;
|
redisplay = 1;
|
||||||
@ -2123,9 +2125,27 @@ keyedit_menu( const char *username, STRLIST locusr,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdSHOWPHOTO:
|
case cmdSHOWPHOTO:
|
||||||
menu_showphoto(keyblock);
|
menu_showphoto(keyblock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cmdCLEAN:
|
||||||
|
{
|
||||||
|
if(*arg_string)
|
||||||
|
{
|
||||||
|
if(ascii_strcasecmp(arg_string,"sigs")!=0
|
||||||
|
&& ascii_strcasecmp(arg_string,"signatures")!=0
|
||||||
|
&& ascii_strcasecmp(arg_string,"certs")!=0
|
||||||
|
&& ascii_strcasecmp(arg_string,"certificates")!=0)
|
||||||
|
{
|
||||||
|
tty_printf(_("Unable to clean `%s'\n"),arg_string);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modified=menu_clean_uids(keyblock);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case cmdQUIT:
|
case cmdQUIT:
|
||||||
if( have_commands )
|
if( have_commands )
|
||||||
@ -3108,6 +3128,41 @@ menu_delsig( KBNODE pub_keyblock )
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
menu_clean_uids(KBNODE keyblock)
|
||||||
|
{
|
||||||
|
KBNODE uidnode;
|
||||||
|
int modified=0;
|
||||||
|
int select_all=!count_selected_uids(keyblock);
|
||||||
|
|
||||||
|
for(uidnode=keyblock;uidnode;uidnode=uidnode->next)
|
||||||
|
{
|
||||||
|
if(uidnode->pkt->pkttype==PKT_USER_ID
|
||||||
|
&& (uidnode->flag&NODFLG_SELUID || select_all))
|
||||||
|
{
|
||||||
|
int deleted;
|
||||||
|
char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
|
||||||
|
uidnode->pkt->pkt.user_id->len,
|
||||||
|
0);
|
||||||
|
deleted=clean_uid(keyblock,uidnode,opt.verbose);
|
||||||
|
if(deleted)
|
||||||
|
{
|
||||||
|
tty_printf(deleted==1?
|
||||||
|
_("User ID \"%s\": %d signature removed.\n"):
|
||||||
|
_("User ID \"%s\": %d signatures removed.\n"),
|
||||||
|
user,deleted);
|
||||||
|
modified=1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tty_printf(_("User ID \"%s\": already clean.\n"),user);
|
||||||
|
|
||||||
|
m_free(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return modified;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Remove some of the secondary keys
|
* Remove some of the secondary keys
|
||||||
|
108
g10/trustdb.c
108
g10/trustdb.c
@ -1,6 +1,6 @@
|
|||||||
/* trustdb.c
|
/* trustdb.c
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
* 2004 Free Software Foundation, Inc.
|
* 2005 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
@ -1409,8 +1409,9 @@ is_in_klist (struct key_item *k, PKT_signature *sig)
|
|||||||
* To do this, we first revmove all signatures which are not valid and
|
* To do this, we first revmove all signatures which are not valid and
|
||||||
* from the remain ones we look for the latest one. If this is not a
|
* from the remain ones we look for the latest one. If this is not a
|
||||||
* certification revocation signature we mark the signature by setting
|
* certification revocation signature we mark the signature by setting
|
||||||
* node flag bit 8. Note that flag bits 9 and 10 are used for internal
|
* node flag bit 8. Revocations are marked with flag 11, and sigs
|
||||||
* purposes.
|
* from unavailable keys are marked with flag 12. Note that flag bits
|
||||||
|
* 9 and 10 are used for internal purposes.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
||||||
@ -1423,34 +1424,44 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
|||||||
/* first check all signatures */
|
/* first check all signatures */
|
||||||
for (node=uidnode->next; node; node = node->next)
|
for (node=uidnode->next; node; node = node->next)
|
||||||
{
|
{
|
||||||
node->flag &= ~(1<<8 | 1<<9 | 1<<10);
|
int rc;
|
||||||
|
|
||||||
|
node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
|
||||||
if (node->pkt->pkttype == PKT_USER_ID
|
if (node->pkt->pkttype == PKT_USER_ID
|
||||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
break; /* ready */
|
break; /* ready */
|
||||||
if (node->pkt->pkttype != PKT_SIGNATURE)
|
if (node->pkt->pkttype != PKT_SIGNATURE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sig = node->pkt->pkt.signature;
|
sig = node->pkt->pkt.signature;
|
||||||
if (sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
|
if (main_kid
|
||||||
continue; /* ignore self-signatures */
|
&& sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1])
|
||||||
|
continue; /* ignore self-signatures if we pass in a main_kid */
|
||||||
if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
|
if (!IS_UID_SIG(sig) && !IS_UID_REV(sig))
|
||||||
continue; /* we only look at these signature classes */
|
continue; /* we only look at these signature classes */
|
||||||
if(sig->sig_class>=0x11 && sig->sig_class<=0x13 &&
|
if(sig->sig_class>=0x11 && sig->sig_class<=0x13 &&
|
||||||
sig->sig_class-0x10<opt.min_cert_level)
|
sig->sig_class-0x10<opt.min_cert_level)
|
||||||
continue;
|
continue; /* treat anything under our min_cert_level as an
|
||||||
if (!is_in_klist (klist, sig))
|
invalid signature */
|
||||||
|
if (klist && !is_in_klist (klist, sig))
|
||||||
continue; /* no need to check it then */
|
continue; /* no need to check it then */
|
||||||
if (check_key_signature (keyblock, node, NULL))
|
if ((rc=check_key_signature (keyblock, node, NULL)))
|
||||||
continue; /* ignore invalid signatures */
|
{
|
||||||
|
/* we ignore anything that won't verify, but tag the
|
||||||
|
no_pubkey case */
|
||||||
|
if(rc==G10ERR_NO_PUBKEY)
|
||||||
|
node->flag |= 1<<12;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
node->flag |= 1<<9;
|
node->flag |= 1<<9;
|
||||||
}
|
}
|
||||||
/* reset the remaining flags */
|
/* reset the remaining flags */
|
||||||
for (; node; node = node->next)
|
for (; node; node = node->next)
|
||||||
node->flag &= ~(1<<8 | 1<<9 | 1 << 10);
|
node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12);
|
||||||
|
|
||||||
/* kbnode flag usage: bit 9 is here set for signatures to consider,
|
/* kbnode flag usage: bit 9 is here set for signatures to consider,
|
||||||
* bit 10 will be set by the loop to keep track of keyIDs already
|
* bit 10 will be set by the loop to keep track of keyIDs already
|
||||||
* processed, bit 8 will be set for the usable signatures */
|
* processed, bit 8 will be set for the usable signatures, and bit
|
||||||
|
* 11 will be set for usable revocations. */
|
||||||
|
|
||||||
/* for each cert figure out the latest valid one */
|
/* for each cert figure out the latest valid one */
|
||||||
for (node=uidnode->next; node; node = node->next)
|
for (node=uidnode->next; node; node = node->next)
|
||||||
@ -1470,6 +1481,8 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
|||||||
signode = node;
|
signode = node;
|
||||||
sigdate = sig->timestamp;
|
sigdate = sig->timestamp;
|
||||||
kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
|
kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1];
|
||||||
|
|
||||||
|
/* Now find the latest and greatest signature */
|
||||||
for (n=uidnode->next; n; n = n->next)
|
for (n=uidnode->next; n; n = n->next)
|
||||||
{
|
{
|
||||||
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY)
|
||||||
@ -1532,6 +1545,7 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
|||||||
sigdate = sig->timestamp;
|
sigdate = sig->timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sig = signode->pkt->pkt.signature;
|
sig = signode->pkt->pkt.signature;
|
||||||
if (IS_UID_SIG (sig))
|
if (IS_UID_SIG (sig))
|
||||||
{ /* this seems to be a usable one which is not revoked.
|
{ /* this seems to be a usable one which is not revoked.
|
||||||
@ -1550,13 +1564,77 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode,
|
|||||||
if (expire==0 || expire > curtime )
|
if (expire==0 || expire > curtime )
|
||||||
{
|
{
|
||||||
signode->flag |= (1<<8); /* yeah, found a good cert */
|
signode->flag |= (1<<8); /* yeah, found a good cert */
|
||||||
if (expire && expire < *next_expire)
|
if (next_expire && expire && expire < *next_expire)
|
||||||
*next_expire = expire;
|
*next_expire = expire;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
signode->flag |= (1<<11);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
clean_uid(KBNODE keyblock,KBNODE uidnode,int noisy)
|
||||||
|
{
|
||||||
|
int deleted=0;
|
||||||
|
KBNODE node;
|
||||||
|
|
||||||
|
assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
|
||||||
|
|
||||||
|
/* Passing in a 0 for current time here means that we'll never weed
|
||||||
|
out an expired sig. This is correct behavior since we want to
|
||||||
|
keep the most recent expired sig in a series. */
|
||||||
|
mark_usable_uid_certs(keyblock,uidnode,NULL,NULL,0,NULL);
|
||||||
|
|
||||||
|
/* What we want to do here is remove signatures that are not
|
||||||
|
considered as part of the trust calculations. Thus, all invalid
|
||||||
|
signatures are out, as are any signatures that aren't the last of
|
||||||
|
a series of uid sigs or revocations It breaks down like this:
|
||||||
|
coming out of mark_usable_uid_certs, if a sig is unflagged, it is
|
||||||
|
not even a candidate. If a sig has flag 9 or 10, that means it
|
||||||
|
was selected as a candidate and vetted. If a sig has flag 8 it
|
||||||
|
is a usable signature. If a sig has flag 11 it is a usable
|
||||||
|
revocation. If a sig has flag 12 it was issued by an unavailable
|
||||||
|
key. "Usable" here means the most recent valid
|
||||||
|
signature/revocation in a series from a particular signer.
|
||||||
|
|
||||||
|
Delete everything that isn't a usable uid sig (which might be
|
||||||
|
expired), a usable revocation, or a sig from an unavailable
|
||||||
|
key. */
|
||||||
|
|
||||||
|
for(node=uidnode->next;
|
||||||
|
node && node->pkt->pkttype==PKT_SIGNATURE;
|
||||||
|
node=node->next)
|
||||||
|
{
|
||||||
|
/* Keep usable uid sigs ... */
|
||||||
|
if(node->flag & (1<<8))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ... and usable revocations... */
|
||||||
|
if(node->flag & (1<<11))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ... and sigs from unavailable keys. */
|
||||||
|
if(node->flag & (1<<12))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Everything else we delete */
|
||||||
|
|
||||||
|
/* if 9 or 10 is set, but we get this far, it's superceded,
|
||||||
|
otherwise, it's invalid */
|
||||||
|
|
||||||
|
if(noisy)
|
||||||
|
log_info("removing signature issued by key %s: %s\n",
|
||||||
|
keystr(node->pkt->pkt.signature->keyid),
|
||||||
|
node->flag&(1<<9)?"superceded":"invalid");
|
||||||
|
|
||||||
|
delete_kbnode(node);
|
||||||
|
deleted++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
/* Used by validate_one_keyblock to confirm a regexp within a trust
|
/* Used by validate_one_keyblock to confirm a regexp within a trust
|
||||||
signature. Returns 1 for match, and 0 for no match or regex
|
signature. Returns 1 for match, and 0 for no match or regex
|
||||||
error. */
|
error. */
|
||||||
|
@ -81,6 +81,8 @@ const char *get_ownertrust_string (PKT_public_key *pk);
|
|||||||
void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
|
void update_ownertrust (PKT_public_key *pk, unsigned int new_trust );
|
||||||
int clear_ownertrusts (PKT_public_key *pk);
|
int clear_ownertrusts (PKT_public_key *pk);
|
||||||
|
|
||||||
|
int clean_uid(KBNODE keyblock,KBNODE uidnode,int noisy);
|
||||||
|
|
||||||
/*-- tdbdump.c --*/
|
/*-- tdbdump.c --*/
|
||||||
void list_trustdb(const char *username);
|
void list_trustdb(const char *username);
|
||||||
void export_ownertrust(void);
|
void export_ownertrust(void);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user