some bug fixes

This commit is contained in:
Werner Koch 1998-11-18 19:59:06 +00:00
parent 4cad562da9
commit f9d2bd8cb9
14 changed files with 441 additions and 225 deletions

48
AUTHORS
View File

@ -1,38 +1,50 @@
Authors of GNU Privacy Guard (gnupg). Authors of GNU Privacy Guard (GnuPG).
Werner Koch. Designed and implemented gnupg. Werner Koch. Designed and implemented GnuPG.
GNUPG Matthew Skala Canada 1998-08-10 GNUPG Matthew Skala 1998-08-10
<mskala@ansuz.sooke.bc.ca> disclaims changes. Disclaims changes.
Wrote cipher/twofish.c mskala@ansuz.sooke.bc.ca
Wrote cipher/twofish.c.
GNUPG Natural Resources Canada 1998-08-11 GNUPG Natural Resources Canada 1998-08-11
Disclaims changes by Matthew Skala. Disclaims changes by Matthew Skala.
GNUPG Michael Roth Germany 1998-09-17 GNUPG Michael Roth Germany 1998-09-17
<mroth@nessie.de> assigns changes. Assigns changes.
mroth@nessie.de
Wrote cipher/des.c. Wrote cipher/des.c.
GNUPG Niklas Hernaeus Sweden? 1998-09-18
<nh@df.lth.se> disclaims changes. GNUPG Niklas Hernaeus 1998-09-18
Disclaims changes.
nh@df.lth.se
Weak key patches. Weak key patches.
TRANSLATIONS Marco d'Itri 1997-02-22 TRANSLATIONS Marco d'Itri 1997-02-22
Disclaims Disclaimer. [it]
it.po md@linux.it
TRANSLATIONS Gaël Quéri ??????????
fr.po
TRANSLATIONS Walter Koch ?????????? TRANSLATIONS Gael Queri 1998-09-08
de.po Disclaimer. [fr]
gqueri@mail.dotcom.fr
TRANSLATIONS Gregory Steuck ??????????
ru.po
TRANSLATIONS Urko Lusa ?????????? TRANSLATIONS Walter Koch 1998-09-08
Disclaimer. [de]
walterk@dip.de
TRANSLATIONS Gregory Steuck 1998-10-20
Disclaimer. [ru?]
steuck@iname.com
TRANSLATIONS Urko Lusa ??????????
es_ES.po es_ES.po

10
NEWS
View File

@ -4,6 +4,16 @@ This is NOT a released version!
* Add option --charset to support "koi8-r" encoding of user ids. * Add option --charset to support "koi8-r" encoding of user ids.
(Not yet tested). (Not yet tested).
* Preferences should now work again. You should run
"gpgm --check-trustdb \*" to rebuild all preferences.
* Checking of certificates should now work but this needs a lot
of testing. Key validation values are now cached in the
trustdb; they should be recalculated as needed, but you may
use --check-trustdb or --update-trustdb to do this.
* Spanish translation by Urko Lusa.
Noteworthy changes in version 0.4.3 Noteworthy changes in version 0.4.3

7
TODO
View File

@ -1,6 +1,6 @@
* hash calculation for cleartext sigs without a "Hash: xxx" line * hash calculation for cleartext sigs without a "Hash: xxx" line
does it work as specified in the RFC? does it work as specified in the RFC? - Hmmm, I think so
* Check Berkeley BD - it is in glibc -any licensing problems? * Check Berkeley BD - it is in glibc -any licensing problems?
@ -11,9 +11,8 @@
* Update the keyring at ftp.guug.de * Update the keyring at ftp.guug.de
* expire date is not shown in --edit-key for subkeys. * expire date is not shown in --edit-key for subkeys.
and prefs are not correctly listed for some keys???? (Brian)
* support for mpi/powerpc split is still combined or whatever * check support for mpi/powerpc
* add a note, that gettext 10.35 is needed (for gettext) - and install * add a note, that gettext 10.35 is needed (for gettext) - and install
it on tobold. it on tobold.
@ -31,8 +30,6 @@
* Check revocation and expire stuff. * Check revocation and expire stuff.
* check preferences (cipher and compress)
* OpenBSD: dynamic loading with dlopen works on OpenBSD, but: * OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
OpenBSD binaries are a.out, so every symbol begins with "_" OpenBSD binaries are a.out, so every symbol begins with "_"

View File

