diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/OPTIONS | 17 | ||||
-rw-r--r-- | g10/keyedit.c | 27 | ||||
-rw-r--r-- | g10/pkclist.c | 25 | ||||
-rw-r--r-- | g10/tdbio.c | 43 | ||||
-rw-r--r-- | g10/tdbio.h | 4 | ||||
-rw-r--r-- | g10/trustdb.c | 81 | ||||
-rw-r--r-- | g10/trustdb.h | 4 |
7 files changed, 143 insertions, 58 deletions
diff --git a/g10/OPTIONS b/g10/OPTIONS index 4def8e60e..03ef351ee 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -26,24 +26,13 @@ print-md algo print-mds # print all message digests of all give filenames -sign-key store # simply packs the input data into a rfc1991 packet format -list-secret-keys -# - -export-secret-keys -# export secret keys (which may be usefuil in some cases) - check-trustdb - - - - #----------------------------------------------- #--- options #----------------------------------------------- @@ -57,9 +46,3 @@ compress-sigs # Normally, compressing of signatures does not make sense; so this # is disabled for detached signatures unless this option is used. - -emulate-pgp-sign-bug -# PGP 2.x can only cope with 2 byte length headers of the -# signature packets, this option forces. - - diff --git a/g10/keyedit.c b/g10/keyedit.c index 73772328b..c137d1af7 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -34,6 +34,7 @@ #include "memory.h" #include "util.h" #include "main.h" +#include "trustdb.h" #include "filter.h" #include "ttyio.h" #include "i18n.h" @@ -541,7 +542,7 @@ keyedit_menu( const char *username, STRLIST locusr ) enum cmdids { cmdNONE = 0, cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN, cmdDEBUG, cmdSAVE, cmdADDUID, cmdDELUID, cmdADDKEY, cmdDELKEY, - cmdTOGGLE, cmdSELKEY, cmdPASSWD, + cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdNOP }; static struct { const char *name; enum cmdids id; @@ -571,6 +572,7 @@ keyedit_menu( const char *username, STRLIST locusr ) "and public key listing") }, { N_("t" ) , cmdTOGGLE , 1, NULL }, { N_("passwd") , cmdPASSWD , 1, N_("change the passphrase") }, + { N_("trust") , cmdTRUST , 0, N_("change the ownertrust") }, { NULL, cmdNONE } }; enum cmdids cmd; @@ -805,6 +807,16 @@ keyedit_menu( const char *username, STRLIST locusr ) sec_modified = 1; break; + case cmdTRUST: + show_key_with_all_names( keyblock, 0, 0, 1 ); + tty_printf("\n"); + if( edit_ownertrust( find_kbnode( keyblock, + PKT_PUBLIC_KEY )->pkt->pkt.public_key->local_id, 1 ) ) + redisplay = 1; + /* we don't need to set modified here, as the trustvalues + * are updated immediately */ + break; + case cmdNOP: break; @@ -839,7 +851,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, if( node->pkt->pkttype == PKT_PUBLIC_KEY || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) { PKT_public_key *pk = node->pkt->pkt.public_key; - tty_printf("%s%c %4u%c/%08lX created: %s expires: %s\n", + tty_printf("%s%c %4u%c/%08lX created: %s expires: %s", node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub", (node->flag & NODFLG_SELKEY)? '*':' ', nbits_from_pk( pk ), @@ -847,8 +859,15 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, (ulong)keyid_from_pk(pk,NULL), datestr_from_pk(pk), expirestr_from_pk(pk) ); - if( with_fpr && node->pkt->pkttype == PKT_PUBLIC_KEY ) - show_fingerprint( pk ); + if( node->pkt->pkttype == PKT_PUBLIC_KEY ) { + int otrust, trust; + trust = query_trust_info(pk); + otrust = get_ownertrust_info( pk->local_id ); + tty_printf(" trust: %c/%c", otrust, trust ); + if( with_fpr ) + show_fingerprint( pk ); + } + tty_printf("\n"); } else if( node->pkt->pkttype == PKT_SECRET_KEY || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) { diff --git a/g10/pkclist.c b/g10/pkclist.c index 7fbe065b6..dbbcbbdd8 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -39,8 +39,8 @@ /**************** * Returns true if an ownertrust has changed. */ -static int -query_ownertrust( ulong lid ) +int +edit_ownertrust( ulong lid, int mode ) { char *p; int rc; @@ -63,14 +63,17 @@ query_ownertrust( ulong lid ) return 0; } - tty_printf(_("No owner trust defined for %lu:\n" - "%4u%c/%08lX %s \""), lid, - nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), - (ulong)keyid[1], datestr_from_pk( pk ) ); - p = get_user_id( keyid, &n ); - tty_print_string( p, n ), - m_free(p); - tty_printf(_("\"\n\n" + if( !mode ) { + tty_printf(_("No owner trust defined for %lu:\n" + "%4u%c/%08lX %s \""), lid, + nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), + (ulong)keyid[1], datestr_from_pk( pk ) ); + p = get_user_id( keyid, &n ); + tty_print_string( p, n ), + m_free(p); + tty_printf("\"\n\n"); + } + tty_printf(_( "Please decide how far you trust this user to correctly\n" "verify other users' keys (by looking at passports,\n" "checking fingerprints from different sources...)?\n\n" @@ -146,7 +149,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n" log_fatal("Ooops: couldn't get owner trust for %lu\n", lid); if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED || trust == TRUST_UNKNOWN ) { - if( query_ownertrust( lid ) ) + if( edit_ownertrust( lid, 0 ) ) any=1; } } diff --git a/g10/tdbio.c b/g10/tdbio.c index 36f0ac503..381d0b2ec 100644 --- a/g10/tdbio.c +++ b/g10/tdbio.c @@ -734,19 +734,40 @@ tdbio_new_recnum() * The local_id of PK is set to the correct value */ int -tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) +tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ) { - ulong recnum; - u32 keyid[2]; byte *fingerprint; size_t fingerlen; + u32 keyid[2]; + int rc; + + keyid_from_pk( pk, keyid ); + fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen ); + rc = tdbio_search_dir_byfpr( fingerprint, fingerlen, + pk->pubkey_algo, rec ); + + if( !rc ) { + if( pk->local_id && pk->local_id != rec->recnum ) + log_error_f(db_name, + "found record, but LID from memory does " + "not match recnum (%lu,%lu)\n", + pk->local_id, rec->recnum ); + pk->local_id = rec->recnum; + } + return rc; +} + + +int +tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, + int pubkey_algo, TRUSTREC *rec ) +{ + ulong recnum; int rc; ulong hashrec, item; int msb; int level=0; - keyid_from_pk( pk, keyid ); - fingerprint = fingerprint_from_pk( pk, NULL, &fingerlen ); assert( fingerlen == 20 || fingerlen == 16 ); /* locate the key using the hash table */ @@ -794,7 +815,7 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) g10_errstr(rc) ); return rc; } - if( tmp.r.key.pubkey_algo == pk->pubkey_algo + if( (!pubkey_algo || tmp.r.key.pubkey_algo == pubkey_algo) && tmp.r.key.fingerprint_len == fingerlen && !memcmp(tmp.r.key.fingerprint, fingerprint, fingerlen) ) { @@ -820,7 +841,7 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) } else if( rec->rectype == RECTYPE_KEY ) { /* must check that it is the requested key */ - if( rec->r.key.pubkey_algo != pk->pubkey_algo + if( (pubkey_algo && rec->r.key.pubkey_algo != pubkey_algo) || rec->r.key.fingerprint_len != fingerlen || memcmp(rec->r.key.fingerprint, fingerprint, fingerlen) ) return -1; /* no: not found */ @@ -832,14 +853,6 @@ tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ) } recnum = rec->r.key.lid; - - if( pk->local_id && pk->local_id != recnum ) - log_error_f(db_name, - "found record, but LID from memory does " - "not match recnum (%lu,%lu)\n", - pk->local_id, recnum ); - pk->local_id = recnum; - /* Now read the dir record */ rc = tdbio_read_record( recnum, rec, RECTYPE_DIR); if( rc ) diff --git a/g10/tdbio.h b/g10/tdbio.h index c37c3ac1f..6fb0e545c 100644 --- a/g10/tdbio.h +++ b/g10/tdbio.h @@ -143,7 +143,9 @@ int tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected ); int tdbio_write_record( TRUSTREC *rec ); int tdbio_delete_record( ulong recnum ); ulong tdbio_new_recnum(void); -int tdbio_search_dir_record( PKT_public_key *pk, TRUSTREC *rec ); +int tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec ); +int tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen, + int pubkey_algo, TRUSTREC *rec ); int tdbio_delete_uidrec( ulong dirlid, ulong uidlid ); diff --git a/g10/trustdb.c b/g10/trustdb.c index 2bd986c79..d1f0fd051 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -193,7 +193,7 @@ set_signature_packets_lid( PKT_signature *sig ) if( rc) goto leave; if( !pk->local_id ) { - rc = tdbio_search_dir_record( pk, &rec ); + rc = tdbio_search_dir_bypk( pk, &rec ); if( rc == -1 ) rc = insert_trust_record( pk ); if( rc ) @@ -935,7 +935,8 @@ update_sigs( TRUSTREC *dir ) rec->r.sig.sig[sigidx].lid = sig->local_id; rec->r.sig.sig[sigidx].flag = 0; sigidx++; - log_debug("key %08lX.%lu, uid %02X%02X: " + if( DBG_TRUST ) + log_debug("key %08lX.%lu, uid %02X%02X: " "signed by LID %lu\n", (ulong)keyid[1], lid, urec.r.uid.namehash[18], urec.r.uid.namehash[19], sig->local_id); @@ -1263,7 +1264,7 @@ list_trustdb( const char *username ) if( (rc = get_pubkey_byname( pk, username )) ) log_error("user '%s' not found: %s\n", username, g10_errstr(rc) ); - else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) + else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) log_error("problem finding '%s' in trustdb: %s\n", username, g10_errstr(rc)); else if( rc == -1 ) @@ -1343,6 +1344,9 @@ import_ownertrust( const char *fname ) } while( fgets( line, DIM(line)-1, fp ) ) { + TRUSTREC rec; + int rc; + if( !*line || *line == '#' ) continue; n = strlen(line); @@ -1373,7 +1377,44 @@ import_ownertrust( const char *fname ) line[fprlen++] = HEXTOBIN(p[0]) * 16 + HEXTOBIN(p[1]); line[fprlen] = 0; - log_hexdump("found: ", line, fprlen ); + repeat: + rc = tdbio_search_dir_byfpr( line, fprlen, 0, &rec ); + if( !rc ) { /* found: update */ + if( rec.r.dir.ownertrust ) + log_info("LID %lu: changing trust from %u to %u\n", + rec.r.dir.lid, rec.r.dir.ownertrust, otrust ); + else + log_info("LID %lu: setting trust to %u\n", + rec.r.dir.lid, otrust ); + rec.r.dir.ownertrust = otrust; + rc = tdbio_write_record( &rec ); + if( rc ) + log_error_f(fname, "error updating otrust: %s\n", + g10_errstr(rc)); + } + else if( rc == -1 ) { /* not found; get the key from the ring */ + PKT_public_key *pk = m_alloc_clear( sizeof *pk ); + + log_info_f(fname, "key not in trustdb, searching ring.\n"); + rc = get_pubkey_byfprint( pk, line, fprlen ); + if( rc ) + log_info_f(fname, "key not in ring: %s\n", g10_errstr(rc)); + else { + rc = query_trust_record( pk ); /* only as assertion */ + if( rc != -1 ) + log_error_f(fname, "Oops: key is now in trustdb???\n"); + else { + rc = insert_trust_record( pk ); + if( !rc ) + goto repeat; /* update the ownertrust */ + log_error_f(fname, "insert trust record failed: %s\n", + g10_errstr(rc) ); + } + } + } + else /* error */ + log_error_f(fname, "error finding dir record: %s\n", + g10_errstr(rc)); } if( ferror(fp) ) log_error_f(fname, _("read error: %s\n"), strerror(errno) ); @@ -1398,7 +1439,7 @@ list_trust_path( int max_depth, const char *username ) if( (rc = get_pubkey_byname( pk, username )) ) log_error("user '%s' not found: %s\n", username, g10_errstr(rc) ); - else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) + else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) log_error("problem finding '%s' in trustdb: %s\n", username, g10_errstr(rc)); else if( rc == -1 ) { @@ -1495,7 +1536,7 @@ check_trustdb( const char *username ) if( (rc = get_pubkey_byname( pk, username )) ) log_error("user '%s' not found: %s\n", username, g10_errstr(rc) ); - else if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) + else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) log_error("problem finding '%s' in trustdb: %s\n", username, g10_errstr(rc)); else if( rc == -1 ) @@ -1564,7 +1605,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel ) } } else { /* no local_id: scan the trustdb */ - if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) { + if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) { log_error("check_trust: search dir record failed: %s\n", g10_errstr(rc)); return rc; @@ -1702,6 +1743,25 @@ get_ownertrust( ulong lid, unsigned *r_otrust ) return 0; } +int +get_ownertrust_info( ulong lid ) +{ + unsigned otrust; + int c; + + if( get_ownertrust( lid, &otrust ) ) + return '?'; + switch( (otrust & TRUST_MASK) ) { + case TRUST_NEVER: c = 'n'; break; + case TRUST_MARGINAL: c = 'm'; break; + case TRUST_FULLY: c = 'f'; break; + case TRUST_ULTIMATE: c = 'u'; break; + default: c = '-'; break; + } + return c; +} + + /**************** * This function simply looks for the key in the trustdb @@ -1723,7 +1783,7 @@ query_trust_record( PKT_public_key *pk ) } } else { /* no local_id: scan the trustdb */ - if( (rc=tdbio_search_dir_record( pk, &rec )) && rc != -1 ) { + if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) { log_error("query_trust_record: search_record failed: %s\n", g10_errstr(rc)); return rc; @@ -1774,6 +1834,9 @@ insert_trust_record( PKT_public_key *orig_pk ) size_t fingerlen; int rc = 0; + keylist_head = NULL; keylist_tail = &keylist_head; keylist = NULL; + uidlist_head = NULL; uidlist_tail = &uidlist_head; uidlist = NULL; + /* prepare dir record */ memset( &dirrec, 0, sizeof dirrec ); dirrec.rectype = RECTYPE_DIR; @@ -1796,8 +1859,6 @@ insert_trust_record( PKT_public_key *orig_pk ) } /* build data structure as linked lists in memory */ - keylist_head = NULL; keylist_tail = &keylist_head; keylist = NULL; - uidlist_head = NULL; uidlist_tail = &uidlist_head; uidlist = NULL; keyid[0] = keyid[1] = 0; for( node=keyblock; node; node = node->next ) { if( node->pkt->pkttype == PKT_PUBLIC_KEY diff --git a/g10/trustdb.h b/g10/trustdb.h index dba38188b..3f24cd514 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -46,9 +46,13 @@ int check_trust( PKT_public_key *pk, unsigned *r_trustlevel ); int query_trust_info( PKT_public_key *pk ); int enum_trust_web( void **context, ulong *lid ); int get_ownertrust( ulong lid, unsigned *r_otrust ); +int get_ownertrust_info( ulong lid ); int keyid_from_lid( ulong lid, u32 *keyid ); int query_trust_record( PKT_public_key *pk ); int insert_trust_record( PKT_public_key *pk ); int update_ownertrust( ulong lid, unsigned new_trust ); +/*-- pkclist.c --*/ +int edit_ownertrust( ulong lid, int mode ); + #endif /*G10_TRUSTDB_H*/ |