diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 45 | ||||
-rw-r--r-- | g10/OPTIONS | 8 | ||||
-rw-r--r-- | g10/armor.c | 21 | ||||
-rw-r--r-- | g10/build-packet.c | 3 | ||||
-rw-r--r-- | g10/comment.c | 14 | ||||
-rw-r--r-- | g10/compress.c | 8 | ||||
-rw-r--r-- | g10/dearmor.c | 9 | ||||
-rw-r--r-- | g10/encode.c | 59 | ||||
-rw-r--r-- | g10/export.c | 5 | ||||
-rw-r--r-- | g10/g10.c | 137 | ||||
-rw-r--r-- | g10/getkey.c | 72 | ||||
-rw-r--r-- | g10/import.c | 9 | ||||
-rw-r--r-- | g10/keyedit.c | 32 | ||||
-rw-r--r-- | g10/keygen.c | 9 | ||||
-rw-r--r-- | g10/keyid.c | 2 | ||||
-rw-r--r-- | g10/main.h | 3 | ||||
-rw-r--r-- | g10/openfile.c | 21 | ||||
-rw-r--r-- | g10/options.h | 2 | ||||
-rw-r--r-- | g10/parse-packet.c | 7 | ||||
-rw-r--r-- | g10/passphrase.c | 3 | ||||
-rw-r--r-- | g10/pkclist.c | 15 | ||||
-rw-r--r-- | g10/revoke.c | 4 | ||||
-rw-r--r-- | g10/seckey-cert.c | 25 | ||||
-rw-r--r-- | g10/sign.c | 32 | ||||
-rw-r--r-- | g10/status.c | 18 | ||||
-rw-r--r-- | g10/trustdb.c | 5 |
26 files changed, 376 insertions, 192 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 6aef10371..526cf152d 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,48 @@ +Tue Aug 11 17:54:50 1998 Werner Koch (wk@(none)) + + * build-packet.c (do_secret_key): Fixed handling of old keys. + + * getkey.c (compare_name): Fixed exact and email matching + + * openfile.c (open_outfile): Changed arguments and all callers. + +Tue Aug 11 09:14:35 1998 Werner Koch (wk@(none)) + + * encode.c (encode_simple): Applied option set-filename and comment. + (encode_crypt): Ditto. + * sign.c (sign_file): Ditto. + * armor.c (armor_filter): Applied option comment. + + * encode.c (encode_crypt): Moved init_packet to the begin. + (encode_simple): add an init_packet(). + + * comment (write_comment): Now enforces a hash sign as the 1st byte. + + * import.c (import_one): Add explanation for "no user ids". + + * compress.c (do_uncompress): Applied Brian Warner's patch to support + zlib 1.1.3 etc. + + * trustdb.c (check_trust): Fixed a problem after inserting new keys. + + * getkey (lookup): do not return the primary key if usage is given + (lookup_sk): Ditto and take usage into account. + + * status.c (cpr_get_answer_is_yes): add display_help. + +Mon Aug 10 10:11:28 1998 Werner Koch (wk@(none)) + + * getkey.c (lookup_sk): Now always returns the primary if arg + primary is true. + (lookup): Likewise. + (get_pubkey_byname): Now returns the primary key + (get_seckey_byname): Ditto. + + +Mon Aug 10 08:34:03 1998 Werner Koch (wk@(none)) + + * keyid.c (pubkey_letter): ELG_E is now a small g. + Sat Aug 8 17:26:12 1998 Werner Koch (wk@(none)) * openfile (overwrite_filep): Changed semantics and all callers. diff --git a/g10/OPTIONS b/g10/OPTIONS index 2e933f57e..9555ce06a 100644 --- a/g10/OPTIONS +++ b/g10/OPTIONS @@ -50,3 +50,11 @@ run-as-shm-coprocess [request-locked-shm-size] # very special :-) # You will have to use "--status-fd" too + +set-filename <name> +# Set <name> as the filename into the plaintext packet + +comment <string> +# Add <string> as comment to the output + + diff --git a/g10/armor.c b/g10/armor.c index 45f962f01..f5116acd0 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1002,8 +1002,25 @@ armor_filter( void *opaque, int control, iobuf_writestr(a, "-----\n"); iobuf_writestr(a, "Version: GNUPG v" VERSION " (" PRINTABLE_OS_NAME ")\n"); - iobuf_writestr(a, - "Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/\n"); + + if( opt.comment_string ) { + const char *s = opt.comment_string; + iobuf_writestr(a, "Comment: " ); + for( ; *s; s++ ) { + if( *s == '\n' ) + iobuf_writestr(a, "\\n" ); + else if( *s == '\r' ) + iobuf_writestr(a, "\\r" ); + else if( *s == '\v' ) + iobuf_writestr(a, "\\v" ); + else + iobuf_put(a, *s ); + } + iobuf_put(a, '\n' ); + } + else + iobuf_writestr(a, + "Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/\n"); if( afx->hdrlines ) iobuf_writestr(a, afx->hdrlines); iobuf_put(a, '\n'); diff --git a/g10/build-packet.c b/g10/build-packet.c index 6373e0cbd..a7c709302 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -291,7 +291,8 @@ do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk ) for(i=0; i < npkey; i++ ) mpi_write(a, sk->skey[i] ); if( sk->is_protected ) { - if( is_RSA(sk->pubkey_algo) && sk->version < 4 ) { + if( is_RSA(sk->pubkey_algo) && sk->version < 4 + && !sk->protect.s2k.mode ) { iobuf_put(a, sk->protect.algo ); iobuf_write(a, sk->protect.iv, 8 ); } diff --git a/g10/comment.c b/g10/comment.c index fef831cc7..71d524c40 100644 --- a/g10/comment.c +++ b/g10/comment.c @@ -44,9 +44,17 @@ write_comment( IOBUF out, const char *s ) int rc=0; pkt.pkttype = PKT_COMMENT; - pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n - 1 ); - pkt.pkt.comment->len = n; - strcpy(pkt.pkt.comment->data, s); + if( *s != '#' ) { + pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n ); + pkt.pkt.comment->len = n+1; + *pkt.pkt.comment->data = '#'; + strcpy(pkt.pkt.comment->data+1, s); + } + else { + pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n - 1 ); + pkt.pkt.comment->len = n; + strcpy(pkt.pkt.comment->data, s); + } if( (rc = build_packet( out, &pkt )) ) log_error("build_packet(comment) failed: %s\n", g10_errstr(rc) ); free_packet( &pkt ); diff --git a/g10/compress.c b/g10/compress.c index ca5adaebd..917a96033 100644 --- a/g10/compress.c +++ b/g10/compress.c @@ -151,19 +151,23 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs, if( DBG_FILTER ) log_debug("call inflate: avail_in=%u, avail_out=%u\n", (unsigned)zs->avail_in, (unsigned)zs->avail_out); + #ifdef Z_SYNC_FLUSH + zrc = inflate( zs, Z_SYNC_FLUSH ); + #else zrc = inflate( zs, Z_PARTIAL_FLUSH ); + #endif if( DBG_FILTER ) log_debug("inflate returned: avail_in=%u, avail_out=%u, zrc=%d\n", (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc); if( zrc == Z_STREAM_END ) rc = -1; /* eof */ - else if( zrc != Z_OK ) { + else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) { if( zs->msg ) log_fatal("zlib inflate problem: %s\n", zs->msg ); else log_fatal("zlib inflate problem: rc=%d\n", zrc ); } - } while( zs->avail_out && zrc != Z_STREAM_END ); + } while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR ); *ret_len = zfx->outbufsize - zs->avail_out; if( DBG_FILTER ) log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len ); diff --git a/g10/dearmor.c b/g10/dearmor.c index 5fa038255..6b15f491b 100644 --- a/g10/dearmor.c +++ b/g10/dearmor.c @@ -58,10 +58,9 @@ dearmor_file( const char *fname ) iobuf_push_filter( inp, armor_filter, &afx ); - if( !(out = open_outfile( fname, 0 )) ) { - rc = G10ERR_CREATE_FILE; + if( (rc = open_outfile( fname, 0, &out )) ) goto leave; - } + while( (c = iobuf_get(inp)) != -1 ) @@ -100,10 +99,8 @@ enarmor_file( const char *fname ) } - if( !(out = open_outfile( fname, 1 )) ) { - rc = G10ERR_CREATE_FILE; + if( (rc = open_outfile( fname, 1, &out )) ) goto leave; - } afx.what = 4; afx.hdrlines = "Comment: Use \"gpgm --dearmor\" for unpacking\n"; diff --git a/g10/encode.c b/g10/encode.c index 142a5e201..1d505500a 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -80,6 +80,7 @@ encode_simple( const char *filename, int mode ) memset( &cfx, 0, sizeof cfx); memset( &afx, 0, sizeof afx); memset( &zfx, 0, sizeof zfx); + init_packet(&pkt); /* prepare iobufs */ if( !(inp = iobuf_open(filename)) ) { @@ -107,19 +108,21 @@ encode_simple( const char *filename, int mode ) } } - if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) { + if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) { iobuf_close(inp); m_free(cfx.dek); m_free(s2k); - return G10ERR_CREATE_FILE; /* or user said: do not overwrite */ + return rc; } if( opt.armor ) iobuf_push_filter( out, armor_filter, &afx ); - else + else { write_comment( out, "#created by GNUPG v" VERSION " (" PRINTABLE_OS_NAME ")"); - + if( opt.comment_string ) + write_comment( out, opt.comment_string ); + } if( s2k && !opt.rfc1991 ) { PKT_symkey_enc *enc = m_alloc_clear( sizeof *enc ); enc->version = 4; @@ -133,18 +136,22 @@ encode_simple( const char *filename, int mode ) } /* setup the inner packet */ - if( filename ) { - pt = m_alloc( sizeof *pt + strlen(filename) - 1 ); - pt->namelen = strlen(filename); - memcpy(pt->name, filename, pt->namelen ); - if( !(filesize = iobuf_get_filelength(inp)) ) - log_info(_("%s: warning: empty file\n"), filename ); + if( filename || opt.set_filename ) { + const char *s = opt.set_filename ? opt.set_filename : filename; + pt = m_alloc( sizeof *pt + strlen(s) - 1 ); + pt->namelen = strlen(s); + memcpy(pt->name, s, pt->namelen ); } else { /* no filename */ pt = m_alloc( sizeof *pt - 1 ); pt->namelen = 0; - filesize = 0; /* stdin */ } + if( filename ) { + if( !(filesize = iobuf_get_filelength(inp)) ) + log_info(_("%s: warning: empty file\n"), filename ); + } + else + filesize = 0; /* stdin */ pt->timestamp = make_timestamp(); pt->mode = 'b'; pt->len = filesize; @@ -194,6 +201,7 @@ encode_crypt( const char *filename, STRLIST remusr ) memset( &cfx, 0, sizeof cfx); memset( &afx, 0, sizeof afx); memset( &zfx, 0, sizeof zfx); + init_packet(&pkt); if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) ) return rc; @@ -208,16 +216,18 @@ encode_crypt( const char *filename, STRLIST remusr ) else if( opt.verbose ) log_info(_("reading from '%s'\n"), filename? filename: "[stdin]"); - if( !(out = open_outfile( filename, opt.armor? 1:0 )) ) { - rc = G10ERR_CREATE_FILE; /* or user said: do not overwrite */ + if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) goto leave; - } + if( opt.armor ) iobuf_push_filter( out, armor_filter, &afx ); - else + else { write_comment( out, "#created by GNUPG v" VERSION " (" PRINTABLE_OS_NAME ")"); + if( opt.comment_string ) + write_comment( out, opt.comment_string ); + } /* create a session key */ cfx.dek = m_alloc_secure( sizeof *cfx.dek ); @@ -237,24 +247,27 @@ encode_crypt( const char *filename, STRLIST remusr ) goto leave; /* setup the inner packet */ - if( filename ) { - pt = m_alloc( sizeof *pt + strlen(filename) - 1 ); - pt->namelen = strlen(filename); - memcpy(pt->name, filename, pt->namelen ); - if( !(filesize = iobuf_get_filelength(inp)) ) - log_info(_("%s: warning: empty file\n"), filename ); + if( filename || opt.set_filename ) { + const char *s = opt.set_filename ? opt.set_filename : filename; + pt = m_alloc( sizeof *pt + strlen(s) - 1 ); + pt->namelen = strlen(s); + memcpy(pt->name, s, pt->namelen ); } else { /* no filename */ pt = m_alloc( sizeof *pt - 1 ); pt->namelen = 0; - filesize = 0; /* stdin */ } + if( filename ) { + if( !(filesize = iobuf_get_filelength(inp)) ) + log_info(_("%s: warning: empty file\n"), filename ); + } + else + filesize = 0; /* stdin */ pt->timestamp = make_timestamp(); pt->mode = 'b'; pt->len = filesize; pt->new_ctb = !pt->len && !opt.rfc1991; pt->buf = inp; - init_packet(&pkt); pkt.pkttype = PKT_PLAINTEXT; pkt.pkt.plaintext = pt; cfx.datalen = filesize && !opt.compress? calc_packet_length( &pkt ) : 0; diff --git a/g10/export.c b/g10/export.c index 2c824d2b0..301cb5ece 100644 --- a/g10/export.c +++ b/g10/export.c @@ -71,10 +71,9 @@ do_export( STRLIST users, int secret ) memset( &zfx, 0, sizeof zfx); init_packet( &pkt ); - if( !(out = open_outfile( NULL, 0 )) ) { - rc = G10ERR_CREATE_FILE; + if( (rc = open_outfile( NULL, 0, &out )) ) goto leave; - } + if( opt.armor ) { afx.what = secret?5:1; @@ -47,18 +47,68 @@ #endif +enum cmd_and_opt_values { aNull = 0, + oArmor = 'a', + aDetachedSign = 'b', + aSym = 'c', + aDecrypt = 'd', + aEncr = 'e', + oKOption = 'k', + oDryRun = 'n', + oOutput = 'o', + oRemote = 'r', + aSign = 's', + oTextmode = 't', + oUser = 'u', + oVerbose = 'v', + oCompress = 'z', + oBatch = 500, + aClearsign = 539, + aStore, + aKeygen, + aSignEncr, + aSignKey, + aListPackets, + aEditKey, + aDeleteKey, + aDeleteSecretKey, + aKMode, + aKModeC, + aImport, + aVerify, + aListKeys, + aListSigs, + aListSecretKeys, + aExport, + aExportSecret, + aCheckKeys, + aGenRevoke, + aPrimegen, + aPrintMD, + aPrintMDs, + aCheckTrustDB, + aListTrustDB, + aListTrustPath, + aExportOwnerTrust, + aImportOwnerTrust, + aDeArmor, + aEnArmor, + aGenRandom, +aTest }; + + static ARGPARSE_OPTS opts[] = { { 300, NULL, 0, N_("@Commands:\n ") }, #ifdef IS_G10 - { 's', "sign", 256, N_("|[file]|make a signature")}, - { 539, "clearsign", 256, N_("|[file]|make a clear text signature") }, - { 'b', "detach-sign", 256, N_("make a detached signature")}, - { 'e', "encrypt", 256, N_("encrypt data")}, - { 'c', "symmetric", 256, N_("encryption only with symmetric cipher")}, + { aSign, "sign", 256, N_("|[file]|make a signature")}, + { 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")}, + { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")}, { 507, "store", 256, N_("store only")}, - { 'd', "decrypt", 256, N_("decrypt data (default)")}, + { aDecrypt, "decrypt", 256, N_("decrypt data (default)")}, { 550, "verify" , 256, N_("verify a signature")}, #endif { 551, "list-keys", 256, N_("list keys")}, @@ -93,17 +143,17 @@ static ARGPARSE_OPTS opts[] = { { 301, NULL, 0, N_("@\nOptions:\n ") }, - { 'a', "armor", 0, N_("create ascii armored output")}, + { oArmor, "armor", 0, N_("create ascii armored output")}, #ifdef IS_G10 - { 'u', "local-user",2, N_("use this user-id to sign or decrypt")}, - { 'r', "remote-user", 2, N_("use this user-id for encryption")}, - { 'z', NULL, 1, N_("|N|set compress level N (0 disables)") }, - { 't', "textmode", 0, N_("use canonical text mode")}, + { oUser, "local-user",2, N_("use this user-id to sign or decrypt")}, + { oRemote, "remote-user", 2, N_("use this user-id for encryption")}, + { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") }, + { oTextmode, "textmode", 0, N_("use canonical text mode")}, #endif - { 'o', "output", 2, N_("use as output file")}, - { 'v', "verbose", 0, N_("verbose") }, - { 'n', "dry-run", 0, N_("do not make any changes") }, - { 500, "batch", 0, N_("batch mode: never ask")}, + { oOutput, "output", 2, N_("use as output file")}, + { oVerbose, "verbose", 0, N_("verbose") }, + /* { oDryRun, "dry-run", 0, N_("do not make any changes") }, */ + { oBatch, "batch", 0, N_("batch mode: never ask")}, { 501, "yes", 0, N_("assume yes on most questions")}, { 502, "no", 0, N_("assume no on most questions")}, { 509, "keyring" ,2, N_("add this keyring to the list of keyrings")}, @@ -147,7 +197,7 @@ static ARGPARSE_OPTS opts[] = { { 533, "list-trust-path",0, "@"}, #endif #ifdef IS_G10 - { 'k', NULL, 0, "@"}, + { oKOption, NULL, 0, "@"}, { 504, "delete-secret-key",0, "@" }, { 524, "edit-sig" ,0, "@"}, /* alias for edit-key */ { 523, "passphrase-fd",1, "@" }, @@ -173,27 +223,18 @@ static ARGPARSE_OPTS opts[] = { { 559, "always-trust", 0, "@"}, { 562, "emulate-checksum-bug", 0, "@"}, { 554, "run-as-shm-coprocess", 4, "@" }, - /* 568 unused */ + { 568, "set-filename", 2, "@" }, + { 569, "comment", 2, "@" }, {0} }; -enum cmd_values { aNull = 0, - aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, - aSignKey, aClearsign, aListPackets, aEditKey, aDeleteKey, aDeleteSecretKey, - aKMode, aKModeC, aImport, aVerify, aDecrypt, aListKeys, - aListSigs, aListSecretKeys, aExport, aExportSecret, - aCheckKeys, aGenRevoke, aPrimegen, aPrintMD, aPrintMDs, - aCheckTrustDB, aListTrustDB, aListTrustPath, - aExportOwnerTrust, aImportOwnerTrust, - aDeArmor, aEnArmor, aGenRandom, -aTest }; static int maybe_setuid = 1; static char *build_list( const char *text, const char *(*mapf)(int), int (*chkf)(int) ); -static void set_cmd( enum cmd_values *ret_cmd, - enum cmd_values new_cmd ); +static void set_cmd( enum cmd_and_opt_values *ret_cmd, + enum cmd_and_opt_values new_cmd ); #ifdef IS_G10MAINT static void print_hex( byte *p, size_t n ); static void print_mds( const char *fname, int algo ); @@ -337,9 +378,9 @@ set_debug(void) static void -set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ) +set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ) { - enum cmd_values cmd = *ret_cmd; + enum cmd_and_opt_values cmd = *ret_cmd; if( !cmd || cmd == new_cmd ) cmd = new_cmd; @@ -383,7 +424,7 @@ main( int argc, char **argv ) int errors=0; int default_keyring = 1; int greeting = 1; - enum cmd_values cmd = 0; + enum cmd_and_opt_values cmd = 0; const char *trustdb_name = NULL; char *def_cipher_string = NULL; char *def_digest_string = NULL; @@ -478,27 +519,27 @@ main( int argc, char **argv ) &pargs, opts) ) { switch( pargs.r_opt ) { - case 'a': opt.armor = 1; opt.no_armor=0; break; + case oArmor: opt.armor = 1; opt.no_armor=0; break; #ifdef IS_G10 - case 'b': detached_sig = 1; set_cmd( &cmd, aSign ); break; - case 'c': set_cmd( &cmd, aSym); break; - case 'd': set_cmd( &cmd, aDecrypt); break; - case 'e': set_cmd( &cmd, aEncr); break; - case 'r': /* store the remote users */ + case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break; + case aSym: set_cmd( &cmd, aSym); break; + case aDecrypt: set_cmd( &cmd, aDecrypt); break; + case aEncr: set_cmd( &cmd, aEncr); break; + case oRemote: /* store the remote users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); strcpy(sl->d, pargs.r.ret_str); sl->next = remusr; remusr = sl; break; - case 's': set_cmd( &cmd, aSign ); break; - case 't': opt.textmode=1; break; - case 'u': /* store the local users */ + case aSign: set_cmd( &cmd, aSign ); break; + case oTextmode: opt.textmode=1; break; + case oUser: /* store the local users */ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str)); strcpy(sl->d, pargs.r.ret_str); sl->next = locusr; locusr = sl; break; - case 'z': opt.compress = pargs.r.ret_int; break; + case oCompress: opt.compress = pargs.r.ret_int; break; case 503: set_cmd( &cmd, aKeygen); break; case 504: set_cmd( &cmd, aDeleteSecretKey); break; case 505: set_cmd( &cmd, aDeleteKey); break; @@ -508,7 +549,7 @@ main( int argc, char **argv ) case 524: set_cmd( &cmd, aEditKey); break; case 527: def_cipher_string = m_strdup(pargs.r.ret_str); break; case 529: def_digest_string = m_strdup(pargs.r.ret_str); break; - case 539: set_cmd( &cmd, aClearsign); break; + case aClearsign: set_cmd( &cmd, aClearsign); break; case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; case 542: set_cmd( &cmd, aGenRevoke); break; case 550: set_cmd( &cmd, aVerify); break; @@ -536,12 +577,12 @@ main( int argc, char **argv ) case 525: set_cmd( &cmd, aImportOwnerTrust); break; #endif /* IS_G10MAINT */ - case 'o': opt.outfile = pargs.r.ret_str; break; - case 'v': g10_opt_verbose++; + case oOutput: opt.outfile = pargs.r.ret_str; break; + case oVerbose: g10_opt_verbose++; opt.verbose++; opt.list_sigs=1; break; - case 'k': set_cmd( &cmd, aKMode ); break; + case oKOption: set_cmd( &cmd, aKMode ); break; - case 500: opt.batch = 1; greeting = 0; break; + case oBatch: opt.batch = 1; greeting = 0; break; case 501: opt.answer_yes = 1; break; case 502: opt.answer_no = 1; break; case 508: set_cmd( &cmd, aCheckKeys); break; @@ -598,6 +639,8 @@ main( int argc, char **argv ) log_error("shared memory coprocessing is not available\n"); #endif break; + case 568: opt.set_filename = pargs.r.ret_str; break; + case 569: opt.comment_string = pargs.r.ret_str; break; default : errors++; pargs.err = configfp? 1:2; break; } } diff --git a/g10/getkey.c b/g10/getkey.c index 72bb3d990..10899a6df 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -71,9 +71,9 @@ static int pk_cache_entries; /* number of entries in pk cache */ static int lookup( PKT_public_key *pk, int mode, u32 *keyid, const char *name, - KBNODE *ret_keyblock ); + KBNODE *ret_keyblock, int primary ); static int lookup_sk( PKT_secret_key *sk, - int mode, u32 *keyid, const char *name ); + int mode, u32 *keyid, const char *name, int primary ); /* note this function may be called before secure memory is * available @@ -263,7 +263,7 @@ get_pubkey( PKT_public_key *pk, u32 *keyid ) /* do a lookup */ - rc = lookup( pk, 11, keyid, NULL, NULL ); + rc = lookup( pk, 11, keyid, NULL, NULL, 0 ); if( !rc ) goto leave; @@ -321,15 +321,13 @@ hextobyte( const byte *s ) * on the length a short or complete one. * - If the username starts with 32,33,40 or 41 hex-digits (the first one * must be in the range 0..9), this is considered a fingerprint. - * (Not yet implemented) * - If the username starts with a left angle, we assume it is a complete * email address and look only at this part. * - If the username starts with a '.', we assume it is the ending * part of an email address * - If the username starts with an '@', we assume it is a part of an * email address - * - If the userid start with an '=' an exact compare is done; this may - * also follow the keyid in which case both parts are matched. + * - If the userid start with an '=' an exact compare is done. * - If the userid starts with a '*' a case insensitive substring search is * done (This is also the default). */ @@ -436,16 +434,16 @@ key_byname( int secret, sk = m_alloc_clear( sizeof *sk ); internal++; } - rc = mode < 16? lookup_sk( sk, mode, keyid, name ) - : lookup_sk( sk, mode, keyid, fprint ); + rc = mode < 16? lookup_sk( sk, mode, keyid, s, 1 ) + : lookup_sk( sk, mode, keyid, fprint, 1 ); } else { if( !pk ) { pk = m_alloc_clear( sizeof *pk ); internal++; } - rc = mode < 16? lookup( pk, mode, keyid, name, NULL ) - : lookup( pk, mode, keyid, fprint, NULL ); + rc = mode < 16? lookup( pk, mode, keyid, s, NULL, 1 ) + : lookup( pk, mode, keyid, fprint, NULL, 1 ); } @@ -473,7 +471,7 @@ get_pubkey_byfprint( PKT_public_key *pk, const byte *fprint, size_t fprint_len) int rc; if( fprint_len == 20 || fprint_len == 16 ) - rc = lookup( pk, fprint_len, NULL, fprint, NULL ); + rc = lookup( pk, fprint_len, NULL, fprint, NULL, 0 ); else rc = G10ERR_GENERAL; /* Oops */ return rc; @@ -491,7 +489,7 @@ get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint, PKT_public_key *pk = m_alloc_clear( sizeof *pk ); if( fprint_len == 20 || fprint_len == 16 ) - rc = lookup( pk, fprint_len, NULL, fprint, ret_keyblock ); + rc = lookup( pk, fprint_len, NULL, fprint, ret_keyblock, 0 ); else rc = G10ERR_GENERAL; /* Oops */ @@ -507,7 +505,7 @@ get_seckey( PKT_secret_key *sk, u32 *keyid ) { int rc; - rc = lookup_sk( sk, 11, keyid, NULL ); + rc = lookup_sk( sk, 11, keyid, NULL, 0 ); if( !rc ) { /* check the secret key (this may prompt for a passprase to * unlock the secret key @@ -530,7 +528,7 @@ seckey_available( u32 *keyid ) int rc; sk = m_alloc_clear( sizeof *sk ); - rc = lookup_sk( sk, 11, keyid, NULL ); + rc = lookup_sk( sk, 11, keyid, NULL, 0 ); free_secret_key( sk ); return rc; } @@ -549,7 +547,7 @@ get_seckey_byname( PKT_secret_key *sk, const char *name, int unprotect ) if( !name && opt.def_secret_key && *opt.def_secret_key ) rc = key_byname( 1, NULL, sk, opt.def_secret_key ); else if( !name ) /* use the first one as default key */ - rc = lookup_sk( sk, 15, NULL, NULL ); + rc = lookup_sk( sk, 15, NULL, NULL, 1 ); else rc = key_byname( 1, NULL, sk, name ); if( !rc && unprotect ) @@ -587,7 +585,7 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode ) if( i < uidlen ) { i = se - s; if( mode == 3 ) { /* exact email address */ - if( strlen(name) == i && !memicmp( s, name, i) ) + if( strlen(name)-2 == i && !memicmp( s, name+1, i) ) return 0; } else if( mode == 4 ) { /* email substring */ @@ -679,7 +677,7 @@ add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode ) */ static int lookup( PKT_public_key *pk, int mode, u32 *keyid, - const char *name, KBNODE *ret_keyblock ) + const char *name, KBNODE *ret_keyblock, int primary ) { int rc; KBNODE keyblock = NULL; @@ -705,7 +703,7 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, && !compare_name( k->pkt->pkt.user_id->name, k->pkt->pkt.user_id->len, name, mode)) { /* we found a matching name, look for the key */ - for(kk=keyblock; kk; kk = kk->next ) + for(kk=keyblock; kk; kk = kk->next ) { if( ( kk->pkt->pkttype == PKT_PUBLIC_KEY || kk->pkt->pkttype == PKT_PUBLIC_SUBKEY ) && ( !pk->pubkey_algo @@ -716,7 +714,8 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, kk->pkt->pkt.public_key->pubkey_algo, pk->pubkey_usage )) ) - break; + break; + } if( kk ) { u32 aki[2]; keyid_from_pk( kk->pkt->pkt.public_key, aki ); @@ -805,9 +804,17 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, if( k ) { /* found */ assert( k->pkt->pkttype == PKT_PUBLIC_KEY || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ); - copy_public_key_new_namehash( pk, k->pkt->pkt.public_key, - use_namehash? namehash:NULL); - add_stuff_from_selfsig( keyblock, k ); + assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ); + if( primary && !pk->pubkey_usage ) { + copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key, + use_namehash? namehash:NULL); + add_stuff_from_selfsig( keyblock, keyblock ); + } + else { + copy_public_key_new_namehash( pk, k->pkt->pkt.public_key, + use_namehash? namehash:NULL); + add_stuff_from_selfsig( keyblock, k ); + } if( ret_keyblock ) { *ret_keyblock = keyblock; keyblock = NULL; @@ -833,7 +840,8 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid, * Ditto for secret keys */ static int -lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name ) +lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name, + int primary ) { int rc; KBNODE keyblock = NULL; @@ -857,13 +865,19 @@ lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name ) && !compare_name( k->pkt->pkt.user_id->name, k->pkt->pkt.user_id->len, name, mode)) { /* we found a matching name, look for the key */ - for(kk=keyblock; kk; kk = kk->next ) + for(kk=keyblock; kk; kk = kk->next ) { if( ( kk->pkt->pkttype == PKT_SECRET_KEY || kk->pkt->pkttype == PKT_SECRET_SUBKEY ) && ( !sk->pubkey_algo || sk->pubkey_algo - == kk->pkt->pkt.secret_key->pubkey_algo)) - break; + == kk->pkt->pkt.secret_key->pubkey_algo) + && ( !sk->pubkey_usage + || !check_pubkey_algo2( + kk->pkt->pkt.secret_key->pubkey_algo, + sk->pubkey_usage )) + ) + break; + } if( kk ) { u32 aki[2]; keyid_from_sk( kk->pkt->pkt.secret_key, aki ); @@ -936,7 +950,11 @@ lookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name ) if( k ) { /* found */ assert( k->pkt->pkttype == PKT_SECRET_KEY || k->pkt->pkttype == PKT_SECRET_SUBKEY ); - copy_secret_key( sk, k->pkt->pkt.secret_key ); + assert( keyblock->pkt->pkttype == PKT_SECRET_KEY ); + if( primary && !sk->pubkey_usage ) + copy_secret_key( sk, keyblock->pkt->pkt.secret_key ); + else + copy_secret_key( sk, k->pkt->pkt.secret_key ); break; /* enumeration */ } release_kbnode( keyblock ); diff --git a/g10/import.c b/g10/import.c index c5eaf9ba8..73e04cb3d 100644 --- a/g10/import.c +++ b/g10/import.c @@ -246,6 +246,7 @@ import_one( const char *fname, KBNODE keyblock ) KBPOS kbpos; u32 keyid[2]; int rc = 0; + int new_key = 0; /* get the key and print some info about it */ node = find_kbnode( keyblock, PKT_PUBLIC_KEY ); @@ -279,6 +280,7 @@ import_one( const char *fname, KBNODE keyblock ) if( !delete_inv_parts( fname, keyblock, keyid ) ) { log_info_f( fname, _("key %08lX: no valid user ids\n"), (ulong)keyid[1]); + log_info(_("this may be caused by a missing self-signature\n")); return 0; } @@ -307,6 +309,7 @@ import_one( const char *fname, KBNODE keyblock ) unlock_keyblock( &kbpos ); /* we are ready */ log_info_f( fname, _("key %08lX: public key imported\n"), (ulong)keyid[1]); + new_key = 1; } else { /* merge */ int n_uids, n_sigs, n_subk; @@ -382,11 +385,11 @@ import_one( const char *fname, KBNODE keyblock ) log_info_f(fname, _("key %08lX: not changed\n"), (ulong)keyid[1] ); } if( !rc ) { - rc = query_trust_record( pk_orig ); + rc = query_trust_record( new_key? pk : pk_orig ); if( rc && rc != -1 ) log_error("trustdb error: %s\n", g10_errstr(rc) ); - else if( rc == -1 ) { - rc = insert_trust_record( pk_orig ); + else if( rc == -1 ) { /* not found trustdb */ + rc = insert_trust_record( new_key? pk : pk_orig ); if( rc ) log_error("key %08lX: trustdb insert failed: %s\n", (ulong)keyid[1], g10_errstr(rc) ); diff --git a/g10/keyedit.c b/g10/keyedit.c index c991be101..a0a62526d 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -264,15 +264,11 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified ) "with your key: \"")); p = get_user_id( sk_keyid, &n ); tty_print_string( p, n ); + m_free(p); p = NULL; tty_printf("\"\n\n"); - m_free(p); - p = cpr_get(N_("sign_uid.okay"), _("Really sign? ")); - cpr_kill_prompt(); - if( !answer_is_yes(p) ) { - m_free(p); - continue; /* No */ - } - m_free(p); + + if( !cpr_get_answer_is_yes(N_("sign_uid.okay"), _("Really sign? ")) ) + continue;; /* now we can sign the user ids */ reloop: /* (must use this, because we are modifing the list) */ primary_pk = NULL; @@ -328,6 +324,7 @@ delete_key( const char *username, int secret ) PKT_secret_key *sk = NULL; u32 keyid[2]; int okay=0; + int yes; /* search the userid */ rc = secret? find_secret_keyblock_byname( &kbpos, username ) @@ -376,11 +373,11 @@ delete_key( const char *username, int secret ) if( rc ) rc = 0; else if( opt.batch && secret ) - log_error(_("can't do that in batch-mode\n")); + log_error(_("can't do that in batchmode\n")); else if( opt.batch && opt.answer_yes ) okay++; else if( opt.batch ) - log_error(_("can't do that in batch-mode without \"--yes\"\n")); + log_error(_("can't do that in batchmode without \"--yes\"\n")); else { char *p; size_t n; @@ -400,23 +397,20 @@ delete_key( const char *username, int secret ) m_free(p); tty_printf("\n\n"); - p = cpr_get( secret? N_("delete_key.secret.okay") + yes = cpr_get_answer_is_yes( secret? N_("delete_key.secret.okay") : N_("delete_key.okay"), _("Delete this key from the keyring? ")); - cpr_kill_prompt(); - if( !cpr_enabled() && secret && answer_is_yes(p)) { + if( !cpr_enabled() && secret && yes ) { /* I think it is not required to check a passphrase; if * the user is so stupid as to let others access his secret keyring * (and has no backup) - it is up him to read some very * basic texts about security. */ - m_free(p); - p = cpr_get(N_("delete_key.secret.okay"), + yes = cpr_get_answer_is_yes(N_("delete_key.secret.okay"), _("This is a secret key! - really delete? ")); } - if( answer_is_yes(p) ) + if( yes ) okay++; - m_free(p); } @@ -596,7 +590,7 @@ keyedit_menu( const char *username, STRLIST locusr ) if( opt.batch ) { - log_error(_("can't do that in batch-mode\n")); + log_error(_("can't do that in batchmode\n")); goto leave; } @@ -735,7 +729,7 @@ keyedit_menu( const char *username, STRLIST locusr ) case cmdSIGN: /* sign (only the public key) */ if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) { - if( !cpr_get_answer_is_yes(N_("keyedit.signall.okay"), + if( !cpr_get_answer_is_yes(N_("keyedit.sign_all.okay"), _("Really sign all user ids? ")) ) { tty_printf(_("Hint: Select the user ids to sign\n")); break; diff --git a/g10/keygen.c b/g10/keygen.c index 90a6c712d..afe5bb4f9 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -444,8 +444,9 @@ ask_keysize( int algo ) else if( nbits < 768 ) tty_printf(_("keysize too small; 768 is smallest value allowed.\n")); else if( nbits > 2048 && !cpr_enabled() ) { - tty_printf(_("Keysizes larger than 2048 are not suggested because " - "computations take REALLY long!\n")); + tty_printf( + _("Keysizes larger than 2048 are not suggested because\n" + "computations take REALLY long!\n")); if( cpr_get_answer_is_yes(N_("keygen.size.huge.okay"),_( "Are you sure that you want this keysize? ")) ) { tty_printf(_("Okay, but keep in mind that your monitor " @@ -625,8 +626,10 @@ 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 */ for(;;) { - char *ansstr = N_("NnCcEeOoQq"); + char *ansstr = _("NnCcEeOoQq"); + if( strlen(ansstr) != 10 ) + BUG(); if( cpr_enabled() ) { answer = m_strdup(ansstr+6); answer[1] = 0; diff --git a/g10/keyid.c b/g10/keyid.c index 349356406..2de67ccf2 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -40,7 +40,7 @@ pubkey_letter( int algo ) case PUBKEY_ALGO_RSA: return 'R' ; case PUBKEY_ALGO_RSA_E: return 'r' ; case PUBKEY_ALGO_RSA_S: return 's' ; - case PUBKEY_ALGO_ELGAMAL_E: + case PUBKEY_ALGO_ELGAMAL_E: return 'g'; case PUBKEY_ALGO_ELGAMAL: return 'G' ; case PUBKEY_ALGO_DSA: return 'D' ; default: return '?'; diff --git a/g10/main.h b/g10/main.h index 573158a73..bba90ef5a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -82,7 +82,7 @@ int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock ); /*-- openfile.c --*/ int overwrite_filep( const char *fname ); -IOBUF open_outfile( const char *fname, int mode ); +int open_outfile( const char *iname, int mode, IOBUF *a ); IOBUF open_sigfile( const char *iname ); /*-- seskey.c --*/ @@ -124,5 +124,6 @@ int hash_datafiles( MD_HANDLE md, STRLIST files, const char *sigfilename, /*-- signal.c --*/ void init_signals(void); +void pause_on_sigusr( int which ); #endif /*G10_MAIN_H*/ diff --git a/g10/openfile.c b/g10/openfile.c index b8a6825a3..763ac2f9a 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -65,19 +65,22 @@ overwrite_filep( const char *fname ) /**************** * Make an output filename for the inputfile INAME. - * Returns an IOBUF + * Returns an IOBUF and an errorcode * Mode 0 = use ".gpg" * 1 = use ".asc" * 2 = use ".sig" */ -IOBUF -open_outfile( const char *iname, int mode ) +int +open_outfile( const char *iname, int mode, IOBUF *a ) { - IOBUF a = NULL; + int rc = 0; + *a = NULL; if( (!iname || (*iname=='-' && !iname[1])) && !opt.outfile ) { - if( !(a = iobuf_create(NULL)) ) + if( !(*a = iobuf_create(NULL)) ) { log_error("can't open [stdout]: %s\n", strerror(errno) ); + rc = G10ERR_CREATE_FILE; + } else if( opt.verbose ) log_info("writing to stdout\n"); } @@ -94,14 +97,18 @@ open_outfile( const char *iname, int mode ) name = buf; } if( overwrite_filep( name ) ) { - if( !(a = iobuf_create( name )) ) + if( !(*a = iobuf_create( name )) ) { log_error("can't create %s: %s\n", name, strerror(errno) ); + rc = G10ERR_CREATE_FILE; + } else if( opt.verbose ) log_info("writing to '%s'\n", name ); } + else + rc = G10ERR_FILE_EXISTS; m_free(buf); } - return a; + return rc; } diff --git a/g10/options.h b/g10/options.h index 630e43f44..4c8ec6138 100644 --- a/g10/options.h +++ b/g10/options.h @@ -52,6 +52,8 @@ struct { int rfc1991; unsigned emulate_bugs; /* bug emulation flags EMUBUG_xxxx */ int shm_coprocess; + const char *set_filename; + const char *comment_string; } opt; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index f534cbbdd..bc7aca510 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1068,15 +1068,14 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, sk->protect.s2k.count = iobuf_get(inp); pktlen--; } - } else { /* old version; no S2K, so we set mode to 0, hash MD5 */ sk->protect.s2k.mode = 0; /* We need a kludge to cope with old GNUPG versions */ sk->protect.s2k.hash_algo = - ( sk->protect.algo == CIPHER_ALGO_BLOWFISH160 - && algorithm == PUBKEY_ALGO_ELGAMAL_E ) ? - DIGEST_ALGO_RMD160 : DIGEST_ALGO_MD5; + ( sk->protect.algo == CIPHER_ALGO_BLOWFISH160 + && algorithm == PUBKEY_ALGO_ELGAMAL_E ) ? + DIGEST_ALGO_RMD160 : DIGEST_ALGO_MD5; if( list_mode ) printf( "\tprotect algo: %d (hash algo: %d)\n", sk->protect.algo, sk->protect.s2k.hash_algo ); diff --git a/g10/passphrase.c b/g10/passphrase.c index b9f41510f..7dbaeb466 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -223,8 +223,9 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) count -= len2; } if( count ) { - if( count < 8 ) + if( count < 8 ) { md_write( md, s2k->salt, count ); + } else { md_write( md, s2k->salt, 8 ); count -= 8; diff --git a/g10/pkclist.c b/g10/pkclist.c index 59cc9b7d3..e85b289f5 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -81,9 +81,17 @@ edit_ownertrust( ulong lid, int mode ) " 2 = I do NOT trust\n" " 3 = I trust marginally\n" " 4 = I trust fully\n" -" s = please show me more information\n\n") ); +" s = please show me more information\n") ); + if( mode ) + tty_printf(_(" m = back to the main menu\n")); + tty_printf("\n"); for(;;) { + /* a string with valid answers */ + char *ans = _("sSmM"); + + if( strlen(ans) != 4 ) + BUG(); p = cpr_get(N_("edit_ownertrust.value"),_("Your decision? ")); trim_spaces(p); cpr_kill_prompt(); @@ -102,9 +110,12 @@ edit_ownertrust( ulong lid, int mode ) changed++; break; } - else if( *p == 's' || *p == 'S' ) { + else if( *p == ans[0] || *p == ans[1] ) { tty_printf(_("You will see a list of signators etc. here\n")); } + else if( mode && (*p == ans[2] || *p == ans[3]) ) { + break ; /* back to the menu */ + } m_free(p); p = NULL; } m_free(p); diff --git a/g10/revoke.c b/g10/revoke.c index c78d79c85..278bdca35 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -142,10 +142,8 @@ gen_revoke( const char *uname ) if( !opt.armor ) tty_printf("ASCII armored output forced.\n"); - if( !(out = open_outfile( NULL, 0 )) ) { - rc = G10ERR_CREATE_FILE; + if( (rc = open_outfile( NULL, 0, &out )) ) goto leave; - } afx.what = 1; afx.hdrlines = "Comment: A revocation certificate should follow\n"; diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index 78673dfdc..df5c2b9b8 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -51,10 +51,12 @@ do_check( PKT_secret_key *sk ) if( sk->protect.algo == CIPHER_ALGO_NONE ) BUG(); - if( check_cipher_algo( sk->protect.algo ) ) - return G10ERR_CIPHER_ALGO; /* unsupported protection algorithm */ - if( cipher_get_blocksize( sk->protect.algo ) != 8 ) - return G10ERR_CIPHER_ALGO; /* unsupported protection algorithm */ + if( check_cipher_algo( sk->protect.algo ) + || cipher_get_blocksize( sk->protect.algo ) != 8 ) { + log_info(_("protection algorithm %d is not supported\n"), + sk->protect.algo ); + return G10ERR_CIPHER_ALGO; + } keyid_from_sk( sk, keyid ); dek = passphrase_to_dek( keyid, sk->protect.algo, &sk->protect.s2k, 0 ); @@ -164,21 +166,6 @@ check_secret_key( PKT_secret_key *sk ) if( i ) log_error(_("Invalid passphrase; please try again ...\n")); rc = do_check( sk ); - #if 0 /* set to 1 to enable the workaround */ - if( rc == G10ERR_BAD_PASS && sk->is_protected - && sk->protect.algo == CIPHER_ALGO_BLOWFISH - && sk->pubkey_algo != PUBKEY_ALGO_ELGAMAL ) { - /* Workaround for a bug in 0.2.16 which still used - * a 160 bit key for BLOWFISH. */ - log_info("trying workaround for 0.2.16 passphrase bug ...\n"); - log_info("If you don't need this, uncomment it in g10/seckey-cert.c\n\n"); - sk->protect.algo = CIPHER_ALGO_BLOWFISH160; - rc = do_check( sk ); - if( rc ) - rc = G10ERR_BAD_PASS; - sk->protect.algo = CIPHER_ALGO_BLOWFISH; - } - #endif if( get_passphrase_fd() != -1 ) break; } diff --git a/g10/sign.c b/g10/sign.c index a5034c702..d3f49e1df 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -156,6 +156,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, int compr_algo = -1; /* unknown */ + memset( &afx, 0, sizeof afx); memset( &zfx, 0, sizeof zfx); memset( &mfx, 0, sizeof mfx); @@ -203,10 +204,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, else if( opt.verbose ) log_info("writing to '%s'\n", outfile ); } - else if( !(out = open_outfile( fname, opt.armor? 1: detached? 2:0 )) ) { - rc = G10ERR_CREATE_FILE; + else if( (rc = open_outfile( fname, opt.armor? 1: detached? 2:0, &out ))) goto leave; - } /* prepare to calculate the MD over the input */ if( opt.textmode && !outfile ) @@ -223,9 +222,12 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( opt.armor && !outfile ) iobuf_push_filter( out, armor_filter, &afx ); - else + else { write_comment( out, "#created by GNUPG v" VERSION " (" PRINTABLE_OS_NAME ")"); + if( opt.comment_string ) + write_comment( out, opt.comment_string ); + } if( encrypt ) { efx.pk_list = pk_list; /* fixme: set efx.cfx.datalen if known */ @@ -312,10 +314,17 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, } } else { + if( fname || opt.set_filename ) { + const char *s = opt.set_filename ? opt.set_filename : fname; + pt = m_alloc( sizeof *pt + strlen(s) - 1 ); + pt->namelen = strlen(s); + memcpy(pt->name, s, pt->namelen ); + } + else { /* no filename */ + pt = m_alloc( sizeof *pt - 1 ); + pt->namelen = 0; + } if( fname ) { - pt = m_alloc( sizeof *pt + strlen(fname) - 1 ); - pt->namelen = strlen(fname); - memcpy(pt->name, fname, pt->namelen ); if( !(filesize = iobuf_get_filelength(inp)) ) log_info("warning: '%s' is an empty file\n", fname ); @@ -329,11 +338,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( opt.textmode && !outfile ) filesize = 0; } - else { /* no filename */ - pt = m_alloc( sizeof *pt - 1 ); - pt->namelen = 0; + else filesize = 0; /* stdin */ - } pt->timestamp = make_timestamp(); pt->mode = opt.textmode && !outfile ? 't':'b'; pt->len = filesize; @@ -533,10 +539,8 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) else if( opt.verbose ) log_info("writing to '%s'\n", outfile ); } - else if( !(out = open_outfile( fname, 1 )) ) { - rc = G10ERR_CREATE_FILE; + else if( (rc = open_outfile( fname, 1, &out )) ) goto leave; - } iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" ); diff --git a/g10/status.c b/g10/status.c index 6eb074909..3c22c0d1c 100644 --- a/g10/status.c +++ b/g10/status.c @@ -286,10 +286,26 @@ cpr_kill_prompt(void) int cpr_get_answer_is_yes( const char *keyword, const char *prompt ) { + int yes; + char *p; + #ifdef USE_SHM_COPROCESSING if( opt.shm_coprocess ) return !!do_shm_get( keyword, 0, 1 ); #endif - return tty_get_answer_is_yes( prompt ); + for(;;) { + p = tty_get( prompt ); + trim_spaces(p); /* it is okay to do this here */ + if( *p == '?' && !p[1] ) { + m_free(p); + display_help( keyword ); + } + else { + tty_kill_prompt(); + yes = answer_is_yes(p); + m_free(p); + return yes; + } + } } diff --git a/g10/trustdb.c b/g10/trustdb.c index cc94ad8e1..642d1b5e9 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1617,6 +1617,11 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel ) } log_info(_("key %08lX.%lu: inserted into trustdb\n"), keyid[1], pk->local_id ); + /* and re-read the dir record */ + if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) { + log_error("check_trust: reread dir record failed\n"); + return G10ERR_TRUSTDB; + } } } cur_time = make_timestamp(); |