Trust stuff works partly.
authorWerner Koch <wk@gnupg.org>
Sat, 24 Jan 1998 16:32:27 +0000 (16:32 +0000)
committerWerner Koch <wk@gnupg.org>
Sat, 24 Jan 1998 16:32:27 +0000 (16:32 +0000)
18 files changed:
README
VERSION
acconfig.h
cipher/random.c
config.h.in
configure.in
g10/build-packet.c
g10/comment.c
g10/g10.c
g10/options.h
g10/pkclist.c
g10/trustdb.c
g10/trustdb.h
include/iobuf.h
include/util.h
mpi/longlong.h
mpi/mpi-bit.c
util/argparse.c

diff --git a/README b/README
index 55be1b2..1f2879c 100644 (file)
--- a/README
+++ b/README
 
     4) You end up with a binary "g10" in /usr/local/bin
 
 
     4) You end up with a binary "g10" in /usr/local/bin
 
+    5) create a directory ".g10" under your hoem directory ("mkdir ~/.g10")
 
 
 
 
 
 
-    Resources
-    ---------
-    G10 needs a directory "~/.g10" to store the default keyrings
-    and other files.
-
-
     Key Generation
     --------------
 
     Key Generation
     --------------
 
@@ -75,8 +70,9 @@
     good random numbers for prime number generation, it uses a /dev/random
     which will emit only bytes if the kernel can gather enough entropy.
     If you see no progress, you should start some other activities such
     good random numbers for prime number generation, it uses a /dev/random
     which will emit only bytes if the kernel can gather enough entropy.
     If you see no progress, you should start some other activities such
-    as mouse moves or a "find /".  Because we have no hardware device
-    to generate random we have to use this method.
+    as mouse moves, "find /" or using the keyboard (on another window).
+    Because we have no hardware device to generate random we have to use
+    this method.
 
     Key generation shows progress by printing different characters to
     stderr:
 
     Key generation shows progress by printing different characters to
     stderr:
 
        g10 --sign-key Donald
 
 
        g10 --sign-key Donald
 
-    To sign the key of of "Donald" with your default userid
+    This let you sign the key of "Donald" with your default userid.
 
        g10 --sign-key -u Karl -u Joe Donald
 
 
        g10 --sign-key -u Karl -u Joe Donald
 
-    To sign the key of of "Donald" with the userids of "Karl" and "Joe".
+    This let you sign the key of of "Donald" with the userids of "Karl"
+    and "Joe".
     All existing signatures are checked, if some are invalid, a menu is
     offered to delete some of them, and the you are asked for every user
     wether you want to sign this key.
 
     All existing signatures are checked, if some are invalid, a menu is
     offered to delete some of them, and the you are asked for every user
     wether you want to sign this key.
 
-    You may remove a signature at any time by usiing the option "--edit-sig",
-    which also asks for the sigs to remove.
+    You may remove a signature at any time using the option "--edit-sig",
+    which asks for the sigs to remove.
 
 
     Sign
 
 
     Sign
     Ditto, but sign the file with the user id "Suttner"
 
 
     Ditto, but sign the file with the user id "Suttner"
 
 
-
-    Examine a data or key file
-    --------------------------
-
-       g10 --list-packets datafile
-
-    Use this to list the contents of a data file. If the file is encrypted
-    you are asked for the passphrase, so that G10 is able to look at the
-    inner structure of a encrypted packet.
-
-
     Batch mode
     ----------
     If you use the option "--batch", G10 runs in non-interactive mode and
     Batch mode
     ----------
     If you use the option "--batch", G10 runs in non-interactive mode and
     you can use the option "--passhrase-fd n", which works like PGPs
     PGPPASSFD.
 
     you can use the option "--passhrase-fd n", which works like PGPs
     PGPPASSFD.
 
-    Batch mode also causes PGP to terminate as soon as a BAD signature is
+    Batch mode also causes G10 to terminate as soon as a BAD signature is
     detected.
 
 
     detected.
 
 
     stderr to get detailed informations about the errors.
 
 
     stderr to get detailed informations about the errors.
 
 
+    Esoteric commands
+    -----------------
+
+       g10 --list-packets datafile
+
+    Use this to list the contents of a data file. If the file is encrypted
+    you are asked for the passphrase, so that G10 is able to look at the
+    inner structure of a encrypted packet.
+
+       --quick-random
+
+    Do not use the stroing random generator but a faster one.  This can be
+    used to generate keys for tests; those are marked as insecure.
+
+       --list-trustdb
+
+    List the contents of the trustdb in a human readable format
+
+       --list-trustdb  <usernames>
+
+    List the tree of certificates for the given usernames
+
+       --list-trust-path  depth  username
+
+    List the possible trust paths for the given username, up to the specified
+    depth.  If depth is negative, duplicate introducers are not listed,
+    because those would increase the trust probabilty only minimal.
+    (you must use the special option "--" to stop option parsing when
+     using a negative number)
+
+       --print-mds  filenames
+
+    List all available message digest values for the fiven filenames
+
+       --gen-prime n
+
+    Generate and print a simple prime number of size n
+
+       --gen-prime n q
+
+    Generate a prime number suitable for ElGamal signatures of size n with
+    a q as largest primefactor of n-1.
+
+       --gen-prime n q 1
+
+    Ditto, but calculate a generator too.
+
+
+    For more options/commands see the file g10/OPTIONS.
+
 
     Debug Flags
     -----------
 
     Debug Flags
     -----------
          32    memory allocation stuff
          64    caching
          128   show memory statistics at exit
          32    memory allocation stuff
          64    caching
          128   show memory statistics at exit
-
+         256   trust verification stuff
 
 
     Other Notes
 
 
     Other Notes
diff --git a/VERSION b/VERSION
index b1e80bb..845639e 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.1.3
+0.1.4
index 113ec9f..3f83ef1 100644 (file)
 @BOTTOM@
 
 
 @BOTTOM@
 
 
+/* The AC_CHECK_SIZEOF() fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+  #undef SIZEOF_UNSIGNED_SHORT
+  #define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+  #undef SIZEOF_UNSIGNED_INT
+  #define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+  #undef SIZEOF_UNSIGNED_LONG
+  #define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
 #endif /*G10_CONFIG_H*/
 #endif /*G10_CONFIG_H*/
