Changeset View
Changeset View
Standalone View
Standalone View
g10/delkey.c
Context not available. | |||||
Returns true if the search description at DESC is an exact key specification | Returns true if the search description at DESC is an exact key specification | ||||
that doesn't match the key at PK. */ | that doesn't match the key at PK. */ | ||||
static int | static int | ||||
should_skip (KEYDB_SEARCH_DESC *desc, PKT_public_key *pk) | should_skip (KEYDB_SEARCH_DESC *desc, PACKET *pkt, int subkeys_only) | ||||
{ | { | ||||
u32 kid[2]; | u32 kid[2]; | ||||
byte fpr[MAX_FINGERPRINT_LEN]; | byte fpr[MAX_FINGERPRINT_LEN]; | ||||
size_t fprlen; | size_t fprlen; | ||||
if (subkeys_only) | |||||
{ | |||||
if (pkt->pkttype != PKT_PUBLIC_SUBKEY) | |||||
return 1; | |||||
} | |||||
else | |||||
{ | |||||
if (!(pkt->pkttype == PKT_PUBLIC_KEY || pkt->pkttype == PKT_PUBLIC_SUBKEY)) | |||||
return 1; | |||||
} | |||||
if (!desc->exact) | if (!desc->exact) | ||||
return 0; | return 0; | ||||
Context not available. | |||||
{ | { | ||||
case KEYDB_SEARCH_MODE_SHORT_KID: | case KEYDB_SEARCH_MODE_SHORT_KID: | ||||
case KEYDB_SEARCH_MODE_LONG_KID: | case KEYDB_SEARCH_MODE_LONG_KID: | ||||
keyid_from_pk (pk, kid); | keyid_from_pk (pkt->pkt.public_key, kid); | ||||
break; | break; | ||||
case KEYDB_SEARCH_MODE_FPR: | case KEYDB_SEARCH_MODE_FPR: | ||||
fingerprint_from_pk (pk, fpr, &fprlen); | fingerprint_from_pk (pkt->pkt.public_key, fpr, &fprlen); | ||||
if (fprlen == desc->fprlen && !memcmp (desc->u.fpr, fpr, desc->fprlen)) | if (fprlen == desc->fprlen && !memcmp (desc->u.fpr, fpr, desc->fprlen)) | ||||
return 0; | return 0; | ||||
break; | break; | ||||
Context not available. | |||||
* key can't be deleted for that reason. | * key can't be deleted for that reason. | ||||
*/ | */ | ||||
static gpg_error_t | static gpg_error_t | ||||
do_delete_key (ctrl_t ctrl, const char *username, int secret, int force, | do_delete_key (ctrl_t ctrl, const char *username, | ||||
int secret, int force, int subkeys_only, | |||||
int *r_sec_avail) | int *r_sec_avail) | ||||
{ | { | ||||
gpg_error_t err; | gpg_error_t err; | ||||
Context not available. | |||||
setup_main_keyids (keyblock); | setup_main_keyids (keyblock); | ||||
for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) | for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) | ||||
{ | { | ||||
if (!(node->pkt->pkttype == PKT_PUBLIC_KEY | if (should_skip (&desc, node->pkt, subkeys_only)) | ||||
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY)) | |||||
continue; | |||||
if (should_skip (&desc, node->pkt->pkt.public_key)) | |||||
continue; | continue; | ||||
if (confirm_deletion (ctrl, node->pkt, secret, exactmatch)) | if (confirm_deletion (ctrl, node->pkt, secret, exactmatch)) | ||||
Context not available. | |||||
* Delete a public or secret key from a keyring. | * Delete a public or secret key from a keyring. | ||||
*/ | */ | ||||
gpg_error_t | gpg_error_t | ||||
delete_keys (ctrl_t ctrl, strlist_t names, int secret, int allow_both) | delete_keys (ctrl_t ctrl, strlist_t names, int secret, int allow_both, int subkeys_only) | ||||
{ | { | ||||
gpg_error_t err; | gpg_error_t err; | ||||
int avail; | int avail; | ||||
Context not available. | |||||
for ( ;names ; names=names->next ) | for ( ;names ; names=names->next ) | ||||
{ | { | ||||
err = do_delete_key (ctrl, names->d, secret, force, &avail); | err = do_delete_key (ctrl, names->d, secret, force, subkeys_only, &avail); | ||||
if (err && avail) | if (err && avail) | ||||
{ | { | ||||
if (allow_both) | if (allow_both) | ||||
{ | { | ||||
err = do_delete_key (ctrl, names->d, 1, 0, &avail); | err = do_delete_key (ctrl, names->d, 1, 0, subkeys_only, &avail); | ||||
if (!err) | if (!err) | ||||
err = do_delete_key (ctrl, names->d, 0, 0, &avail); | err = do_delete_key (ctrl, names->d, 0, 0, subkeys_only, &avail); | ||||
} | } | ||||
else | else | ||||
{ | { | ||||
Context not available. |