Merged most of David Shaw's changes in 1.3 since 2003-06-03.
authorWerner Koch <wk@gnupg.org>
Tue, 23 Sep 2003 17:48:33 +0000 (17:48 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 23 Sep 2003 17:48:33 +0000 (17:48 +0000)
45 files changed:
ChangeLog
TODO
common/ChangeLog
common/iobuf.c
common/ttyio.c
common/util.h
configure.ac
g10/ChangeLog
g10/Makefile.am
g10/armor.c
g10/build-packet.c
g10/encode.c
g10/exec.c
g10/g10.c
g10/getkey.c
g10/gpgv.c
g10/import.c
g10/keyedit.c
g10/keygen.c
g10/keylist.c
g10/keyring.c
g10/keyserver.c
g10/main.h
g10/mainproc.c
g10/misc.c
g10/options.h
g10/options.skel
g10/packet.h
g10/parse-packet.c
g10/passphrase.c
g10/photoid.c
g10/pkclist.c
g10/revoke.c
g10/sig-check.c
g10/sign.c
g10/signal.c
g10/status.c
g10/status.h
g10/tdbdump.c
g10/tdbio.c
g10/trustdb.c
g10/trustdb.h
include/ChangeLog
include/cipher.h
include/types.h

index 172dd0f..ce3d769 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2003-09-23  Werner Koch  <wk@gnupg.org>
+
+       Merged most of David Shaw's changes in 1.3 since 2003-06-03.
+       
+       * configure.ac: Drop all TIGER/192 support.
+       (uint64_t): Check for UINT64_C to go along with uint64_t.
+       (getaddrinfo): Check for it.
+       (sigset_t): Check for sigset_t and struct sigaction.  This is for
+       Forte c89 on Solaris which seems to define only the function call
+       half of the two pairs by default.
+       (W32LIBS): Include wsock32 in W32LIBS.  This is different from
+       NETLIBS so we don't need to force other platforms to pull in the
+       netlibs when they aren't actually needed.
+
 2003-09-06  Werner Koch  <wk@gnupg.org>
 
        Released 1.9.1.
diff --git a/TODO b/TODO
index fe81d02..da337f2 100644 (file)
--- a/TODO
+++ b/TODO
@@ -63,3 +63,5 @@ might want to have an agent context for each service request
 
 * ALL
 ** Return IMPORT_OK status.
+
+* Where is http.c, regcomp.c, srv.c, w32reg.c  ?
index 66e935b..caabdd4 100644 (file)
@@ -1,3 +1,11 @@
+2003-09-23  Werner Koch  <wk@gnupg.org>
+
+       * iobuf.c (check_special_filename): Replaced is isdigit by digitp
+       to avoid passing negative values and potential locale problems.
+       Problem noted by Christian Biere.
+
+       * util.h (ascii_isspace): New.
+
 2003-09-18  Werner Koch  <wk@gnupg.org>
 
        * ttyio.c (tty_fprintf): New.
index 773e299..4d73539 100644 (file)
@@ -101,7 +101,7 @@ typedef struct close_cache_s *CLOSE_CACHE;
 static CLOSE_CACHE close_cache;
 #endif
 
-#ifdef __MINGW32__
+#ifdef _WIN32
 typedef struct
 {
   int sock;
@@ -112,7 +112,7 @@ typedef struct
   char fname[1];               /* name of the file */
 }
 sock_filter_ctx_t;
-#endif /*__MINGW32__*/
+#endif /*_WIN32*/
 
 /* The first partial length header block must be of size 512
  * to make it easier (and efficienter) we use a min. block size of 512
@@ -580,7 +580,7 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf,
   return rc;
 }
 
-#ifdef __MINGW32__
+#ifdef _WIN32
 /* Becuase sockets are an special object under Lose32 we have to
  * use a special filter */
 static int
@@ -667,7 +667,7 @@ sock_filter (void *opaque, int control, iobuf_t chain, byte * buf,
     }
   return rc;
 }
-#endif /*__MINGW32__*/
+#endif /*_WIN32*/
 
 /****************
  * This is used to implement the block write mode.
@@ -1171,7 +1171,7 @@ check_special_filename (const char *fname)
       int i;
 
       fname += 2;
-      for (i = 0; isdigit (fname[i]); i++)
+      for (i = 0; digitp (fname+i); i++)
        ;
       if (!fname[i])
        return atoi (fname);
@@ -1262,7 +1262,7 @@ iobuf_t
 iobuf_sockopen (int fd, const char *mode)
 {
   iobuf_t a;
-#ifdef __MINGW32__
+#ifdef _WIN32
   sock_filter_ctx_t *scx;
   size_t len;
 
@@ -1405,7 +1405,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
            b->keep_open = intval;
            return 0;
          }
-#ifdef __MINGW32__
+#ifdef _WIN32
        else if (!a->chain && a->filter == sock_filter)
          {
            sock_filter_ctx_t *b = a->filter_ov;
@@ -1440,7 +1440,7 @@ iobuf_ioctl (iobuf_t a, int cmd, int intval, void *ptrval)
            b->no_cache = intval;
            return 0;
          }
-#ifdef __MINGW32__
+#ifdef _WIN32
        else if (!a->chain && a->filter == sock_filter)
          {
            sock_filter_ctx_t *b = a->filter_ov;
@@ -2363,7 +2363,7 @@ iobuf_read_line (iobuf_t a, byte ** addr_of_buffer,
 int
 iobuf_translate_file_handle (int fd, int for_write)
 {
-#ifdef __MINGW32__
+#ifdef _WIN32
   {
     int x;
 
@@ -2387,7 +2387,7 @@ iobuf_translate_file_handle (int fd, int for_write)
 static int
 translate_file_handle (int fd, int for_write)
 {
-#ifdef __MINGW32__
+#ifdef _WIN32
 #ifdef FILE_FILTER_USES_STDIO
   fd = iobuf_translate_file_handle (fd, for_write);
 #else
index c77b4a8..eab805e 100644 (file)
@@ -37,7 +37,7 @@
 #define HAVE_TCGETATTR
 #endif
 #endif
-#ifdef __MINGW32__ /* use the odd Win32 functions */
+#ifdef _WIN32 /* use the odd Win32 functions */
 #include <windows.h>
 #ifdef HAVE_TCGETATTR
 #error mingw32 and termios
@@ -51,7 +51,7 @@
 
 #define CONTROL_D ('D' - 'A' + 1)
 
-#ifdef __MINGW32__ /* use the odd Win32 functions */
+#ifdef _WIN32 /* use the odd Win32 functions */
 static struct {
     HANDLE in, out;
 } con;
@@ -124,7 +124,7 @@ init_ttyfp(void)
     if( initialized )
        return;
 
-#if defined(__MINGW32__)
+#if defined(_WIN32)
     {
        SECURITY_ATTRIBUTES sa;
 
@@ -194,7 +194,7 @@ tty_printf( const char *fmt, ... )
        init_ttyfp();
 
     va_start( arg_ptr, fmt ) ;
-#ifdef __MINGW32__
+#ifdef _WIN32
     {   
         char *buf = NULL;
         int n;
@@ -241,7 +241,7 @@ tty_fprintf (FILE *fp, const char *fmt, ... )
     init_ttyfp();
 
     va_start( arg_ptr, fmt ) ;
-#ifdef __MINGW32__
+#ifdef _WIN32
     {   
         char *buf = NULL;
         int n;
@@ -278,7 +278,7 @@ tty_print_string ( const byte *p, size_t n )
     if( !initialized )
        init_ttyfp();
 
-#ifdef __MINGW32__
+#ifdef _WIN32
     /* not so effective, change it if you want */
     for( ; n; n--, p++ )
        if( iscntrl( *p ) ) {
@@ -372,7 +372,7 @@ do_get( const char *prompt, int hidden )
     buf = xmalloc((n=50));
     i = 0;
 
-#ifdef __MINGW32__ /* windoze version */
+#ifdef _WIN32 /* windoze version */
     if( hidden )
        SetConsoleMode(con.in, HID_INPMODE );
 
@@ -527,7 +527,7 @@ tty_kill_prompt()
        last_prompt_len = 0;
     if( !last_prompt_len )
        return;
-#ifdef __MINGW32__
+#ifdef _WIN32
     tty_printf("\r%*s\r", last_prompt_len, "");
 #else
     {
index 0458514..78aa2f8 100644 (file)
@@ -107,6 +107,10 @@ int asprintf (char **result, const char *format, ...);
 #define hexdigitp(a) (digitp (a)                     \
                       || (*(a) >= 'A' && *(a) <= 'F')  \
                       || (*(a) >= 'a' && *(a) <= 'f'))
+  /* Note this isn't identical to a C locale isspace() without \f and
+     \v, but works for the purposes used here. */
+#define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
+
 /* the atoi macros assume that the buffer has only valid digits */
 #define atoi_1(p)   (*(p) - '0' )
 #define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1))
index 4ee1898..23baee4 100644 (file)
@@ -647,7 +647,17 @@ AC_CHECK_SIZEOF(unsigned short)
 AC_CHECK_SIZEOF(unsigned int)
 AC_CHECK_SIZEOF(unsigned long)
 AC_CHECK_SIZEOF(unsigned long long)
-AC_CHECK_SIZEOF(uint64_t)
+# Ensure that we have UINT64_C before we bother to check for uint64_t
+# fixme: really needed in gnupg?  I think it is only useful in libcgrypt.
+AC_CACHE_CHECK([for UINT64_C],[gnupg_cv_uint64_c_works],
+   AC_COMPILE_IFELSE(AC_LANG_PROGRAM([#include <inttypes.h>
+uint64_t foo=UINT64_C(42);]),gnupg_cv_uint64_c_works=yes,gnupg_cv_uint64_c_works=no))
+if test "$gnupg_cv_uint64_c_works" = "yes" ; then
+   AC_CHECK_SIZEOF(uint64_t)
+fi
+
+
 
 if test "$ac_cv_sizeof_unsigned_short" = "0" \
    || test "$ac_cv_sizeof_unsigned_int" = "0" \
@@ -660,19 +670,8 @@ if test "$ac_cv_sizeof_unsigned_int" != "8" \
    && test "$ac_cv_sizeof_unsigned_long" != "8" \
    && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
    && test "$ac_cv_sizeof_uint64_t" != "8"; then
-    AC_MSG_WARN([No 64-bit types.  Disabling TIGER/192, SHA-384, and SHA-512])
+    AC_MSG_WARN([No 64-bit types.  Disabling SHA-384, and SHA-512])
 else
-  if test x"$use_tiger192" = xyes ; then
-     AC_SUBST(TIGER_O,tiger.o)
-     AC_DEFINE(USE_TIGER192,1,[Define to include the TIGER/192 digest])
-  fi
-
-  if test "$use_old_tiger192" = yes ; then
-     AC_SUBST(TIGER_O,tiger.o)
-     AC_DEFINE(USE_TIGER192,1,[Define to include the TIGER/192 digest])
-     AC_DEFINE(USE_OLD_TIGER,1,[Define to use the old fake OID for TIGER/192 digest support])
-  fi
-
   if test x"$use_sha512" = xyes ; then
      AC_SUBST(SHA512_O,sha512.o)
      AC_DEFINE(USE_SHA512,1,[Define to include the SHA-384 and SHA-512 digests])
@@ -689,9 +688,11 @@ AC_CHECK_FUNCS(strerror stpcpy strsep strlwr tcgetattr strtoul mmap)
 AC_CHECK_FUNCS(strcasecmp strncasecmp ctermid times)
 AC_CHECK_FUNCS(memmove gettimeofday getrusage setrlimit clock_gettime)
 AC_CHECK_FUNCS(atexit raise getpagesize strftime nl_langinfo setlocale)
-AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat)
+AC_CHECK_FUNCS(waitpid wait4 sigaction sigprocmask rand pipe stat getaddrinfo)
+
+AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include <signal.h>])
 
-# These are needed by libjnlib - fixme: we should have macros for them
+# These are needed by libjnlib - fixme: we should have macros for them
 AC_CHECK_FUNCS(memicmp stpcpy strlwr strtoul memmove stricmp strtol)
 AC_CHECK_FUNCS(getrusage setrlimit stat setlocale)
 AC_CHECK_FUNCS(flockfile funlockfile)
@@ -703,6 +704,8 @@ AC_REPLACE_FUNCS(fseeko ftello)
 AC_REPLACE_FUNCS(isascii)
 AC_REPLACE_FUNCS(putc_unlocked)
 
+
+
 #
 # check for gethrtime and run a testprogram to see whether
 # it is broken.  It has been reported that some Solaris and HP UX systems 
@@ -877,7 +880,7 @@ GNUPG_CHECK_GNUMAKE
 # mysterious reasons - the final link step should bail out. 
 case "${target}" in
     *-*-mingw32*)
-        LIBS="$LIBS -lwsock32"
+        W32LIBS="-lwsock32"
         ;;
     *)
        ;;
@@ -893,6 +896,7 @@ if test "$GCC" = yes; then
 fi
 
 AC_SUBST(NETLIBS)
+AC_SUBST(W32LIBS)
 
 
 # We use jnlib, so tell other modules about it
