See ChangeLog: Wed May 19 16:04:30 CEST 1999 Werner Koch
authorWerner Koch <wk@gnupg.org>
Wed, 19 May 1999 14:12:26 +0000 (14:12 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 19 May 1999 14:12:26 +0000 (14:12 +0000)
17 files changed:
BUGS
NEWS
TODO
checks/defs.inc
configure.in
doc/gpg.1pod
g10/ChangeLog
g10/filter.h
g10/g10.c
g10/import.c
g10/keyedit.c
g10/main.h
g10/mainproc.c
g10/mdfilter.c
g10/openfile.c
g10/options.h
g10/plaintext.c

diff --git a/BUGS b/BUGS
index 21ac85d..9a1f5d7 100644 (file)
--- a/BUGS
+++ b/BUGS
@@ -16,7 +16,11 @@ and after about half a day in the rsync snapshots.
 [  *] #1
     pgp263in works fine even with a source file with CR,LF but GnuPG
     and pgp263in has problems if the clearsign has been created by
-    pgp263ia.
+    pgp263ia.  The reason for this problem is that pgp2 sometimes
+    converts CR,LF to CR,CR,LF and to fix for this it hashes both
+    versions.  I was able to reproduce such a problem, that PGP263in
+    was not able to verify it's own signature.
+    FIX: 1999-05-19  (Most cases are now handled)
 
 [  *] #3
     --list-packets should continue even w/o a passphrase (or in batch
@@ -48,5 +52,8 @@ and after about half a day in the rsync snapshots.
     --> IRIX bug still there
 
 
-Next #17
+[ **] #17 1999-05-18 <Bodo_Moeller@public.uni-hamburg.de> 0.9.6
+    Import does not detect identical user IDs.
+
+Next #18
 
diff --git a/NEWS b/NEWS
index c5cf2fa..aadd1b1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,8 @@
 
+    * New option --interactive to prompt before overwriting files.
 
-
-
+    * Add a work around for a bug in pgp 2 which led to bad signatures
+      when used with canoncial texts in some cases.
 
 
 Noteworthy changes in version 0.9.6
diff --git a/TODO b/TODO
index c835bae..4425430 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,6 +5,7 @@
   * Speed up calculation of key validity.
 
   * See why we always get this "Hmmm, public key not anymore available"
+    Rewrite that stuff.
 
   * print a warning when a revoked/expired _secret_ key is used.
 
@@ -21,8 +22,6 @@
   * Solaris make has problems with the generated POTFILES - seems to be a
     gettext bug.
 
-  * cvs -d :pserver:anoncvs@anoncvs.gnu.org:/gd/gnu/anoncvsroot co common
-
   * find a way to allow the import of non-self-signed keys.  This is needed
     for the IN ENCR/SIGN hack.
 
@@ -50,4 +49,7 @@ Nice to have
   * Stats about used random numbers.
   * the pubkey encrypt functions should do some sanity checks.
   * dynload: implement the hint stuff.
+  * "gpg filename.tar.gz.asc" sollte wie mit --verify funktionieren (-sab).
+  * Den Dateinamen aus der message nicht benutzen, sondern nur
+    das gpg/asc strippen.
 
index 45d54df..5c4a82b 100755 (executable)
@@ -25,6 +25,9 @@ plain_files="plain-1 plain-2 plain-3"
 data_files="data-500 data-9000 data-32000 data-80000"
 exp_files=""
 
+# The testscripts expect the original language
+LANG=
+LANGUAGE=
 
 #--------------------------------
 #------ utility functions -------
index 21d5f8c..944325d 100644 (file)
@@ -195,6 +195,7 @@ esac
 AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME")
 
 dnl  Fixme: Are these the best flags for OpenBSD????
+dnl (I have removed the -lc from * ...CFLAGS for test purposes.)
 case "${target}" in
     *-openbsd*)
         NAME_OF_DEV_RANDOM="/dev/srandom"
@@ -204,7 +205,7 @@ case "${target}" in
     *)
         NAME_OF_DEV_RANDOM="/dev/random"
         NAME_OF_DEV_URANDOM="/dev/urandom"
-        DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC -lc"
+        DYNLINK_MOD_CFLAGS="-shared $CFLAGS_PIC"
         ;;
 esac
 AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM")
index 26d96f9..33791e5 100644 (file)
@@ -295,6 +295,9 @@ B<-t>, B<--textmode>
 B<-n>, B<--dry-run>
     Don't make any changes (not yet implemented).
 
+B<-i>, B<--interactive>
+    Prompt before overwriting any files.
+
 B<--batch>
     Use batch mode.  Never ask, do not allow interactive
     commands.
