diff options
Diffstat (limited to '')
-rw-r--r-- | g10/ChangeLog | 14 | ||||
-rw-r--r-- | g10/armor.c | 53 | ||||
-rw-r--r-- | g10/encr-data.c | 99 | ||||
-rw-r--r-- | g10/filter.h | 6 | ||||
-rw-r--r-- | g10/import.c | 5 | ||||
-rw-r--r-- | g10/keyedit.c | 18 | ||||
-rw-r--r-- | g10/keyserver.c | 11 |
7 files changed, 158 insertions, 48 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 6cc2548e1..20d3ec178 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,17 @@ +2006-12-04 Werner Koch <[email protected]> + + * filter.h (armor_filter_context_t): New field REFCOUNT. + * armor.c (new_armor_context, release_armor_context) + (push_armor_filter): New. + (armor_filter): Call releae_armor_context for IOBUFCTRL_FREE. + * import.c (import): Use the new function here instead of the + old hack using the iobuf_push_filter2. + * keyserver.c (keyserver_spawn): Ditto. + +2006-12-03 Werner Koch <[email protected]> + + * keyedit.c (menu_clean): Made strings translatable. + 2006-12-03 David Shaw <[email protected]> * keyedit.c (menu_clean): Show "already minimized" rather than diff --git a/g10/armor.c b/g10/armor.c index e437d3db0..65804a75b 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -114,6 +114,58 @@ static char *tail_strings[] = { }; +/* Create a new context for armor filters. */ +armor_filter_context_t * +new_armor_context (void) +{ + armor_filter_context_t *afx; + + afx = xcalloc (1, sizeof *afx); + afx->refcount = 1; + + return afx; +} + +/* Release an armor filter context. Passing NULL is explicitly + allowed and a no-op. */ +void +release_armor_context (armor_filter_context_t *afx) +{ + if (!afx) + return; + + /* In contrast to 2.0, we use in 1.4 heap based contexts only in a + very few places and in general keep the stack based contexts. A + REFCOUNT of 0 indicates a stack based context and thus we don't + do anything in this case. */ + if (!afx->refcount) + return; + + if ( --afx->refcount ) + return; + xfree (afx); +} + +/* Push the armor filter onto the iobuf stream IOBUF. */ +int +push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf) +{ + int rc; + + if (!afx->refcount) + return iobuf_push_filter (iobuf, armor_filter, afx); + + afx->refcount++; + rc = iobuf_push_filter (iobuf, armor_filter, afx); + if (rc) + afx->refcount--; + return rc; +} + + + + + static void initialize(void) { @@ -1168,6 +1220,7 @@ armor_filter( void *opaque, int control, "probably a buggy MTA has been used\n") ); xfree( afx->buffer ); afx->buffer = NULL; + release_armor_context (afx); } else if( control == IOBUFCTRL_DESC ) *(char**)buf = "armor_filter"; diff --git a/g10/encr-data.c b/g10/encr-data.c index 924b35f0c..acb090abe 100644 --- a/g10/encr-data.c +++ b/g10/encr-data.c @@ -45,7 +45,27 @@ typedef struct { char defer[22]; int defer_filled; int eof_seen; -} decode_filter_ctx_t; + int refcount; +} *decode_filter_ctx_t; + + +/* Helper to release the decode context. */ +static void +release_dfx_context (decode_filter_ctx_t dfx) +{ + if (!dfx) + return; + + assert (dfx->refcount); + if ( !--dfx->refcount ) + { + cipher_close (dfx->cipher_hd); + dfx->cipher_hd = NULL; + md_close (dfx->mdc_hash); + dfx->mdc_hash = NULL; + xfree (dfx); + } +} /**************** @@ -61,7 +81,10 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) unsigned blocksize; unsigned nprefix; - memset( &dfx, 0, sizeof dfx ); + + dfx = xcalloc (1, sizeof *dfx); + dfx->refcount = 1; + if( opt.verbose && !dek->algo_info_printed ) { const char *s = cipher_algo_to_string( dek->algo ); if( s ) @@ -80,15 +103,15 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) BUG(); if( ed->mdc_method ) { - dfx.mdc_hash = md_open( ed->mdc_method, 0 ); + dfx->mdc_hash = md_open ( ed->mdc_method, 0 ); if ( DBG_HASHING ) - md_start_debug(dfx.mdc_hash, "checkmdc"); + md_start_debug (dfx->mdc_hash, "checkmdc"); } - dfx.cipher_hd = cipher_open( dek->algo, - ed->mdc_method? CIPHER_MODE_CFB - : CIPHER_MODE_AUTO_CFB, 1 ); + dfx->cipher_hd = cipher_open ( dek->algo, + ed->mdc_method? CIPHER_MODE_CFB + : CIPHER_MODE_AUTO_CFB, 1 ); /* log_hexdump( "thekey", dek->key, dek->keylen );*/ - rc = cipher_setkey( dfx.cipher_hd, dek->key, dek->keylen ); + rc = cipher_setkey ( dfx->cipher_hd, dek->key, dek->keylen ); if( rc == G10ERR_WEAK_KEY ) { log_info(_("WARNING: message was encrypted with" @@ -106,7 +129,7 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) goto leave; } - cipher_setiv( dfx.cipher_hd, NULL, 0 ); + cipher_setiv ( dfx->cipher_hd, NULL, 0 ); if( ed->len ) { for(i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) { @@ -123,8 +146,8 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) else temp[i] = c; } - cipher_decrypt( dfx.cipher_hd, temp, temp, nprefix+2); - cipher_sync( dfx.cipher_hd ); + cipher_decrypt ( dfx->cipher_hd, temp, temp, nprefix+2); + cipher_sync ( dfx->cipher_hd ); p = temp; /* log_hexdump( "prefix", temp, nprefix+2 ); */ if(dek->symmetric @@ -134,17 +157,18 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) goto leave; } - if( dfx.mdc_hash ) - md_write( dfx.mdc_hash, temp, nprefix+2 ); + if ( dfx->mdc_hash ) + md_write ( dfx->mdc_hash, temp, nprefix+2 ); - if( ed->mdc_method ) - iobuf_push_filter( ed->buf, mdc_decode_filter, &dfx ); + dfx->refcount++; + if ( ed->mdc_method ) + iobuf_push_filter( ed->buf, mdc_decode_filter, dfx ); else - iobuf_push_filter( ed->buf, decode_filter, &dfx ); + iobuf_push_filter( ed->buf, decode_filter, dfx ); proc_packets( procctx, ed->buf ); ed->buf = NULL; - if( ed->mdc_method && dfx.eof_seen == 2 ) + if( ed->mdc_method && dfx->eof_seen == 2 ) rc = G10ERR_INVALID_PACKET; else if( ed->mdc_method ) { /* check the mdc */ /* We used to let parse-packet.c handle the MDC packet but @@ -162,24 +186,25 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) that we know that 22 bytes are appended. */ int datalen = md_digest_length( ed->mdc_method ); - cipher_decrypt( dfx.cipher_hd, dfx.defer, dfx.defer, 22); - md_write (dfx.mdc_hash, dfx.defer, 2); - md_final( dfx.mdc_hash ); - if (dfx.defer[0] != '\xd3' || dfx.defer[1] != '\x14' ) { + assert (dfx->cipher_hd); + assert (dfx->mdc_hash); + cipher_decrypt ( dfx->cipher_hd, dfx->defer, dfx->defer, 22); + md_write ( dfx->mdc_hash, dfx->defer, 2); + md_final ( dfx->mdc_hash ); + if (dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' ) { log_error("mdc_packet with invalid encoding\n"); rc = G10ERR_INVALID_PACKET; } else if ( datalen != 20 - || memcmp(md_read( dfx.mdc_hash, 0 ), dfx.defer+2, datalen) ) + || memcmp(md_read( dfx->mdc_hash, 0 ), dfx->defer+2, datalen) ) rc = G10ERR_BAD_SIGN; - /*log_hexdump("MDC calculated:", md_read( dfx.mdc_hash, 0), datalen);*/ - /*log_hexdump("MDC message :", dfx.defer, 20);*/ + /*log_hexdump("MDC calculated:",md_read( dfx->mdc_hash, 0), datalen);*/ + /*log_hexdump("MDC message :", dfx->defer, 20);*/ } leave: - cipher_close(dfx.cipher_hd); - md_close( dfx.mdc_hash ); + release_dfx_context (dfx); return rc; } @@ -190,7 +215,7 @@ static int mdc_decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) { - decode_filter_ctx_t *dfx = opaque; + decode_filter_ctx_t dfx = opaque; size_t n, size = *ret_len; int rc = 0; int c; @@ -245,8 +270,10 @@ mdc_decode_filter( void *opaque, int control, IOBUF a, } if( n ) { - cipher_decrypt( dfx->cipher_hd, buf, buf, n); - md_write( dfx->mdc_hash, buf, n ); + if (dfx->cipher_hd) + cipher_decrypt( dfx->cipher_hd, buf, buf, n); + if (dfx->mdc_hash) + md_write( dfx->mdc_hash, buf, n ); } else { assert( dfx->eof_seen ); @@ -254,6 +281,9 @@ mdc_decode_filter( void *opaque, int control, IOBUF a, } *ret_len = n; } + else if ( control == IOBUFCTRL_FREE ) { + release_dfx_context (dfx); + } else if( control == IOBUFCTRL_DESC ) { *(char**)buf = "mdc_decode_filter"; } @@ -263,7 +293,7 @@ mdc_decode_filter( void *opaque, int control, IOBUF a, static int decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) { - decode_filter_ctx_t *fc = opaque; + decode_filter_ctx_t fc = opaque; size_t n, size = *ret_len; int rc = 0; @@ -271,12 +301,17 @@ decode_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len) assert(a); n = iobuf_read( a, buf, size ); if( n == -1 ) n = 0; - if( n ) - cipher_decrypt( fc->cipher_hd, buf, buf, n); + if( n ) { + if (fc->cipher_hd) + cipher_decrypt( fc->cipher_hd, buf, buf, n); + } else rc = -1; /* eof */ *ret_len = n; } + else if ( control == IOBUFCTRL_FREE ) { + release_dfx_context (fc); + } else if( control == IOBUFCTRL_DESC ) { *(char**)buf = "decode_filter"; } diff --git a/g10/filter.h b/g10/filter.h index bb06ecc6e..c9fe872d2 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -32,6 +32,9 @@ typedef struct { } md_filter_context_t; typedef struct { + int refcount; /* Reference counter. If 0 this structure + is not allocated on the heap. */ + /* these fields may be initialized */ int what; /* what kind of armor headers to write */ int only_keyblocks; /* skip all headers but ".... key block" */ @@ -130,6 +133,9 @@ int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); void free_md_filter_context( md_filter_context_t *mfx ); /*-- armor.c --*/ +armor_filter_context_t *new_armor_context (void); +void release_armor_context (armor_filter_context_t *afx); +int push_armor_filter (armor_filter_context_t *afx, IOBUF iobuf); int use_armor_filter( IOBUF a ); int armor_filter( void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len); diff --git a/g10/import.c b/g10/import.c index e2ad0e314..7260301f6 100644 --- a/g10/import.c +++ b/g10/import.c @@ -249,9 +249,10 @@ import( IOBUF inp, const char* fname,struct stats_s *stats, getkey_disable_caches(); if( !opt.no_armor ) { /* armored reading is not disabled */ - armor_filter_context_t *afx = xmalloc_clear( sizeof *afx ); + armor_filter_context_t *afx = new_armor_context (); afx->only_keyblocks = 1; - iobuf_push_filter2( inp, armor_filter, afx, 1 ); + push_armor_filter (afx, inp); + release_armor_context (afx); } while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) { diff --git a/g10/keyedit.c b/g10/keyedit.c index c6f594730..c1e0ec3ca 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -3232,25 +3232,25 @@ menu_clean(KBNODE keyblock,int self_only) else reason=_("invalid"); - tty_printf("User ID \"%s\" compacted: %s\n",user,reason); + tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason); modified=1; } else if(sigs) { - tty_printf(sigs==1? - "User ID \"%s\": %d signature removed\n": - "User ID \"%s\": %d signatures removed\n", - user,sigs); + tty_printf (sigs==1? + _("User ID \"%s\": %d signature removed\n"): + _("User ID \"%s\": %d signatures removed\n"), + user,sigs); modified=1; } else { - tty_printf(self_only==1? - "User ID \"%s\": already minimized\n": - "User ID \"%s\": already clean\n", - user); + tty_printf (self_only==1? + _("User ID \"%s\": already minimized\n"): + _("User ID \"%s\": already clean\n"), + user); } xfree(user); diff --git a/g10/keyserver.c b/g10/keyserver.c index 939bcea92..4f692457b 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -1187,23 +1187,24 @@ keyserver_spawn(enum ks_action action,STRLIST list,KEYDB_SEARCH_DESC *desc, for(key=list;key!=NULL;key=key->next) { - armor_filter_context_t afx; + armor_filter_context_t *afx; IOBUF buffer=iobuf_temp(); KBNODE block; temp=NULL; add_to_strlist(&temp,key->d); - memset(&afx,0,sizeof(afx)); - afx.what=1; + afx = new_armor_context (); + afx->what = 1; /* Tell the armor filter to use Unix-style \n line endings, since we're going to fprintf this to a file that (on Win32) is open in text mode. The win32 stdio will transform the \n to \r\n and we'll end up with the proper line endings on win32. This is a no-op on Unix. */ - afx.eol[0]='\n'; - iobuf_push_filter(buffer,armor_filter,&afx); + afx->eol[0]='\n'; + push_armor_filter (afx, buffer); + release_armor_context (afx); /* TODO: Remove Comment: lines from keys exported this way? */ |