index 221961c..ac7a694 100644 (file)
@@ -1,3 +1,267 @@
+2003-09-23  Werner Koch  <wk@gnupg.org>
+
+       Merged most of David Shaw's changes in 1.3 since 2003-06-03.
+       
+       * Makefile.am: Include W32LIBS where appropriate.
+
+       * armor.c (parse_hash_header,armor_filter): Drop TIGER/192 support.
+       * g10.c (print_hex,print_mds): Ditto.
+       * pkclist.c (algo_available): Ditto.
+
+       * armor.c (armor_filter): Allow using --comment multiple times to
+       get multiple Comment header lines.  --no-comments resets list.
+       * options.h, g10.c (main): Ditto. Deprecate --default-comment in
+       favor of --no-comments.
+
+       * g10.c (main): Trim --help to commonly used options.  Remove -f.
+
+       * g10.c (main): Add --multifile as an alias to turn --encrypt into
+       --encrypt-files (plus --verify-files, --decrypt-files).  Error out
+       if --multifile is used with the commands that don't support it yet.
+
+       * encode.c (use_mdc), g10.c (main): Use RFC1991 and RFC2440
+       directly to check for MDC usability.  Do not set the force_mdc or
+       disable_mdc flags since there is no point any longer.
+       
+       * g10.c (main): Use "keyserver-url" instead of
+       "preferred-keyserver" for the sake of short and simple commands.
+       (add_keyserver_url): Clarify a few strings.  It's a
+       "preferred keyserver URL".
+       * keyedit.c (keyedit_menu): Ditto.
+       * sign.c (mk_notation_policy_etc): Ditto. 
+
+       * main.h, keygen.c (keygen_add_keyserver_url): Signature callback
+       for adding a keyserver URL.
+       * keyedit.c (keyedit_menu, menu_set_keyserver_url): New command to
+       set preferred keyserver to specified (or all) user IDs.
+       * build-packet.c (build_sig_subpkt): Set preferred keyserver flag
+       while building a preferred keyserver subpacket.
+
+       * keylist.c (show_policy_url, show_keyserver_url): URLs might be
+       UTF8.
+
+       * keyedit.c (menu_addrevoker): Fix leaking a few bytes.
+
+       * keyedit.c (show_key_with_all_names): Use list-option
+       show-long-keyid in main --edit-key display.
+
+       * keyedit.c (print_and_check_one_sig): Use list-option
+       show-long-keyid in --edit-key "check" function.
+
+       * passphrase.c (agent_send_all_options): Make use of $GPG_TTY.
+
+       * g10.c (main): Disable use-agent if passphrase-fd is given
+       later. Suggested by Kurt Garloff.
+
+       * exec.c, g10.c, gpgv.c, passphrase.c, photoid.c:
+       s/__MINGW32__/_WIN32/ to help building on native Windows
+       compilers.  Requested by Brian Gladman.  From Werner on stable
+       branch.
+
+       * options.h, g10.c (main): Add list-option
+       list-preferred-keyserver.
+
+       * keyedit.c (change_passphrase): When responding 'no' to the blank
+       passphrase question, re-prompt for a new passphrase.  This is bug
+       #202.
+
+       * mainproc.c (check_sig_and_print): Use two different preferred
+       keyserver displays - one if the key is not present (to tell the
+       user where to get the key), the other if it is present (to tell
+       the user where the key can be refreshed).
+
+       * packet.h, parse-packet.c (parse_signature): Set flag if a
+       preferred keyserver is present.
+
+       * keylist.c (list_keyblock_print): Show keyserver url in listings
+       with list-option show-keyserver-url.
+
+       * mainproc.c (check_sig_and_print): Get the uid validity before
+       printing any sig results to avoid munging the output with trustdb
+       warnings.
+
+       * g10.c (main): Don't include --show-keyring in --help as it is
+       deprecated.
+
+       * options.skel: Note that keyserver.pgp.com isn't synchronized,
+       and explain the roundrobin a bit better.
+
+       * sig-check.c (check_key_signature2), import.c (import_one,
+       import_revoke_cert, chk_self_sigs, delete_inv_parts,
+       collapse_uids, merge_blocks): Make much quieter during import of
+       slightly munged, but recoverable, keys. Use log_error for
+       unrecoverable import failures.
+
+       * keyring.c (keyring_rebuild_cache): Comment.
+
+       * sign.c (mk_notation_and_policy): Making a v3 signature with
+       notations or policy urls is an error, not an info (i.e. increment
+       the errorcount). Don't print the notation or policy url to stdout
+       since it can be mixed into the output stream when piping and munge
+       the stream.
+
+       * packet.h, sig-check.c (signature_check2, do_check,
+       do_check_messages): Provide a signing-key-is-revoked flag.  Change
+       all callers.
+
+       * status.h, status.c (get_status_string): New REVKEYSIG status tag
+       for a good signature from a revoked key.
+
+       * mainproc.c (do_check_sig, check_sig_and_print): Use it here.
+
+       * import.c (import_revoke_cert, merge_blocks, merge_sigs): Compare
+       actual signatures on import rather than using keyid or class
+       matching.  This does not change actual behavior with a key, but
+       does mean that all sigs are imported whether they will be used or
+       not.
+
+       * parse-packet.c (parse_signature): Don't give "signature packet
+       without xxxx" warnings for experimental pk algorithms.  An
+       experimental algorithm may not have a notion of (for example) a
+       keyid (i.e. PGP's x.509 stuff).
+
+       * options.h, g10.c (main), keylist.c (list_keyblock_print),
+       keyedit.c (print_and_check_one_sig): New "show-sig-expire"
+       list-option to show signature expiration dates (if any).
+
+       * options.h, g10.c (main, add_keyserver_url): Add
+       --sig-preferred-keyserver to implant a "where to get my key"
+       subpacket into a signature.
+
+       * sign.c (mk_notation_and_policy): Rename to
+       mk_notation_policy_etc and add preferred keyserver support for
+       signatures.
+
+       * keygen.c (do_add_key_flags): Don't set the certify flag for
+       subkeys.
+       (ask_algo): Provide key flags for DSA, Elgamal_e, and Elgamal
+       subkeys.
+       (generate_keypair): Provide key flags for the default DSA/Elgamal
+       keys.
+
+       * sig-check.c (signature_check, signature_check2,
+       check_key_signature, check_key_signature2): Allow passing NULLs
+       for unused parameters in the x2 form of each function to avoid the
+       need for dummy variables. getkey.c, mainproc.c: Change all
+       callers.
+
+       * trustdb.h, trustdb.c (read_trust_options): New.  Returns items
+       from the trustdb version record.
+       * keylist.c (public_key_list): Use it here for the new "tru"
+       record.
+       * gpgv.c (read_trust_options): Stub.
+
+       * keyedit.c (show_key_with_all_names): Use list-option
+       show-validity in --edit-key interface as well.
+
+       * options.h, g10.c (main), mainproc.c (check_sig_and_print): Add
+       verify-options "show-validity" and "show-long-keyid" to show
+       trustdb validity and long keyids during (file) signature
+       verification.
+
+       * packet.h, main.h, sig-check.c (signature_check2)
+       (check_key_signature2, do_check): If ret_pk is set, fill in the pk
+       used to verify the signature.  Change all callers in getkey.c,
+       mainproc.c, and sig-check.c.
+
+       * keylist.c (list_keyblock_colon): Use the ret_pk from above to
+       put the fingerprint of the signing key in "sig" records during a
+       --with-colons --check-sigs.  This requires --no-sig-cache as well
+       since we don't cache fingerprints.
+
+       * parse-packet.c (parse_signature): No need to reserve 8 bytes for
+       the unhashed signature cache any longer.
+
+       * misc.c (pct_expando): Add two new expandos - signer's
+       fingerprint (%g), and signer's primary fingerprint (%p).
+
+       * g10.c (main): Add --rfc2440 alias for --openpgp since in a few
+       months, they won't be the same thing.
+
+       * keyserver.c (parse_keyserver_uri): Accept "http" as an alias for
+       "hkp", since it is occasionally written that way.
+       (keyserver_spawn): Use ascii_isspace to avoid locale issues.
+
+       * keygen.c (ask_user_id): Make --allow-freeform-uid apply to the
+       email field as well as the name field, and allow mixing fields
+       when it is set.
+
+       * trustdb.c (validate_one_keyblock): Certifications on revoked or
+       expired uids do not count in the web of trust.
+
+       * signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
+       sigprocmask() if we have sigset_t, and only use sigaction() if we
+       have struct sigaction.  This is for Forte c89 on Solaris which
+       seems to define only the function call half of the two pairs by
+       default.
+       (pause_on_sigusr): Typo.
+       (do_block): If we can't use sigprocmask() and sigset_t, try to get
+       the number of signals from NSIG as well as MAXSIG, and if we
+       can't, fail with an explanation.
+
+       * signal.c, tdbio.c: Comment out the transaction code.  It was not
+       used in this version, and was causing some build problems on
+       quasi-posix platforms (Solaris and Forte c89).
+
+       * keylist.c (list_keyblock_colon): Don't include validity values
+       when listing secret keys since they can be incorrect and/or
+       misleading.  This is a temporary kludge, and will be handled
+       properly in 1.9/2.0.
+
+       * mainproc.c (check_sig_and_print): Only show the "key available
+       from" preferred keyserver line if the key is not currently
+       present.
+
+       * keyedit.c (sign_uids): Do not sign expired uids without --expert
+       (same behavior as revoked uids).  Do not allow signing a user ID
+       without a self-signature.  --expert overrides.  Add additional
+       prompt to the signature level question.
+       (menu_expire): When changing expiration dates, don't replace
+       selfsigs on revoked uids since this would effectively unrevoke
+       them. There is also no point in replacing expired selfsigs.  This
+       is bug #181
+
+       * g10.c (add_notation_data): Make sure that only ascii is passed
+       to iscntrl.  Noted by Christian Biere.
+       * getkey.c (classify_user_id2): Replaced isspace by spacep
+       * keygen.c (ask_user_id): Ditto.
+       (get_parameter_algo): Ditto.
+       * keyedit.c (keyedit_menu): Ditto.
+       * tdbdump.c (import_ownertrust): Ditto.  s/isxdigit/hexdigitp/.
+       * revoke.c (ask_revocation_reason): 
+       * keyserver.c (keyserver_spawn): Dito.
+
+       * parse-packet.c (parse): Disallow old style partial length for
+       all key material packets to avoid possible corruption of keyrings.
+
+       * import.c (import_keys_internal): Invalidate the cache so that
+       the file descriptor gets closed.  Fixes bug reported by Juan
+       F. Codagnone.
+
+       * options.h, g10.c (main), main.h, keylist.c (show_keyserver_url),
+       mainproc.c (check_sig_and_print), parse-packet.c (dump_sig_subpkt,
+       parse_one_sig_subpkt, can_handle_critical): Add read-only support
+       for preferred keyserver subpackets.  They're basically policy URLs
+       with a different name.  Add a verify-option
+       "show-preferred-keyserver" to turn them on and off (on by default,
+       as per stable branch).
+
+       * g10.c (main): Add "--set-notation" as alias to "--notation-data"
+       this is to make things consistent with --set-policy-url meaning
+       both sigs and certs.
+
+       * options.h, g10.c (main), keylist.c (list_keyblock_print): Add
+       "show-validity" and "show-long-keyid" list-options.
+
+       * gpgv.c (get_validity, trust_value_to_string): Stubs.
+
+       * g10.c (main): Use SAFE_VERSION instead of VERSION in the
+       version-specific gpg.conf file so it can be overridden on RISCOS.
+
+       * keyedit.c (show_key_with_all_names): Fix assertion failure when
+       using toggle to see a secret key.  Reported by Maxim Britov.
+
+
 2003-09-22  Timo Schulz  <twoaday@freakmail.de>
 
        * card-util.c (card_status): Free pk in case of an error
index 59213d0..ef2b0c3 100644 (file)
@@ -109,7 +109,7 @@ gpgv2_SOURCES = gpgv.c           \
 #             ks-db.h \
 #             $(common_source)
 
-LDADD =  $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ 
+LDADD =  $(needed_libs) @INTLLIBS@ @CAPLIBS@ @ZLIBS@ @W32LIBS@
 gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error
 gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error
 
index c6930e2..121ec3a 100644 (file)
@@ -249,16 +249,12 @@ parse_hash_header( const char *line )
            found |= 2;
        else if( !strncmp( s, "MD5", s2-s ) )
            found |= 4;
-       else if( !strncmp( s, "TIGER192", s2-s ) )
-           found |= 8;
-       else if( !strncmp( s, "TIGER", s2-s ) ) /* used by old versions */
-           found |= 8;
        else if( !strncmp( s, "SHA256", s2-s ) )
-           found |= 16;
+           found |= 8;
        else if( !strncmp( s, "SHA384", s2-s ) )
-           found |= 32;
+           found |= 16;
        else if( !strncmp( s, "SHA512", s2-s ) )
-           found |= 64;
+           found |= 32;
        else
            return 0;
        for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
@@ -899,12 +895,10 @@ armor_filter( void *opaque, int control,
                 if( hashes & 4 )
                     buf[n++] = DIGEST_ALGO_MD5;
                 if( hashes & 8 )
-                    buf[n++] = DIGEST_ALGO_TIGER;
-                if( hashes & 16 )
                     buf[n++] = DIGEST_ALGO_SHA256;
-                if( hashes & 32 )
+                if( hashes & 16 )
                     buf[n++] = DIGEST_ALGO_SHA384;
-                if( hashes & 64 )
+                if( hashes & 32 )
                     buf[n++] = DIGEST_ALGO_SHA512;
                 buf[1] = n - 2;
 
@@ -932,6 +926,7 @@ armor_filter( void *opaque, int control,
     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
        if( !afx->status ) { /* write the header line */
            const char *s;
+            STRLIST comment = opt.comments;
 
            if( afx->what >= DIM(head_strings) )
                log_bug("afx->what=%d", afx->what);
@@ -942,22 +937,24 @@ armor_filter( void *opaque, int control,
                iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
                                              PRINTABLE_OS_NAME ")" LF );
 
-           /* write the comment string or a default one */
-           s = opt.comment_string;
-           if( s && *s ) {
+           /* Write the comment string. */
+           for(s=comment? comment->d:NULL; comment;
+                comment=comment->next,s=comment->d)
+             {
                iobuf_writestr(a, "Comment: " );
-               for( ; *s; s++ ) {
+               for ( ; *s; s++ )
+                  {
                    if( *s == '\n' )
-                       iobuf_writestr(a, "\\n" );
+                      iobuf_writestr(a, "\\n" );
                    else if( *s == '\r' )
-                       iobuf_writestr(a, "\\r" );
+                      iobuf_writestr(a, "\\r" );
                    else if( *s == '\v' )
-                       iobuf_writestr(a, "\\v" );
+                      iobuf_writestr(a, "\\v" );
                    else
-                       iobuf_put(a, *s );
-               }
+                      iobuf_put(a, *s );
+                  }
                iobuf_writestr(a, LF );
-           }
+              }
 
            if ( afx->hdrlines ) {
                 for ( s = afx->hdrlines; *s; s++ ) {
index a24bdfc..d2c5384 100644 (file)
@@ -756,6 +756,10 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type,
        sig->flags.policy_url=1;
        break;
 
+      case SIGSUBPKT_PREF_KS:
+       sig->flags.pref_ks=1;
+       break;
+
       case SIGSUBPKT_EXPORTABLE:
        if(buffer[0])
          sig->flags.exportable=1;
index 9fc0018..7794bdb 100644 (file)
@@ -122,6 +122,10 @@ use_mdc (PK_LIST pk_list,int algo)
     CIPHER_ALGO_TWOFISH
   };
   int i;
+
+  /* RFC-1991 and 2440 don't have MDC */
+  if(RFC1991 || RFC2440)
+    return 0;
   
   /* --force-mdc overrides --disable-mdc */
   if (opt.force_mdc)
index f3b58aa..a49fe15 100644 (file)
@@ -1,5 +1,5 @@
 /* exec.c - generic call-a-program code
- * Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -59,7 +59,7 @@ int set_exec_path(const char *path,int method) { return GPG_ERR_GENERAL; }
 char *mkdtemp(char *template);
 #endif
 
-#if defined (__MINGW32__)
+#if defined (_WIN32)
 /* This is a nicer system() for windows that waits for programs to
    return before returning control to the caller.  I hate helpful
    computers. */
@@ -139,7 +139,7 @@ static int make_tempdir(struct exec_info *info)
 
   if(tmp==NULL)
     {
-#if defined (__MINGW32__)
+#if defined (_WIN32)
       tmp=xmalloc (256);
       if(GetTempPath(256,tmp)==0)
        strcpy(tmp,"c:\\windows\\temp");
@@ -176,7 +176,7 @@ static int make_tempdir(struct exec_info *info)
 
   sprintf(info->tempdir,"%s" DIRSEP_S "gpg-XXXXXX",tmp);
 
-#if defined (__MINGW32__)
+#if defined (_WIN32)
   xfree (tmp);
 #endif
 
@@ -502,7 +502,7 @@ int exec_read(struct exec_info *info)
       if(DBG_EXTPROG)
        log_debug("system() command is %s\n",info->command);
 
-#if defined (__MINGW32__)
+#if defined (_WIN32)
       info->progreturn=win_system(info->command);
 #else
       info->progreturn=system(info->command);
index 6198323..cdd10d8 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -59,7 +59,6 @@ enum cmd_and_opt_values { aNull = 0,
     aSym         = 'c',
     aDecrypt     = 'd',
     aEncr        = 'e',
-    aEncrFiles,
     oInteractive  = 'i',
     aListKeys    = 'k',
     aListSecretKeys = 'K',
@@ -73,12 +72,13 @@ enum cmd_and_opt_values { aNull = 0,
     oUser        = 'u',
     oVerbose     = 'v',
     oCompress    = 'z',
-    oNotation    = 'N',
+    oSetNotation  = 'N',
     oBatch       = 500,
     oSigNotation,
     oCertNotation,
     oShowNotation,
     oNoShowNotation,
+    aEncrFiles,
     aDecryptFiles,                          
     aClearsign,
     aStore,
@@ -172,6 +172,7 @@ enum cmd_and_opt_values { aNull = 0,
     oLoadExtension,
     oGnuPG,
     oRFC1991,
+    oRFC2440,
     oOpenPGP,
     oPGP2,
     oPGP6,
@@ -219,9 +220,11 @@ enum cmd_and_opt_values { aNull = 0,
     oCertPolicyURL,
     oShowPolicyURL,
     oNoShowPolicyURL,
+    oSigKeyserverURL,
     oUseEmbeddedFilename,
     oComment,
     oDefaultComment,
+    oNoComments,
     oThrowKeyid,
     oNoThrowKeyid,
     oShowPhotos,
@@ -315,6 +318,7 @@ enum cmd_and_opt_values { aNull = 0,
     oMangleDosFilenames,
     oNoMangleDosFilenames,
     oEnableProgressFilter,                          
+    oMultifile,
 aTest };
 
 
@@ -326,17 +330,17 @@ static ARGPARSE_OPTS opts[] = {
     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
     { aEncr, "encrypt",   256, N_("encrypt data")},
-    { aEncrFiles, "encrypt-files", 256, N_("|[files]|encrypt files")},
+    { aEncrFiles, "encrypt-files", 256, "@"},
     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
-    { aStore, "store",     256, N_("store only")},
+    { aStore, "store",     256, "@"},
     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
-    { aDecryptFiles, "decrypt-files", 256, N_("|[files]|decrypt files")},
+    { aDecryptFiles, "decrypt-files", 256, "@"},
     { aVerify, "verify"   , 256, N_("verify a signature")},
     { aVerifyFiles, "verify-files" , 256, "@" },
     { aListKeys, "list-keys", 256, N_("list keys")},
     { aListKeys, "list-public-keys", 256, "@" },
     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
-    { aCheckKeys, "check-sigs",256, N_("check key signatures")},
+    { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
     { aKeygen,    "gen-key",  256, N_("generate a new key pair")},
@@ -345,8 +349,8 @@ static ARGPARSE_OPTS opts[] = {
                                    N_("remove keys from the secret keyring")},
     { aSignKey,  "sign-key"   ,256, N_("sign a key")},
     { aLSignKey, "lsign-key"  ,256, N_("sign a key locally")},
-    { aNRSignKey, "nrsign-key"  ,256, N_("sign a key non-revocably")},
-    { aNRLSignKey, "nrlsign-key"  ,256, N_("sign a key locally and non-revocably")},
+    { aNRSignKey, "nrsign-key"  ,256, "@"},
+    { aNRLSignKey, "nrlsign-key"  ,256, "@"},
     { aEditKey,  "edit-key"   ,256, N_("sign or edit a key")},
     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
     { aDesigRevoke, "desig-revoke",256, "@" },
@@ -366,19 +370,15 @@ static ARGPARSE_OPTS opts[] = {
     { aCardEdit,   "card-edit",  256, N_("change data on a card")},
     { aChangePIN,  "change-pin", 256, N_("change a card's PIN")},
 
-    { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
-    { aExportOwnerTrust,
-             "export-ownertrust", 256, N_("export the ownertrust values")},
-    { aImportOwnerTrust,
-             "import-ownertrust", 256, N_("import ownertrust values")},
-    { aUpdateTrustDB,
-             "update-trustdb",0 , N_("update the trust database")},
-    { aCheckTrustDB,
-             "check-trustdb",0 , N_("unattended trust database update")},
+    { aListPackets, "list-packets",256, "@"},
+    { aExportOwnerTrust, "export-ownertrust", 256, "@"},
+    { aImportOwnerTrust, "import-ownertrust", 256, "@"},
+    { aUpdateTrustDB, "update-trustdb",0 , N_("update the trust database")},
+    { aCheckTrustDB,  "check-trustdb",0 , "@"},
     { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
-    { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
+    { aDeArmor, "dearmor", 256, "@" },
     { aDeArmor, "dearmour", 256, "@" },
-    { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
+    { aEnArmor, "enarmor", 256, "@" },
     { aEnArmor, "enarmour", 256, "@" },
     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
     { aPrimegen, "gen-prime" , 256, "@" },
@@ -391,10 +391,8 @@ static ARGPARSE_OPTS opts[] = {
     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
     { oHiddenRecipient, "hidden-recipient", 2, "@" },
     { oRecipient, "remote-user", 2, "@"},  /* old option name */
-    { oDefRecipient, "default-recipient" ,2,
-                                 N_("|NAME|use NAME as default recipient")},
-    { oDefRecipientSelf, "default-recipient-self" ,0,
-                               N_("use the default key as default recipient")},
+    { oDefRecipient, "default-recipient" ,2, "@" },
+    { oDefRecipientSelf, "default-recipient-self" ,0, "@" },
     { oNoDefRecipient, "no-default-recipient", 0, "@" },
     { oTempDir, "temp-directory", 2, "@" },
     { oExecPath, "exec-path", 2, "@" },
@@ -414,82 +412,82 @@ static ARGPARSE_OPTS opts[] = {
     { oNoAskCertExpire, "no-ask-cert-expire",   0, "@"},
     { oOutput, "output",    2, N_("use as output file")},
     { oVerbose, "verbose",   0, N_("verbose") },
-    { oQuiet,  "quiet",   0, N_("be somewhat more quiet") },
-    { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
-    { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
-    { oNoForceV3Sigs, "no-force-v3-sigs", 0, N_("do not force v3 signatures") },
-    { oForceV4Certs, "force-v4-certs", 0, N_("force v4 key signatures") },
-    { oNoForceV4Certs, "no-force-v4-certs", 0, N_("do not force v4 key signatures") },
-    { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
+    { oQuiet,  "quiet",     0, "@" },
+    { oNoTTY,   "no-tty",    0, "@" },
+    { oForceV3Sigs, "force-v3-sigs", 0, "@" },
+    { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@" },
+    { oForceV4Certs, "force-v4-certs", 0, "@" },
+    { oNoForceV4Certs, "no-force-v4-certs", 0, "@" },
+    { oForceMDC, "force-mdc", 0, "@" },
     { oNoForceMDC, "no-force-mdc", 0, "@" },
-    { oDisableMDC, "disable-mdc", 0, N_("never use a MDC for encryption") },
+    { oDisableMDC, "disable-mdc", 0, "@" },
     { oNoDisableMDC, "no-disable-mdc", 0, "@" },
     { oDryRun, "dry-run",   0, N_("do not make any changes") },
     { oInteractive, "interactive", 0, N_("prompt before overwriting") },
-    { oUseAgent, "use-agent",0, N_("use the gpg-agent")},
+    { oUseAgent, "use-agent",0, "@"},
     { oNoUseAgent, "no-use-agent",0, "@"},
     { oGpgAgentInfo, "gpg-agent-info",2, "@"},
-    { oBatch, "batch",     0, N_("batch mode: never ask")},
-    { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
-    { oAnswerNo,  "no",        0, N_("assume no on most questions")},
-    { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
+    { oBatch, "batch",     0, "@"},
+    { oAnswerYes, "yes",       0, "@"},
+    { oAnswerNo,  "no",        0, "@"},
+    { oKeyring, "keyring"   ,  2, "@"},
     { oPrimaryKeyring, "primary-keyring",2, "@" },
-    { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
-    { oShowKeyring, "show-keyring", 0, N_("show which keyring a listed key is on")},
-    { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
-    { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
+    { oSecretKeyring, "secret-keyring" ,2, "@"},
+    { oShowKeyring, "show-keyring", 0, "@"},
+    { oDefaultKey, "default-key" ,  2, "@"},
+    { oKeyServer, "keyserver",      2, "@"},
     { oKeyServerOptions, "keyserver-options",2,"@"},
     { oImportOptions, "import-options",2,"@"},
     { oExportOptions, "export-options",2,"@"},
     { oListOptions, "list-options",2,"@"},
-    { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
-    { oOptions, "options"   , 2, N_("read options from file")},
+    { oVerifyOptions, "verify-options",2,"@"},
+    { oCharset, "charset"   , 2, "@" },
+    { oOptions, "options"   , 2, "@"},
 
     { oDebug, "debug"     ,4|16, "@"},
     { oDebugAll, "debug-all" ,0, "@"},
-    { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
+    { oStatusFD, "status-fd" ,1, "@" },
 #ifdef __riscos__
-    { oStatusFile, "status-file" ,2, N_("|[file]|write status info to file") },
+    { oStatusFile, "status-file" ,2, "@" },
 #endif /* __riscos__ */
     { oAttributeFD, "attribute-fd" ,1, "@" },
 #ifdef __riscos__
     { oAttributeFile, "attribute-file" ,2, "@" },
 #endif /* __riscos__ */
-    { oNoSKComments, "no-comment", 0,   "@"},
     { oNoSKComments, "no-sk-comments", 0,   "@"},
     { oSKComments, "sk-comments", 0,   "@"},
     { oCompletesNeeded, "completes-needed", 1, "@"},
     { oMarginalsNeeded, "marginals-needed", 1, "@"},
     { oMaxCertDepth,   "max-cert-depth", 1, "@" },
-    { oTrustedKey, "trusted-key", 2, N_("|KEYID|ultimately trust this key")},
-    { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
+    { oTrustedKey, "trusted-key", 2, "@"},
+    { oLoadExtension, "load-extension" ,2, "@"},
     { oGnuPG, "gnupg",   0, "@"},
     { oGnuPG, "no-pgp2", 0, "@"},
     { oGnuPG, "no-pgp6", 0, "@"},
     { oGnuPG, "no-pgp7", 0, "@"},
     { oGnuPG, "no-pgp8", 0, "@"},
-    { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
-    { oOpenPGP, "openpgp", 0, N_("set all packet, cipher and digest options to OpenPGP behavior")},
-    { oPGP2, "pgp2", 0, N_("set all packet, cipher and digest options to PGP 2.x behavior")},
+    { oRFC1991, "rfc1991",   0, "@"},
+    { oRFC2440, "rfc2440",   0, "@"},
+    { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
+    { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
     { oPGP6, "pgp6", 0, "@"},
     { oPGP7, "pgp7", 0, "@"},
     { oPGP8, "pgp8", 0, "@"},
-    { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
-    { oS2KDigest, "s2k-digest-algo",2,
-               N_("|NAME|use message digest algorithm NAME for passphrases")},
-    { oS2KCipher, "s2k-cipher-algo",2,
-               N_("|NAME|use cipher algorithm NAME for passphrases")},
+    { oS2KMode, "s2k-mode",  1, "@"},
+    { oS2KDigest, "s2k-digest-algo",2, "@"},
+    { oS2KCipher, "s2k-cipher-algo",2, "@"},
     { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
-    { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
-    { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
+    { oCipherAlgo, "cipher-algo", 2 , "@"},
+    { oDigestAlgo, "digest-algo", 2 , "@"},
     { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
-    { oCompressAlgo,"compress-algo",2,N_("|NAME|use compression algorithm NAME")},
-    { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
+    { oCompressAlgo,"compress-algo",2, "@"},
+    { oThrowKeyid, "throw-keyid", 0,  "@"},
     { oNoThrowKeyid, "no-throw-keyid", 0, "@" },
     { oShowPhotos,   "show-photos", 0, "@" },
     { oNoShowPhotos, "no-show-photos", 0, "@" },
     { oPhotoViewer,  "photo-viewer", 2, "@" },
-    { oNotation,   "notation-data", 2, "@" },
+    { oSetNotation,  "set-notation", 2, "@" },
+    { oSetNotation,  "notation-data", 2, "@" }, /* Alias */
     { oSigNotation,   "sig-notation", 2, "@" },
     { oCertNotation,  "cert-notation", 2, "@" },
 
@@ -556,8 +554,10 @@ static ARGPARSE_OPTS opts[] = {
     { oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
     { oShowNotation, "show-notation", 0, "@" },
     { oNoShowNotation, "no-show-notation", 0, "@" },
+    { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
     { oComment, "comment", 2, "@" },
     { oDefaultComment, "default-comment", 0, "@" },
+    { oNoComments, "no-comments", 0, "@" },
     { oEmitVersion, "emit-version", 0, "@"},
     { oNoEmitVersion, "no-emit-version", 0, "@"},
     { oNoEmitVersion, "no-version", 0, "@"}, /* alias */
@@ -625,6 +625,7 @@ static ARGPARSE_OPTS opts[] = {
     { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
     { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
     { oEnableProgressFilter, "enable-progress-filter", 0, "@" },
+    { oMultifile, "multifile", 0, "@" },
 {0} };
 
 
@@ -641,6 +642,7 @@ static void set_cmd( enum cmd_and_opt_values *ret_cmd,
 static void print_mds( const char *fname, int algo );
 static void add_notation_data( const char *string, int which );
 static void add_policy_url( const char *string, int which );
+static void add_keyserver_url( const char *string, int which );
 static void emergency_cleanup (void);
 
 #ifdef __riscos__
@@ -1158,6 +1160,7 @@ main( int argc, char **argv )
     char *pers_digest_list = NULL;
     char *pers_compress_list = NULL;
     int eyes_only=0;
+    int multifile=0;
     int pwfd = -1;
     int with_fpr = 0; /* make an option out of --fingerprint */
     int any_explicit_recipient = 0;
@@ -1222,12 +1225,13 @@ main( int argc, char **argv )
     opt.keyserver_options.include_subkeys=1;
     opt.keyserver_options.include_revoked=1;
     opt.keyserver_options.try_dns_srv=1;
-    opt.verify_options=VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION;
+    opt.verify_options=
+      VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER;
     opt.trust_model=TM_AUTO;
     opt.mangle_dos_filenames = 1;
     opt.use_agent = 1;
 
-#if defined (__MINGW32__)
+#if defined (_WIN32)
     set_homedir ( read_w32_registry_string( NULL,
                                     "Software\\GNU\\GnuPG", "HomeDir" ));
 #else
@@ -1389,11 +1393,15 @@ main( int argc, char **argv )
          case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
          case aSym: set_cmd( &cmd, aSym); break;
 
+          case aDecryptFiles: multifile=1; /* fall through */
          case aDecrypt: set_cmd( &cmd, aDecrypt); break;
-          case aDecryptFiles: set_cmd( &cmd, aDecryptFiles); break;
 
+         case aEncrFiles: multifile=1; /* fall through */
          case aEncr: set_cmd( &cmd, aEncr); break;
-         case aEncrFiles: set_cmd( &cmd, aEncrFiles ); break;
+
+         case aVerifyFiles: multifile=1; /* fall through */
+         case aVerify: set_cmd( &cmd, aVerify); break;
+
          case aSign: set_cmd( &cmd, aSign );  break;
          case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
          case aSignKey: set_cmd( &cmd, aSignKey); break;
@@ -1405,8 +1413,7 @@ main( int argc, char **argv )
          case aClearsign: set_cmd( &cmd, aClearsign); break;
          case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
          case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
-         case aVerify: set_cmd( &cmd, aVerify); break;
-         case aVerifyFiles: set_cmd( &cmd, aVerifyFiles); break;
+
          case aPrimegen: set_cmd( &cmd, aPrimegen); break;
          case aGenRandom: set_cmd( &cmd, aGenRandom); break;
          case aPrintMD: set_cmd( &cmd, aPrintMD); break;
@@ -1564,7 +1571,7 @@ main( int argc, char **argv )
            break;
          case oLoadExtension:
 #ifndef __riscos__
-#if defined(USE_DYNAMIC_LINKING) || defined(__MINGW32__)
+#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
            if(check_permissions(pargs.r.ret_str,2))
              log_info(_("cipher extension \"%s\" not loaded due to "
                         "unsafe permissions\n"),pargs.r.ret_str);
@@ -1579,14 +1586,13 @@ main( int argc, char **argv )
          case oRFC1991:
            opt.compliance = CO_RFC1991;
            opt.force_v4_certs = 0;
-           opt.disable_mdc = 1;
            opt.escape_from = 1;
            break;
+          case oRFC2440:
          case oOpenPGP:
            /* TODO: When 2440bis becomes a RFC, these may need
                changing. */
            opt.compliance = CO_RFC2440;
-           opt.disable_mdc = 1;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
@@ -1627,9 +1633,19 @@ main( int argc, char **argv )
            opt.list_options&=~LIST_SHOW_POLICY;
            opt.verify_options&=~VERIFY_SHOW_POLICY;
            break;
+         case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
          case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
-         case oComment: opt.comment_string = pargs.r.ret_str; break;
-         case oDefaultComment: opt.comment_string = NULL; break;
+
+         case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break;
+         case oDefaultComment:
+           deprecated_warning(configname,configlineno,
+                              "--default-comment","--no-comments","");
+           /* fall through */
+         case oNoComments:
+           free_strlist(opt.comments);
+           opt.comments=NULL;
+           break;
+
          case oThrowKeyid: opt.throw_keyid = 1; break;
          case oNoThrowKeyid: opt.throw_keyid = 0; break;
          case oShowPhotos: 
@@ -1686,6 +1702,7 @@ main( int argc, char **argv )
          case oCompress: opt.compress = pargs.r.ret_int; break;
          case oPasswdFD:
             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
+            opt.use_agent = 0;
             break;
 #ifdef __riscos__
          case oPasswdFile:
@@ -1784,9 +1801,11 @@ main( int argc, char **argv )
                  {"show-photos",LIST_SHOW_PHOTOS},
                  {"show-policy-url",LIST_SHOW_POLICY},
                  {"show-notation",LIST_SHOW_NOTATION},
-                 {"show-keyring",LIST_SHOW_KEYRING},
+                  {"show-keyserver-url",LIST_SHOW_KEYSERVER},
                  {"show-validity",LIST_SHOW_VALIDITY},
                  {"show-long-keyid",LIST_SHOW_LONG_KEYID},
+                 {"show-keyring",LIST_SHOW_KEYRING},
+                  {"show-sig-expire",LIST_SHOW_SIG_EXPIRE},
                  {NULL,0}
                };
 
@@ -1807,6 +1826,9 @@ main( int argc, char **argv )
                  {"show-photos",VERIFY_SHOW_PHOTOS},
                  {"show-policy-url",VERIFY_SHOW_POLICY},
                  {"show-notation",VERIFY_SHOW_NOTATION},
+                 {"show-keyserver-url",VERIFY_SHOW_KEYSERVER},
+                 {"show-validity",VERIFY_SHOW_VALIDITY},
+                 {"show-long-keyid",VERIFY_SHOW_LONG_KEYID},
                  {NULL,0}
                };
 
@@ -1827,7 +1849,7 @@ main( int argc, char **argv )
            else
              opt.exec_path_set=1;
            break;
-         case oNotation:
+         case oSetNotation:
            add_notation_data( pargs.r.ret_str, 0 );
            add_notation_data( pargs.r.ret_str, 1 );
            break;
@@ -1931,6 +1953,7 @@ main( int argc, char **argv )
           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
 
           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
+          case oMultifile: multifile=1; break;
 
          default : pargs.err = configfp? 1:2; break;
        }
@@ -2053,8 +2076,6 @@ main( int argc, char **argv )
          compliance_failure();
        else
          {
-           opt.force_mdc = 0;
-           opt.disable_mdc = 1;
            opt.force_v4_certs = 0;
            opt.sk_comments = 0;
            opt.escape_from = 1;
@@ -2073,8 +2094,6 @@ main( int argc, char **argv )
        opt.escape_from=1;
        opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
-       opt.force_mdc=0;
-       opt.disable_mdc=1;
       }
     else if(PGP7)
       {
@@ -2170,6 +2189,37 @@ main( int argc, char **argv )
        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
       log_error(_("invalid personal compress preferences\n"));
 
+    /* We don't support all possible commands with multifile yet */
+    if(multifile)
+      {
+       char *cmdname;
+        
+       switch(cmd)
+         {
+         case aSign:
+           cmdname="--sign";
+           break;
+         case aClearsign:
+           cmdname="--clearsign";
+           break;
+         case aDetachedSign:
+           cmdname="--detach-sign";
+           break;
+         case aSym:
+           cmdname="--symmetric";
+           break;
+         case aStore:
+           cmdname="--store";
+           break;
+         default:
+           cmdname=NULL;
+           break;
+         }
+
+       if(cmdname)
+         log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
+      }
+
     if( log_get_errorcount(0) )
        g10_exit(2);
 
@@ -2262,8 +2312,7 @@ main( int argc, char **argv )
     if( cmd != aDeArmor && cmd != aEnArmor )
       {
         if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
-            && cmd != aVerify && cmd != aVerifyFiles
-            && cmd != aSym)
+            && cmd != aVerify && cmd != aSym)
           {
             if (!sec_nrings || default_keyring) /* add default secret rings */
               keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
@@ -2335,17 +2384,18 @@ main( int argc, char **argv )
        break;
 
       case aEncr: /* encrypt the given file */
-       if( argc > 1 )
-           wrong_args(_("--encrypt [filename]"));
-       if( (rc = encode_crypt(fname,remusr)) )
-           log_error("%s: encryption failed: %s\n",
-                      print_fname_stdin(fname), gpg_strerror (rc) );
+       if(multifile)
+         encode_crypt_files(argc, argv, remusr);
+       else
+         {
+            if( argc > 1 )
+              wrong_args(_("--encrypt [filename]"));
+            if( (rc = encode_crypt(fname,remusr)) )
+              log_error("%s: encryption failed: %s\n",
+                        print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        break;
 
-      case aEncrFiles: /* encrypt the given files */
-        encode_crypt_files(argc, argv, remusr);
-       break;
-          
       case aSign: /* sign the given file */
        sl = NULL;
        if( detached_sig ) { /* sign all files */
@@ -2397,26 +2447,30 @@ main( int argc, char **argv )
        break;
 
       case aVerify:
-       if( (rc = verify_signatures( argc, argv ) ))
-           log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
-       break;
-
-      case aVerifyFiles:
-       if( (rc = verify_files( argc, argv ) ))
-           log_error("verify files failed: %s\n", gpg_strerror (rc) );
+        if(multifile)
+         {
+           if( (rc = verify_files( argc, argv ) ))
+             log_error("verify files failed: %s\n", gpg_strerror (rc) );
+         }
+        else
+          {
+            if( (rc = verify_signatures( argc, argv ) ))
+              log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
+          }
        break;
 
       case aDecrypt:
-       if( argc > 1 )
-           wrong_args(_("--decrypt [filename]"));
-       if( (rc = decrypt_message( fname ) ))
-           log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+        if(multifile)
+         decrypt_messages(argc, argv);
+       else
+          {
+            if( argc > 1 )
+              wrong_args(_("--decrypt [filename]"));
+            if( (rc = decrypt_message( fname ) ))
+              log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+          }
        break;
 
-      case aDecryptFiles:
-        decrypt_messages(argc, argv);
-        break;
-            
       case aSignKey: /* sign the key given as argument */
        if( argc != 1 )
            wrong_args(_("--sign-key user-id"));
@@ -2900,8 +2954,6 @@ print_hex( MD_HANDLE md, int algo, const char *fname )
 
   if(algo==DIGEST_ALGO_RMD160)
     indent+=printf("RMD160 = ");
-  else if(algo==DIGEST_ALGO_TIGER)
-    indent+=printf(" TIGER = ");
   else if(algo>0)
     indent+=printf("%6s = ", gcry_md_algo_name (algo));
   else
@@ -3018,9 +3070,6 @@ print_mds( const char *fname, int algo )
        gcry_md_enable (md, GCRY_MD_MD5 );
        gcry_md_enable (md, GCRY_MD_SHA1 );
        gcry_md_enable (md, GCRY_MD_RMD160 );
-#ifdef USE_TIGER192
-       gcry_md_enable (md, GCRY_MD_TIGER );
-#endif
 #ifdef USE_SHA256
        gcry_md_enable (md, GCRY_MD_SHA256 );
 #endif
@@ -3043,9 +3092,6 @@ print_mds( const char *fname, int algo )
                 print_hashline( md, GCRY_MD_MD5, fname );
                 print_hashline( md, GCRY_MD_SHA1, fname );
                 print_hashline( md, GCRY_MD_RMD160, fname );
-#ifdef USE_TIGER192
-               print_hashline( md, GCRY_MD_TIGER, fname );
-#endif
 #ifdef USE_SHA256
                 print_hashline( md, GCRY_MD_SHA256, fname );
 #endif
@@ -3062,9 +3108,6 @@ print_mds( const char *fname, int algo )
                 print_hex( md, GCRY_MD_MD5, fname );
                 print_hex( md, GCRY_MD_SHA1, fname );
                 print_hex( md, GCRY_MD_RMD160, fname );
-#ifdef USE_TIGER192
-               print_hex( md, GCRY_MD_TIGER, fname );
-#endif
 #ifdef USE_SHA256
                 print_hex( md, GCRY_MD_SHA256, fname );
 #endif
@@ -3132,13 +3175,13 @@ add_notation_data( const char *string, int which )
     /* we only support printable text - therefore we enforce the use
      * of only printable characters (an empty value is valid) */
     for( s++; *s ; s++ ) {
-       if( iscntrl(*s) ) {
+       if( *s & 0x80 )
+           highbit = 1;
+       else if( iscntrl(*s) ) {
            log_error(_("a notation value must not use "
                        "any control characters\n") );
            return;
        }
-       else if( *s & 0x80 )
-           highbit = 1;
     }
 
     if( highbit )   /* must use UTF8 encoding */
@@ -3183,3 +3226,39 @@ add_policy_url( const char *string, int which )
   if(critical)
     sl->flags |= 1;    
 }
+
+
+static void
+add_keyserver_url( const char *string, int which )
+{
+  int i,critical=0;
+  STRLIST sl;
+
+  if(*string=='!')
+    {
+      string++;
+      critical=1;
+    }
+
+  for(i=0;i<strlen(string);i++)
+    if(string[i]&0x80 || iscntrl(string[i]))
+      break;
+
+  if(i==0 || i<strlen(string))
+    {
+      if(which)
+       BUG();
+      else
+       log_error(_("the given signature preferred"
+                   " keyserver URL is invalid\n"));
+    }
+
+  if(which)
+    BUG();
+  else
+    sl=add_to_strlist( &opt.sig_keyserver_url, string );
+
+  if(critical)
+    sl->flags |= 1;    
+}
+
index 7eda938..f51b8f2 100644 (file)
@@ -572,7 +572,7 @@ classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
     memset (desc, 0, sizeof *desc);
 
     /* skip leading spaces.  Fixme: what is with trailing spaces? */
-    for(s = name; *s && isspace(*s); s++ )
+    for(s = name; *s && spacep (s); s++ )
        ;
 
     switch (*s) {
@@ -653,7 +653,7 @@ classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
             }
 
            /* check if a hexadecimal number is terminated by EOS or blank */
-           if (hexlength && s[hexlength] && !isspace(s[hexlength])) {
+           if (hexlength && s[hexlength] && !spacep (s+hexlength)) {
                if (hexprefix)      /* a "0x" prefix without correct */
                    return 0;       /* termination is an error */
                else                /* The first chars looked like */
@@ -1593,8 +1593,6 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
            else if ( k->pkt->pkttype == PKT_SIGNATURE && uidnode )
              {
                PKT_signature *sig = k->pkt->pkt.signature;
-               u32 dummy;
-               int dum2;
 
                if(sig->keyid[0] != kid[0] || sig->keyid[1]!=kid[1])
                  {
@@ -1610,7 +1608,7 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
                        ultimate trust flag.  */
                    if(get_pubkey_fast(ultimate_pk,sig->keyid)==0
                       && check_key_signature2(keyblock,k,ultimate_pk,
-                                              NULL,&dummy,&dum2)==0
+                                              NULL, NULL, NULL, NULL)==0
                       && get_ownertrust(ultimate_pk)==TRUST_ULTIMATE)
                      {
                        free_public_key(ultimate_pk);
index fb96fad..596b09f 100644 (file)
@@ -1,5 +1,6 @@
 /* gpgv.c - The GnuPG signature verify utility
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -155,8 +156,9 @@ main( int argc, char **argv )
     opt.trust_model = TM_ALWAYS;
     opt.batch = 1;
 
-#if defined (__MINGW32__)
-    opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
+#if defined (_WIN32)
+    opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG",
+                                            "HomeDir" );
 #else
     opt.homedir = getenv("GNUPGHOME");
 #endif
@@ -221,6 +223,14 @@ g10_exit( int rc )
 }
 
 
+
+void
+read_trust_options (byte *trust_model,ulong *created,ulong *nextcheck,
+                   byte *marginals,byte *completes,byte *cert_depth) 
+{
+}
+
+
 /* Stub:
  * We have to override the trustcheck from pkclist.c becuase 
  * this utility assumes that all keys in the keyring are trustworthy
index 84d60a1..9c32324 100644 (file)
@@ -1,5 +1,6 @@
-/* import.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+/* import.c - Import OpenPGP key material
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -168,6 +169,8 @@ import_keys_internal( iobuf_t inp, char **fnames, int nnames,
            else {
                rc = import( inp2, fname, stats, options );
                iobuf_close(inp2);
+                /* Must invalidate that ugly cache to actually close it. */
+                iobuf_ioctl (NULL, 2, 0, (char*)fname);
                if( rc )
                    log_error("import from `%s' failed: %s\n", fname,
                                      gpg_strerror (rc) );
@@ -589,7 +592,8 @@ import_one( const char *fname, KBNODE keyblock,
 
     clear_kbnode_flags( keyblock );
 
-    if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock))
+    if((options&IMPORT_REPAIR_PKS_SUBKEY_BUG) && fix_pks_corruption(keyblock)
+       && opt.verbose)
       log_info(_("key %08lX: PKS subkey corruption repaired\n"),
               (ulong)keyid[1]);
 
@@ -611,11 +615,9 @@ import_one( const char *fname, KBNODE keyblock,
          }
 
     if( !delete_inv_parts( fname, keyblock, keyid, options ) ) {
-       if( !opt.quiet ) {
-           log_info( _("key %08lX: no valid user IDs\n"),
-                                                       (ulong)keyid[1]);
+        log_error ( _("key %08lX: no valid user IDs\n"), (ulong)keyid[1]);
+       if( !opt.quiet )
            log_info(_("this may be caused by a missing self-signature\n"));
-       }
        stats->no_user_id++;
        return 0;
     }
@@ -979,8 +981,8 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
     pk = xcalloc (1, sizeof *pk );
     rc = get_pubkey( pk, keyid );
     if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY ) {
-       log_info( _("key %08lX: no public key - "
-                "can't apply revocation certificate\n"), (ulong)keyid[1]);
+       log_error ( _("key %08lX: no public key - "
+                      "can't apply revocation certificate\n"), (ulong)keyid[1]);
        rc = 0;
        goto leave;
     }
@@ -1030,12 +1032,12 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
        if( onode->pkt->pkttype == PKT_USER_ID )
            break;
        else if( onode->pkt->pkttype == PKT_SIGNATURE
-                && onode->pkt->pkt.signature->sig_class == 0x20
-                && keyid[0] == onode->pkt->pkt.signature->keyid[0]
-                && keyid[1] == onode->pkt->pkt.signature->keyid[1] ) {
-           rc = 0;
-           goto leave; /* yes, we already know about it */
-       }
+                 && !cmp_signatures(node->pkt->pkt.signature,
+                                    onode->pkt->pkt.signature))
+          {
+            rc = 0;
+            goto leave; /* yes, we already know about it */
+          }
     }
 
 
@@ -1125,17 +1127,20 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
                  rc = check_key_signature( keyblock, n, NULL);
                  if( rc )
                    {
-                     char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
-                                     strlen(unode->pkt->pkt.user_id->name),0);
-                     log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
-                               _("key %08lX: unsupported public key "
-                                 "algorithm on user id \"%s\"\n"):
-                               _("key %08lX: invalid self-signature "
-                                 "on user id \"%s\"\n"),
-                               (ulong)keyid[1],p);
-                     xfree (p);
-                   }
-                 else
+                      if (opt.verbose)
+                        {
+                          char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
+                                       strlen(unode->pkt->pkt.user_id->name),0);
+                          log_info( gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
+                                    _("key %08lX: unsupported public key "
+                                      "algorithm on user id \"%s\"\n"):
+                                    _("key %08lX: invalid self-signature "
+                                      "on user id \"%s\"\n"),
+                                    (ulong)keyid[1],p);
+                          xfree (p);
+                        }
+                    }
+                  else
                    unode->flag |= 1; /* mark that signature checked */
                }
            }
@@ -1144,39 +1149,49 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
                 like the rest of gpg.  If the standard gets
                 revocation targets, this may need to be revised. */
 
-               if( !knode ) {
-                   log_info( _("key %08lX: no subkey for subkey "
-                               "binding signature\n"),(ulong)keyid[1]);
-                   n->flag |= 4; /* delete this */
-               }
-               else {
-                 rc = check_key_signature( keyblock, n, NULL);
-                 if( rc ) {
-                   log_info(  gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
-                           _("key %08lX: unsupported public key algorithm\n"):
+               if( !knode )
+                  {
+                    if (opt.verbose)
+                      log_info( _("key %08lX: no subkey for subkey "
+                                  "binding signature\n"),(ulong)keyid[1]);
+                    n->flag |= 4; /* delete this */
+                  }
+               else
+                  {
+                    rc = check_key_signature( keyblock, n, NULL);
+                    if( rc )
+                      {
+                        if (opt.verbose)
+                          log_info(  gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
+                            _("key %08lX: unsupported public key algorithm\n"):
                            _("key %08lX: invalid subkey binding\n"),
-                           (ulong)keyid[1]);
-                   n->flag|=4;
-                 }
-                 else {
-                   /* It's valid, so is it newer? */
-                   if(sig->timestamp>=bsdate) {
-                     knode->flag |= 1;  /* the subkey is valid */
-                     if(bsnode) {
-                       bsnode->flag|=4; /* Delete the last binding
-                                           sig since this one is
-                                           newer */
-                       log_info(_("key %08lX: removed multiple subkey "
-                                  "binding\n"),(ulong)keyid[1]);
-                     }
-
-                     bsnode=n;
-                     bsdate=sig->timestamp;
-                   }
-                   else
-                     n->flag|=4; /* older */
-                 }
-               }
+                                     (ulong)keyid[1]);
+                        n->flag|=4;
+                      }
+                    else
+                      {
+                        /* It's valid, so is it newer? */
+                        if(sig->timestamp>=bsdate) 
+                          {
+                            knode->flag |= 1;  /* the subkey is valid */
+                            if(bsnode)
+                              {
+                                bsnode->flag|=4; /* Delete the last binding
+                                                    sig since this one is
+                                                    newer */
+                                if (opt.verbose)
+                                  log_info(_("key %08lX: removed multiple "
+                                             "subkey binding\n"),
+                                           (ulong)keyid[1]);
+                              }
+                            
+                            bsnode=n;
+                            bsdate=sig->timestamp;
+                          }
+                        else
+                          n->flag|=4; /* older */
+                      }
+                  }
            }
            else if( sig->sig_class == 0x28 ) {
              /* We don't actually mark the subkey as revoked right
@@ -1186,14 +1201,16 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
                  See the comment in getkey.c:merge_selfsigs_subkey for
                  more */
                if( !knode ) {
+                  if (opt.verbose)
                    log_info( _("key %08lX: no subkey for subkey "
                                "revocation signature\n"),(ulong)keyid[1]);
-                   n->flag |= 4; /* delete this */
+                  n->flag |= 4; /* delete this */
                }
                else {
                  rc = check_key_signature( keyblock, n, NULL);
                  if( rc ) {
-                   log_info(  gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
+                    if (opt.verbose)
+                      log_info(  gpg_err_code (rc) == GPG_ERR_PUBKEY_ALGO ?
                            _("key %08lX: unsupported public key algorithm\n"):
                            _("key %08lX: invalid subkey revocation\n"),
                               (ulong)keyid[1]);
@@ -1206,8 +1223,10 @@ chk_self_sigs( const char *fname, KBNODE keyblock,
                        rsnode->flag|=4; /* Delete the last revocation
                                            sig since this one is
                                            newer */
-                       log_info(_("key %08lX: removed multiple subkey "
-                                  "revocation signatures\n"),(ulong)keyid[1]);
+                        if (opt.verbose)
+                          log_info(_("key %08lX: removed multiple subkey "
+                                     "revocation signatures\n"),
+                                   (ulong)keyid[1]);
                      }
 
                      rsnode=n;
@@ -1291,23 +1310,25 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
                 !node->pkt->pkt.signature->flags.exportable &&
                 !(options&IMPORT_ALLOW_LOCAL_SIGS) &&
                 seckey_available( node->pkt->pkt.signature->keyid ) ) {
-           /* here we violate the rfc a bit by still allowing
+           /* Here we violate the rfc a bit by still allowing
             * to import non-exportable signature when we have the
             * the secret key used to create this signature - it
-            * seems that this makes sense */
+            * seems that this makes sense. */
+          if (opt.verbose)
            log_info( _("key %08lX: non exportable signature "
                                    "(class %02x) - skipped\n"),
-                                   (ulong)keyid[1],
+                      (ulong)keyid[1],
                                     node->pkt->pkt.signature->sig_class );
-           delete_kbnode( node );
+          delete_kbnode( node );
        }
        else if( node->pkt->pkttype == PKT_SIGNATURE
                 && node->pkt->pkt.signature->sig_class == 0x20 )  {
            if( uid_seen ) {
+              if (opt.verbose)
                log_error( _("key %08lX: revocation certificate "
-                                    "at wrong place - skipped\n"),
+                             "at wrong place - skipped\n"),
                                    (ulong)keyid[1]);
-               delete_kbnode( node );
+              delete_kbnode( node );
            }
            else {
              /* If the revocation cert is from a different key than
@@ -1321,9 +1342,10 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
                  int rc = check_key_signature( keyblock, node, NULL);
                  if( rc )
                    {
-                     log_error( _("key %08lX: invalid revocation "
-                                  "certificate: %s - skipped\n"),
-                                (ulong)keyid[1], gpg_strerror (rc));
+                      if (opt.verbose)
+                        log_info ( _("key %08lX: invalid revocation "
+                                     "certificate: %s - skipped\n"),
+                                   (ulong)keyid[1], gpg_strerror (rc));
                      delete_kbnode( node );
                    }
                }
@@ -1333,17 +1355,19 @@ delete_inv_parts( const char *fname, KBNODE keyblock,
                 (node->pkt->pkt.signature->sig_class == 0x18 ||
                  node->pkt->pkt.signature->sig_class == 0x28) &&
                 !subkey_seen ) {
-           log_error( _("key %08lX: subkey signature "
+          if (opt.verbose)
+           log_info ( _("key %08lX: subkey signature "
                         "in wrong place - skipped\n"),
                       (ulong)keyid[1]);
-           delete_kbnode( node );
+          delete_kbnode( node );
        }
        else if( node->pkt->pkttype == PKT_SIGNATURE
                 && !IS_CERT(node->pkt->pkt.signature))
          {
-           log_error(_("key %08lX: unexpected signature class (0x%02X) -"
-                       " skipped\n"),(ulong)keyid[1],
-                     node->pkt->pkt.signature->sig_class);
+            if (opt.verbose)
+              log_info (_("key %08lX: unexpected signature class (0x%02X) -"
+                          " skipped\n"),(ulong)keyid[1],
+                        node->pkt->pkt.signature->sig_class);
            delete_kbnode(node);
          }
        else if( (node->flag & 4) ) /* marked for deletion */
@@ -1439,8 +1463,9 @@ collapse_uids( KBNODE *keyblock )
        kid1 = keyid_from_sk( n->pkt->pkt.secret_key, NULL );
     else
        kid1 = 0;
-    log_info(_("key %08lX: duplicated user ID detected - merged\n"),
-                                                                (ulong)kid1);
+    if (!opt.quiet)
+      log_info (_("key %08lX: duplicated user ID detected - merged\n"),
+                (ulong)kid1);
 
     return 1;
 }
@@ -1557,23 +1582,27 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
                    break;
                else if( onode->pkt->pkttype == PKT_SIGNATURE
                         && onode->pkt->pkt.signature->sig_class == 0x20
-                        && node->pkt->pkt.signature->keyid[0]
-                           == onode->pkt->pkt.signature->keyid[0]
-                        && node->pkt->pkt.signature->keyid[1]
-                           == onode->pkt->pkt.signature->keyid[1] ) {
-                   found = 1;
-                   break;
-               }
+                        && !cmp_signatures(onode->pkt->pkt.signature,
+                                           node->pkt->pkt.signature))
+                  {
+                    found = 1;
+                    break;
+                  }
            }
            if( !found ) {
-               char *p=get_user_id_printable (keyid);
                KBNODE n2 = clone_kbnode(node);
                insert_kbnode( keyblock_orig, n2, 0 );
                n2->flag |= 1;
                 ++*n_sigs;
-               log_info(_("key %08lX: \"%s\" revocation certificate added\n"),
-                                        (ulong)keyid[1],p);
-               xfree (p);
+
+                if (!opt.quiet)
+                  {
+                    char *p=get_user_id_printable (keyid);
+                    log_info(_("key %08lX: \"%s\" "
+                               "revocation certificate added\n"),
+                             (ulong)keyid[1],p);
+                    xfree (p);
+                  }
            }
        }
     }
@@ -1602,8 +1631,9 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
                insert_kbnode( keyblock_orig, n2, 0 );
                n2->flag |= 1;
                 ++*n_sigs;
-               log_info( _("key %08lX: direct key signature added\n"),
-                                        (ulong)keyid[1]);
+                if (!opt.quiet)
+                  log_info( _("key %08lX: direct key signature added\n"),
+                            (ulong)keyid[1]);
            }
        }
     }
@@ -1771,20 +1801,12 @@ merge_sigs( KBNODE dst, KBNODE src, int *n_sigs,
            || n->pkt->pkt.signature->sig_class == 0x28 )
            continue; /* skip signatures which are only valid on subkeys */
        found = 0;
-       for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next){
-           if( n2->pkt->pkttype == PKT_SIGNATURE
-               && n->pkt->pkt.signature->keyid[0]
-                  == n2->pkt->pkt.signature->keyid[0]
-               && n->pkt->pkt.signature->keyid[1]
-                  == n2->pkt->pkt.signature->keyid[1]
-               && n->pkt->pkt.signature->timestamp
-                  <= n2->pkt->pkt.signature->timestamp
-               && n->pkt->pkt.signature->sig_class
-                  == n2->pkt->pkt.signature->sig_class ) {
-               found++;
-               break;
-           }
-       }
+       for(n2=dst->next; n2 && n2->pkt->pkttype != PKT_USER_ID; n2 = n2->next)
+         if(!cmp_signatures(n->pkt->pkt.signature,n2->pkt->pkt.signature))
+           {
+             found++;
+             break;
+           }   
        if( !found ) {
            /* This signature is new or newer, append N to DST.
             * We add a clone to the original keyblock, because this
index 85f2b92..bd41772 100644 (file)
@@ -56,6 +56,7 @@ static int menu_addrevoker( KBNODE pub_keyblock,
 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
+static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock );
 static int menu_select_uid( KBNODE keyblock, int idx );
 static int menu_select_key( KBNODE keyblock, int idx );
 static int count_uids( KBNODE keyblock );
@@ -135,7 +136,7 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
        break;
     }
     if( sigrc != '?' || print_without_key ) {
-        tty_printf("%s%c%c %c%c%c%c%c%c %08lX %s   ",
+        tty_printf("%s%c%c %c%c%c%c%c%c ",
                   is_rev? "rev":"sig",sigrc,
                   (sig->sig_class-0x10>0 &&
                    sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
@@ -145,8 +146,15 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
                   sig->flags.notation?'N':' ',
                    sig->flags.expired?'X':' ',
                   (sig->trust_depth>9)?'T':
-                  (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
-                  (ulong)sig->keyid[1], datestr_from_sig(sig));
+                  (sig->trust_depth>0)?'0'+sig->trust_depth:' ');
+       if(opt.list_options&LIST_SHOW_LONG_KEYID)
+         tty_printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]);
+       else
+         tty_printf("%08lX",(ulong)sig->keyid[1]);
+       tty_printf(" %s", datestr_from_sig(sig));
+       if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
+         tty_printf(" %s",expirestr_from_sig(sig));
+       tty_printf("  ");
        if( sigrc == '%' )
            tty_printf("[%s] ", gpg_strerror (rc) );
        else if( sigrc == '?' )
@@ -168,6 +176,9 @@ print_and_check_one_sig( KBNODE keyblock, KBNODE node,
 
        if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
          show_notation(sig,3,0);
+
+       if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
+         show_keyserver_url(sig,3,0);
     }
 
     return (sigrc == '!');
@@ -500,12 +511,47 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
                            tty_printf(_("  Unable to sign.\n"));
                          }
                      }
-                   else if(!uidnode->pkt->pkt.user_id->created)
+                   else if(uidnode->pkt->pkt.user_id->is_expired)
                      {
-                       tty_printf(_("WARNING: user ID \"%s\" is not "
-                                    "self-signed.\n"),user);
+                       tty_printf(_("User ID \"%s\" is expired."),user);
+
+                       if(opt.expert)
+                         {
+                           tty_printf("\n");
+                           /* No, so remove the mark and continue */
+                           if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
+                                                     _("Are you sure you "
+                                                       "still want to sign "
+                                                       "it? (y/N) ")))
+                             uidnode->flag &= ~NODFLG_MARK_A;
+                         }
+                       else
+                         {
+                           uidnode->flag &= ~NODFLG_MARK_A;
+                           tty_printf(_("  Unable to sign.\n"));
+                         }
                      }
+                   else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
+                     {
+                       tty_printf(_("User ID \"%s\" is not self-signed."),
+                                  user);
 
+                       if(opt.expert)
+                         {
+                           tty_printf("\n");
+                           /* No, so remove the mark and continue */
+                           if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
+                                                     _("Are you sure you "
+                                                       "still want to sign "
+                                                       "it? (y/N) ")))
+                             uidnode->flag &= ~NODFLG_MARK_A;
+                         }
+                       else
+                         {
+                           uidnode->flag &= ~NODFLG_MARK_A;
+                           tty_printf(_("  Unable to sign.\n"));
+                         }
+                      }
                    xfree (user);
                  }
            }
@@ -739,7 +785,8 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
 
                while(class==0)
                  {
-                   answer = cpr_get("sign_uid.class",_("Your selection? "));
+                   answer = cpr_get("sign_uid.class",_("Your selection? "
+                                       "(enter '?' for more information): "));
 
                    if(answer[0]=='\0')
                      class=0x10+opt.def_cert_check_level; /* Default */
@@ -970,8 +1017,10 @@ change_passphrase( KBNODE keyblock )
                            " this is probably a *bad* idea!\n\n"));
                if( cpr_get_answer_is_yes("change_passwd.empty.okay",
                               _("Do you really want to do this? ")))
+                  {
                    changed++;
-               break;
+                    break;
+                  }
            }
            else { /* okay */
                rc = 0;
@@ -1067,7 +1116,8 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
           cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER,
           cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
           cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
-          cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, cmdNOP };
+          cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
+          cmdNOP };
     static struct { const char *name;
                    enum cmdids id;
                    int need_sk;
@@ -1108,10 +1158,14 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
        { N_("toggle")  , cmdTOGGLE    , 1,0,0, N_("toggle between secret "
                                                   "and public key listing") },
        { N_("t"     )  , cmdTOGGLE    , 1,0,0, NULL },
-       { N_("pref")    , cmdPREF      , 0,1,0, N_("list preferences (expert)") },
-       { N_("showpref"), cmdSHOWPREF  , 0,1,0, N_("list preferences (verbose)") },
+       { N_("pref")    , cmdPREF      , 0,1,0,
+                                         N_("list preferences (expert)")},
+       { N_("showpref"), cmdSHOWPREF  , 0,1,0,
+                                         N_("list preferences (verbose)")},
        { N_("setpref") , cmdSETPREF   , 1,1,0, N_("set preference list") },
        { N_("updpref") , cmdUPDPREF   , 1,1,0, N_("updated preferences") },
+       { N_("keyserver"),cmdPREFKS    , 1,1,0,
+                                         N_("set preferred keyserver URL")},
        { N_("passwd")  , cmdPASSWD    , 1,1,0, N_("change the passphrase") },
        { N_("trust")   , cmdTRUST     , 0,1,0, N_("change the ownertrust") },
        { N_("revsig")  , cmdREVSIG    , 0,1,0, N_("revoke signatures") },
@@ -1238,7 +1292,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
            cmd = cmdLIST;
        else if( *answer == CONTROL_D )
            cmd = cmdQUIT;
-       else if( isdigit( *answer ) ) {
+       else if( digitp( answer ) ) {
            cmd = cmdSELUID;
            arg_number = atoi(answer);
        }
@@ -1565,6 +1619,14 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
             }
            break;
 
+         case cmdPREFKS:
+           if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) {
+               merge_keys_and_selfsig( keyblock );
+               modified = 1;
+               redisplay = 1;
+           }
+           break;
+
          case cmdNOP:
            break;
 
@@ -1950,6 +2012,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
     int i, rc;
     int do_warn = 0;
     byte pk_version=0;
+    PKT_public_key *primary=NULL;
 
     if (opt.with_colons)
       {
@@ -1979,7 +2042,8 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
                     do_warn = 1;
                 }
 
-               pk_version=pk->version;
+               pk_version = pk->version;
+                primary = pk;
            }
 
            if(with_revoker) {
@@ -2006,19 +2070,27 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
                       }
             }
 
-           tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
-                         node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
-                         (node->flag & NODFLG_SELKEY)? '*':' ',
-                         nbits_from_pk( pk ),
-                         pubkey_letter( pk->pubkey_algo ),
-                         (ulong)keyid_from_pk(pk,NULL),
-                         datestr_from_pk(pk),
-                         expirestr_from_pk(pk) );
+           keyid_from_pk(pk,NULL);
+           tty_printf("%s%c %4u%c/",
+                      node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
+                      (node->flag & NODFLG_SELKEY)? '*':' ',
+                      nbits_from_pk( pk ),
+                      pubkey_letter( pk->pubkey_algo ));
+
+           if(opt.list_options&LIST_SHOW_LONG_KEYID)
+             tty_printf("%08lX",(ulong)pk->keyid[0]);
+
+           tty_printf("%08lX  ",(ulong)pk->keyid[1]);
+           tty_printf(_("created: %s expires: %s"),
+                      datestr_from_pk(pk),
+                      expirestr_from_pk(pk) );
            tty_printf("\n");
 
            if( node->pkt->pkttype == PKT_PUBLIC_KEY )
              {
                tty_printf("                     ");
+               if(opt.list_options&LIST_SHOW_LONG_KEYID)
+                 tty_printf("        ");
                tty_printf(_("trust: %-13s"), otrust);
                tty_printf(_("validity: %s"), trust );
                tty_printf("\n");
@@ -2072,6 +2144,9 @@ show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
            PKT_user_id *uid = node->pkt->pkt.user_id;
            ++i;
            if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
+                if(opt.list_options&LIST_SHOW_VALIDITY && primary)
+                 tty_printf("[%8.8s] ",
+                            trust_value_to_string(get_validity(primary,uid)));
                if( only_marked )
                   tty_printf("     ");
                else if( node->flag & NODFLG_SELUID )
@@ -2599,16 +2674,23 @@ menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
       answer=cpr_get_utf8("keyedit.add_revoker",
                          _("Enter the user ID of the designated revoker: "));
       if(answer[0]=='\0' || answer[0]=='\004')
-       goto fail;
-
+       {
+         xfree(answer); answer = NULL;
+         goto fail;
+       }
+      
       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
 
       if(rc)
        {
          log_error (_("key `%s' not found: %s\n"),answer,gpg_strerror (rc));
+          xfree (answer); answer = NULL;
          continue;
        }
 
+      xfree (answer); answer = NULL;
+      
+
       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
       if(fprlen!=20)
        {
@@ -2788,7 +2870,8 @@ menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
                 && ( mainkey || sub_pk ) ) {
            PKT_signature *sig = node->pkt->pkt.signature;
            if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
-               && (    (mainkey && uid && (sig->sig_class&~3) == 0x10)
+               && (    (mainkey && uid
+                         && uid->created && (sig->sig_class&~3) == 0x10)
                     || (!mainkey && sig->sig_class == 0x18)  ) ) {
                /* this is a selfsignature which is to be replaced */
                PKT_signature *newsig;
@@ -3084,6 +3167,101 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
 }
 
 
+
+static int
+menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock )
+{
+    PKT_secret_key *sk;    /* copy of the main sk */
+    PKT_public_key *main_pk;
+    PKT_user_id *uid;
+    KBNODE node;
+    u32 keyid[2];
+    int selected, select_all;
+    int modified = 0;
+    char *answer;
+
+    no_primary_warning(pub_keyblock,1);
+
+    answer=cpr_get_utf8("keyedit.add_keyserver",
+                       _("Enter your preferred keyserver URL: "));
+    if(answer[0]=='\0' || answer[0]=='\004')
+      {
+       xfree(answer);
+       return 0;
+      }
+
+    select_all = !count_selected_uids (pub_keyblock);
+
+    node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
+    sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
+
+    /* Now we can actually change the self signature(s) */
+    main_pk = NULL;
+    uid = NULL;
+    selected = 0;
+    for ( node=pub_keyblock; node; node = node->next ) {
+       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+            break; /* ready */
+
+       if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
+           main_pk = node->pkt->pkt.public_key;
+           keyid_from_pk( main_pk, keyid );
+       }
+       else if ( node->pkt->pkttype == PKT_USER_ID ) {
+           uid = node->pkt->pkt.user_id;
+                   selected = select_all || (node->flag & NODFLG_SELUID);
+        }
+       else if ( main_pk && uid && selected
+                  && node->pkt->pkttype == PKT_SIGNATURE ) {
+           PKT_signature *sig = node->pkt->pkt.signature;
+           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
+                && (uid && (sig->sig_class&~3) == 0x10) ) {
+             if( sig->version < 4 ) {
+               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
+
+               log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
+                        user);
+               xfree(user);
+             }
+             else {
+               /* This is a selfsignature which is to be replaced 
+                 * We have to ignore v3 signatures because they are
+                 * not able to carry the preferences */
+               PKT_signature *newsig;
+               PACKET *newpkt;
+                int rc;
+
+                rc = update_keysig_packet (&newsig, sig,
+                                           main_pk, uid, NULL,
+                                           sk,
+                                           keygen_add_keyserver_url,
+                                           answer );
+                if( rc ) {
+                    log_error ("update_keysig_packet failed: %s\n",
+                               gpg_strerror (rc));
+                   xfree(answer);
+                   free_secret_key( sk );
+                    return 0;
+                }
+                /* replace the packet */
+                newpkt = xcalloc (1, sizeof *newpkt );
+                newpkt->pkttype = PKT_SIGNATURE;
+                newpkt->pkt.signature = newsig;
+                free_packet( node->pkt );
+                xfree (node->pkt);
+                node->pkt = newpkt;
+                modified = 1;
+             }
+            }
+       }
+    }
+
+    xfree(answer);
+    free_secret_key( sk );
+    return modified;
+}
+
+
 /****************
  * Select one user id or remove all selection if index is 0.
  * Returns: True if the selection changed;
index bc98cee..38e9115 100644 (file)
@@ -1,6 +1,6 @@
 /* keygen.c - generate a key pair
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- *                                               Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -147,7 +147,12 @@ do_add_key_flags (PKT_signature *sig, unsigned int use)
 
     buf[0] = 0;
     if (use & PUBKEY_USAGE_SIG)
-        buf[0] |= 0x01 | 0x02;
+      {
+       if(sig->sig_class==0x18)
+         buf[0] |= 0x02; /* Don't set the certify flag for subkeys */
+       else
+         buf[0] |= 0x01 | 0x02;
+      }
     if (use & PUBKEY_USAGE_ENC)
         buf[0] |= 0x04 | 0x08;
     if (use & PUBKEY_USAGE_AUTH)
@@ -587,6 +592,18 @@ keygen_add_std_prefs( PKT_signature *sig, void *opaque )
     return 0;
 }
 
+
+int
+keygen_add_keyserver_url(PKT_signature *sig, void *opaque)
+{
+  const char *url=opaque;
+
+  build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url));
+
+  return 0;
+}
+
+
 int
 keygen_add_revkey(PKT_signature *sig, void *opaque)
 {
@@ -1138,10 +1155,10 @@ gen_rsa(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
 static int
 check_valid_days( const char *s )
 {
-    if( !isdigit(*s) )
+    if( !digitp(s) )
        return 0;
     for( s++; *s; s++)
-       if( !isdigit(*s) )
+       if( !digitp(s) )
            break;
     if( !*s )
        return 1;
@@ -1219,15 +1236,18 @@ ask_algo (int addmode, unsigned int *r_usage)
                                      _("Create anyway? ")))
              {
                algo = PUBKEY_ALGO_ELGAMAL;
+                *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG;
                break;
              }
        }
        else if( algo == 3 && addmode ) {
            algo = PUBKEY_ALGO_ELGAMAL_E;
+            *r_usage = PUBKEY_USAGE_ENC;
            break;
        }
        else if( algo == 2 ) {
            algo = PUBKEY_ALGO_DSA;
+            *r_usage = PUBKEY_USAGE_SIG;
            break;
        }
        else
@@ -1489,7 +1509,7 @@ ask_user_id( int mode )
 
                if( strpbrk( aname, "<>" ) )
                    tty_printf(_("Invalid character in name\n"));
-               else if( isdigit(*aname) )
+               else if( digitp(aname) )
                    tty_printf(_("Name may not start with a digit\n"));
                else if( strlen(aname) < 5 )
                    tty_printf(_("Name must be at least 5 characters long\n"));
@@ -1503,7 +1523,7 @@ ask_user_id( int mode )
                amail = cpr_get("keygen.email",_("Email address: "));
                trim_spaces(amail);
                cpr_kill_prompt();
-               if( !*amail )
+               if( !*amail || opt.allow_freeform_uid )
                    break;   /* no email address is okay */
                else if( has_invalid_email_chars(amail)
                         || count_chr(amail,'@') != 1
@@ -1551,7 +1571,8 @@ ask_user_id( int mode )
 
        tty_printf(_("You selected this USER-ID:\n    \"%s\"\n\n"), uid);
        /* fixme: add a warning if this user-id already exists */
-       if( !*amail && (strchr( aname, '@' ) || strchr( acomment, '@'))) {
+       if( !*amail && !opt.allow_freeform_uid
+            && (strchr( aname, '@' ) || strchr( acomment, '@'))) {
            fail = 1;
            tty_printf(_("Please don't put the email address "
                          "into the real name or the comment\n") );
@@ -1608,7 +1629,7 @@ ask_user_id( int mode )
        }
        xfree (answer);
        if( !amail && !acomment && !amail )
-           break;
+          break;
        xfree (uid); uid = NULL;
     }
     if( uid ) {
@@ -1754,7 +1775,7 @@ get_parameter_algo( struct para_data_s *para, enum para_name key )
     struct para_data_s *r = get_parameter( para, key );
     if( !r )
        return -1;
-    if( isdigit( *r->u.value ) )
+    if( digitp( r->u.value ) )
        i = atoi( r->u.value );
     else
         i = openpgp_pk_map_name ( r->u.value );
@@ -2295,6 +2316,11 @@ generate_keypair( const char *fname )
           strcpy( r->u.value, "1024" );
           r->next = para;
           para = r;
+          r = xcalloc (1, sizeof *r + 20 );
+          r->key = pKEYUSAGE;
+          strcpy( r->u.value, "sign" );
+          r->next = para;
+          para = r;
           
           algo = PUBKEY_ALGO_ELGAMAL_E;
           r = xcalloc (1, sizeof *r + 20 );
@@ -2302,6 +2328,12 @@ generate_keypair( const char *fname )
           sprintf( r->u.value, "%d", algo );
           r->next = para;
           para = r;
+          r = xcalloc (1, sizeof *r + 20 );
+          r->key = pSUBKEYUSAGE;
+          strcpy( r->u.value, "encrypt" );
+          r->next = para;
+          r->next = para;
+          para = r;
         }
       else 
         {
index 0817827..f4344f2 100644 (file)
@@ -1,6 +1,6 @@
-/* keylist.c
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- *                                             Free Software Foundation, Inc.
+/* keylist.c - List all or selected keys
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -58,10 +58,46 @@ static FILE *attrib_fp=NULL;
 void
 public_key_list( STRLIST list )
 {
-    if( !list )
-       list_all(0);
-    else
-       list_one( list, 0 );
+  if(opt.with_colons)
+    {
+      byte trust_model,marginals,completes,cert_depth;
+      ulong created,nextcheck;
+
+      read_trust_options(&trust_model,&created,&nextcheck,
+                        &marginals,&completes,&cert_depth);
+
+      printf("tru:");
+
+      if(nextcheck && nextcheck <= make_timestamp())
+       printf("o");
+      if(trust_model!=opt.trust_model)
+       printf("t");
+      if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
+       {
+         if(marginals!=opt.marginals_needed)
+           printf("m");
+         if(completes!=opt.completes_needed)
+           printf("c");
+         if(cert_depth!=opt.max_cert_depth)
+           printf("d");
+       }
+
+      printf(":%d:%lu:%lu",trust_model,created,nextcheck);
+
+      /* Only show marginals, completes, and cert_depth in the classic
+        or PGP trust models since they are not meaningful
+        otherwise. */
+
+      if(trust_model==TM_PGP || trust_model==TM_CLASSIC)
+       printf(":%d:%d:%d",marginals,completes,cert_depth);
+
+      printf("\n");
+    }
+
+  if( !list )
+    list_all(0);
+  else
+    list_one( list, 0 );
 }
 
 void
@@ -152,7 +188,6 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
          for(i=0;i<indent;i++)
            putchar(' ');
 
-         /* This isn't UTF8 as it is a URL(?) */
          if(crit)
            str=_("Critical signature policy: ");
          else
@@ -161,7 +196,7 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
            log_info("%s",str);
          else
            printf("%s",str);
-         print_string(fp,p,len,0);
+         print_utf8_string(fp,p,len);
          fprintf(fp,"\n");
        }
 
@@ -170,6 +205,48 @@ show_policy_url(PKT_signature *sig,int indent,int mode)
     }
 }
 
+
+/*
+  mode=0 for stdout.
+  mode=1 for log_info + status messages
+  mode=2 for status messages only
+*/
+/* TODO: use this */
+void
+show_keyserver_url(PKT_signature *sig,int indent,int mode)
+{
+  const byte *p;
+  size_t len;
+  int seq=0,crit;
+  FILE *fp=mode?log_get_stream():stdout;
+
+  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit)))
+    {
+      if(mode!=2)
+       {
+         int i;
+         char *str;
+
+         for(i=0;i<indent;i++)
+           putchar(' ');
+
+         if(crit)
+           str=_("Critical preferred keyserver: ");
+         else
+           str=_("Preferred keyserver: ");
+         if(mode)
+           log_info("%s",str);
+         else
+           printf("%s",str);
+         print_utf8_string(fp,p,len);
+         fprintf(fp,"\n");
+       }
+
+      /* TODO: put in a status-fd tag for preferred keyservers */
+    }
+}
+
+
 /*
   mode=0 for stdout.
   mode=1 for log_info + status messages
@@ -788,6 +865,9 @@ list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
            if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
              show_notation(sig,3,0);
 
+           if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
+             show_keyserver_url(sig,3,0);
+
            /* fixme: check or list other sigs here */
        }
     }
@@ -820,7 +900,7 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
        pk = NULL;
        sk = node->pkt->pkt.secret_key;
        keyid_from_sk( sk, keyid );
-        printf("sec:u:%u:%d:%08lX%08lX:%s:%s:::",
+        printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
                    nbits_from_sk( sk ),
                    sk->pubkey_algo,
                    (ulong)keyid[0],(ulong)keyid[1],
@@ -886,13 +966,17 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
            if( any ) {
                int i;
                char *str=uid->attrib_data?"uat":"uid";
-                if ( uid->is_revoked )
+               /* If we're listing a secret key, leave out the
+                  validity values for now.  FIXME: This should be
+                  handled better in 1.9. */
+               if ( sk )
+                   printf("%s:::::",str);
+                else if ( uid->is_revoked )
                    printf("%s:r::::",str);
                 else if ( uid->is_expired )
                    printf("%s:e::::",str);
-               else if ( opt.no_expensive_trust_checks ) {
+               else if ( opt.no_expensive_trust_checks )
                    printf("%s:::::",str);
-               }
                 else {
                    int uid_validity;
 
@@ -1010,8 +1094,10 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
        }
        else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
            PKT_signature *sig = node->pkt->pkt.signature;
-           int sigrc;
+           int sigrc, fprokay=0;
             char *sigstr;
+           size_t fplen;
+           byte fparray[MAX_FINGERPRINT_LEN];
 
            if( !any ) { /* no user id, (maybe a revocation follows)*/
                if( sig->sig_class == 0x20 )
@@ -1045,8 +1131,14 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
                continue;
            }
            if( opt.check_sigs ) {
+               PKT_public_key *signer_pk=NULL;
+
                fflush(stdout);
-               rc = check_key_signature( keyblock, node, NULL );
+               if(opt.no_sig_cache)
+                 signer_pk = xcalloc (1, sizeof(PKT_public_key));
+
+               rc = check_key_signature2( keyblock, node, NULL, signer_pk,
+                                          NULL, NULL, NULL );
                switch( gpg_err_code (rc) ) {
                  case 0:                  sigrc = '!'; break;
                  case GPG_ERR_BAD_SIGNATURE:    sigrc = '-'; break;
@@ -1054,6 +1146,16 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
                  case GPG_ERR_UNUSABLE_PUBKEY:  sigrc = '?'; break;
                  default:                 sigrc = '%'; break;
                }
+
+               if(opt.no_sig_cache)
+                 {
+                   if(!rc)
+                     {
+                       fingerprint_from_pk (signer_pk, fparray, &fplen);
+                       fprokay=1;
+                     }
+                   free_public_key(signer_pk);
+                 }
            }
            else {
                rc = 0;
@@ -1087,7 +1189,20 @@ list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
                 print_string( stdout, p, n, ':' );
                xfree (p);
            }
-            printf(":%02x%c:\n", sig->sig_class,sig->flags.exportable?'x':'l');
+            printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l');
+           if(opt.no_sig_cache && opt.check_sigs && fprokay)
+             {
+               size_t i;
+
+               printf(":");
+
+               for (i=0; i < fplen ; i++ )
+                 printf ("%02X", fparray[i] );
+
+               printf(":");
+             }
+
+           printf("\n");
            /* fixme: check or list other sigs here */
        }
     }
index 4639e94..03a2266 100644 (file)
@@ -1382,6 +1382,13 @@ keyring_rebuild_cache (void *token)
         {
           if (node->pkt->pkttype == PKT_SIGNATURE)
             {
+             /* Note that this doesn't cache the result of a
+                revocation issued by a designated revoker.  This is
+                because the pk in question does not carry the revkeys
+                as we haven't merged the key and selfsigs.  It is
+                questionable whether this matters very much since
+                there are very very few designated revoker revocation
+                packets out there. */
               check_key_signature (keyblock, node, NULL);
               sigcount++;
             }
index e4f56ca..445c076 100644 (file)
@@ -170,7 +170,8 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
       opt.keyserver_scheme="hkp";
       opt.keyserver_options.broken_http_proxy=1;
     }
-  else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0)
+  else if(ascii_strcasecmp(opt.keyserver_scheme,"x-hkp")==0
+         || ascii_strcasecmp(opt.keyserver_scheme,"http")==0)
     {
       /* Canonicalize this to "hkp" so it works with both the internal
         and external keyserver interface. */
@@ -203,7 +204,7 @@ parse_keyserver_uri(char *uri,const char *configname,unsigned int configlineno)
          ch=opt.keyserver_port;
          while(*ch!='\0')
            {
-             if(!isdigit(*ch))
+             if(!digitp(ch))
                return GPG_ERR_BAD_URI;
 
              ch++;
@@ -340,7 +341,7 @@ parse_keyrec(char *keystring)
 
   /* Remove trailing whitespace */
   for(i=strlen(keystring);i>0;i--)
-    if(isspace(keystring[i-1]))
+    if(ascii_isspace(keystring[i-1]))
       keystring[i-1]='\0';
     else
       break;
@@ -978,7 +979,7 @@ keyserver_spawn(int action,STRLIST list,
 
       /* remove trailing whitespace */
       plen=strlen(ptr);
-      while(plen>0 && isspace(ptr[plen-1]))
+      while(plen>0 && ascii_isspace(ptr[plen-1]))
        plen--;
       plen[ptr]='\0';
 
index 320a543..76562fa 100644 (file)
@@ -151,7 +151,8 @@ int sign_symencrypt_file (const char *fname, STRLIST locusr);
 int check_revocation_keys (PKT_public_key *pk, PKT_signature *sig);
 int check_key_signature( KBNODE root, KBNODE node, int *is_selfsig );
 int check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
-                         int *is_selfsig, u32 *r_expiredate, int *r_expired );
+                          PKT_public_key *ret_pk, int *is_selfsig,
+                          u32 *r_expiredate, int *r_expired );
 
 /*-- delkey.c --*/
 int delete_keys( STRLIST names, int secret, int allow_both );
@@ -170,6 +171,7 @@ PKT_user_id *keygen_get_std_prefs (void);
 int keygen_add_key_expire( PKT_signature *sig, void *opaque );
 int keygen_add_std_prefs( PKT_signature *sig, void *opaque );
 int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
+int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
 int keygen_add_revkey(PKT_signature *sig, void *opaque);
 int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
 
@@ -232,6 +234,7 @@ void reorder_keyblock (KBNODE keyblock);
 void list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque );
 void print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode);
 void show_policy_url(PKT_signature *sig,int indent,int mode);
+void show_keyserver_url(PKT_signature *sig,int indent,int mode);
 void show_notation(PKT_signature *sig,int indent,int mode);
 void dump_attribs(const PKT_user_id *uid,
                  PKT_public_key *pk,PKT_secret_key *sk);
index 3689525..40b9bd2 100644 (file)
@@ -668,15 +668,12 @@ proc_compressed( CTX c, PACKET *pkt )
  * Returns: 0 = valid signature or an error code
  */
 static int
-do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
+do_check_sig( CTX c, KBNODE node, int *is_selfsig,
+              int *is_expkey, int *is_revkey )
 {
     PKT_signature *sig;
     MD_HANDLE md = NULL, md2 = NULL;
-    int algo, rc, dum2;
-    u32 dummy;
-
-    if(!is_expkey)
-      is_expkey=&dum2;
+    int algo, rc;
 
     assert( node->pkt->pkttype == PKT_SIGNATURE );
     if( is_selfsig )
@@ -732,9 +729,9 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig, int *is_expkey )
     }
     else
        return GPG_ERR_SIG_CLASS;
-    rc = signature_check2( sig, md, &dummy, is_expkey );
+    rc = signature_check2( sig, md, NULL, is_expkey, is_revkey, NULL );
     if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE && md2 )
-       rc = signature_check2( sig, md2, &dummy, is_expkey );
+       rc = signature_check2( sig, md2, NULL, is_expkey, is_revkey, NULL );
     gcry_md_close (md);
     gcry_md_close (md2);
 
@@ -958,7 +955,8 @@ list_node( CTX c, KBNODE node )
        if( opt.check_sigs ) {
            fflush(stdout);
            switch( gpg_err_code (rc2=do_check_sig( c, node,
-                                                    &is_selfsig, NULL )) ) {
+                                                    &is_selfsig,
+                                                    NULL, NULL )) ) {
              case 0:                     sigrc = '!'; break;
              case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break;
              case GPG_ERR_NO_PUBKEY: 
@@ -1217,7 +1215,7 @@ check_sig_and_print( CTX c, KBNODE node )
 {
     PKT_signature *sig = node->pkt->pkt.signature;
     const char *astr, *tstr;
-    int rc, is_expkey=0;
+    int rc, is_expkey=0, is_revkey=0;
 
     if( opt.skip_verify ) {
        log_info(_("signature verification suppressed\n"));
@@ -1281,19 +1279,51 @@ check_sig_and_print( CTX c, KBNODE node )
 
     tstr = asctimestamp(sig->timestamp);
     astr = gcry_pk_algo_name (sig->pubkey_algo);
-    log_info(_("Signature made %.*s using %s key ID %08lX\n"),
-           (int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] );
+    if(opt.verify_options&VERIFY_SHOW_LONG_KEYID)
+      {
+       log_info(_("Signature made %.*s\n"),(int)strlen(tstr), tstr);
+       log_info(_("               using %s key %08lX%08lX\n"),
+                astr? astr: "?",(ulong)sig->keyid[0],(ulong)sig->keyid[1] );
+      }
+    else
+      log_info(_("Signature made %.*s using %s key ID %08lX\n"),
+              (int)strlen(tstr), tstr, astr? astr: "?",
+              (ulong)sig->keyid[1] );
 
-    rc = do_check_sig(c, node, NULL, &is_expkey );
+    rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
     if( gpg_err_code (rc) == GPG_ERR_NO_PUBKEY
         && opt.keyserver_scheme && opt.keyserver_options.auto_key_retrieve) {
        if( keyserver_import_keyid ( sig->keyid )==0 )
-           rc = do_check_sig(c, node, NULL, &is_expkey );
+           rc = do_check_sig(c, node, NULL, &is_expkey, &is_revkey );
     }
+
+
+    /* If the key still isn't found, try to inform the user where it
+       can be found. */
+    if(gpg_err_code (rc)==GPG_ERR_NO_PUBKEY && sig->flags.pref_ks)
+      {
+       const byte *p;
+       int seq=0;
+       size_t n;
+
+       while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&n,&seq,NULL)))
+         {
+           /* According to my favorite copy editor, in English
+              grammar, you say "at" if the key is located on a web
+              page, but "from" if it is located on a keyserver.  I'm
+              not going to even try to make two strings here :) */
+           log_info(_("Key available at: ") );
+           print_string( log_get_stream(), p, n, 0 );
+           putc( '\n', log_get_stream() );
+         }
+      }
+
+
     if( !rc || gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE ) {
        KBNODE un, keyblock;
        int count=0, statno;
         char keyid_str[50];
+               PKT_public_key *pk=NULL;
 
        if(rc)
          statno=STATUS_BADSIG;
@@ -1301,6 +1331,8 @@ check_sig_and_print( CTX c, KBNODE node )
          statno=STATUS_EXPSIG;
        else if(is_expkey)
          statno=STATUS_EXPKEYSIG;
+       else if(is_revkey)
+         statno=STATUS_REVKEYSIG;
        else
          statno=STATUS_GOODSIG;
 
@@ -1311,6 +1343,13 @@ check_sig_and_print( CTX c, KBNODE node )
 
         /* find and print the primary user ID */
        for( un=keyblock; un; un = un->next ) {
+           int valid;
+
+           if(un->pkt->pkttype==PKT_PUBLIC_KEY)
+             {
+               pk=un->pkt->pkt.public_key;
+               continue;
+             }
            if( un->pkt->pkttype != PKT_USER_ID )
                continue;
            if ( !un->pkt->pkt.user_id->created )
@@ -1325,6 +1364,13 @@ check_sig_and_print( CTX c, KBNODE node )
            if ( un->pkt->pkt.user_id->attrib_data )
                continue;
             
+           assert(pk);
+
+           /* Get it before we print anything to avoid interrupting
+              the output with the "please do a --check-trustdb"
+              line. */
+           valid=get_validity(pk,un->pkt->pkt.user_id);
+
             keyid_str[17] = 0; /* cut off the "[uncertain]" part */
             write_status_text_and_buffer (statno, keyid_str,
                                           un->pkt->pkt.user_id->name,
@@ -1336,7 +1382,11 @@ check_sig_and_print( CTX c, KBNODE node )
                       : _("Good signature from \""));
            print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name,
                                             un->pkt->pkt.user_id->len );
-           fputs("\"\n", log_get_stream() );
+           if(opt.verify_options&VERIFY_SHOW_VALIDITY)
+             fprintf (log_get_stream(),
+                       "\" [%s]\n",trust_value_to_string(valid));
+           else
+             fputs("\"\n", log_get_stream() );
             count++;
        }
        if( !count ) {  /* just in case that we have no valid textual
@@ -1380,10 +1430,7 @@ check_sig_and_print( CTX c, KBNODE node )
         /* If we have a good signature and already printed 
          * the primary user ID, print all the other user IDs */
         if ( count && !rc ) {
-           PKT_public_key *pk=NULL;
             for( un=keyblock; un; un = un->next ) {
-               if(un->pkt->pkttype==PKT_PUBLIC_KEY)
-                   pk=un->pkt->pkt.public_key;
                 if( un->pkt->pkttype != PKT_USER_ID )
                     continue;
                 if ( un->pkt->pkt.user_id->is_revoked )
@@ -1407,28 +1454,46 @@ check_sig_and_print( CTX c, KBNODE node )
                log_info(    _("                aka \""));
                 print_utf8_string( log_get_stream(), un->pkt->pkt.user_id->name,
                                                  un->pkt->pkt.user_id->len );
-                fputs("\"\n", log_get_stream() );
+               if(opt.verify_options&VERIFY_SHOW_VALIDITY)
+                 fprintf (log_get_stream(), "\" [%s]\n",
+                         trust_value_to_string(get_validity(pk,
+                                                            un->pkt->
+                                                            pkt.user_id)));
+               else
+                 fputs("\"\n", log_get_stream() );
             }
        }
        release_kbnode( keyblock );
 
        if( !rc )
          {
-           show_notation(sig,0,1);
-           show_policy_url(sig,0,1);
-         }
+           if(opt.verify_options&VERIFY_SHOW_POLICY)
+             show_policy_url(sig,0,1);
+           else
+             show_policy_url(sig,0,2);
+
+           if(opt.verify_options&VERIFY_SHOW_KEYSERVER)
+             show_keyserver_url(sig,0,1);
+           else
+             show_keyserver_url(sig,0,2);
+
+           if(opt.verify_options&VERIFY_SHOW_NOTATION)
+             show_notation(sig,0,1);
+           else
+             show_notation(sig,0,2);
+         }
 
        if( !rc && is_status_enabled() ) {
            /* print a status response with the fingerprint */
-           PKT_public_key *pk = xcalloc (1, sizeof *pk );
+           PKT_public_key *vpk = xcalloc (1, sizeof *vpk );
 
-           if( !get_pubkey( pk, sig->keyid ) ) {
+           if( !get_pubkey( vpk, sig->keyid ) ) {
                byte array[MAX_FINGERPRINT_LEN], *p;
                char buf[MAX_FINGERPRINT_LEN*4+90], *bufp;
                size_t i, n;
 
                 bufp = buf;
-               fingerprint_from_pk( pk, array, &n );
+               fingerprint_from_pk( vpk, array, &n );
                p = array;
                for(i=0; i < n ; i++, p++, bufp += 2)
                     sprintf(bufp, "%02X", *p );
@@ -1442,27 +1507,27 @@ check_sig_and_print( CTX c, KBNODE node )
                        sig->version,sig->pubkey_algo,sig->digest_algo,
                        sig->sig_class);
                 bufp = bufp + strlen (bufp);
-                if (!pk->is_primary) {
+                if (!vpk->is_primary) {
                    u32 akid[2];
  
-                   akid[0] = pk->main_keyid[0];
-                   akid[1] = pk->main_keyid[1];
-                   free_public_key (pk);
-                   pk = xcalloc (1, sizeof *pk );
-                   if (get_pubkey (pk, akid)) {
+                   akid[0] = vpk->main_keyid[0];
+                   akid[1] = vpk->main_keyid[1];
+                   free_public_key (vpk);
+                   vpk = xcalloc (1, sizeof *vpk );
+                   if (get_pubkey (vpk, akid)) {
                      /* impossible error, we simply return a zeroed out fpr */
                      n = MAX_FINGERPRINT_LEN < 20? MAX_FINGERPRINT_LEN : 20;
                      memset (array, 0, n);
                    }
                    else
-                     fingerprint_from_pk( pk, array, &n );
+                     fingerprint_from_pk( vpk, array, &n );
                 }
                p = array;
                for(i=0; i < n ; i++, p++, bufp += 2)
                     sprintf(bufp, "%02X", *p );
                write_status_text( STATUS_VALIDSIG, buf );
            }
-           free_public_key( pk );
+           free_public_key( vpk );
        }
 
        if( !rc )
index 4abe756..e122f0c 100644 (file)
@@ -369,6 +369,8 @@ pct_expando(const char *string,struct expando_args *args)
   if(args->sk)
     keyid_from_sk(args->sk,sk_keyid);
 
+  /* This is used so that %k works in photoid command strings in
+     --list-secret-keys (which of course has a sk, but no pk). */
   if(!args->pk && args->sk)
     keyid_from_sk(args->sk,pk_keyid);
 
@@ -430,16 +432,37 @@ pct_expando(const char *string,struct expando_args *args)
                }
              break;
 
-           case 'f': /* fingerprint */
+           case 'p': /* primary pk fingerprint of a sk */
+           case 'f': /* pk fingerprint */
+           case 'g': /* sk fingerprint */
              {
                byte array[MAX_FINGERPRINT_LEN];
                size_t len;
                int i;
 
-               if(args->pk)
+               if( ch[1]=='p' && args->sk)
+                 {
+                   if(args->sk->is_primary)
+                     fingerprint_from_sk(args->sk,array,&len);
+                   else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
+                     {
+                       PKT_public_key *pk= xcalloc(1, sizeof(PKT_public_key));
+
+                       if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
+                         fingerprint_from_pk(pk,array,&len);
+                       else
+                         memset(array,0,(len=MAX_FINGERPRINT_LEN));
+                       free_public_key(pk);
+                     }
+                   else
+                     memset(array,0,(len=MAX_FINGERPRINT_LEN));
+                 }
+               else if( ch[1]=='f' && args->pk)
                  fingerprint_from_pk(args->pk,array,&len);
+               else if( ch[1]=='g' && args->sk)
+                 fingerprint_from_sk(args->sk,array,&len);
                else
-                 memset(array,0, (len=MAX_FINGERPRINT_LEN));
+                 memset(array, 0, (len=MAX_FINGERPRINT_LEN));
 
                if(idx+(len*2)<maxlen)
                  {
index 9eda2e2..a4cbc38 100644 (file)
@@ -101,7 +101,7 @@ struct {
     unsigned int emulate_bugs; /* bug emulation flags EMUBUG_xxxx */
     int shm_coprocess;
     const char *set_filename;
-    const char *comment_string;
+    STRLIST comments;
     int throw_keyid;
     const char *photo_viewer;
     int s2k_mode;
@@ -153,6 +153,7 @@ struct {
     STRLIST cert_notation_data;
     STRLIST sig_policy_url;
     STRLIST cert_policy_url;
+    STRLIST sig_keyserver_url;
     int use_embedded_filename;
     int allow_non_selfsigned_uid;
     int allow_freeform_uid;
@@ -230,16 +231,22 @@ struct {
 #define EXPORT_SEXP_FORMAT               16
 
 
-#define LIST_SHOW_PHOTOS      1
-#define LIST_SHOW_POLICY      2
-#define LIST_SHOW_NOTATION    4
-#define LIST_SHOW_KEYRING     8
-#define LIST_SHOW_VALIDITY   16
-#define LIST_SHOW_LONG_KEYID 32
+#define LIST_SHOW_PHOTOS        1
+#define LIST_SHOW_POLICY        2
+#define LIST_SHOW_NOTATION      4
+#define LIST_SHOW_KEYSERVER     8
+#define LIST_SHOW_VALIDITY     16
+#define LIST_SHOW_LONG_KEYID   32
+#define LIST_SHOW_KEYRING      64
+#define LIST_SHOW_SIG_EXPIRE  128
 
-#define VERIFY_SHOW_PHOTOS   1
-#define VERIFY_SHOW_POLICY   2
-#define VERIFY_SHOW_NOTATION 4
+
+#define VERIFY_SHOW_PHOTOS      1
+#define VERIFY_SHOW_POLICY      2
+#define VERIFY_SHOW_NOTATION    4
+#define VERIFY_SHOW_KEYSERVER   8
+#define VERIFY_SHOW_VALIDITY   16
+#define VERIFY_SHOW_LONG_KEYID 32
 
 #endif /*G10_OPTIONS_H*/
 
index e50f66f..3d15f81 100644 (file)
 # support).
 #
 # Example HKP keyserver:
-#      x-hkp://pgp.mit.edu
+#      hkp://subkeys.pgp.net
 #
 # Example email keyserver:
-#      mailto:pgp-public-keys@keys.nl.pgp.net
+#      mailto:pgp-public-keys@keys.pgp.net
 #
 # Example LDAP keyservers:
 #      ldap://pgp.surfnet.nl:11370
 #
 # Regular URL syntax applies, and you can set an alternate port
 # through the usual method:
-#      x-hkp://keyserver.example.net:22742
+#      hkp://keyserver.example.net:22742
 #
 # If you have problems connecting to a HKP server through a buggy http
 # proxy, you can use keyserver option broken-http-proxy (see below),
 # regarding proxies (keyserver option honor-http-proxy)
 #
 # Most users just set the name and type of their preferred keyserver.
-# Most servers do synchronize with each other and DNS round-robin may
-# give you a quasi-random server each time.
-
-#keyserver x-hkp://pgp.mit.edu
+# Note that most servers (with the notable exception of
+# ldap://keyserver.pgp.com) synchronize changes with each other.  Note
+# also that a single server name may actually point to multiple
+# servers via DNS round-robin.  hkp://subkeys.pgp.net is an example of
+# such a "server", which spreads the load over a number of physical
+# servers.
+
+keyserver hkp://subkeys.pgp.net
 #keyserver mailto:pgp-public-keys@keys.nl.pgp.net
 #keyserver ldap://pgp.surfnet.nl:11370
 #keyserver ldap://keyserver.pgp.com
index dc5b158..2d87c9c 100644 (file)
@@ -132,8 +132,9 @@ typedef struct {
        unsigned unknown_critical:1;
         unsigned exportable:1;
         unsigned revocable:1;
-        unsigned policy_url:1; /* Policy URL is present */
-        unsigned notation:1; /* At least one notation is present */
+        unsigned policy_url:1; /* At least one policy URL is present */
+        unsigned notation:1;   /* At least one notation is present */
+        unsigned pref_ks:1;    /* At least one preferred keyserver is present */
         unsigned expired:1;
     } flags;
     u32     keyid[2];      /* 64 bit keyid */
@@ -463,8 +464,8 @@ int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
 
 /*-- sig-check.c --*/
 int signature_check( PKT_signature *sig, MD_HANDLE digest );
-int signature_check2( PKT_signature *sig, MD_HANDLE digest,
-                     u32 *r_expiredate, int *r_expired );
+int signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate,
+                     int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
 
 /*-- seckey-cert.c --*/
 int is_secret_key_protected( PKT_secret_key *sk );
index f70cc3f..c922eb5 100644 (file)
@@ -367,9 +367,29 @@ parse( iobuf_t inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
        lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
        if( !lenbytes ) {
            pktlen = 0; /* don't know the value */
-           if( pkttype != PKT_COMPRESSED )
-               iobuf_set_block_mode(inp, 1);
-       }
+            switch (pkttype) {
+              case PKT_ENCRYPTED:
+              case PKT_PLAINTEXT:
+                /* These partial length encodings are from an very
+                  early GnuPG release and deprecated.  However we
+                  still support them read-wise.  Note, that we should
+                  not allow them for any key related packets, because
+                  this might render a keyring unusable if an errenous
+                  packet indicated this mode but not complying to it
+                  gets imported. */
+                iobuf_set_block_mode(inp, 1);
+               break;
+
+              case PKT_COMPRESSED:
+                break; /* the orginal pgp 2 way. */
+
+              default:
+                log_error ("%s: old style partial length "
+                           "for invalid packet type\n", iobuf_where(inp) );
+                rc = gpg_error (GPG_ERR_INV_PACKET);
+                goto leave;
+            }
+       }
        else {
            for( ; lenbytes; lenbytes-- ) {
                pktlen <<= 8;
@@ -860,7 +880,8 @@ dump_sig_subpkt( int hashed, int type, int critical,
          printf(" %02X", buffer[i]);
        break;
       case SIGSUBPKT_PREF_KS:
-       p = "preferred key server";
+       fputs("preferred key server: ", stdout );
+       print_string( stdout, buffer, length, ')' );
        break;
       case SIGSUBPKT_PRIMARY_UID:
        p = "primary user ID";
@@ -936,6 +957,7 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
       case SIGSUBPKT_PREF_HASH:
       case SIGSUBPKT_PREF_COMPR:
       case SIGSUBPKT_POLICY:
+      case SIGSUBPKT_PREF_KS:
       case SIGSUBPKT_FEATURES:
       case SIGSUBPKT_REGEXP:
        return 0;
@@ -992,9 +1014,11 @@ can_handle_critical( const byte *buffer, size_t n, int type )
       case SIGSUBPKT_KEY_FLAGS:
       case SIGSUBPKT_PRIMARY_UID:
       case SIGSUBPKT_FEATURES:
-      case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
       case SIGSUBPKT_TRUST:
       case SIGSUBPKT_REGEXP:
+       /* Is it enough to show the policy or keyserver? */
+      case SIGSUBPKT_POLICY:
+      case SIGSUBPKT_PREF_KS:
        return 1;
 
       default:
@@ -1220,11 +1244,8 @@ parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
            goto leave;
        }
        if( n ) {
-            /* we add 8 extra bytes so that we have space for the signature
-             * status cache.  Well we are wasting this if there is a cache
-             * packet already, but in the other case it avoids an realloc */
-           sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n + 8 - 1 );
-            sig->unhashed->size = n + 8;
+           sig->unhashed = xmalloc (sizeof(*sig->unhashed) + n - 1 );
+            sig->unhashed->size = n;
            sig->unhashed->len = n;
            if( iobuf_read(inp, sig->unhashed->data, n ) != n ) {
                log_error("premature eof while reading "
@@ -1259,17 +1280,19 @@ parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
        }
 
        p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
-       if( !p )
-           log_error("signature packet without timestamp\n");
-       else
-           sig->timestamp = buffer_to_u32(p);
+       if(p)
+         sig->timestamp = buffer_to_u32(p);
+       else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+         log_error("signature packet without timestamp\n");
+
        p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
-       if( !p )
-           log_error("signature packet without keyid\n");
-       else {
-           sig->keyid[0] = buffer_to_u32(p);
-           sig->keyid[1] = buffer_to_u32(p+4);
+       if( p )
+       {
+          sig->keyid[0] = buffer_to_u32(p);
+          sig->keyid[1] = buffer_to_u32(p+4);
        }
+       else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+         log_error("signature packet without keyid\n");
 
        p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
        if(p)
@@ -1281,6 +1304,10 @@ parse_signature( iobuf_t inp, int pkttype, unsigned long pktlen,
        if(p)
          sig->flags.policy_url=1;
 
+       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL);
+       if(p)
+         sig->flags.pref_ks=1;
+
        p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
        if(p)
          sig->flags.notation=1;
index d003401..ac7e715 100644 (file)
@@ -29,7 +29,7 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 #endif
-#if defined (__MINGW32__) || defined (__CYGWIN32__)
+#if defined (_WIN32) || defined (__CYGWIN32__)
 # include <windows.h>
 #endif
 #include <errno.h>
@@ -101,7 +101,7 @@ static char *fd_passwd = NULL;
 static char *next_pw = NULL;
 static char *last_pw = NULL;
 
-#if defined (__MINGW32__)
+#if defined (_WIN32)
 static int read_fd = 0;
 static int write_fd = 0;
 #endif
@@ -191,7 +191,7 @@ read_passphrase_from_fd( int fd )
 static int
 writen ( int fd, const void *buf, size_t nbytes )
 {
-#if defined (__MINGW32__)
+#if defined (_WIN32)
     DWORD nwritten, nleft = nbytes;
     
     while (nleft > 0) {
@@ -234,7 +234,7 @@ writen ( int fd, const void *buf, size_t nbytes )
 static int
 readn ( int fd, void *buf, size_t buflen, size_t *ret_nread )
 {
-#if defined (__MINGW32__)
+#if defined (_WIN32)
     DWORD nread, nleft = buflen;
     
     while (nleft > 0) {
@@ -328,7 +328,7 @@ readline (int fd, char *buf, size_t buflen)
 
 #if !defined (__riscos__)
 
-#if !defined (__MINGW32__)
+#if !defined (_WIN32)
 /* For the new Assuan protocol we may have to send options */
 static int
 agent_send_option (int fd, const char *name, const char *value)
@@ -376,7 +376,11 @@ agent_send_all_options (int fd)
     }
 
   if (!opt.ttyname)
-    dft_ttyname = tty_get_ttyname ();
+    {
+      dft_ttyname = getenv ("GPG_TTY");
+      if ((!dft_ttyname || !*dft_ttyname) && tty_get_ttyname ())
+        dft_ttyname = tty_get_ttyname ();
+    }
   if (opt.ttyname || dft_ttyname)
     {
       if (agent_send_option (fd, "ttyname",
@@ -433,7 +437,7 @@ agent_send_all_options (int fd)
 #endif
   return rc;
 }
-#endif /*!__MINGW32__*/
+#endif /*!_WIN32*/
 
 
 /*
@@ -444,7 +448,7 @@ agent_send_all_options (int fd)
 static int
 agent_open (int *ret_prot)
 {
-#if defined (__MINGW32__)
+#if defined (_WIN32)
     int fd;
     char *infostr, *p;
     HANDLE h;
@@ -589,7 +593,7 @@ agent_open (int *ret_prot)
 static void
 agent_close ( int fd )
 {
-#if defined (__MINGW32__)
+#if defined (_WIN32)
     HANDLE h = OpenEvent(EVENT_ALL_ACCESS, FALSE, "gpg_agent");
     ResetEvent(h);
 #else
index 1dd6ede..00cc7a2 100644 (file)
@@ -22,7 +22,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#ifdef __MINGW32__ 
+#ifdef _WIN32 
 # include <windows.h>
 # ifndef VER_PLATFORM_WIN32_WINDOWS
 #  define VER_PLATFORM_WIN32_WINDOWS 1
@@ -223,7 +223,7 @@ char *image_type_to_string(byte type,int style)
 #if !defined(FIXED_PHOTO_VIEWER) && !defined(DISABLE_PHOTO_VIEWER)
 static const char *get_default_photo_command(void)
 {
-#if defined(__MINGW32__)
+#if defined(_WIN32)
   OSVERSIONINFO osvi;
 
   memset(&osvi,0,sizeof(osvi));
index 5a4aa25..71e6492 100644 (file)
@@ -1164,10 +1164,6 @@ algo_available( preftype_t preftype, int algo, void *hint )
                  && algo != DIGEST_ALGO_SHA256))
        return 0;
 
-      /* TIGER is not allowed any longer according to 2440bis. */
-      if( RFC2440 && algo == DIGEST_ALGO_TIGER )
-       return 0;
-
       return algo && !gcry_md_test_algo( algo );
     }
   else if( preftype == PREFTYPE_ZIP )
index cf1bfe1..161bd2b 100644 (file)
@@ -608,7 +608,7 @@ ask_revocation_reason( int key_rev, int cert_rev, int hint )
              return NULL; /* cancel */
            if( hint && !*answer )
                n = hint;
-           else if(!isdigit( *answer ) )
+           else if(!digitp( answer ) )
                n = -1;
            else
                n = atoi(answer);
index 4547c6e..b0c89cb 100644 (file)
@@ -43,8 +43,9 @@ struct cmp_help_context_s {
     MD_HANDLE md;
 };
 
-static int do_check( PKT_public_key *pk, PKT_signature *sig,
-                                        MD_HANDLE digest, int *r_expired );
+
+static int do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
+                    int *r_expired, int *r_revoked, PKT_public_key *ret_pk);
 
 /****************
  * Check the signature which is contained in SIG.
@@ -54,20 +55,16 @@ static int do_check( PKT_public_key *pk, PKT_signature *sig,
 int
 signature_check( PKT_signature *sig, MD_HANDLE digest )
 {
-    u32 dummy;
-    int dum2;
-    return signature_check2( sig, digest, &dummy, &dum2 );
+    return signature_check2( sig, digest, NULL, NULL, NULL, NULL );
 }
 
 int
-signature_check2( PKT_signature *sig, MD_HANDLE digest,
-                 u32 *r_expiredate, int *r_expired )
+signature_check2( PKT_signature *sig, MD_HANDLE digest, u32 *r_expiredate, 
+                 int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
 {
     PKT_public_key *pk = xcalloc (1, sizeof *pk );
     int rc=0;
 
-    *r_expiredate = 0;
-
     /* Sanity check that the md has a context for the hash that the
        sig is expecting.  This can happen if a onepass sig header does
        not match the actual sig, and also if the clearsign "Hash:"
@@ -83,8 +80,9 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest,
         rc=GPG_ERR_BAD_PUBKEY; /* you cannot have a good sig from an
                                 invalid subkey */
     else {
-       *r_expiredate = pk->expiredate;
-       rc = do_check( pk, sig, digest, r_expired );
+        if (r_expiredate)
+           *r_expiredate = pk->expiredate;
+       rc = do_check( pk, sig, digest, r_expired, r_revoked, ret_pk );
     }
 
     free_public_key( pk );
@@ -135,11 +133,15 @@ signature_check2( PKT_signature *sig, MD_HANDLE digest,
 
 
 static int
-do_check_messages( PKT_public_key *pk, PKT_signature *sig, int *r_expired )
+do_check_messages( PKT_public_key *pk, PKT_signature *sig,
+                   int *r_expired, int *r_revoked )
 {
     u32 cur_time;
 
-    *r_expired = 0;
+    if (r_expired)
+      *r_expired = 0;
+    if (r_revoked)
+      *r_revoked = 0;
     if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
        log_info(_("key %08lX: this is a PGP generated "
                   "ElGamal key which is NOT secure for signatures!\n"),
@@ -182,22 +184,26 @@ do_check_messages( PKT_public_key *pk, PKT_signature *sig, int *r_expired )
        sprintf(buf,"%lu",(ulong)pk->expiredate);
        write_status_text(STATUS_KEYEXPIRED,buf);
        write_status(STATUS_SIGEXPIRED);
-       *r_expired = 1;
+        if (r_expired)
+          *r_expired = 1;
     }
 
+    if(pk->is_revoked && r_revoked)
+      *r_revoked=1;
+
     return 0;
 }
 
 
 static int
 do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
-                                                   int *r_expired )
+         int *r_expired, int *r_revoked, PKT_public_key *ret_pk )
 {
     gcry_mpi_t result = NULL;
     int rc=0;
     struct cmp_help_context_s ctx;
 
-    if( (rc=do_check_messages(pk,sig,r_expired)) )
+    if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
         return rc;
     if( (rc=gcry_md_test_algo(sig->digest_algo)) )
        return rc;
@@ -280,6 +286,9 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
        rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
     }
 
+    if(!rc && ret_pk)
+      copy_public_key(ret_pk,pk);
+
     return rc;
 }
 
@@ -406,16 +415,19 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
 int
 check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
 {
-    u32 dummy;
-    int dum2;
-    return check_key_signature2(root, node, NULL, is_selfsig, &dummy, &dum2 );
+    return check_key_signature2(root, node, NULL, NULL, is_selfsig, NULL, NULL);
 }
 
 /* If check_pk is set, then use it to check the signature in node
-   rather than getting it from root or the keydb. */
+   rather than getting it from root or the keydb.  If ret_pk is set,
+   fill in the public key that was used to verify the signature.
+   ret_pk is only meaningful when the verification was successful. */
+/* TODO: add r_revoked here as well.  It has the same problems as
+   r_expiredate and r_expired and the cache. */
 int
 check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
-                     int *is_selfsig, u32 *r_expiredate, int *r_expired )
+                     PKT_public_key *ret_pk, int *is_selfsig,
+                      u32 *r_expiredate, int *r_expired )
 {
     MD_HANDLE md;
     PKT_public_key *pk;
@@ -425,8 +437,10 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
 
     if( is_selfsig )
        *is_selfsig = 0;
-    *r_expiredate = 0;
-    *r_expired = 0;
+    if( r_expiredate )
+        *r_expiredate = 0;
+    if( r_expired )
+        *r_expired = 0;
     assert( node->pkt->pkttype == PKT_SIGNATURE );
     assert( root->pkt->pkttype == PKT_PUBLIC_KEY );
 
@@ -444,7 +458,9 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
                if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
                    *is_selfsig = 1;
            }
-           if((rc=do_check_messages(pk,sig,r_expired)))
+           /* BUG: This is wrong for non-self-sigs. Needs to be the
+              actual pk */
+           if((rc=do_check_messages(pk,sig,r_expired,NULL)))
              return rc;
             return sig->flags.valid? 0 : gpg_error (GPG_ERR_BAD_SIGNATURE);
         }
@@ -464,7 +480,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
          {
            gcry_md_open (&md, algo, 0 );
            hash_public_key( md, pk );
-           rc = do_check( pk, sig, md, r_expired );
+           rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
            cache_sig_result ( sig, rc );
            gcry_md_close(md);
          }
@@ -476,12 +492,12 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
            gcry_md_open (&md, algo, 0 );
            hash_public_key( md, pk );
            hash_public_key( md, snode->pkt->pkt.public_key );
-           rc = do_check( pk, sig, md, r_expired );
+           rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
             cache_sig_result ( sig, rc );
            gcry_md_close(md);
        }
        else {
-            if (!opt.quiet)
+            if (opt.verbose)
                 log_info (_("key %08lX: no subkey for subkey "
                            "revocation signature\n"),
                           (ulong)keyid_from_pk (pk, NULL));
@@ -502,7 +518,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
            gcry_md_open (&md, algo, 0 );
            hash_public_key( md, pk );
            hash_public_key( md, snode->pkt->pkt.public_key );
-           rc = do_check( pk, sig, md, r_expired );
+           rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
             cache_sig_result ( sig, rc );
            gcry_md_close(md);
        }
@@ -517,7 +533,7 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
     else if( sig->sig_class == 0x1f ) { /* direct key signature */
        gcry_md_open (&md, algo, 0 );
        hash_public_key( md, pk );
-       rc = do_check( pk, sig, md, r_expired );
+       rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
         cache_sig_result ( sig, rc );
        gcry_md_close(md);
     }
@@ -535,12 +551,13 @@ check_key_signature2( KBNODE root, KBNODE node, PKT_public_key *check_pk,
              {
                if( is_selfsig )
                  *is_selfsig = 1;
-               rc = do_check( pk, sig, md, r_expired );
+               rc = do_check( pk, sig, md, r_expired, NULL, ret_pk );
              }
            else if (check_pk)
-             rc=do_check(check_pk,sig,md,r_expired);
+             rc=do_check(check_pk,sig,md,r_expired, NULL, ret_pk);
            else
-             rc = signature_check2( sig, md, r_expiredate, r_expired );
+             rc = signature_check2( sig, md, r_expiredate, r_expired,
+                                     NULL, ret_pk);
 
             cache_sig_result ( sig, rc );
            gcry_md_close(md);
index 493bfb4..640e36f 100644 (file)
@@ -55,12 +55,12 @@ void __stdcall Sleep(ulong);
 static int recipient_digest_algo=0;
 
 /****************
- * Create a notation.  It is assumed that the stings in STRLIST
- * are already checked to contain only printable data and have a valid
- * NAME=VALUE format.
+ * Create a notation.  We assume thIt is assumed that the strings in
+ * the STRLISTs of the opt struct are already checked to contain only
+ * printable data and have a valid NAME=VALUE format.
  */
 static void
-mk_notation_and_policy( PKT_signature *sig,
+mk_notation_policy_etc( PKT_signature *sig,
                        PKT_public_key *pk, PKT_secret_key *sk )
 {
     const char *string;
@@ -74,18 +74,25 @@ mk_notation_and_policy( PKT_signature *sig,
     args.pk=pk;
     args.sk=sk;
 
+    /* It is actually impossible to get here when making a v3 key
+       signature since keyedit.c:sign_uids will automatically bump a
+       signature with a notation or policy url up to v4, but it is
+       good to do these checks anyway. */
+
     /* notation data */
     if(IS_SIG(sig) && opt.sig_notation_data)
       {
        if(sig->version<4)
-         log_info("can't put notation data into v3 signatures\n");
+         log_error(_("can't put notation data into v3 (PGP 2.x style) "
+                     "signatures\n"));
        else
          nd=opt.sig_notation_data;
       }
     else if( IS_CERT(sig) && opt.cert_notation_data )
       {
        if(sig->version<4)
-         log_info("can't put notation data into v3 key signatures\n");
+         log_error(_("can't put notation data into v3 (PGP 2.x style) "
+                     "key signatures\n"));
        else
          nd=opt.cert_notation_data;
       }
@@ -125,21 +132,20 @@ mk_notation_and_policy( PKT_signature *sig,
        xfree (buf);
     }
 
-    if(opt.list_options&LIST_SHOW_NOTATION)
-      show_notation(sig,0,0);
-
     /* set policy URL */
     if( IS_SIG(sig) && opt.sig_policy_url )
       {
        if(sig->version<4)
-         log_info("can't put a policy URL into v3 signatures\n");
+         log_error(_("can't put a policy URL into v3 (PGP 2.x style) "
+                     "signatures\n"));
        else
          pu=opt.sig_policy_url;
       }
     else if( IS_CERT(sig) && opt.cert_policy_url )
       {
        if(sig->version<4)
-         log_info("can't put a policy URL into v3 key signatures\n");
+         log_error(_("can't put a policy URL into v3 key (PGP 2.x style) "
+                     "signatures\n"));
        else
          pu=opt.cert_policy_url;
       }
@@ -163,8 +169,34 @@ mk_notation_and_policy( PKT_signature *sig,
        xfree (s);
       }
 
-    if(opt.list_options&LIST_SHOW_POLICY)
-      show_policy_url(sig,0,0);
+    /* preferred keyserver URL */
+    if( IS_SIG(sig) && opt.sig_keyserver_url )
+      {
+       if(sig->version<4)
+         log_info (_("can't put a preferred keyserver URL "
+                      "into v3 signatures\n"));
+       else
+         pu=opt.sig_keyserver_url;
+      }
+
+    for(;pu;pu=pu->next)
+      {
+        string = pu->d;
+
+       s=pct_expando(string,&args);
+       if(!s)
+         {
+           log_error(_("WARNING: unable to %%-expand preferred keyserver URL"
+                       " (too large).  Using unexpanded.\n"));
+           s=xstrdup(string);
+         }
+
+       build_sig_subpkt(sig,SIGSUBPKT_PREF_KS|
+                        ((pu->flags & 1)?SIGSUBPKT_FLAG_CRITICAL:0),
+                        s,strlen(s));
+
+       xfree(s);
+      }
 }
 
 
@@ -621,7 +653,8 @@ write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash,
        sig = xcalloc (1,sizeof *sig);
        if(opt.force_v3_sigs || RFC1991)
          sig->version=3;
-       else if(duration || opt.sig_policy_url || opt.sig_notation_data)
+       else if(duration || opt.sig_policy_url
+               || opt.sig_notation_data || opt.sig_keyserver_url)
          sig->version=4;
        else
          sig->version=sk->version;
@@ -640,7 +673,7 @@ write_signature_packets (SK_LIST sk_list, iobuf_t out, MD_HANDLE hash,
 
        if (sig->version >= 4)
            build_sig_subpkt_from_sig (sig);
-       mk_notation_and_policy (sig, NULL, sk);
+       mk_notation_policy_etc (sig, NULL, sk);
 
         hash_sigversion_to_magic (md, sig);
        gcry_md_final (md);
@@ -1308,7 +1341,7 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
     sig->sig_class = sigclass;
     if( sig->version >= 4 )
        build_sig_subpkt_from_sig( sig );
-    mk_notation_and_policy( sig, pk, sk );
+    mk_notation_policy_etc ( sig, pk, sk );
 
     /* Crucial that the call to mksubpkt comes LAST before the calls
        to finalize the sig as that makes it possible for the mksubpkt
index 90c0841..9f50fbe 100644 (file)
@@ -1,5 +1,5 @@
 /* signal.c - signal handling
- * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -42,7 +42,7 @@ static void
 init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
 {
 #ifndef HAVE_DOSISH_SYSTEM
-#ifdef HAVE_SIGACTION
+#if defined(HAVE_SIGACTION) && defined(HAVE_STRUCT_SIGACTION)
     struct sigaction oact, nact;
 
     if (check_ign) {
@@ -132,7 +132,7 @@ void
 pause_on_sigusr( int which )
 {
 #ifndef HAVE_DOSISH_SYSTEM
-#ifdef HAVE_SIGPROCMASK
+#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
     sigset_t mask, oldmask;
 
     assert( which == 1 );
@@ -150,8 +150,8 @@ pause_on_sigusr( int which )
      while (!caught_sigusr1)
          sigpause(SIGUSR1);
      caught_sigusr1 = 0;
-     sigrelse(SIGUSR1); ????
-#endif /*!HAVE_SIGPROCMASK*/
+     sigrelse(SIGUSR1); 
+#endif /*!HAVE_SIGPROCMASK && HAVE_SISET_T*/
 #endif
 }
 
@@ -161,7 +161,7 @@ do_block( int block )
 {
 #ifndef HAVE_DOSISH_SYSTEM
     static int is_blocked;
-#ifdef HAVE_SIGPROCMASK
+#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
     static sigset_t oldmask;
 
     if( block ) {
@@ -180,13 +180,22 @@ do_block( int block )
        is_blocked = 0;
     }
 #else /*!HAVE_SIGPROCMASK*/
-    static void (*disposition[MAXSIG])();
+
+#if defined(NSIG)
+# define SIGSMAX (NSIG)
+#elif defined(MAXSIG)
+# define SIGSMAX (MAXSIG+1)
+#else
+# error "define SIGSMAX to the number of signals on your platform plus one"
+#endif
+
+    static void (*disposition[SIGSMAX])(int);
     int sig;
 
     if( block ) {
        if( is_blocked )
            log_bug("signals are already blocked\n");
-        for (sig=1; sig < MAXSIG; sig++) {
+        for (sig=1; sig < SIGSMAX; sig++) {
             disposition[sig] = sigset (sig, SIG_HOLD);
         }
        is_blocked = 1;
@@ -194,7 +203,7 @@ do_block( int block )
     else {
        if( !is_blocked )
            log_bug("signals are not blocked\n");
-        for (sig=1; sig < MAXSIG; sig++) {
+        for (sig=1; sig < SIGSMAX; sig++) {
             sigset (sig, disposition[sig]);
         }
        is_blocked = 0;
index 4414b33..aa55020 100644 (file)
@@ -129,6 +129,7 @@ get_status_string ( int no )
       case STATUS_SIGEXPIRED     : s = "SIGEXPIRED deprecated-use-keyexpired-instead"; break;
       case STATUS_EXPSIG         : s = "EXPSIG"; break;
       case STATUS_EXPKEYSIG      : s = "EXPKEYSIG"; break;
+      case STATUS_REVKEYSIG      : s = "REVKEYSIG"; break;
       case STATUS_ATTRIBUTE      : s = "ATTRIBUTE"; break;
       default: s = "?"; break;
     }
index 4a0bcd4..d8de810 100644 (file)
@@ -99,6 +99,7 @@
 #define STATUS_ATTRIBUTE        67
 #define STATUS_IMPORT_OK       68
 #define STATUS_IMPORT_CHECK     69
+#define STATUS_REVKEYSIG        70
 
 /*-- status.c --*/
 void set_status_fd ( int fd );
index 3f9e8b3..5eb4829 100644 (file)
@@ -154,7 +154,7 @@ import_ownertrust( const char *fname )
            break; /* can't continue */
        }
        for(p = line; *p && *p != ':' ; p++ )
-           if( !isxdigit(*p) )
+           if( !hexdigitp (p) )
                break;
        if( *p != ':' ) {
            log_error (_("\b%s: error: missing colon\n"), fname );
index 39239be..d1b5ed3 100644 (file)
@@ -337,6 +337,9 @@ tdbio_sync()
 }
 
 
+#if 0
+/* The transaction code is disabled in the 1.2.x branch, as it is not
+   yet used.  It will be enabled in 1.3.x. */
 
 /****************
  * Simple transactions system:
@@ -408,6 +411,8 @@ tdbio_cancel_transaction()
     return 0;
 }
 
+#endif /* transaction code */
+
 
 \f
 /********************************************************
index 16bd96e..864334f 100644 (file)
@@ -591,6 +591,31 @@ trustdb_pending_check(void)
   return pending_check_trustdb;
 }
 
+void
+read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
+                  byte *marginals,byte *completes,byte *cert_depth)
+{
+  TRUSTREC opts;
+
+  init_trustdb();
+
+  read_record(0,&opts,RECTYPE_VER);
+
+  if(trust_model)
+    *trust_model=opts.r.ver.trust_model;
+  if(created)
+    *created=opts.r.ver.created;
+  if(nextcheck)
+    *nextcheck=opts.r.ver.nextcheck;
+  if(marginals)
+    *marginals=opts.r.ver.marginals;
+  if(completes)
+    *completes=opts.r.ver.completes;
+  if(cert_depth)
+    *cert_depth=opts.r.ver.cert_depth;
+}
+
+
 \f
 /***********************************************
  ***********  Ownertrust et al. ****************
@@ -1573,10 +1598,14 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
         signed (but not self-signed) uid does carry trust, of a sort,
         even if it is a statement being made by people other than the
         key owner "through" the uids on the key owner's key.  I'm
-        going with the latter. -dshaw */
+        going with the latter.  However, if the user ID was
+        explicitly revoked, or passively allowed to expire, that
+        should stop validity through the user ID until it is
+        resigned.  -dshaw */
 
-      /* && node->pkt->pkt.user_id->created) */
-      if (node->pkt->pkttype == PKT_USER_ID)
+      if (node->pkt->pkttype == PKT_USER_ID
+         && !node->pkt->pkt.user_id->is_revoked
+         && !node->pkt->pkt.user_id->is_expired)
         {
           if (uidnode && issigned)
             {
@@ -1590,12 +1619,11 @@ validate_one_keyblock (KBNODE kb, struct key_item *klist,
             }
           uidnode = node;
          uid=uidnode->pkt->pkt.user_id;
-#if 0
-         /* If the selfsig is going to expire...  This is disabled as
-            we do count un-self-signed uids in the web of trust. */
+
+         /* If the selfsig is going to expire... */
          if(uid->expiredate && uid->expiredate<*next_expire)
            *next_expire = uid->expiredate;
-#endif
+
           issigned = 0;
          get_validity_counts(pk,uid);
           mark_usable_uid_certs (kb, uidnode, main_kid, klist, 
index 720385a..414c377 100644 (file)
@@ -64,6 +64,9 @@ int enum_cert_paths( void **context, ulong *lid,
 void enum_cert_paths_print( void **context, FILE *fp,
                                           int refresh, ulong selected_lid );
 
+void read_trust_options(byte *trust_model,ulong *created,ulong *nextcheck,
+                       byte *marginals,byte *completes,byte *cert_depth);
+
 unsigned int get_ownertrust (PKT_public_key *pk);
 unsigned int get_min_ownertrust (PKT_public_key *pk);
 int get_ownertrust_info (PKT_public_key *pk);
index 380d63b..5b343f5 100644 (file)
@@ -1,3 +1,14 @@
+2003-09-04  David Shaw  <dshaw@jabberwocky.com>
+
+       * cipher.h: Drop TIGER/192 support.
+
+       * types.h: Prefer using uint64_t when creating a 64-bit unsigned
+       type. This avoids a warning on compilers that support but complain
+       about unsigned long long.
+
+       * util.h: Make sure that only ascii is passed to isfoo
+       functions. (From Werner on stable branch).
+
 2003-09-04  Werner Koch  <wk@gnupg.org>
 
        * cipher.h (PUBKEY_USAGE_AUTH): Added.
index 90cedb0..e7e36c6 100644 (file)
@@ -53,7 +53,6 @@
 #define DIGEST_ALGO_MD5       GCRY_MD_MD5
 #define DIGEST_ALGO_SHA1      GCRY_MD_SHA1
 #define DIGEST_ALGO_RMD160    GCRY_MD_RMD160
-#define DIGEST_ALGO_TIGER     GCRY_MD_TIGER
 #define DIGEST_ALGO_SHA256    GCRY_MD_SHA256
 #define DIGEST_ALGO_SHA384    GCRY_MD_SHA384
 #define DIGEST_ALGO_SHA512    GCRY_MD_SHA512
index 838897a..dff5120 100644 (file)
@@ -101,7 +101,11 @@ typedef unsigned long u32;
  */
 #ifndef HAVE_U64_TYPEDEF
 #undef u64         /* maybe there is a macro with this name */
-#if SIZEOF_UNSIGNED_INT == 8
+#if SIZEOF_UINT64_T == 8
+typedef uint64_t u64;
+#define U64_C(c) (UINT64_C(c))
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_INT == 8
 typedef unsigned int u64;
 #define U64_C(c) (c ## U)
 #define HAVE_U64_TYPEDEF
@@ -113,10 +117,6 @@ typedef unsigned long u64;
 typedef unsigned long long u64;
 #define U64_C(c) (c ## ULL)
 #define HAVE_U64_TYPEDEF
-#elif SIZEOF_UINT64_T == 8
-typedef uint64_t u64;
-#define U64_C(c) (UINT64_C(c))
-#define HAVE_U64_TYPEDEF
 #endif
 #endif