@ -75,7 +75,7 @@ B<-k> [I<username>] [I<keyring>]
B<-kvc> List fingerprints B<-kvc> List fingerprints
B<-kvvc> List fingerprints and signatures B<-kvvc> List fingerprints and signatures
B<--list-keys> [I<names>] B<--list-keys> [I<names>]
List all keys from the public keyrings, or just the List all keys from the public keyrings, or just the
ones given on the command line. ones given on the command line.
@ -83,7 +83,7 @@ B<--list-secret-keys> [I<names>]
List all keys from the secret keyrings, or just the List all keys from the secret keyrings, or just the
ones given on the command line. ones given on the command line.
B<--list-sigs> [I<names>] B<--list-sigs> [I<names>]
Same as B<--list-keys>, but the signatures are listed Same as B<--list-keys>, but the signatures are listed
too. too.
@ -129,7 +129,7 @@ B<--edit-key> I<name>
B<delkey> B<delkey>
Remove a subkey. Remove a subkey.
B<expire> B<expire>
Change the key expiration time. If a key is Change the key expiration time. If a key is
select, the time of this key will be changed. select, the time of this key will be changed.
With no selection the key expiration of the With no selection the key expiration of the
primary key is changed. primary key is changed.
@ -158,9 +158,8 @@ B<--edit-key> I<name>
displayed with the primary key: The first one is the displayed with the primary key: The first one is the
assigned owner trust and the second the calculated assigned owner trust and the second the calculated
trust value; letters are used for the values: trust value; letters are used for the values:
B<-> No ownertrust assigned. B<-> No ownertrust assigned / not yet calculated.
B<o> Trust not yet calculated. B<e> Trust calculation has failed.
B<e> Trust calculation failed.
B<q> Not enough information for calculation. B<q> Not enough information for calculation.
B<n> Never trust this key. B<n> Never trust this key.
B<m> Marginally trusted. B<m> Marginally trusted.
@ -191,7 +190,7 @@ B<--export-secret-keys> [I<names>
This is normally not very useful. This is normally not very useful.
B<--import>, B<--fast-import> B<--import>, B<--fast-import>
Import/merge keys. The fast version does not build Import/merge keys. The fast version does not build
the trustdb; this can be deon at anytime with the the trustdb; this can be deon at anytime with the
command B<--update-trustdb>. command B<--update-trustdb>.
@ -208,7 +207,7 @@ B<--import-ownertrust> [I<filename>]
Long options can be put in an options file (default F<~/.gnupg/options>); Long options can be put in an options file (default F<~/.gnupg/options>);
do not write the 2 dashes, but simply the name of the option and any do not write the 2 dashes, but simply the name of the option and any
arguments if required. Lines with a hash as the first non-white-space arguments if required. Lines with a hash as the first non-white-space
character are ignored. Commands may be put in this file too, but that character are ignored. Commands may be put in this file too, but that
does not make sense. does not make sense.
@ -457,11 +456,11 @@ a signature was bad and other errorcode for fatal errors.
=head1 EXAMPLES =head1 EXAMPLES
-se -r Bob [file] sign and encrypt for user Bob -se -r Bob [file] sign and encrypt for user Bob
-sat [file] make a clear text signature -sat [file] make a clear text signature
-sb [file] make a detached signature -sb [file] make a detached signature
-k [userid] show keys -k [userid] show keys
-kc [userid] show fingerprint -kc [userid] show fingerprint
=head1 ENVIRONMENT =head1 ENVIRONMENT
@ -476,13 +475,13 @@ F<~/.gnupg/pubring.gpg> The public keyring
F<~/.gnupg/trustdb.gpg> The trust database F<~/.gnupg/trustdb.gpg> The trust database
F<~/.gnupg/options> May contain options F<~/.gnupg/options> May contain options
F</usr[/local]/lib/gnupg/> Default location for extensions F</usr[/local]/lib/gnupg/> Default location for extensions
=head1 SEE ALSO =head1 SEE ALSO
gpg(1) gpgm(1) gpg(1) gpgm(1)
=head1 WARNINGS =head1 WARNINGS

View File

@ -1,3 +1,22 @@
Wed Nov 18 20:33:50 1998 Werner Koch (wk@isil.d.shuttle.de)
* trustdb.c (check_trustdb): Now rechecks all gived userids.
(collect_paths): Some fixes.
(upd_pref_records): Skips empty items, evaluate all items.
* parse-packet.c (dump_sig_subpkt): Better listing of prefs.
(skip_packet): Now knows about marker packet
* g10.c: removed cmd "--edit-sig".
* pubring.asc: Updated.
Sat Nov 14 14:01:29 1998 Werner Koch (wk@isil.d.shuttle.de)
* g10.c (main): Changed syntax of --list-trust-path
* trustdb.c (list_trust_path): Replaced max_depth by
opt.max_cert_depth
Fri Nov 13 07:39:58 1998 Werner Koch <werner.koch@guug.de> Fri Nov 13 07:39:58 1998 Werner Koch <werner.koch@guug.de>
* trustdb.c (collect_paths): Removed a warning message. * trustdb.c (collect_paths): Removed a warning message.

View File

@ -1,14 +1,14 @@
/* armor.c - Armor filter /* armor.c - Armor filter
* Copyright (C) 1998 Free Software Foundation, Inc. * Copyright (C) 1998 Free Software Foundation, Inc.
* *
* This file is part of GNUPG. * This file is part of GnuPG.
* *
* GNUPG is free software; you can redistribute it and/or modify * GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* GNUPG is distributed in the hope that it will be useful, * GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
@ -1008,7 +1008,7 @@ armor_filter( void *opaque, int control,
iobuf_writestr(a, "-----"); iobuf_writestr(a, "-----");
iobuf_writestr(a, head_strings[afx->what] ); iobuf_writestr(a, head_strings[afx->what] );
iobuf_writestr(a, "-----\n"); iobuf_writestr(a, "-----\n");
iobuf_writestr(a, "Version: GNUPG v" VERSION " (" iobuf_writestr(a, "Version: GnuPG v" VERSION " ("
PRINTABLE_OS_NAME ")\n"); PRINTABLE_OS_NAME ")\n");
if( opt.comment_string ) { if( opt.comment_string ) {

View File

@ -268,7 +268,6 @@ static ARGPARSE_OPTS opts[] = {
#endif #endif
#ifdef IS_G10 #ifdef IS_G10
{ oKOption, NULL, 0, "@"}, { oKOption, NULL, 0, "@"},
{ aEditKey, "edit-sig" ,0, "@"}, /* alias for edit-key */
{ oPasswdFD, "passphrase-fd",1, "@" }, { oPasswdFD, "passphrase-fd",1, "@" },
{ aSignKey, "sign-key" ,256, "@" }, /* alias for edit-key */ { aSignKey, "sign-key" ,256, "@" }, /* alias for edit-key */
#endif #endif
@ -1217,9 +1216,10 @@ main( int argc, char **argv )
break; break;
case aListTrustPath: case aListTrustPath:
if( argc != 2 ) if( !argc )
wrong_args("--list-trust-path [-- -]<maxdepth> <username>"); wrong_args("--list-trust-path <usernames>");
list_trust_path( atoi(*argv), argv[1] ); for( ; argc; argc--, argv++ )
list_trust_path( *argv );
break; break;
case aExportOwnerTrust: case aExportOwnerTrust:

View File

@ -278,11 +278,13 @@ proc_plaintext( CTX c, PACKET *pkt )
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 ); md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
md_enable( c->mfx.md, DIGEST_ALGO_MD5 ); md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
} }
#if 0
if( c->mfx.md ) { if( c->mfx.md ) {
m_check(c->mfx.md); m_check(c->mfx.md);
if( c->mfx.md->list ) if( c->mfx.md->list )
m_check( c->mfx.md->list ); m_check( c->mfx.md->list );
} }
#endif
rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig ); rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
if( rc == G10ERR_CREATE_FILE && !c->sigs_only) { if( rc == G10ERR_CREATE_FILE && !c->sigs_only) {
/* can't write output but we hash it anyway to /* can't write output but we hash it anyway to

View File

@ -407,10 +407,14 @@ static void
skip_packet( IOBUF inp, int pkttype, unsigned long pktlen ) skip_packet( IOBUF inp, int pkttype, unsigned long pktlen )
{ {
if( list_mode ) { if( list_mode ) {
printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen ); if( pkttype == PKT_MARKER )
fputs(":marker packet:\n", stdout );
else
printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
if( pkttype ) { if( pkttype ) {
int c, i=0 ; int c, i=0 ;
printf("dump:"); if( pkttype != PKT_MARKER )
fputs("dump:", stdout );
if( iobuf_in_block_mode(inp) ) { if( iobuf_in_block_mode(inp) ) {
while( (c=iobuf_get(inp)) != -1 ) while( (c=iobuf_get(inp)) != -1 )
dump_hex_line(c, &i); dump_hex_line(c, &i);
@ -611,9 +615,10 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
static void static void
dump_sig_subpkt( int hashed, int type, int critical, dump_sig_subpkt( int hashed, int type, int critical,
const char * buffer, size_t buflen, size_t length ) const byte *buffer, size_t buflen, size_t length )
{ {
const char *p=NULL; const char *p=NULL;
int i;
printf("\t%s%ssubpkt %d len %u (", /*)*/ printf("\t%s%ssubpkt %d len %u (", /*)*/
critical ? "critical ":"", critical ? "critical ":"",
@ -654,7 +659,9 @@ dump_sig_subpkt( int hashed, int type, int critical,
p = "additional recipient request"; p = "additional recipient request";
break; break;
case SIGSUBPKT_PREF_SYM: case SIGSUBPKT_PREF_SYM:
p = "preferred symmetric algorithms"; fputs("pref-sym-algos:", stdout );
for( i=0; i < length; i++ )
printf(" %d", buffer[i] );
break; break;
case SIGSUBPKT_REV_KEY: case SIGSUBPKT_REV_KEY:
p = "revocation key"; p = "revocation key";
@ -669,10 +676,14 @@ dump_sig_subpkt( int hashed, int type, int critical,
p = "notation data"; p = "notation data";
break; break;
case SIGSUBPKT_PREF_HASH: case SIGSUBPKT_PREF_HASH:
p = "preferred hash algorithms"; fputs("pref-hash-algos:", stdout );
for( i=0; i < length; i++ )
printf(" %d", buffer[i] );
break; break;
case SIGSUBPKT_PREF_COMPR: case SIGSUBPKT_PREF_COMPR:
p = "preferred compression algorithms"; fputs("pref-zip-algos:", stdout );
for( i=0; i < length; i++ )
printf(" %d", buffer[i] );
break; break;
case SIGSUBPKT_KS_FLAGS: case SIGSUBPKT_KS_FLAGS:
p = "key server preferences"; p = "key server preferences";

View File

@ -41,12 +41,13 @@
static void static void
show_paths( ulong lid ) show_paths( ulong lid, int only_first )
{ {
void *context = NULL; void *context = NULL;
unsigned otrust, validity; unsigned otrust, validity;
int level; int last_level, level;
last_level = 0;
while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){ while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
char *p; char *p;
int rc; int rc;
@ -54,6 +55,10 @@ show_paths( ulong lid )
u32 keyid[2]; u32 keyid[2];
PKT_public_key *pk ; PKT_public_key *pk ;
if( level < last_level && only_first )
break;
last_level = level;
rc = keyid_from_lid( lid, keyid ); rc = keyid_from_lid( lid, keyid );
if( rc ) { if( rc ) {
log_error("ooops: can't get keyid for lid %lu\n", lid); log_error("ooops: can't get keyid for lid %lu\n", lid);
@ -69,15 +74,17 @@ show_paths( ulong lid )
} }
tty_printf("%*s%4u%c/%08lX.%lu %s \"", tty_printf("%*s%4u%c/%08lX.%lu %s \"",
level*2, level*2, "",
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], lid, datestr_from_pk( pk ) ); (ulong)keyid[1], lid, datestr_from_pk( pk ) );
p = get_user_id( keyid, &n ); p = get_user_id( keyid, &n );
tty_print_string( p, n ), tty_print_string( p, n ),
m_free(p); m_free(p);
tty_printf("\"\n\n"); tty_printf("\"\n");
free_public_key( pk );
} }
enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */ enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
tty_printf("\n");
} }
@ -160,7 +167,7 @@ edit_ownertrust( ulong lid, int mode )
else if( *p == ans[0] || *p == ans[1] ) { else if( *p == ans[0] || *p == ans[1] ) {
tty_printf(_( tty_printf(_(
"Certificates leading to an ultimately trusted key:\n")); "Certificates leading to an ultimately trusted key:\n"));
show_paths( lid ); show_paths( lid, 1 );
} }
else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) { else if( mode && (*p == ans[2] || *p == ans[3] || *p == CONTROL_D ) ) {
break ; /* back to the menu */ break ; /* back to the menu */

View File

@ -1,111 +1,189 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GNUPG v0.3.1 (GNU/Linux)
Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/
mQGiBDWiIPMRBAC2D3tFzbD48fop00PiM8+du2SZ6HOgYVopP+Gtm2WBDUjkFwDCkw0DL9pS pub 1024D/57548DCD 1998-07-07 Werner Koch (gnupg sig) <dd9jn@gnu.org>
3iNIunHgfeuzDbm4R3lXTXjlmBxUjNVBkX4ZmRESEoaN26fsFWb1RvBgVcKcN+DyY4GFP9LQ Key fingerprint = 6BD9 050F D8FC 941B 4341 2DCC 68B7 AB89 5754 8DCD
8JyWifAc1+o9HnE0k40D52lBLXSf7v4JhvY9NtfE8wCg4oXTaCiRFPSClIko3RqJkrnpv1cE pub 1024D/621CC013 1998-07-07 Werner Koch <werner.koch@guug.de>
AKx32rnEog5mPPs8mW1Sy5yulCTKrbCL9S7wINtMcF6FJNm2PB97Vy+FGfGHKEl2KM8AC6t3 Key fingerprint = ECAF 7590 EB34 43B5 C7CF 3ACB 6C7E E1B8 621C C013
CKOVGSdKvTn+9ZiPFiytohUmFaZaU19FjApQHZBrdx4FW+8bToRrdZhCnkUIzWdi7XlEK0Qw sub 1536G/B5A18FF4 1998-07-07
/TE0Pl8XLxDdCKQI+JASXvW0eh8wA/4nnAphsEpR1GWa4Kls7+/KO/V8Q3XLi3ZeItny+5MB pub 768R/0C9857A5 1995-09-30 Werner Koch <werner.koch@guug.de>
Dn/Y7A3u4RrNu8q3SRJgBvUBfUzhfSyRZhNQqpIFvhKSsbGNNVo5tARSQdUe4j1GlLRUWcWK Key fingerprint = 62 9E 97 C0 D5 55 76 3B 90 5A FA E9 81 1C 64 09
n4F2q5j46pdogYvnFYy8xrvuAUqI1QD4D/4YXJyKMH+DOHnT4iAjD9RlY/0kI2NyZWF0ZWQg uid Werner Koch (mein alter key) <wk@computer.org>
YnkgR05VUEcgdjAuMy4xIChHTlUvTGludXgptCFXZXJuZXIgS29jaCA8d2VybmVyLmtvY2hA pub 768g/E1D81275 1998-02-09 werner <dd9jn@amsat.org>
Z3V1Zy5kZT6IXQQTEQIAHQUCNaIg8wUJB4TOAAMLBAMFFQMCBgEDFgIBAheAAAoJEGx+4bhi Key fingerprint = 86E2 6681 6C0B 6DD5 4C06 BA6C E113 9763 E1D8 1275
HMATKBoAoIxtScHtWy+Jhc/ggATuVGYrkRhoAJ9GurZr7zF3IBEiDOdE/AwEvDFvmbkBjQQ1
oiE8FAYAkQmAlOXixb8wra83rE1i7LCENLzlvBZWKBXN4ONelZAnnkOm7IqRjMhtKRJN75zq
VyKUaUwDKjpf9J5K2t75mSxBtnbNRqL3XodjHK93OcAUkz3ci7iuC/b24JI2q4XeQG/v4YR1 -----BEGIN PGP PUBLIC KEY BLOCK-----
VodM0zEQ1IC0JCq4Pl39QZyXJdZCrUFvMcXq5ruNSldztBqTFFUiFbkw1Fug/ZyXJve2FVcb Version: GNUPG v0.4.3b (GNU/Linux)
sRXFrB7EEuy+iiU/kZ/NViKk0L4T6KRHVsEiriNlCiibW19fAAMFBf9Tbv67KFMDrLqQan/0 Comment: For info finger gcrypt@ftp.guug.de
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
=oqcL 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
=ahHm
-----END PGP PUBLIC KEY BLOCK----- -----END PGP PUBLIC KEY BLOCK-----

View File

@ -423,6 +423,20 @@ walk_sigrecs( SIGREC_CONTEXT *c )
************* Trust stuff ****************** ************* Trust stuff ******************
***********************************************/ ***********************************************/
static int
trust_letter( unsigned value )
{
switch( value ) {
case TRUST_UNKNOWN: return '-';
case TRUST_EXPIRED: return 'e';
case TRUST_UNDEFINED: return 'q';
case TRUST_NEVER: return 'n';
case TRUST_MARGINAL: return 'm';
case TRUST_FULLY: return 'f';
case TRUST_ULTIMATE: return 'u';
default: return 0 ;
}
}
/**************** /****************
* Verify that all our public keys are in the trustDB. * Verify that all our public keys are in the trustDB.
@ -737,22 +751,23 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
if( depth >= max_depth ) /* max cert_depth reached */ if( depth >= max_depth ) /* max cert_depth reached */
return TRUST_UNDEFINED; return TRUST_UNDEFINED;
stack[depth].lid = drec->r.dir.lid;
stack[depth].otrust = drec->r.dir.ownertrust;
stack[depth].trust = 0;
{ int i; { int i;
for(i=0; i < depth; i++ ) for(i=0; i < depth; i++ )
if( stack[i].lid == drec->r.dir.lid ) if( stack[i].lid == drec->r.dir.lid )
return TRUST_UNDEFINED; /* closed (we already visited this lid) */ return TRUST_UNDEFINED; /* closed (we already visited this lid) */
} }
stack[depth].lid = drec->r.dir.lid;
stack[depth].otrust = drec->r.dir.ownertrust;
stack[depth].trust = 0;
if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) { if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
/* we are at the end of a path */ /* we are at the end of a path */
TRUST_SEG_LIST tsl; TRUST_SEG_LIST tsl;
int i; int i;
stack[depth].trust = TRUST_ULTIMATE; stack[depth].trust = TRUST_ULTIMATE;
stack[depth].otrust = TRUST_ULTIMATE;
if( trust_seg_head ) { if( trust_seg_head ) {
/* we can now put copy our current stack to the trust_seg_list */ /* we can now put copy our current stack to the trust_seg_list */
tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) ); tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
@ -838,6 +853,9 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
} }
} }
if( nt > ot )
nt = ot;
if( nt >= TRUST_FULLY ) if( nt >= TRUST_FULLY )
fully++; fully++;
if( nt >= TRUST_MARGINAL ) if( nt >= TRUST_MARGINAL )
@ -1149,40 +1167,51 @@ import_ownertrust( const char *fname )
static void static void
print_path( int pathlen, TRUST_INFO *path ) print_path( int pathlen, TRUST_INFO *path )
{ {
int rc, i; int rc, c, i;
u32 keyid[2]; u32 keyid[2];
char *p;
size_t n;
fputs("path:", stdout);
for( i = 0; i < pathlen; i++ ) { for( i = 0; i < pathlen; i++ ) {
if( i && !(i%4) ) printf("%*s", i*2, "" );
fputs(" ", stdout );
rc = keyid_from_lid( path[i].lid, keyid ); rc = keyid_from_lid( path[i].lid, keyid );
if( rc ) if( rc )
printf(" ????????.%lu:", path[i].lid ); printf("????????.%lu:", path[i].lid );
else else
printf(" %08lX.%lu:", (ulong)keyid[1], path[i].lid ); printf("%08lX.%lu:", (ulong)keyid[1], path[i].lid );
print_sigflags( stdout, path[i].otrust ); c = trust_letter(path[i].otrust);
if( c )
putchar( c );
else
printf( "%02x", path[i].otrust );
putchar('/');
c = trust_letter(path[i].trust);
if( c )
putchar( c );
else
printf( "%02x", path[i].trust );
putchar(' ');
p = get_user_id( keyid, &n );
putchar(' ');
putchar('\"');
print_string( stdout, p, n > 40? 40:n, 0 );
putchar('\"');
m_free(p);
putchar('\n');
} }
putchar('\n');
} }
void void
list_trust_path( int max_depth, const char *username ) list_trust_path( const char *username )
{ {
int rc; int rc;
int wipe=0;
TRUSTREC rec; TRUSTREC rec;
TRUST_INFO *tmppath; TRUST_INFO *tmppath;
TRUST_SEG_LIST trust_seg_list, tsl, tsl2; TRUST_SEG_LIST trust_seg_list, tsl, tsl2;
PKT_public_key *pk = m_alloc_clear( sizeof *pk ); PKT_public_key *pk = m_alloc_clear( sizeof *pk );
if( max_depth < 0 ) {
wipe = 1;
max_depth = -max_depth;
}
if( (rc = get_pubkey_byname(NULL, pk, username, NULL )) ) if( (rc = get_pubkey_byname(NULL, pk, username, NULL )) )
log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) ); log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 ) else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
@ -1201,9 +1230,9 @@ list_trust_path( int max_depth, const char *username )
free_public_key( pk ); free_public_key( pk );
/* collect the paths */ /* collect the paths */
tmppath = m_alloc_clear( (max_depth+1)* sizeof *tmppath ); tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
trust_seg_list = NULL; trust_seg_list = NULL;
collect_paths( 0, max_depth, 1, &rec, tmppath, &trust_seg_list ); collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &trust_seg_list );
m_free( tmppath ); m_free( tmppath );
/* and now print them */ /* and now print them */
for(tsl = trust_seg_list; tsl; tsl = tsl->next ) { for(tsl = trust_seg_list; tsl; tsl = tsl->next ) {
@ -1221,7 +1250,9 @@ list_trust_path( int max_depth, const char *username )
/**************** /****************
* Check the complete trustdb or only the entries for the given username. * Check the complete trustdb or only the entries for the given username.
* We check the complete database and recalculate all flags. * We check the complete database. If a username is given or the special
* username "*" is used, a complete recheck is done. With no user ID
* only the records which are not yet checkd are now checked.
*/ */
void void
check_trustdb( const char *username ) check_trustdb( const char *username )
@ -1230,8 +1261,9 @@ check_trustdb( const char *username )
KBNODE keyblock = NULL; KBNODE keyblock = NULL;
KBPOS kbpos; KBPOS kbpos;
int rc; int rc;
int recheck = username && *username == '*' && !username[1];
if( username ) { if( username && !recheck ) {
rc = find_keyblock_byname( &kbpos, username ); rc = find_keyblock_byname( &kbpos, username );
if( !rc ) if( !rc )
rc = read_keyblock( &kbpos, &keyblock ); rc = read_keyblock( &kbpos, &keyblock );
@ -1242,7 +1274,7 @@ check_trustdb( const char *username )
else { else {
int modified; int modified;
rc = update_trust_record( keyblock, 0, &modified ); rc = update_trust_record( keyblock, 1, &modified );
if( rc == -1 ) { /* not yet in trustdb: insert */ if( rc == -1 ) { /* not yet in trustdb: insert */
rc = insert_trust_record( rc = insert_trust_record(
find_kbnode( keyblock, PKT_PUBLIC_KEY find_kbnode( keyblock, PKT_PUBLIC_KEY
@ -1290,7 +1322,7 @@ check_trustdb( const char *username )
continue; continue;
} }
rc = update_trust_record( keyblock, 0, &modified ); rc = update_trust_record( keyblock, recheck, &modified );
if( rc ) { if( rc ) {
log_error(_("lid %lu: update failed: %s\n"), log_error(_("lid %lu: update failed: %s\n"),
recnum, g10_errstr(rc) ); recnum, g10_errstr(rc) );
@ -1480,6 +1512,8 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
} }
int int
query_trust_info( PKT_public_key *pk ) query_trust_info( PKT_public_key *pk )
{ {
@ -1490,16 +1524,9 @@ query_trust_info( PKT_public_key *pk )
return '?'; return '?';
if( trustlevel & TRUST_FLAG_REVOKED ) if( trustlevel & TRUST_FLAG_REVOKED )
return 'r'; return 'r';
switch( (trustlevel & TRUST_MASK) ) { c = trust_letter( (trustlevel & TRUST_MASK) );
case TRUST_UNKNOWN: c = 'o'; break; if( !c )
case TRUST_EXPIRED: c = 'e'; break; c = '?';
case TRUST_UNDEFINED: c = 'q'; break;
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: BUG();
}
return c; return c;
} }
@ -1553,7 +1580,7 @@ enum_cert_paths( void **context, ulong *lid,
TRUST_INFO *tmppath; TRUST_INFO *tmppath;
TRUSTREC rec; TRUSTREC rec;
if( !lid ) if( !*lid )
return -1; return -1;
ctx = m_alloc_clear( sizeof *ctx ); ctx = m_alloc_clear( sizeof *ctx );
@ -1572,7 +1599,7 @@ enum_cert_paths( void **context, ulong *lid,
else else
ctx = *context; ctx = *context;
while( ctx->tsl && ctx->idx >= tsl->pathlen ) { while( ctx->tsl && ctx->idx >= ctx->tsl->pathlen ) {
ctx->tsl = ctx->tsl->next; ctx->tsl = ctx->tsl->next;
ctx->idx = 0; ctx->idx = 0;
} }
@ -1609,17 +1636,21 @@ get_ownertrust_info( ulong lid )
int c; int c;
otrust = get_ownertrust( lid ); otrust = get_ownertrust( lid );
switch( (otrust & TRUST_MASK) ) { c = trust_letter( (otrust & TRUST_MASK) );
case TRUST_NEVER: c = 'n'; break; if( !c )
case TRUST_MARGINAL: c = 'm'; break; c = '?';
case TRUST_FULLY: c = 'f'; break;
case TRUST_ULTIMATE: c = 'u'; break;
default: c = '-'; break;
}
return c; return c;
} }
/*
* Return an allocated buffer with the preference values for
* the key with LID and the userid which is identified by the
* HAMEHASH or the firstone if namehash is NULL. ret_n receives
* the length of the allcoated buffer. Structure of the buffer is
* a repeated sequences of 2 bytes; where the first byte describes the
* type of the preference and the second one the value. The constants
* PREFTYPE_xxxx should be used to reference a type.
*/
byte * byte *
get_pref_data( ulong lid, const byte *namehash, size_t *ret_n ) get_pref_data( ulong lid, const byte *namehash, size_t *ret_n )
{ {
@ -2353,14 +2384,16 @@ upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
for(k=0; ptable[k].subpkttype; k++ ) { for(k=0; ptable[k].subpkttype; k++ ) {
s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n ); s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
if( s ) { if( s ) {
if( n_prefs_sig >= DIM(prefs_sig)-1 ) { for( ; n; n--, s++ ) {
log_info("uid %08lX.%lu/%02X%02X: %s\n", if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
(ulong)keyid[1], lid, uidhash[18], uidhash[19], log_info("uid %08lX.%lu/%02X%02X: %s\n",
_("Too many preferences") ); (ulong)keyid[1], lid, uidhash[18], uidhash[19],
break; _("Too many preferences") );
break;
}
prefs_sig[n_prefs_sig++] = ptable[k].preftype;
prefs_sig[n_prefs_sig++] = *s;
} }
prefs_sig[n_prefs_sig++] = ptable[k].preftype;
prefs_sig[n_prefs_sig++] = *s;
} }
} }
for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) { for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
@ -2372,13 +2405,15 @@ upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
_("Too many preference items") ); _("Too many preference items") );
break; break;
} }
prefs_rec[n_prefs_rec++] = prec.r.pref.data[i]; if( prec.r.pref.data[i] ) {
prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1]; prefs_rec[n_prefs_rec++] = prec.r.pref.data[i];
prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1];
}
} }
} }
if( n_prefs_sig == n_prefs_rec if( n_prefs_sig == n_prefs_rec
&& !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) ) && !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) )
return; /* not chnaged */ return; /* not changed */
/* Preferences have changed: Delete all pref records /* Preferences have changed: Delete all pref records
* This is much simpler than checking whether we have to * This is much simpler than checking whether we have to

View File

@ -42,7 +42,7 @@
/*-- trustdb.c --*/ /*-- trustdb.c --*/
void list_trustdb(const char *username); void list_trustdb(const char *username);
void list_trust_path( int max_depth, const char *username ); void list_trust_path( const char *username );
void export_ownertrust(void); void export_ownertrust(void);
void import_ownertrust(const char *fname); void import_ownertrust(const char *fname);
void check_trustdb( const char *username ); void check_trustdb( const char *username );

