some bug fixes
authorWerner Koch <wk@gnupg.org>
Wed, 18 Nov 1998 19:59:06 +0000 (19:59 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 18 Nov 1998 19:59:06 +0000 (19:59 +0000)
14 files changed:
AUTHORS
NEWS
TODO
doc/gpg.1pod
g10/ChangeLog
g10/armor.c
g10/g10.c
g10/mainproc.c
g10/parse-packet.c
g10/pkclist.c
g10/pubring.asc
g10/trustdb.c
g10/trustdb.h
util/strgutil.c

diff --git a/AUTHORS b/AUTHORS
index 35e0b5b..5ad1f87 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
-<mskala@ansuz.sooke.bc.ca> disclaims changes.
-Wrote cipher/twofish.c
+GNUPG  Matthew Skala              1998-08-10
+Disclaims changes.
+mskala@ansuz.sooke.bc.ca
+Wrote cipher/twofish.c.
 
 GNUPG  Natural Resources Canada    1998-08-11
 Disclaims changes by Matthew Skala.
 
+
 GNUPG  Michael Roth    Germany     1998-09-17
-<mroth@nessie.de> assigns changes.
+Assigns changes.
+mroth@nessie.de
 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.
 
 
-TRANSLATIONS   Marco d'Itri        1997-02-22
-Disclaims
-it.po
+TRANSLATIONS   Marco d'Itri    1997-02-22
+Disclaimer.  [it]
+md@linux.it
+
+
+TRANSLATIONS   Gael Queri      1998-09-08
+Disclaimer.  [fr]
+gqueri@mail.dotcom.fr
+
+
+TRANSLATIONS   Walter Koch     1998-09-08
+Disclaimer.  [de]
+walterk@dip.de
 
-TRANSLATIONS   Gaël Quéri          ??????????
-fr.po
 
-TRANSLATIONS   Walter Koch         ??????????
-de.po
+TRANSLATIONS   Gregory Steuck  1998-10-20
+Disclaimer.  [ru?]
+steuck@iname.com
 
-TRANSLATIONS   Gregory Steuck      ??????????
-ru.po
 
-TRANSLATIONS   Urko Lusa           ??????????
+TRANSLATIONS   Urko Lusa       ??????????
 es_ES.po
 
 
diff --git a/NEWS b/NEWS
index a860bdc..fb03b4e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,16 @@ This is NOT a released version!
     * Add option --charset to support "koi8-r" encoding of user ids.
       (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
diff --git a/TODO b/TODO
index 97a80b1..8f7809d 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,6 @@
 
     * 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?
 
@@ -11,9 +11,8 @@
     * Update the keyring at ftp.guug.de
 
     * 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
       it on tobold.
@@ -31,8 +30,6 @@
 
     * Check revocation and expire stuff.
 
-    * check preferences (cipher and compress)
-
     * OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
        OpenBSD binaries are a.out, so every symbol begins with "_"
 
index e299b38..0258139 100644 (file)
@@ -75,7 +75,7 @@ B<-k> [I<username>] [I<keyring>]
     B<-kvc>   List fingerprints
     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
     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
     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
     too.
 
@@ -129,7 +129,7 @@ B<--edit-key> I<name>
     B<delkey>
        Remove a subkey.
     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.
        With no selection the key expiration of the
        primary key is changed.
@@ -158,9 +158,8 @@ B<--edit-key> I<name>
     displayed with the primary key: The first one is the
     assigned owner trust and the second the calculated
     trust value; letters are used for the values:
-      B<->  No ownertrust assigned.
-      B<o>  Trust not yet calculated.
-      B<e>  Trust calculation failed.
+      B<->  No ownertrust assigned / not yet calculated.
+      B<e>  Trust calculation has failed.
       B<q>  Not enough information for calculation.
       B<n>  Never trust this key.
       B<m>  Marginally trusted.
@@ -191,7 +190,7 @@ B<--export-secret-keys> [I<names>
     This is normally not very useful.
 
 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
     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>);
 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
 does not make sense.
 
@@ -457,11 +456,11 @@ a signature was bad and other errorcode for fatal errors.
 
 =head1 EXAMPLES
 
-  -se -r Bob [file]          sign and encrypt for user Bob
-  -sat [file]                make a clear text signature
-  -sb  [file]                make a detached signature
-  -k   [userid]              show keys
-  -kc  [userid]              show fingerprint
+  -se -r Bob [file]         sign and encrypt for user Bob
+  -sat [file]               make a clear text signature
+  -sb  [file]               make a detached signature
+  -k   [userid]             show keys
+  -kc  [userid]             show fingerprint
 
 =head1 ENVIRONMENT
 
@@ -476,13 +475,13 @@ F<~/.gnupg/pubring.gpg>     The public keyring
 
 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
 
 =head1 SEE ALSO
 
-gpg(1)  gpgm(1)
+gpg(1) gpgm(1)
 
 
 =head1 WARNINGS
index 1f072a9..f904c37 100644 (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>
 
        * trustdb.c (collect_paths): Removed a warning message.
index 46c3cc6..c1da9ac 100644 (file)
@@ -1,14 +1,14 @@
 /* armor.c - Armor filter
  *     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
  * the Free Software Foundation; either version 2 of the License, or
  * (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
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
@@ -1008,7 +1008,7 @@ armor_filter( void *opaque, int control,
            iobuf_writestr(a, "-----");
            iobuf_writestr(a, head_strings[afx->what] );
            iobuf_writestr(a, "-----\n");
-           iobuf_writestr(a, "Version: GNUPG v"  VERSION " ("
+           iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
                                            PRINTABLE_OS_NAME ")\n");
 
            if( opt.comment_string ) {
index 86dd901..d2e196e 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -268,7 +268,6 @@ static ARGPARSE_OPTS opts[] = {
   #endif
   #ifdef IS_G10
     { oKOption, NULL,   0, "@"},
-    { aEditKey, "edit-sig"  ,0, "@"}, /* alias for edit-key */
     { oPasswdFD, "passphrase-fd",1, "@" },
     { aSignKey, "sign-key"  ,256, "@" }, /* alias for edit-key */
   #endif
@@ -1217,9 +1216,10 @@ main( int argc, char **argv )
        break;
 
       case aListTrustPath:
-       if( argc != 2 )
-           wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
-       list_trust_path( atoi(*argv), argv[1] );
+       if( !argc )
+           wrong_args("--list-trust-path <usernames>");
+       for( ; argc; argc--, argv++ )
+           list_trust_path( *argv );
        break;
 
       case aExportOwnerTrust:
index c21516d..50600a1 100644 (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_MD5 );
     }
+  #if 0
     if( c->mfx.md ) {
        m_check(c->mfx.md);
        if( c->mfx.md->list )
            m_check( c->mfx.md->list );
     }
+  #endif
     rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
     if( rc == G10ERR_CREATE_FILE && !c->sigs_only) {
        /* can't write output but we hash it anyway to
index 1400df7..a2923d9 100644 (file)
@@ -407,10 +407,14 @@ static void
 skip_packet( IOBUF inp, int pkttype, unsigned long pktlen )
 {
     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 ) {
            int c, i=0 ;
-           printf("dump:");
+           if( pkttype != PKT_MARKER )
+               fputs("dump:", stdout );
            if( iobuf_in_block_mode(inp) ) {
                while( (c=iobuf_get(inp)) != -1 )
                    dump_hex_line(c, &i);
@@ -611,9 +615,10 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
 
 static void
 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;
+    int i;
 
     printf("\t%s%ssubpkt %d len %u (", /*)*/
              critical ? "critical ":"",
@@ -654,7 +659,9 @@ dump_sig_subpkt( int hashed, int type, int critical,
        p = "additional recipient request";
        break;
       case SIGSUBPKT_PREF_SYM:
-       p = "preferred symmetric algorithms";
+       fputs("pref-sym-algos:", stdout );
+       for( i=0; i < length; i++ )
+           printf(" %d", buffer[i] );
        break;
       case SIGSUBPKT_REV_KEY:
        p = "revocation key";
@@ -669,10 +676,14 @@ dump_sig_subpkt( int hashed, int type, int critical,
        p = "notation data";
        break;
       case SIGSUBPKT_PREF_HASH:
-       p = "preferred hash algorithms";
+       fputs("pref-hash-algos:", stdout );
+       for( i=0; i < length; i++ )
+           printf(" %d", buffer[i] );
        break;
       case SIGSUBPKT_PREF_COMPR:
-       p = "preferred compression algorithms";
+       fputs("pref-zip-algos:", stdout );
+       for( i=0; i < length; i++ )
+           printf(" %d", buffer[i] );
        break;
       case SIGSUBPKT_KS_FLAGS:
        p = "key server preferences";
index f56708c..d2b4eb2 100644 (file)
 
 
 static void
-show_paths( ulong lid )
+show_paths( ulong lid, int only_first )
 {
     void *context = NULL;
     unsigned otrust, validity;
-    int level;
+    int last_level, level;
 
+    last_level = 0;
     while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
        char *p;
        int rc;
@@ -54,6 +55,10 @@ show_paths( ulong lid )
        u32 keyid[2];
        PKT_public_key *pk ;
 
+       if( level < last_level && only_first )
+           break;
+       last_level = level;
+
        rc = keyid_from_lid( lid, keyid );
        if( rc ) {
            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 \"",
-                 level*2,
+                 level*2, "",
                  nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
                  (ulong)keyid[1], lid, datestr_from_pk( pk ) );
        p = get_user_id( keyid, &n );
        tty_print_string( p, n ),
        m_free(p);
-       tty_printf("\"\n\n");
+       tty_printf("\"\n");
+       free_public_key( pk );
     }
     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] ) {
            tty_printf(_(
                "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 ) ) {
            break ; /* back to the menu */
index ed8ccbd..55ab28e 100644 (file)
+
+pub  1024D/57548DCD 1998-07-07 Werner Koch (gnupg sig) <dd9jn@gnu.org>
+     Key fingerprint = 6BD9 050F D8FC 941B 4341  2DCC 68B7 AB89 5754 8DCD
+pub  1024D/621CC013 1998-07-07 Werner Koch <werner.koch@guug.de>
+     Key fingerprint = ECAF 7590 EB34 43B5 C7CF  3ACB 6C7E E1B8 621C C013
+sub  1536G/B5A18FF4 1998-07-07
+pub   768R/0C9857A5 1995-09-30 Werner Koch <werner.koch@guug.de>
+     Key fingerprint = 62 9E 97 C0 D5 55 76 3B 90 5A FA E9 81 1C 64 09
+uid                           Werner Koch (mein alter key) <wk@computer.org>
+pub   768g/E1D81275 1998-02-09 werner <dd9jn@amsat.org>
+     Key fingerprint = 86E2 6681 6C0B 6DD5 4C06  BA6C E113 9763 E1D8 1275
+
+
 -----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GNUPG v0.3.1 (GNU/Linux)
-Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/
+Version: GNUPG v0.4.3b (GNU/Linux)
+Comment: For info finger gcrypt@ftp.guug.de
 
-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
-=oqcL
+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
+=ahHm
 -----END PGP PUBLIC KEY BLOCK-----
+
index 4cdb7e8..84a5250 100644 (file)
@@ -423,6 +423,20 @@ walk_sigrecs( SIGREC_CONTEXT *c )
  ************* 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.
@@ -737,22 +751,23 @@ collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
 
     if( depth >= max_depth )  /* max cert_depth reached */
        return TRUST_UNDEFINED;
+
+    stack[depth].lid = drec->r.dir.lid;
+    stack[depth].otrust = drec->r.dir.ownertrust;
+    stack[depth].trust = 0;
     {  int i;
 
        for(i=0; i < depth; i++ )
            if( stack[i].lid == drec->r.dir.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 ) ) {
        /* we are at the end of a path */
        TRUST_SEG_LIST tsl;
        int i;
 
        stack[depth].trust = TRUST_ULTIMATE;
+       stack[depth].otrust = TRUST_ULTIMATE;
        if( trust_seg_head ) {
            /* we can now put copy our current stack to the trust_seg_list */
            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 )
                    fully++;
                if( nt >= TRUST_MARGINAL )
@@ -1149,40 +1167,51 @@ import_ownertrust( const char *fname )
 static void
 print_path( int pathlen, TRUST_INFO *path )
 {
-    int rc, i;
+    int rc, c, i;
     u32 keyid[2];
+    char *p;
+    size_t n;
 
-    fputs("path:", stdout);
     for( i = 0; i < pathlen; i++ )  {
-       if( i && !(i%4) )
-           fputs("     ", stdout );
+       printf("%*s", i*2, "" );
        rc = keyid_from_lid( path[i].lid, keyid );
        if( rc )
-           printf(" ????????.%lu:", path[i].lid );
+           printf("????????.%lu:", path[i].lid );
        else
-           printf(" %08lX.%lu:", (ulong)keyid[1], path[i].lid );
-       print_sigflags( stdout, path[i].otrust );
+           printf("%08lX.%lu:", (ulong)keyid[1], path[i].lid );
+       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
-list_trust_path( int max_depth, const char *username )
+list_trust_path( const char *username )
 {
     int rc;
-    int wipe=0;
     TRUSTREC rec;
     TRUST_INFO *tmppath;
     TRUST_SEG_LIST trust_seg_list, tsl, tsl2;
     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 )) )
        log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
     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 );
 
     /* 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;
-    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 );
     /* and now print them */
     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.
- * 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
 check_trustdb( const char *username )
@@ -1230,8 +1261,9 @@ check_trustdb( const char *username )
     KBNODE keyblock = NULL;
     KBPOS kbpos;
     int rc;
+    int recheck = username && *username == '*' && !username[1];
 
-    if( username ) {
+    if( username && !recheck ) {
        rc = find_keyblock_byname( &kbpos, username );
        if( !rc )
            rc = read_keyblock( &kbpos, &keyblock );
@@ -1242,7 +1274,7 @@ check_trustdb( const char *username )
        else {
            int modified;
 
-           rc = update_trust_record( keyblock, 0, &modified );
+           rc = update_trust_record( keyblock, 1, &modified );
            if( rc == -1 ) { /* not yet in trustdb: insert */
                rc = insert_trust_record(
                            find_kbnode( keyblock, PKT_PUBLIC_KEY
@@ -1290,7 +1322,7 @@ check_trustdb( const char *username )
                    continue;
                }
 
-               rc = update_trust_record( keyblock, 0, &modified );
+               rc = update_trust_record( keyblock, recheck, &modified );
                if( rc ) {
                    log_error(_("lid %lu: update failed: %s\n"),
                                                 recnum, g10_errstr(rc) );
@@ -1480,6 +1512,8 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
 }
 
 
+
+
 int
 query_trust_info( PKT_public_key *pk )
 {
@@ -1490,16 +1524,9 @@ query_trust_info( PKT_public_key *pk )
        return '?';
     if( trustlevel & TRUST_FLAG_REVOKED )
        return 'r';
-    switch( (trustlevel & TRUST_MASK) ) {
-      case TRUST_UNKNOWN:   c = 'o'; break;
-      case TRUST_EXPIRED:   c = 'e'; break;
-      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();
-    }
+    c = trust_letter( (trustlevel & TRUST_MASK) );
+    if( !c )
+       c = '?';
     return c;
 }
 
@@ -1553,7 +1580,7 @@ enum_cert_paths( void **context, ulong *lid,
        TRUST_INFO *tmppath;
        TRUSTREC rec;
 
-       if( !lid )
+       if( !*lid )
            return -1;
 
        ctx = m_alloc_clear( sizeof *ctx );
@@ -1572,7 +1599,7 @@ enum_cert_paths( void **context, ulong *lid,
     else
        ctx = *context;
 
-    while( ctx->tsl && ctx->idx >= tsl->pathlen )  {
+    while( ctx->tsl && ctx->idx >= ctx->tsl->pathlen ) {
        ctx->tsl = ctx->tsl->next;
        ctx->idx = 0;
     }
@@ -1609,17 +1636,21 @@ get_ownertrust_info( ulong lid )
     int c;
 
     otrust = get_ownertrust( lid );
-    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;
-    }
+    c = trust_letter( (otrust & TRUST_MASK) );
+    if( !c )
+       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 *
 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++ ) {
        s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
        if( s ) {
-           if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
-               log_info("uid %08lX.%lu/%02X%02X: %s\n",
-                         (ulong)keyid[1], lid, uidhash[18], uidhash[19],
-                         _("Too many preferences") );
-               break;
+           for( ; n; n--, s++ ) {
+               if( n_prefs_sig >= DIM(prefs_sig)-1 ) {
+                   log_info("uid %08lX.%lu/%02X%02X: %s\n",
+                             (ulong)keyid[1], lid, uidhash[18], uidhash[19],
+                             _("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 ) {
@@ -2372,13 +2405,15 @@ upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
                          _("Too many preference items") );
                break;
            }
-           prefs_rec[n_prefs_rec++] = prec.r.pref.data[i];
-           prefs_rec[n_prefs_rec++] = prec.r.pref.data[i+1];
+           if( prec.r.pref.data[i] ) {
+               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
        && !memcmp( prefs_sig, prefs_rec, n_prefs_sig ) )
-       return;  /* not chnaged */
+       return;  /* not changed */
 
     /* Preferences have changed:  Delete all pref records
      * This is much simpler than checking whether we have to
index 04b2435..cb9d743 100644 (file)
@@ -42,7 +42,7 @@
 
 /*-- trustdb.c --*/
 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 import_ownertrust(const char *fname);
 void check_trustdb( const char *username );
index ce76038..20489da 100644 (file)
@@ -275,13 +275,59 @@ native_to_utf8( const char *string )
 /****************
  * Convert string, which is in UTF8 to native encoding.  Replace
  * illegal encodings by some "\xnn".
- * This code assumes that native is iso-8859-1.
  */
 char *
 utf8_to_native( const char *string )
 {
-    /* FIXME: Not yet done */
-    return m_strdup(string);
+  #if 0
+    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);
+
 }