index 177850f..4b8d989 100644 (file)
@@ -1,5 +1,15 @@
-Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+Wed May 19 16:04:30 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * g10.c: New option --interactive.
 
+       * mainproc.c (proc_plaintext): Add workaround for pgp2 bug
+       (do_check_sig): Ditto.
+       (proc_tree): Ditto.
+       * plaintext.c (do_hash): Ditto.
+       (hash_datafiles): Ditto, add an arg, changed all callers.
+       * mdfilter.c (md_filter): Add support for the alternate hash context.
+
+Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * parse-packet.c (parse_encrypted): Support for PKT_ENCRYPTED_MDC.
        * build-packet.c (do_encrypted_mdc): Ditto.
@@ -13,7 +23,6 @@ Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
        length calculation
        (parse_signature): Fixed even more stupid bug.
 
-
 Sat May  8 19:28:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * build-packet.c (do_signature): Removed MDC hack.
index 8fb875d..30a59d1 100644 (file)
@@ -25,6 +25,7 @@
 
 typedef struct {
     MD_HANDLE md;      /* catch all */
+    MD_HANDLE md2;     /* if we want to calculate an alternate hash */
     size_t maxbuf_size;
 } md_filter_context_t;
 
index 945ed04..8d06632 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -52,6 +52,7 @@ enum cmd_and_opt_values { aNull = 0,
     aSym         = 'c',
     aDecrypt     = 'd',
     aEncr        = 'e',
+    oInteractive  = 'i',
     oKOption     = 'k',
     oDryRun      = 'n',
     oOutput      = 'o',
@@ -223,6 +224,7 @@ static ARGPARSE_OPTS opts[] = {
     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
     { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
     { oDryRun, "dry-run",   0, N_("do not make any changes") },
+    { oInteractive, "interactive", 0, N_("prompt before overwriting") },
     { 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")},
@@ -637,6 +639,7 @@ main( int argc, char **argv )
          case oOutput: opt.outfile = pargs.r.ret_str; break;
          case oQuiet: opt.quiet = 1; break;
          case oDryRun: opt.dry_run = 1; break;
+         case oInteractive: opt.interactive = 1; break;
          case oVerbose: g10_opt_verbose++;
                    opt.verbose++; opt.list_sigs=1; break;
          case oKOption: set_cmd( &cmd, aKMode ); break;
index 0d8463c..f9ddcd4 100644 (file)
@@ -423,8 +423,11 @@ import_one( const char *fname, KBNODE keyblock, int fast )
        }
        /* and try to merge the block */
        clear_kbnode_flags( keyblock_orig );
-       clear_kbnode_flags( keyblock );
        n_uids = n_sigs = n_subk = 0;
+       rc = collapse_uids( fname, keyblock, keyid );
+       if( rc )
+           goto leave;
+       clear_kbnode_flags( keyblock );
        rc = merge_blocks( fname, keyblock_orig, keyblock,
                                keyid, &n_uids, &n_sigs, &n_subk );
        if( rc )
@@ -845,6 +848,43 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
 
 
 /****************
+ * It may happen that the imported keyblock has duplicated user IDs.
+ * We check this here and collapse those user IDs together with their
+ * sigs into one.
+ * This function modifies the node flags!
+ */
+static int
+collapse_uids( const char *fname, KBNODE keyblock, u32 *keyid )
+{
+    KBNODE n, n2, n3;
+    int rc, found;
+
+    for(found = 0, n=keyblock; n && !found ; n = n->next ) {
+       if( n->pkt->pkttype == PKT_USER_ID ) {
+           for( n2 = n->next; n2; n2 = n2->next ) {
+               if( n2->pkt->pkttype == PKT_USER_ID
+                   && !cmp_user_ids( n->pkt->pkt.user_id,
+                                     n2->pkt->pkt.user_id ) ) {
+                   found = 1;
+                   break;
+               }
+           }
+       }
+    }
+    if( !found )
+       return 0; /* nothing to do */
+
+    clear_kbnode_flags( keyblock );
+
+    /* now transfer the cloned nodes to the original ones */
+    #warning We are working HERE!!!
+
+    return 0;
+}
+
+
+
+/****************
  * compare and merge the blocks
  *
  * o compare the signatures: If we already have this signature, check
@@ -991,11 +1031,6 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
 
 /****************
  * append the userid starting with NODE and all signatures to KEYBLOCK.
- * Mark all new and copied packets by setting flag bit 0.
- * FIXME: It may happen that two identical user ID gets imported; should we
- *       add another check and how can we handle the signature?  Maybe
- *       we have to collapse both UIDs into one and then remove duplicated
- *       signatures.
  */
 static int
 append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
index 85f3dfa..a8e783f 100644 (file)
@@ -474,7 +474,7 @@ change_passphrase( KBNODE keyblock )
 /****************
  * There are some keys out (due to a bug in gnupg), where the sequence
  * of the packets is wrong.  This function fixes that.
- * Returns: true if the keyblock has fixed.
+ * Returns: true if the keyblock has been fixed.
  */
 static int
 fix_keyblock( KBNODE keyblock )
index c3f2363..ce7e8ac 100644 (file)
@@ -137,8 +137,8 @@ int verify_signatures( int nfiles, char **files );
 int decrypt_message( const char *filename );
 
 /*-- plaintext.c --*/
-int hash_datafiles( MD_HANDLE md, STRLIST files, const char *sigfilename,
-                   int textmode );
+int hash_datafiles( MD_HANDLE md, MD_HANDLE md2,
+                   STRLIST files, const char *sigfilename, int textmode );
 
 /*-- signal.c --*/
 void init_signals(void);
index a560fcb..5fa934c 100644 (file)
@@ -268,7 +268,7 @@ static void
 proc_plaintext( CTX c, PACKET *pkt )
 {
     PKT_plaintext *pt = pkt->pkt.plaintext;
-    int any, clearsig, rc;
+    int any, clearsig, only_md5, rc;
     KBNODE n;
 
     if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) )
@@ -283,13 +283,21 @@ proc_plaintext( CTX c, PACKET *pkt )
      * Should we assume that plaintext in mode 't' has always sigclass 1??
      * See: Russ Allbery's mail 1999-02-09
      */
-    any = clearsig = 0;
+    any = clearsig = only_md5 = 0;
     for(n=c->list; n; n = n->next ) {
        if( n->pkt->pkttype == PKT_ONEPASS_SIG ) {
            if( n->pkt->pkt.onepass_sig->digest_algo ) {
                md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo );
+               if( !any && n->pkt->pkt.onepass_sig->digest_algo
+                                                     == DIGEST_ALGO_MD5 )
+                   only_md5 = 1;
+               else
+                   only_md5 = 0;
                any = 1;
            }
+           if( n->pkt->pkt.onepass_sig->sig_class != 0x01 )
+               only_md5 = 0;
+
            /* Check whether this is a cleartext signature.  We assume that
             * we have one if the sig_class is 1 and the keyid is 0, that
             * are the faked packets produced by armor.c.  There is a
@@ -309,6 +317,14 @@ proc_plaintext( CTX c, PACKET *pkt )
        md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
        md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
     }
+    if( only_md5 ) {
+       /* This is a kludge to work around a bug in pgp2.  It does only
+        * catch those mails which are armored.  To catch the non-armored
+        * pgp mails we could see whether there is the signature packet
+        * in front of the plaintext.  If someone needs this, send me a patch.
+        */
+       c->mfx.md2 = md_open( DIGEST_ALGO_MD5, 0);
+    }
   #if 0
     #warning md_start_debug is enabled
     md_start_debug( c->mfx.md, "verify" );
@@ -366,7 +382,7 @@ static int
 do_check_sig( CTX c, KBNODE node, int *is_selfsig )
 {
     PKT_signature *sig;
-    MD_HANDLE md;
+    MD_HANDLE md = NULL, md2 = NULL;
     int algo, rc;
 
     assert( node->pkt->pkttype == PKT_SIGNATURE );
@@ -387,10 +403,16 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
     else if( sig->sig_class == 0x01 ) {
        /* how do we know that we have to hash the (already hashed) text
         * in canonical mode ??? (calculating both modes???) */
-       if( c->mfx.md )
+       if( c->mfx.md ) {
            md = md_copy( c->mfx.md );
-       else /* detached signature */
+           if( c->mfx.md2 )
+              md2 = md_copy( c->mfx.md2 );
+       }
+       else { /* detached signature */
+         log_debug("Do we really need this here?");
            md = md_open( 0, 0 ); /* signature_check() will enable the md*/
+           md2 = md_open( 0, 0 );
+       }
     }
     else if( (sig->sig_class&~3) == 0x10
             || sig->sig_class == 0x18
@@ -409,7 +431,10 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
     else
        return G10ERR_SIG_CLASS;
     rc = signature_check( sig, md );
+    if( rc == G10ERR_BAD_SIGN && md2 )
+       rc = signature_check( sig, md2 );
     md_close(md);
+    md_close(md2);
 
     return rc;
 }
@@ -978,13 +1003,15 @@ proc_tree( CTX c, KBNODE node )
            free_md_filter_context( &c->mfx );
            /* prepare to create all requested message digests */
            c->mfx.md = md_open(0, 0);
+
            /* fixme: why looking for the signature packet and not 1passpacket*/
            for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) {
                md_enable( c->mfx.md, n1->pkt->pkt.signature->digest_algo);
            }
            /* ask for file and hash it */
            if( c->sigs_only )
-               rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
+               rc = hash_datafiles( c->mfx.md, NULL,
+                                    c->signed_data, c->sigfilename,
                        n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
            else
                rc = ask_for_detached_datafile( &c->mfx,
@@ -1004,8 +1031,14 @@ proc_tree( CTX c, KBNODE node )
        if( !c->have_data ) {
            free_md_filter_context( &c->mfx );
            c->mfx.md = md_open(sig->digest_algo, 0);
+           if( sig->digest_algo == DIGEST_ALGO_MD5
+               && is_RSA( sig->pubkey_algo ) ) {
+               /* enable a workaround for a pgp2 bug */
+               c->mfx.md2 = md_open( DIGEST_ALGO_MD5, 0 );
+           }
            if( c->sigs_only )
-               rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
+               rc = hash_datafiles( c->mfx.md, c->mfx.md2,
+                                    c->signed_data, c->sigfilename,
                                     sig->sig_class == 0x01 );
            else
                rc = ask_for_detached_datafile( &c->mfx,
index 1d26e20..2cdbd32 100644 (file)
@@ -53,8 +53,11 @@ md_filter( void *opaque, int control,
            buf[i] = c;
        }
 
-       if( i )
+       if( i ) {
            md_write(mfx->md, buf, i );
+           if( mfx->md2 )
+               md_write(mfx->md2, buf, i );
+       }
        else
            rc = -1; /* eof */
        *ret_len = i;
@@ -69,7 +72,9 @@ void
 free_md_filter_context( md_filter_context_t *mfx )
 {
     md_close(mfx->md);
+    md_close(mfx->md2);
     mfx->md = NULL;
+    mfx->md2 = NULL;
     mfx->maxbuf_size = 0;
 }
 
index afe5314..1af95cf 100644 (file)
@@ -39,6 +39,8 @@
   #define SKELEXT ".skel"
 #endif
 
+#warning Implement opt.interactive.
+
 /****************
  * Check whether FNAME exists and ask if it's okay to overwrite an
  * existing one.
index 4f5457a..3e81044 100644 (file)
@@ -72,6 +72,7 @@ struct {
     int lock_once;
     const char *keyserver_name;
     int no_encrypt_to;
+    int interactive;
 } opt;
 
 
index 98c4314..577641a 100644 (file)
@@ -247,7 +247,7 @@ ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname )
 
 
 static void
-do_hash( MD_HANDLE md, IOBUF fp, int textmode )
+do_hash( MD_HANDLE md, MD_HANDLE md2, IOBUF fp, int textmode )
 {
     text_filter_context_t tfx;
     int c;
@@ -256,8 +256,18 @@ do_hash( MD_HANDLE md, IOBUF fp, int textmode )
        memset( &tfx, 0, sizeof tfx);
        iobuf_push_filter( fp, text_filter, &tfx );
     }
-    while( (c = iobuf_get(fp)) != -1 )
-       md_putc(md, c );
+    if( md2 ) { /* work around a strange behaviour in pgp2 */
+       while( (c = iobuf_get(fp)) != -1 ) {
+           if( c == '\n' )
+              md_putc(md2, '\r' );
+           md_putc(md, c );
+           md_putc(md2, c );
+       }
+    }
+    else {
+       while( (c = iobuf_get(fp)) != -1 )
+           md_putc(md, c );
+    }
 }
 
 
@@ -266,7 +276,7 @@ do_hash( MD_HANDLE md, IOBUF fp, int textmode )
  * If FILES is NULL, hash stdin.
  */
 int
-hash_datafiles( MD_HANDLE md, STRLIST files,
+hash_datafiles( MD_HANDLE md, MD_HANDLE md2, STRLIST files,
                const char *sigfilename, int textmode )
 {
     IOBUF fp;
@@ -276,7 +286,7 @@ hash_datafiles( MD_HANDLE md, STRLIST files,
        /* check whether we can open the signed material */
        fp = open_sigfile( sigfilename );
        if( fp ) {
-           do_hash( md, fp, textmode );
+           do_hash( md, md2, fp, textmode );
            iobuf_close(fp);
            return 0;
        }
@@ -295,7 +305,7 @@ hash_datafiles( MD_HANDLE md, STRLIST files,
                free_strlist(sl);
            return G10ERR_OPEN_FILE;
        }
-       do_hash( md, fp, textmode );
+       do_hash( md, md2, fp, textmode );
        iobuf_close(fp);
     }