View File

@ -275,13 +275,59 @@ native_to_utf8( const char *string )
/**************** /****************
* Convert string, which is in UTF8 to native encoding. Replace * Convert string, which is in UTF8 to native encoding. Replace
* illegal encodings by some "\xnn". * illegal encodings by some "\xnn".
* This code assumes that native is iso-8859-1.
*/ */
char * char *
utf8_to_native( const char *string ) utf8_to_native( const char *string )
{ {
/* FIXME: Not yet done */ #if 0
return m_strdup(string); const byte *s;
size_t n;
byte *buffer, *p;
/* quick check whether we actually have characters with bit 8 set */
for( s=string; *s; s++ )
if( *s & 0x80 )
break;
if( !*s ) /* that is easy */
return m_strdup(string);
/* count the extended utf-8 characters */
110x xxxx
1110 xxxx
1111 0xxx
for( n=1, s=string; *s; s++ ) {
if( !(*s & 0x80) )
n++;
else if( (*s & 0xe0) == 0xc0 )
n += 2;
else if( (*s & 0xf0) == 0xe0 )
n += 3;
else if( (*s & 0xf8) == 0xf0 )
n += 4;
else
n++; /* invalid encoding */
}
buffer = p = m_alloc( n );
for( s=string; *s; ) {
if( !(*s & 0x80) )
*p++ = *s++;
else if( (*s & 0xe0) == 0xc0 ) {
u32 val;
if( (s[1] & 0xc0) != 0x80 )
;
val = (*s << 6) | (s[1] & 0x3f);
}
else if( (*s & 0xf0) == 0xe0 )
n += 3;
else if( (*s & 0xf8) == 0xf0 )
n += 4;
else
n++; /* invalid encoding */
}
#endif
return m_strdup(string);
} }