index b082022..dbf7147 100644 (file)
@@ -167,6 +167,10 @@ the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
 #else /* not HAVE_DEV_RANDOM */
 
 
 #else /* not HAVE_DEV_RANDOM */
 
 
+#ifndef RAND_MAX   /* for SunOS */
+  #define RAND_MAX 32767
+#endif
+
 static void
 fill_buffer( byte *buffer, size_t length, int level )
 {
 static void
 fill_buffer( byte *buffer, size_t length, int level )
 {
@@ -178,11 +182,20 @@ fill_buffer( byte *buffer, size_t length, int level )
                   "it compile - it is in no way a strong RNG!\n\n"
                   "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n");
        initialized=1;
                   "it compile - it is in no way a strong RNG!\n\n"
                   "DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n");
        initialized=1;
+      #ifdef HAVE_RAND
        srand(make_timestamp()*getpid());
        srand(make_timestamp()*getpid());
+      #else
+       srandom(make_timestamp()*getpid());
+      #endif
     }
 
     }
 
+  #ifdef HAVE_RAND
     while( length-- )
        *buffer++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
     while( length-- )
        *buffer++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
+  #else
+    while( length-- )
+       *buffer++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
+  #endif
 }
 
 #endif
 }
 
 #endif
index 2a3bd36..94550cc 100644 (file)
@@ -72,6 +72,9 @@
 /* The number of bytes in a unsigned short.  */
 #undef SIZEOF_UNSIGNED_SHORT
 
 /* The number of bytes in a unsigned short.  */
 #undef SIZEOF_UNSIGNED_SHORT
 
+/* Define if you have the rand function.  */
+#undef HAVE_RAND
+
 /* Define if you have the stpcpy function.  */
 #undef HAVE_STPCPY
 
 /* Define if you have the stpcpy function.  */
 #undef HAVE_STPCPY
 
@@ -81,6 +84,9 @@
 /* Define if you have the strlwr function.  */
 #undef HAVE_STRLWR
 
 /* Define if you have the strlwr function.  */
 #undef HAVE_STRLWR
 
+/* Define if you have the strtoul function.  */
+#undef HAVE_STRTOUL
+
 /* Define if you have the tcgetattr function.  */
 #undef HAVE_TCGETATTR
 
 /* Define if you have the tcgetattr function.  */
 #undef HAVE_TCGETATTR
 
 #undef HAVE_ZLIB_H
 
 
 #undef HAVE_ZLIB_H
 
 
+/* The AC_CHECK_SIZEOF() fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+  #undef SIZEOF_UNSIGNED_SHORT
+  #define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+  #undef SIZEOF_UNSIGNED_INT
+  #define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+  #undef SIZEOF_UNSIGNED_LONG
+  #define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
 #endif /*G10_CONFIG_H*/
 #endif /*G10_CONFIG_H*/
index 6a97d41..39e8776 100644 (file)
@@ -8,7 +8,7 @@ AC_CONFIG_AUX_DIR(scripts)
 AC_CONFIG_HEADER(config.h)
 
 
 AC_CONFIG_HEADER(config.h)
 
 
-VERSION=`cat ./VERSION`
+VERSION=`cat $srcdir/VERSION`
 PACKAGE=g10
 AC_SUBST(VERSION)
 AC_SUBST(PACKAGE)
 PACKAGE=g10
 AC_SUBST(VERSION)
 AC_SUBST(PACKAGE)
@@ -90,10 +90,6 @@ dnl Checks for libraries.
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(unistd.h)
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS(unistd.h)
-AC_CHECK_HEADERS(zlib.h,
-                [LIBS="$LIBS -lz"],
-                AC_MSG_WARN([zlib missing - creating without ZLIB support!])
-               )
 
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 
 
 dnl Checks for typedefs, structures, and compiler characteristics.
@@ -150,12 +146,20 @@ AC_CHECK_SIZEOF(unsigned short, 2)
 AC_CHECK_SIZEOF(unsigned int, 4)
 AC_CHECK_SIZEOF(unsigned long, 4)
 
 AC_CHECK_SIZEOF(unsigned int, 4)
 AC_CHECK_SIZEOF(unsigned long, 4)
 
+if test "$ac_cv_sizeof_unsigned_short" = "0" \
+   || test "$ac_cv_sizeof_unsigned_int" = "0" \
+   || test "$ac_cv_sizeof_unsigned_long" = "0"; then
+    AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
+fi
 
 
 
 dnl Checks for library functions.
 AC_FUNC_VPRINTF
 
 
 
 dnl Checks for library functions.
 AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr)
+AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul)
+
+
+
 
 dnl check wether we have a random device
 AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
 
 dnl check wether we have a random device
 AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
@@ -175,8 +179,8 @@ if test "$ac_cv_mpi_config_done" = yes; then
     AC_MSG_RESULT(done)
 else
 ac_cv_mpi_config_done=""
     AC_MSG_RESULT(done)
 else
 ac_cv_mpi_config_done=""
-if test -f ./mpi/config.links ; then
-    . ./mpi/config.links
+if test -f $srcdir/mpi/config.links ; then
+    . $srcdir/mpi/config.links
     ac_cv_mpi_extra_asm_modules="$mpi_extra_modules"
     AC_LINK_FILES( ${mpi_ln_src}, ${mpi_ln_dst} )
     ac_cv_mpi_config_done="yes"
     ac_cv_mpi_extra_asm_modules="$mpi_extra_modules"
     AC_LINK_FILES( ${mpi_ln_src}, ${mpi_ln_dst} )
     ac_cv_mpi_config_done="yes"
@@ -198,11 +202,18 @@ fi
 AC_SUBST(MPI_EXTRA_ASM_OBJS)
 
 
 AC_SUBST(MPI_EXTRA_ASM_OBJS)
 
 
