diff options
-rw-r--r-- | BUGS | 11 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | TODO | 6 | ||||
-rwxr-xr-x | checks/defs.inc | 3 | ||||
-rw-r--r-- | configure.in | 3 | ||||
-rw-r--r-- | doc/gpg.1pod | 3 | ||||
-rw-r--r-- | g10/ChangeLog | 13 | ||||
-rw-r--r-- | g10/filter.h | 1 | ||||
-rw-r--r-- | g10/g10.c | 3 | ||||
-rw-r--r-- | g10/import.c | 47 | ||||
-rw-r--r-- | g10/keyedit.c | 2 | ||||
-rw-r--r-- | g10/main.h | 4 | ||||
-rw-r--r-- | g10/mainproc.c | 47 | ||||
-rw-r--r-- | g10/mdfilter.c | 7 | ||||
-rw-r--r-- | g10/openfile.c | 2 | ||||
-rw-r--r-- | g10/options.h | 1 | ||||
-rw-r--r-- | g10/plaintext.c | 22 |
17 files changed, 148 insertions, 32 deletions
@@ -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 @@ -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 @@ -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. diff --git a/checks/defs.inc b/checks/defs.inc index 45d54dfed..5c4a82b75 100755 --- a/checks/defs.inc +++ b/checks/defs.inc @@ -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 ------- diff --git a/configure.in b/configure.in index 21d5f8cfd..944325df8 100644 --- a/configure.in +++ b/configure.in @@ -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") diff --git a/doc/gpg.1pod b/doc/gpg.1pod index 26d96f979..33791e594 100644 --- a/doc/gpg.1pod +++ b/doc/gpg.1pod @@ -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. diff --git a/g10/ChangeLog b/g10/ChangeLog index 177850fe8..4b8d98942 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -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. diff --git a/g10/filter.h b/g10/filter.h index 8fb875dd2..30a59d199 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -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; @@ -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; diff --git a/g10/import.c b/g10/import.c index 0d8463c1e..f9ddcd4b2 100644 --- a/g10/import.c +++ b/g10/import.c @@ -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, diff --git a/g10/keyedit.c b/g10/keyedit.c index 85f3dfaf7..a8e783f36 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -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 ) diff --git a/g10/main.h b/g10/main.h index c3f236379..ce7e8ac1a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -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); diff --git a/g10/mainproc.c b/g10/mainproc.c index a560fcbe5..5fa934c2a 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -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, diff --git a/g10/mdfilter.c b/g10/mdfilter.c index 1d26e20ba..2cdbd326d 100644 --- a/g10/mdfilter.c +++ b/g10/mdfilter.c @@ -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; } diff --git a/g10/openfile.c b/g10/openfile.c index afe531465..1af95cf6c 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -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. diff --git a/g10/options.h b/g10/options.h index 4f5457a4a..3e81044be 100644 --- a/g10/options.h +++ b/g10/options.h @@ -72,6 +72,7 @@ struct { int lock_once; const char *keyserver_name; int no_encrypt_to; + int interactive; } opt; diff --git a/g10/plaintext.c b/g10/plaintext.c index 98c4314ea..577641a6d 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -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); } |