+dnl Do we have zlib? Must do it here because Solaris failed
+dnl when compiling a conftest (due to the "-lz" from LIBS).
+AC_CHECK_HEADERS(zlib.h,
+                [LIBS="$LIBS -lz"],
+                AC_MSG_WARN([zlib missing - creating without ZLIB support!])
+               )
+
 dnl checking whether we have other cipher source files
 CIPHER_EXTRA_OBJS=""
 CIPHER_EXTRA_DIST=""
 AC_CACHE_CHECK(for extra cipher modules, ac_cv_have_rsa_cipher,
 dnl checking whether we have other cipher source files
 CIPHER_EXTRA_OBJS=""
 CIPHER_EXTRA_DIST=""
 AC_CACHE_CHECK(for extra cipher modules, ac_cv_have_rsa_cipher,
-[if test -f cipher/rsa.c && test -f cipher/rsa.h; then
+[if test -f $srcdir/cipher/rsa.c && test -f $srcdir/cipher/rsa.h; then
   ac_cv_have_rsa_cipher=yes; else ac_cv_have_rsa_cipher=no; fi])
 if test $ac_cv_have_rsa_cipher = yes; then
     AC_DEFINE(HAVE_RSA_CIPHER)
   ac_cv_have_rsa_cipher=yes; else ac_cv_have_rsa_cipher=no; fi])
 if test $ac_cv_have_rsa_cipher = yes; then
     AC_DEFINE(HAVE_RSA_CIPHER)
index a541c8c..b0fd085 100644 (file)
@@ -147,9 +147,11 @@ calc_packet_length( PACKET *pkt )
 static int
 do_comment( IOBUF out, int ctb, PKT_comment *rem )
 {
 static int
 do_comment( IOBUF out, int ctb, PKT_comment *rem )
 {
-    write_header(out, ctb, rem->len);
-    if( iobuf_write( out, rem->data, rem->len ) )
-       return G10ERR_WRITE_FILE;
+    if( !opt.no_comment ) {
+       write_header(out, ctb, rem->len);
+       if( iobuf_write( out, rem->data, rem->len ) )
+           return G10ERR_WRITE_FILE;
+    }
     return 0;
 }
 
     return 0;
 }
 
index 4d50452..00bbac7 100644 (file)
@@ -57,9 +57,10 @@ write_comment( IOBUF out, const char *s )
 KBNODE
 make_comment_node( const char *s )
 {
 KBNODE
 make_comment_node( const char *s )
 {
-    PACKET *pkt = m_alloc_clear( sizeof *pkt );
+    PACKET *pkt;
     size_t n = strlen(s);
 
     size_t n = strlen(s);
 
+    pkt = m_alloc_clear( sizeof *pkt );
     pkt->pkttype = PKT_COMMENT;
     pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n - 1 );
     pkt->pkt.comment->len = n;
     pkt->pkttype = PKT_COMMENT;
     pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n - 1 );
     pkt->pkt.comment->len = n;
index a00a3f9..d36717a 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -190,6 +190,7 @@ main( int argc, char **argv )
     { 531, "list-trustdb",0 , "\r"},
     { 532, "quick-random", 0, "\r"},
     { 533, "list-trust-path",0, "\r"},
     { 531, "list-trustdb",0 , "\r"},
     { 532, "quick-random", 0, "\r"},
     { 533, "list-trust-path",0, "\r"},
+    { 534, "no-comment", 0,   "do not write comment packets"},
 
     {0} };
     ARGPARSE_ARGS pargs;
 
     {0} };
     ARGPARSE_ARGS pargs;
@@ -336,6 +337,7 @@ main( int argc, char **argv )
          case 531: set_cmd( &cmd, aListTrustDB); break;
          case 532: quick_random_gen(1); break;
          case 533: set_cmd( &cmd, aListTrustPath); break;
          case 531: set_cmd( &cmd, aListTrustDB); break;
          case 532: quick_random_gen(1); break;
          case 533: set_cmd( &cmd, aListTrustPath); break;
+         case 534: opt.no_comment=1; break;
          default : errors++; pargs.err = configfp? 1:2; break;
        }
     }
          default : errors++; pargs.err = configfp? 1:2; break;
        }
     }
index 3b72547..7a9a4c5 100644 (file)
@@ -39,7 +39,7 @@ struct {
     int def_cipher_algo;
     int def_pubkey_algo;
     int def_digest_algo;
     int def_cipher_algo;
     int def_pubkey_algo;
     int def_digest_algo;
-    int reserved9;
+    int no_comment;
     int reserved10;
     int reserved11;
     int reserved12;
     int reserved10;
     int reserved11;
     int reserved12;
index bd871a9..5381ac3 100644 (file)
 #include "trustdb.h"
 #include "ttyio.h"
 
 #include "trustdb.h"
 #include "ttyio.h"
 
+/****************
+ * Returns true if a ownertrust has changed.
+ */
 static int
 static int
-query_ownertrust( PKT_public_cert *pkc )
+query_ownertrust( ulong lid )
 {
     char *p;
 {
     char *p;
+    int rc;
     size_t n;
     u32 keyid[2];
     size_t n;
     u32 keyid[2];
+    PKT_public_cert *pkc ;
+    int changed=0;
+
+    rc = keyid_from_trustdb( lid, keyid );
+    if( rc ) {
+       log_error("ooops: can't get keyid for lid %lu\n", lid);
+       return 0;
+    }
+
+    pkc = m_alloc_clear( sizeof *pkc );
+    rc = get_pubkey( pkc, keyid );
+    if( rc ) {
+       log_error("keyid %08lX: pubkey not found: %s\n",
+                               (ulong)keyid[1], g10_errstr(rc) );
+       return 0;
+    }
 
 
-    keyid_from_pkc( pkc, keyid );
-    tty_printf("No ownertrust specified for:\n"
-              "%4u%c/%08lX %s \"",
+    tty_printf("No ownertrust defined for %lu:\n"
+              "%4u%c/%08lX %s \"", lid,
              nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ),
              (ulong)keyid[1], datestr_from_pkc( pkc ) );
     p = get_user_id( keyid, &n );
              nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ),
              (ulong)keyid[1], datestr_from_pkc( pkc ) );
     p = get_user_id( keyid, &n );
@@ -72,7 +91,16 @@ query_ownertrust( PKT_public_cert *pkc )
 "to do with the (implicitly created) web-of-certificates.\n");
        }
        else if( !p[1] && (*p >= '1' && *p <= '4') ) {
 "to do with the (implicitly created) web-of-certificates.\n");
        }
        else if( !p[1] && (*p >= '1' && *p <= '4') ) {
-           /* okay */
+           unsigned trust;
+           switch( *p ) {
+             case '1': trust = TRUST_UNDEFINED; break;
+             case '2': trust = TRUST_NEVER    ; break;
+             case '3': trust = TRUST_MARGINAL ; break;
+             case '4': trust = TRUST_FULLY    ; break;
+             default: BUG();
+           }
+           if( !update_ownertrust( lid, trust ) )
+               changed++;
            break;
        }
        else if( *p == 's' || *p == 'S' ) {
            break;
        }
        else if( *p == 's' || *p == 'S' ) {
@@ -81,10 +109,53 @@ query_ownertrust( PKT_public_cert *pkc )
        m_free(p); p = NULL;
     }
     m_free(p);
        m_free(p); p = NULL;
     }
     m_free(p);
-    return 0;
+    m_free(pkc);
+    return changed;
 }
 
 
 }
 
 
+/****************
+ * Try to add some more owner trusts (interactive)
+ * Returns: -1 if no ownertrust were added.
+ */
+static int
+add_ownertrust( PKT_public_cert *pkc )
+{
+    int rc;
+    void *context = NULL;
+    ulong lid;
+    unsigned trust;
+    int any=0;
+
+    tty_printf(
+"Could not find a valid trust path to the key.  Lets see, wether we\n"
+"can assign some missing owner trust values.\n\n");
+
+    rc = query_trust_record( pkc );
+    if( rc ) {
+       log_error("Ooops: not in trustdb\n");
+       return -1;
+    }
+
+    lid = pkc->local_id;
+    while( !(rc=enum_trust_web( &context, &lid )) ) {
+       rc = get_ownertrust( lid, &trust );
+       if( rc )
+           log_fatal("Ooops: couldn't get ownertrust for %lu\n", lid);
+       if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
+           trust == TRUST_UNKNOWN ) {
+           if( query_ownertrust( lid ) )
+               any=1;
+       }
+    }
+    if( rc == -1 )
+       rc = 0;
+    enum_trust_web( &context, NULL ); /* close */
+
+
+    return rc? rc : any? 0:-1;
+}
+
 
 /****************
  * Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
 
 /****************
  * Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
@@ -119,7 +190,15 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel )
        if( opt.batch || opt.answer_no )
            log_info("no info to calculate a trust probability\n");
        else {
        if( opt.batch || opt.answer_no )
            log_info("no info to calculate a trust probability\n");
        else {
-           query_ownertrust( pkc );
+           rc = add_ownertrust( pkc );
+           if( !rc ) {
+               rc = check_trust( pkc, &trustlevel );
+               if( rc )
+                   log_fatal("trust check after add_ownertrust failed: %s\n",
+                                                             g10_errstr(rc) );
+               /* FIXME: this is recursive; we better should unroll it */
+               return do_we_trust( pkc, trustlevel );
+           }
        }
        return 0; /* no */
 
        }
        return 0; /* no */
 
@@ -137,7 +216,7 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel )
        return 1; /* yes */
 
       case TRUST_ULTIMATE:
        return 1; /* yes */
 
       case TRUST_ULTIMATE:
-       log_info("Our own key is always good.\n");
+       log_info("Our own keys is always good.\n");
        return 1; /* yes */
 
       default: BUG();
        return 1; /* yes */
 
       default: BUG();
index 51ee9b8..4f89751 100644 (file)
@@ -110,15 +110,28 @@ struct local_id_info {
 };
 
 
 };
 
 
+typedef struct trust_info TRUST_INFO;
+struct trust_info {
+    ulong    lid;
+    unsigned trust;
+};
+
+
 typedef struct trust_seg_list *TRUST_SEG_LIST;
 struct trust_seg_list {
     TRUST_SEG_LIST next;
     int   nseg;     /* number of segmens */
     int   dup;
 typedef struct trust_seg_list *TRUST_SEG_LIST;
 struct trust_seg_list {
     TRUST_SEG_LIST next;
     int   nseg;     /* number of segmens */
     int   dup;
-    ulong seg[1];   /* segment list */
+    TRUST_INFO seg[1];  /* segment list */
 };
 
 
 };
 
 
+typedef struct {
+    TRUST_SEG_LIST tsl;
+    int index;
+} ENUM_TRUST_WEB_CONTEXT;
+
+
 static void create_db( const char *fname );
 static void open_db(void);
 static int  read_record( ulong recnum, TRUSTREC *rec );
 static void create_db( const char *fname );
 static void open_db(void);
 static int  read_record( ulong recnum, TRUSTREC *rec );
@@ -134,11 +147,12 @@ static int qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag );
 static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
 
 static void print_user_id( const char *text, u32 *keyid );
 static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
 
 static void print_user_id( const char *text, u32 *keyid );
-static int do_list_path( ulong *stack, int depth, int max_depth,
+static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
                         LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
 
 static int list_sigs( ulong pubkey_id );
                         LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
 
 static int list_sigs( ulong pubkey_id );
-static int do_check( ulong pubkeyid, int *trustlevel );
+static int propagate_trust( TRUST_SEG_LIST tslist );
+static int do_check( ulong pubkeyid, unsigned *trustlevel );
 
 
 static char *db_name;
 
 
 static char *db_name;
@@ -147,6 +161,9 @@ static int  db_fd = -1;
  * which are the ones from our secrings */
 static LOCAL_ID_INFO *ultikey_table;
 
  * which are the ones from our secrings */
 static LOCAL_ID_INFO *ultikey_table;
 
+static ulong last_trust_web_key;
+static TRUST_SEG_LIST last_trust_web_tslist;
+
 #define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
                       (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
 #define buftoushort( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
 #define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
                       (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
 #define buftoushort( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
@@ -642,13 +659,15 @@ void
 list_trust_path( int max_depth, const char *username )
 {
     int rc;
 list_trust_path( int max_depth, const char *username )
 {
     int rc;
+    int wipe=0;
     int i;
     TRUSTREC rec;
     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
 
     int i;
     TRUSTREC rec;
     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
 
-    if( max_depth < 0 )
-       max_depth = MAX_LIST_SIGS_DEPTH+1;
-
+    if( max_depth < 0 ) {
+       wipe = 1;
+       max_depth = -max_depth;
+    }
 
     if( (rc = get_pubkey_byname( pkc, username )) )
        log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
 
     if( (rc = get_pubkey_byname( pkc, username )) )
        log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
@@ -658,37 +677,53 @@ list_trust_path( int max_depth, const char *username )
     else if( rc == -1 )
        log_error("user '%s' not in trustdb\n", username);
     else {
     else if( rc == -1 )
        log_error("user '%s' not in trustdb\n", username);
     else {
-       LOCAL_ID_INFO *lids;
-       LOCAL_ID_INFO *work;
-       ulong stack[MAX_LIST_SIGS_DEPTH];
        TRUST_SEG_LIST tsl, tslist = NULL;
 
        TRUST_SEG_LIST tsl, tslist = NULL;
 
-       lids = new_lid_table();
-       stack[0] = pkc->local_id;
-       rc = do_list_path( stack, 1, max_depth, lids, &tslist );
-       /* wipe out duplicates */
-       work = new_lid_table();
-       for( tsl=tslist; tsl; tsl = tsl->next ) {
-           for(i=1; i < tsl->nseg-1; i++ ) {
-               if( ins_lid_table_item( work, tsl->seg[i], 0 ) ) {
-                   tsl->dup = 1; /* mark as duplicate */
-                   break;
+       if( !qry_lid_table_flag( ultikey_table, pkc->local_id, NULL ) ) {
+           tslist = m_alloc( sizeof *tslist );
+           tslist->nseg = 1;
+           tslist->dup = 0;
+           tslist->seg[0].lid = pkc->local_id;
+           tslist->seg[0].trust = 0;
+           tslist->next = NULL;
+           rc = 0;
+       }
+       else {
+           LOCAL_ID_INFO *lids = new_lid_table();
+           TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
+
+           stack[0].lid = pkc->local_id;
+           stack[0].trust = 0;
+           rc = do_list_path( stack, 1, max_depth, lids, &tslist );
+           if( wipe ) { /* wipe out duplicates */
+               LOCAL_ID_INFO *work;
+
+               work = new_lid_table();
+               for( tsl=tslist; tsl; tsl = tsl->next ) {
+                   for(i=1; i < tsl->nseg-1; i++ ) {
+                       if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
+                           tsl->dup = 1; /* mark as duplicate */
+                           break;
+                       }
+                   }
                }
                }
+               release_lid_table(work);
            }
            }
+           release_lid_table(lids);
        }
        }
-       release_lid_table(work);
-
-       release_lid_table(lids);
        if( rc )
            log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
        if( rc )
            log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
+       rc = propagate_trust( tslist );
+       if( rc )
+           log_error("user '%s' trust problem: %s\n", username, g10_errstr(rc));
        for(tsl = tslist; tsl; tsl = tsl->next ) {
            int i;
 
            if( tsl->dup )
                continue;
        for(tsl = tslist; tsl; tsl = tsl->next ) {
            int i;
 
            if( tsl->dup )
                continue;
-           printf("tslist segs:" );
+           printf("trust path:" );
            for(i=0; i < tsl->nseg; i++ )
            for(i=0; i < tsl->nseg; i++ )
-               printf("  %lu", tsl->seg[i]);
+               printf("  %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust );
            putchar('\n');
        }
     }
            putchar('\n');
        }
     }
@@ -855,8 +890,7 @@ keyid_from_local_id( ulong lid, u32 *keyid )
 
 
 /****************
 
 
 /****************
- * Verify, that all our public keys are in the trustDB and marked as
- * ultimately trusted.
+ * Verify, that all our public keys are in the trustDB.
  */
 static int
 verify_own_certs()
  */
 static int
 verify_own_certs()
@@ -866,7 +900,6 @@ verify_own_certs()
     PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
     u32 keyid[2];
     PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
     PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
     u32 keyid[2];
-    int trust;
 
     while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
        /* fixed: to be sure that it is a secret key of our own,
 
     while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
        /* fixed: to be sure that it is a secret key of our own,
@@ -895,23 +928,21 @@ verify_own_certs()
            rc = G10ERR_GENERAL;
            goto leave;
        }
            rc = G10ERR_GENERAL;
            goto leave;
        }
-       /* look into the trustdb */
-       rc = check_trust( pkc, &trust );
-       if( rc ) {
-           log_info("keyid %08lX: problem in trustdb: %s\n", (ulong)keyid[1],
-                                                             g10_errstr(rc) );
-           goto leave;
-       }
-       if( trust == TRUST_UNKNOWN ) {
+
+       /* make sure that the pubkey is in the trustdb */
+       rc = query_trust_record( pkc );
+       if( rc == -1 ) { /* put it into the trustdb */
            rc = insert_trust_record( pkc );
            rc = insert_trust_record( pkc );
-           if( rc )
-               log_error("keyid %08lX: insert failed: %s\n",
-                                           (ulong)keyid[1], g10_errstr(rc) );
-           else
-               log_info("keyid %08lX: inserted\n", (ulong)keyid[1] );
+           if( rc ) {
+               log_error("keyid %08lX: can't put it into the trustdb\n",
+                                                           (ulong)keyid[1] );
+               goto leave;
+           }
        }
        }
-       else {
-           /* FIXME: we should chek the other values */
+       else if( rc ) {
+           log_error("keyid %08lX: query record failed\n", (ulong)keyid[1] );
+           goto leave;
+
        }
 
        if( DBG_TRUST )
        }
 
        if( DBG_TRUST )
@@ -921,6 +952,7 @@ verify_own_certs()
            log_error("keyid %08lX: already in ultikey_table\n",
                                                        (ulong)keyid[1]);
 
            log_error("keyid %08lX: already in ultikey_table\n",
                                                        (ulong)keyid[1]);
 
+
        release_secret_cert_parts( skc );
        release_public_cert_parts( pkc );
     }
        release_secret_cert_parts( skc );
        release_public_cert_parts( pkc );
     }
@@ -1042,7 +1074,7 @@ list_sigs( ulong pubkey_id )
 
 
 static int
 
 
 static int
-do_list_path( ulong *stack, int depth, int max_depth,
+do_list_path( TRUST_INFO *stack, int depth, int max_depth,
              LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
 {
     SIGREC_CONTEXT sx;
              LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
 {
     SIGREC_CONTEXT sx;
@@ -1057,12 +1089,13 @@ do_list_path( ulong *stack, int depth, int max_depth,
        return 0;
     }
     memset( &sx, 0, sizeof sx );
        return 0;
     }
     memset( &sx, 0, sizeof sx );
-    sx.pubkey_id = stack[depth-1];
+    sx.pubkey_id = stack[depth-1].lid;
     while( !(rc = walk_sigrecs( &sx )) ) {
        TRUST_SEG_LIST tsl, t2, tl;
        int i;
 
     while( !(rc = walk_sigrecs( &sx )) ) {
        TRUST_SEG_LIST tsl, t2, tl;
        int i;
 
-       stack[depth] = sx.sig_id;
+       stack[depth].lid = sx.sig_id;
+       stack[depth].trust = 0;
        if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
            /*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
            ins_lid_table_item( lids, sx.sig_id, depth);
        if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
            /*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
            ins_lid_table_item( lids, sx.sig_id, depth);
@@ -1078,7 +1111,7 @@ do_list_path( ulong *stack, int depth, int max_depth,
            /*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
        else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
            /* found end of path; store it, ordered by path length */
            /*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
        else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
            /* found end of path; store it, ordered by path length */
-           tsl = m_alloc( sizeof *tsl + depth*sizeof(ulong) );
+           tsl = m_alloc( sizeof *tsl + depth*sizeof(TRUST_INFO) );
            tsl->nseg = depth+1;
            tsl->dup = 0;
            for(i=0; i <= depth; i++ )
            tsl->nseg = depth+1;
            tsl->dup = 0;
            for(i=0; i <= depth; i++ )
@@ -1268,19 +1301,110 @@ build_sigrecs( ulong pubkeyid )
     return rc;
 }
 
     return rc;
 }
 
+/****************
+ * Make a list of trust paths
+ */
+static int
+make_tsl( ulong pubkey_id, TRUST_SEG_LIST *ret_tslist )
+{
+    int i, rc;
+    LOCAL_ID_INFO *lids = new_lid_table();
+    TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
+    TRUST_SEG_LIST tsl, tslist;
+    int max_depth = 4;
+
+    tslist = *ret_tslist = NULL;
+
+    if( !qry_lid_table_flag( ultikey_table, pubkey_id, NULL ) ) {
+       tslist = m_alloc( sizeof *tslist );
+       tslist->nseg = 1;
+       tslist->dup = 0;
+       tslist->seg[0].lid = pubkey_id;
+       tslist->seg[0].trust = 0;
+       tslist->next = NULL;
+       rc = 0;
+    }
+    else {
+       stack[0].lid = pubkey_id;
+       stack[0].trust = 0;
+       rc = do_list_path( stack, 1, max_depth, lids, &tslist );
+    }
+    if( !rc ) { /* wipe out duplicates */
+       LOCAL_ID_INFO *work = new_lid_table();
+       for( tsl=tslist; tsl; tsl = tsl->next ) {
+           for(i=1; i < tsl->nseg-1; i++ ) {
+               if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
+                   tsl->dup = 1; /* mark as duplicate */
+                   break;
+               }
+           }
+       }
+       release_lid_table(work);
+       *ret_tslist = tslist;
+    }
+    else
+       ; /* FIXME: release tslist */
+    release_lid_table(lids);
+    return rc;
+}
+
 
 
+/****************
+ * Given a trust segment list tslist, walk over all paths and fill in
+ * the trust information for each segment.  What this function does is
+ * to assign a trustvalue to the first segment (which is the requested key)
+ * of each path.
+ *
+ * FIXME: We have to do more thinks here. e.g. we should never increase
+ *       the trust value.
+ *
+ * Do not do it for duplicates.
+ */
+static int
+propagate_trust( TRUST_SEG_LIST tslist )
+{
+    int i, rc;
+    unsigned trust;
+    TRUST_SEG_LIST tsl;
 
 
+    for(tsl = tslist; tsl; tsl = tsl->next ) {
+       if( tsl->dup )
+           continue;
+       assert( tsl->nseg );
+       /* the last segment is always a ultimately trusted one, so we can
+        * assign a fully trust to the next one */
+       i = tsl->nseg-1;
+       tsl->seg[i].trust = TRUST_ULTIMATE;
+       trust = TRUST_FULLY;
+       for(i-- ; i >= 0; i-- ) {
+           tsl->seg[i].trust = trust;
+           if( i > 0 ) {
+               /* get the trust of this pubkey */
+               rc = get_ownertrust( tsl->seg[i].lid, &trust );
+               if( rc )
+                   return rc;
+           }
+       }
+    }
+    return 0;
+}
 
 
 /****************
 
 
 /****************
- *
+ * we have the pubkey record but nothing more is known
  */
 static int
  */
 static int
-do_check( ulong pubkeyid, int *trustlevel )
+do_check( ulong pubkeyid, unsigned *trustlevel )
 {
 {
-    int rc=0;
+    int i, rc=0;
     ulong rnum;
     TRUSTREC rec;
     ulong rnum;
     TRUSTREC rec;
+    TRUST_SEG_LIST tsl, tsl2, tslist;
+    int marginal, fully;
+    int fully_needed = 4;
+    int marginal_needed = 6;
+
+    *trustlevel = TRUST_UNDEFINED;
 
     /* verify the cache */
 
 
     /* verify the cache */
 
@@ -1294,11 +1418,64 @@ do_check( ulong pubkeyid, int *trustlevel )
     if( rc )
        return rc;  /* error while looking for sigrec or building sigrecs */
 
     if( rc )
        return rc;  /* error while looking for sigrec or building sigrecs */
 
+    /* fixme: take it from the cache if it is valid */
+
+    /* Make a list of all possible trust-paths */
+    rc = make_tsl( pubkeyid, &tslist );
+    if( rc )
+       return rc;
+    rc = propagate_trust( tslist );
+    if( rc )
+       return rc;
+    for(tsl = tslist; tsl; tsl = tsl->next ) {
+       if( tsl->dup )
+           continue;
+
+       log_debug("tslist segs:" );
+       for(i=0; i < tsl->nseg; i++ )
+           fprintf(stderr, "  %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust );
+       putc('\n',stderr);
+    }
+
+    /* and look wether there is a trusted path.
+     * We only have to look at the first segment, because
+     * propagate_trust has investigated all other segments */
+    marginal = fully = 0;
+    for(tsl = tslist; tsl; tsl = tsl->next ) {
+       if( tsl->dup )
+           continue;
+       if( tsl->seg[0].trust == TRUST_ULTIMATE ) {
+           *trustlevel = TRUST_ULTIMATE; /* our own key */
+           break;
+       }
+       if( tsl->seg[0].trust == TRUST_FULLY ) {
+           marginal++;
+           fully++;
+       }
+       else if( tsl->seg[0].trust == TRUST_MARGINAL )
+           marginal++;
+
+       if( fully >= fully_needed ) {
+           *trustlevel = TRUST_FULLY;
+           break;
+       }
+    }
+    if( !tsl && marginal >= marginal_needed )
+       *trustlevel = TRUST_MARGINAL;
+
+    /* cache the tslist */
+    if( last_trust_web_key ) {
+       for( tsl = last_trust_web_tslist; tsl; tsl = tsl2 ) {
+           tsl2 = tsl->next;
+           m_free(tsl);
+       }
+    }
+    last_trust_web_key = pubkeyid;
+    last_trust_web_tslist = tslist;
     return 0;
 }
 
 
     return 0;
 }
 
 
-
 /*********************************************************
  ****************  API Interface  ************************
  *********************************************************/
 /*********************************************************
  ****************  API Interface  ************************
  *********************************************************/
@@ -1375,10 +1552,10 @@ init_trustdb( int level )
  *          is not necessary to check this if we use a local pubring. Hmmmm.
  */
 int
  *          is not necessary to check this if we use a local pubring. Hmmmm.
  */
 int
-check_trust( PKT_public_cert *pkc, int *r_trustlevel )
+check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel )
 {
     TRUSTREC rec;
 {
     TRUSTREC rec;
-    int trustlevel = TRUST_UNKNOWN;
+    unsigned trustlevel = TRUST_UNKNOWN;
     int rc=0;
 
     if( DBG_TRUST )
     int rc=0;
 
     if( DBG_TRUST )
@@ -1409,10 +1586,6 @@ check_trust( PKT_public_cert *pkc, int *r_trustlevel )
        log_error("check_trust: do_check failed: %s\n", g10_errstr(rc));
        return rc;
     }
        log_error("check_trust: do_check failed: %s\n", g10_errstr(rc));
        return rc;
     }
-    if( !rec.r.pubkey.ownertrust )
-       trustlevel = TRUST_UNDEFINED;
-    else
-       trustlevel = TRUST_EXPIRED;
 
 
   leave:
 
 
   leave:
@@ -1423,29 +1596,109 @@ check_trust( PKT_public_cert *pkc, int *r_trustlevel )
 }
 
 
 }
 
 
+
+
+/****************
+ * Enumerate all keys, which are needed to build all trust paths for
+ * the given key.  This function dies not return the key itself or
+ * the ultimate key.
+ *
+ *  1) create a void pointer and initialize it to NULL
+ *  2) pass this void pointer by reference to this function.
+ *     Set lid to the key you want to enumerate and pass it by reference.
+ *  3) call this function as long as it does not return -1
+ *     to indicate EOF. LID does contain the next key used to build the web
+ *  4) Always call this function a last time with LID set to NULL,
+ *     so that it can free it's context.
+ */
+int
+enum_trust_web( void **context, ulong *lid )
+{
+    ENUM_TRUST_WEB_CONTEXT *c = *context;
+
+    if( !c ) { /* make a new context */
+       c = m_alloc_clear( sizeof *c );
+       *context = c;
+       if( *lid != last_trust_web_key )
+           log_bug("enum_trust_web: nyi\n");
+       c->tsl = last_trust_web_tslist;
+       c->index = 1;
+    }
+
+    if( !lid ) { /* free the context */
+       m_free( c );
+       *context = NULL;
+       return 0;
+    }
+
+    while( c->tsl ) {
+       if( !c->tsl->dup && c->index < c->tsl->nseg-1 ) {
+           *lid = c->tsl->seg[c->index].lid;
+           c->index++;
+           return 0;
+       }
+       c->index = 1;
+       c->tsl = c->tsl->next;
+    }
+    return -1; /* eof */
+}
+
+
+/****************
+ * Return the assigned ownertrust value for the given LID
+ */
+int
+get_ownertrust( ulong lid, unsigned *r_otrust )
+{
+    TRUSTREC rec;
+
+    if( read_record( lid, &rec ) ) {
+       log_error("get_ownertrust: read record failed\n");
+       return G10ERR_TRUSTDB;
+    }
+    if( r_otrust )
+       *r_otrust = rec.r.pubkey.ownertrust;
+    return 0;
+}
+
+int
+keyid_from_trustdb( ulong lid, u32 *keyid )
+{
+    TRUSTREC rec;
+
+    if( read_record( lid, &rec ) ) {
+       log_error("keyid_from_trustdb: read record failed\n");
+       return G10ERR_TRUSTDB;
+    }
+    if( keyid ) {
+       keyid[0] = rec.r.pubkey.keyid[0];
+       keyid[1] = rec.r.pubkey.keyid[1];
+    }
+    return 0;
+}
+
+
 int
 int
-get_ownertrust( PKT_public_cert *pkc, int *r_otrust )
+query_trust_record( PKT_public_cert *pkc )
 {
     TRUSTREC rec;
 {
     TRUSTREC rec;
-    int rc;
+    int rc=0;
 
 
-    /* get the pubkey record */
     if( pkc->local_id ) {
        if( read_record( pkc->local_id, &rec ) ) {
     if( pkc->local_id ) {
        if( read_record( pkc->local_id, &rec ) ) {
-           log_error("get_ownertrust: read record failed\n");
+           log_error("query_trust_record: read record failed\n");
            return G10ERR_TRUSTDB;
        }
     }
     else { /* no local_id: scan the trustdb */
        if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) {
            return G10ERR_TRUSTDB;
        }
     }
     else { /* no local_id: scan the trustdb */
        if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) {
-           log_error("get_ownertrust: scan_record_by_pkc(2) failed: %s\n",
+           log_error("query_trust_record: scan_record_by_pkc(2) failed: %s\n",
                                                            g10_errstr(rc));
            return rc;
        }
        else if( rc == -1 )
            return rc;
     }
                                                            g10_errstr(rc));
            return rc;
        }
        else if( rc == -1 )
            return rc;
     }
-    *r_otrust = rec.r.pubkey.ownertrust;
     return 0;
 }
 
     return 0;
 }
 
@@ -1494,23 +1747,23 @@ insert_trust_record( PKT_public_cert *pkc )
 
 
 int
 
 
 int
-update_trust_record( PKT_public_cert *pkc, int new_trust )
+update_ownertrust( ulong lid, unsigned new_trust )
 {
     TRUSTREC rec;
 {
     TRUSTREC rec;
-    ulong recnum;
-
-
-    assert( pkc->local_id );
 
 
-    if( read_record( pkc->local_id, &rec ) ) {
-       log_error("update_trust_record: read failed\n");
+    if( read_record( lid, &rec ) ) {
+       log_error("update_ownertrust: read failed\n");
        return G10ERR_TRUSTDB;
     }
     /* check keyid, fingerprint etc ? */
        return G10ERR_TRUSTDB;
     }
     /* check keyid, fingerprint etc ? */
+    if( rec.rectype != 2 ) {
+       log_error("update_ownertrust: invalid record type\n");
+       return G10ERR_TRUSTDB;
+    }
 
 
-    rec.r.pubkey.ownertrust = 0;
-    if( write_record( recnum, &rec ) ) {
-       log_error("insert_trust_record: write failed\n");
+    rec.r.pubkey.ownertrust = new_trust;
+    if( write_record( lid, &rec ) ) {
+       log_error("update_ownertrust: write failed\n");
        return G10ERR_TRUSTDB;
     }
 
        return G10ERR_TRUSTDB;
     }
 
index 75ead66..ee604de 100644 (file)
 void list_trustdb(const char *username);
 void list_trust_path( int max_depth, const char *username );
 int init_trustdb( int level );
 void list_trustdb(const char *username);
 void list_trust_path( int max_depth, const char *username );
 int init_trustdb( int level );
-int check_trust( PKT_public_cert *pkc, int *r_trustlevel );
-int get_ownertrust( PKT_public_cert *pkc, int *r_otrust );
+int check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel );
+int enum_trust_web( void **context, ulong *lid );
+int get_ownertrust( ulong lid, unsigned *r_otrust );
+int keyid_from_trustdb( ulong lid, u32 *keyid );
+int query_trust_record( PKT_public_cert *pkc );
 int insert_trust_record( PKT_public_cert *pkc );
 int insert_trust_record( PKT_public_cert *pkc );
+int update_ownertrust( ulong lid, unsigned new_trust );
 int verify_private_data(void);
 int sign_private_data(void);
 
 int verify_private_data(void);
 int sign_private_data(void);
 
index e381445..81e23f2 100644 (file)
@@ -54,7 +54,7 @@ struct iobuf_struct {
     IOBUF chain;       /* next iobuf used for i/o if any (passed to filter) */
     int no, subno;
     const char *desc;
     IOBUF chain;       /* next iobuf used for i/o if any (passed to filter) */
     int no, subno;
     const char *desc;
-    void *opaque;      /* can be used to old any information   */
+    void *opaque;      /* can be used to hold any information   */
                       /* this value is copied to all instances */
 };
 
                       /* this value is copied to all instances */
 };
 
index a33b7f2..fe834e1 100644 (file)
@@ -121,7 +121,9 @@ char *stpcpy(char *a,const char *b);
 #ifndef HAVE_STRLWR
 char *strlwr(char *a);
 #endif
 #ifndef HAVE_STRLWR
 char *strlwr(char *a);
 #endif
-
+#ifndef HAVE_STRTOUL
+  #define strtoul(a,b,c)  ((unsigned long)strtol((a),(b),(c)))
+#endif
 
 /******** some macros ************/
 #ifndef STR
 
 /******** some macros ************/
 #ifndef STR
index c341c3d..c924355 100644 (file)
@@ -1,4 +1,5 @@
 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+   Note: I added some stuff for use with g10
 
 Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
 
 
 Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
 
@@ -1440,6 +1441,7 @@ extern
 const
 #endif
 unsigned char __clz_tab[];
 const
 #endif
 unsigned char __clz_tab[];
+#define MPI_INTERNAL_NEED_CLZ_TAB 1
 #define count_leading_zeros(count, x) \
   do {                                                                 \
     UWtype __xr = (x);                                                 \
 #define count_leading_zeros(count, x) \
   do {                                                                 \
     UWtype __xr = (x);                                                 \
index 864dc02..d1f440a 100644 (file)
 #include "longlong.h"
 
 
 #include "longlong.h"
 
 
+#ifdef MPI_INTERNAL_NEED_CLZ_TAB
+unsigned char
+__clz_tab[] =
+{
+  0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+  8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+#endif
+
+
+
+
+
+
+
+
 /****************
  * Return the number of bits in A.
  */
 /****************
  * Return the number of bits in A.
  */
index c6c0302..89c873c 100644 (file)
@@ -286,7 +286,7 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
        else if( state == 3 ) { /* skip leading spaces of the argument */
            if( !isspace(c) ) {
                i = 0;
        else if( state == 3 ) { /* skip leading spaces of the argument */
            if( !isspace(c) ) {
                i = 0;
-               keyword[i] = c;
+               keyword[i++] = c;
                state = 4;
            }
        }
                state = 4;
            }
        }