diff options
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 45 | ||||
-rw-r--r-- | g10/armor.c | 22 | ||||
-rw-r--r-- | g10/g10.c | 2 | ||||
-rw-r--r-- | g10/getkey.c | 40 | ||||
-rw-r--r-- | g10/mainproc.c | 116 | ||||
-rw-r--r-- | g10/misc.c | 1 | ||||
-rw-r--r-- | g10/options.h | 2 | ||||
-rw-r--r-- | g10/options.skel | 8 | ||||
-rw-r--r-- | g10/packet.h | 1 | ||||
-rw-r--r-- | g10/parse-packet.c | 43 | ||||
-rw-r--r-- | g10/sign.c | 2 | ||||
-rw-r--r-- | g10/signal.c | 114 |
12 files changed, 228 insertions, 168 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index 315ef5b79..5acdaf4a1 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,8 +1,53 @@ +2001-03-12 Werner Koch <[email protected]> + + * armor.c (parse_header_line): Removed double empty line check. + (parse_header_line): Replaced trim_trailing_ws with a counting + function so that we can adjust for the next read. + + * options.skel: Fixed 3 typos. By Thomas Klausner. Replaced the + keyserver example by a better working server. + + * parse-packet.c (parse_symkeyenc): Return Invalid_Packet on error. + (parse_pubkeyenc): Ditto. + (parse_onepass_sig): Ditto. + (parse_plaintext): Ditto. + (parse_encrypted): Ditto. + (parse_signature): Return error at other places too. + (parse_key): Ditto. + * g10.c (main): Set opt.list_packets to another value when invoked + with the --list-packets command. + * mainproc.c (do_proc_packets): Don's stop processing when running + under --list-packets command. + + * signal.c (do_sigaction): Removed. + (init_one_signal): New to replace the above. Needed to support + systems without sigactions. Suggested by Dave Dykstra. + (got_fatal_signal,init_signals): Use the above here. + (do_block): Use sigset() if sigprocmask() is not available. + + * armor.c (parse_hash_header): Test on TIGER192, which is the + correct value as per rfc2440. By Edwin Woudt. + 2001-03-08 Werner Koch <[email protected]> + * misc.c: Include time.h. By James Troup. + * getkey.c: Re-enabled the unknown user Id and PK caches and increased their sizes. + * getkey.c (merge_selfsigs_main): Set expire date and continue + processing even if we found a revoked key. + (merge_selfsigs_subkeys): Ditto. + + * packet.h: Add an is_revoked flag to the user_id packet. + * getkey.c (fixup_uidnode): Set that flag here. + (merge_selfsigs_main): Fix so that the latest signature is used to + find the self-signature for an UID. + * parse-packet.c (parse_user_id): Zero out all fields. + * mainproc.c (check_sig_and_print): Print the primary user ID + according the the node flag and then all other non-revoked user IDs. + (is_uid_revoked): Removed; it is now handled by the key selection code. + Changed the year list of all copyright notices. 2001-03-07 Werner Koch <[email protected]> diff --git a/g10/armor.c b/g10/armor.c index f07cf8e1d..03d52b1fe 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -245,7 +245,9 @@ parse_hash_header( const char *line ) found |= 2; else if( !strncmp( s, "MD5", s2-s ) ) found |= 4; - else if( !strncmp( s, "TIGER", s2-s ) ) + else if( !strncmp( s, "TIGER192", s2-s ) ) + found |= 8; + else if( !strncmp( s, "TIGER", s2-s ) ) /* used by old versions */ found |= 8; else return 0; @@ -312,19 +314,19 @@ is_armor_header( byte *line, unsigned len ) * >0: Good header line */ static int -parse_header_line( armor_filter_context_t *afx, byte *line, unsigned len ) +parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len ) { byte *p; int hashes=0; + unsigned int len2; - /* fixme: why this double check? I think the original code w/o the - * second check for an empty line was done from an early draft of - * of OpenPGP - or simply very stupid code */ - if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) ) - return 0; /* empty line */ - len = trim_trailing_ws( line, len ); - if( !len ) - return 0; /* WS only same as empty line */ + len2 = check_trailing_ws( line, len ); + if( !len2 ) { + afx->buffer_pos = len2; /* (it is not the fine way to do it here) */ + return 0; /* WS only: same as empty line */ + } + len = len2; + line[len2] = 0; p = strchr( line, ':'); if( !p || !p[1] ) { @@ -1574,7 +1574,7 @@ main( int argc, char **argv ) break; case aListPackets: - opt.list_packets=1; + opt.list_packets=2; default: if( argc > 1 ) wrong_args(_("[filename]")); diff --git a/g10/getkey.c b/g10/getkey.c index 75222bde8..d00a2ebd9 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -1354,12 +1354,13 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode ) uid->created = 0; /* not created == invalid */ if ( !signode ) return; /* no self-signature */ - if ( IS_UID_REV ( sig ) ) + if ( IS_UID_REV ( sig ) ) { + uid->is_revoked = 1; return; /* has been revoked */ + } uid->created = sig->timestamp; /* this one is okay */ - /* store the key flags in the helper variable for later processing */ uid->help_key_usage = 0; p = parse_sig_subpkt ( sig->hashed_data, SIGSUBPKT_KEY_FLAGS, &n ); @@ -1434,13 +1435,15 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) ; /* signature did not verify */ else if ( IS_KEY_REV (sig) ){ /* key has been revoked - there is no way to override - * such a revocation, so we can stop now. - * we can't cope with expiration times for revocations - * here because we have to assumethat an attacker can - * generate all kinds of signatures. + * such a revocation, so we theoretically can stop now. + * We should not cope with expiration times for revocations + * here because we have to assume that an attacker can + * generate all kinds of signatures. However due to the + * fact that the key has been revoked it does not harm + * either and by continuing we gather some more info on + * that key. */ *r_revoked = 1; - return; } else if ( IS_KEY_SIG (sig) && sig->timestamp >= sigdate ) { const byte *p; @@ -1511,8 +1514,9 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) if ( sig->keyid[0] == kid[0] && sig->keyid[1]==kid[1] ) { if ( check_key_signature( keyblock, k, NULL ) ) ; /* signature did not verify */ - else if ( IS_UID_SIG (sig) || IS_UID_REV (sig)) { - /* Note: we allow to invalidated cert revocations + else if ( (IS_UID_SIG (sig) || IS_UID_REV (sig)) + && sig->timestamp >= sigdate ) { + /* Note: we allow to invalidate cert revocations * by a newer signature. An attacker can't use this * because a key should be revoced with a key revocation. * The reason why we have to allow for that is that at @@ -1583,10 +1587,9 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) } pk->pubkey_usage = key_usage; - if ( !key_expire_seen ) { /* find the latest valid user ID with a key expiration set - * Note, that this may be a diferent one from the above because + * Note, that this may be a different one from the above because * some user IDs may have no expiration date set */ uiddate = 0; for(k=keyblock; k && k->pkt->pkttype != PKT_PUBLIC_SUBKEY; @@ -1603,8 +1606,10 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked ) } pk->has_expired = key_expire >= curtime? 0 : key_expire; - /* FIXME: we should see how to get rid of the expiretime fields */ - + if ( pk->version >= 4 ) + pk->expiredate = key_expire; + /* Fixme: we should see how to get rid of the expiretime fields but + * this needs changes at other palces too. */ /* and now find the real primary user ID and delete all others */ uiddate = uiddate2 = 0; @@ -1681,12 +1686,10 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode ) if ( check_key_signature( keyblock, k, NULL ) ) ; /* signature did not verify */ else if ( IS_SUBKEY_REV (sig) ) { - /* key has been revoked - given the fact that it is easy - * to create a new subkey, it does not make sense to - * revive a revoked key. So we can stop here. - */ subpk->is_revoked = 1; - return; + /* although we could stop now, we continue to + * figure out other information like the old expiration + * time */ } else if ( IS_SUBKEY_SIG (sig) && sig->timestamp >= sigdate ) { p = parse_sig_subpkt( sig->hashed_data, @@ -1735,6 +1738,7 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode ) else key_expire = 0; subpk->has_expired = key_expire >= curtime? 0 : key_expire; + subpk->expiredate = key_expire; } diff --git a/g10/mainproc.c b/g10/mainproc.c index f05350e15..71d6a0f7f 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -245,8 +245,8 @@ proc_symkey_enc( CTX c, PACKET *pkt ) PKT_symkey_enc *enc; enc = pkt->pkt.symkey_enc; - if( enc->seskeylen ) - log_error( "symkey_enc packet with session keys are not supported!\n"); + if (enc->seskeylen) + log_error ("symkey_enc packet with session keys are not supported!\n"); else { c->last_was_session_key = 2; c->dek = passphrase_to_dek( NULL, 0, enc->cipher_algo, &enc->s2k, 0 ); @@ -1040,7 +1040,9 @@ do_proc_packets( CTX c, IOBUF a ) any_data = 1; if( rc ) { free_packet(pkt); - if( rc == G10ERR_INVALID_PACKET ) + /* stop processing hwne an invalid packet has been encountered + * but don't do so when we are doing a --list-packet. */ + if( rc == G10ERR_INVALID_PACKET && opt.list_packets != 2 ) break; continue; } @@ -1163,68 +1165,6 @@ do_proc_packets( CTX c, IOBUF a ) } -/* fixme: This code is a duplicate fro keylist.c and should be replaced - * by flags set in getkey.c. gpg 1.1 already does this */ -static int -is_uid_revoked ( KBNODE keyblock, KBNODE uidnode, u32 *mainkid ) -{ - KBNODE node; - PKT_signature *selfsig = NULL; /* the latest valid self signature */ - - assert ( uidnode->pkt->pkttype == PKT_USER_ID ); - - /* first find out about the latest valid self-signature */ - for ( node = uidnode->next; node; node = node->next ) { - PKT_signature *sig; - - if ( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PHOTO_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - if ( node->pkt->pkttype != PKT_SIGNATURE ) - continue; - sig = node->pkt->pkt.signature; - if ( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] ) - continue; /* we only care about self-signatures for now */ - - if ( (sig->sig_class&~3) == 0x10 ) { /* regular self signature */ - if ( !check_key_signature( keyblock, node, NULL ) ) { - if ( !selfsig ) - selfsig = sig; /* use the first valid sig */ - else if ( sig->timestamp > selfsig->timestamp - && sig->sig_class >= selfsig->sig_class ) - selfsig = sig; /* but this one is newer */ - } - } - } - - /* watch out for a newer revocation */ - for ( node = uidnode->next; node; node = node->next ) { - PKT_signature *sig; - - if ( node->pkt->pkttype == PKT_USER_ID - || node->pkt->pkttype == PKT_PHOTO_ID - || node->pkt->pkttype == PKT_PUBLIC_SUBKEY - || node->pkt->pkttype == PKT_SECRET_SUBKEY ) - break; - if ( node->pkt->pkttype != PKT_SIGNATURE ) - continue; - sig = node->pkt->pkt.signature; - if ( mainkid[0] != sig->keyid[0] || mainkid[1] != sig->keyid[1] ) - continue; /* we only care about self-signatures */ - - if ( sig->sig_class == 0x30 - && (!selfsig || sig->timestamp >= selfsig->timestamp) ) { - if ( !check_key_signature( keyblock, node, NULL ) ) - return 1; - } - } - return 0; -} - - - static int check_sig_and_print( CTX c, KBNODE node ) { @@ -1282,8 +1222,6 @@ check_sig_and_print( CTX c, KBNODE node ) KBNODE un, keyblock; char *us; int count=0; - u32 mainkid[2]; - int mainkid_ok = 0; keyblock = get_pubkeyblock( sig->keyid ); @@ -1291,35 +1229,45 @@ check_sig_and_print( CTX c, KBNODE node ) write_status_text( rc? STATUS_BADSIG : STATUS_GOODSIG, us ); m_free(us); - /* fixme: list only user ids which are valid and add information - * about the trustworthiness of each user id, sort them. - * Integrate this with check_signatures_trust(). */ + /* find an print the primary user ID */ for( un=keyblock; un; un = un->next ) { - if ( !mainkid_ok && un->pkt->pkttype == PKT_PUBLIC_KEY ) { - keyid_from_pk( un->pkt->pkt.public_key, mainkid ); - mainkid_ok = 1; - } - if( !mainkid_ok || un->pkt->pkttype != PKT_USER_ID ) + if( un->pkt->pkttype != PKT_USER_ID ) continue; - if ( is_uid_revoked (keyblock, un, mainkid ) ) + if ( un->pkt->pkt.user_id->is_revoked ) continue; - - if( !count++ ) - log_info(rc? _("BAD signature from \"") - : _("Good signature from \"")); - else - log_info( _(" aka \"")); + if ( !un->pkt->pkt.user_id->is_primary ) + continue; + + log_info(rc? _("BAD signature from \"") + : _("Good signature from \"")); print_utf8_string( log_stream(), un->pkt->pkt.user_id->name, un->pkt->pkt.user_id->len ); fputs("\"\n", log_stream() ); - if( rc ) - break; /* print only one id in this case */ + count++; } if( !count ) { /* just in case that we have no userid */ log_info(rc? _("BAD signature from \"") : _("Good signature from \"")); fputs("[?]\"\n", log_stream() ); } + + /* If we have a good signature and already printed + * the primary user ID, print all the other user IDs */ + if ( count && !rc ) { + for( un=keyblock; un; un = un->next ) { + if( un->pkt->pkttype != PKT_USER_ID ) + continue; + if ( un->pkt->pkt.user_id->is_revoked ) + continue; + if ( un->pkt->pkt.user_id->is_primary ) + continue; + + log_info( _(" aka \"")); + print_utf8_string( log_stream(), un->pkt->pkt.user_id->name, + un->pkt->pkt.user_id->len ); + fputs("\"\n", log_stream() ); + } + } release_kbnode( keyblock ); if( !rc ) print_notation_data( sig ); diff --git a/g10/misc.c b/g10/misc.c index c1936aeee..573ff1b50 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -29,6 +29,7 @@ #include <asm/unistd.h> #endif #ifdef HAVE_SETRLIMIT + #include <time.h> #include <sys/time.h> #include <sys/resource.h> #endif diff --git a/g10/options.h b/g10/options.h index 2d0a9c529..20e60e6b9 100644 --- a/g10/options.h +++ b/g10/options.h @@ -44,7 +44,7 @@ struct { int fingerprint; /* list fingerprints */ int list_sigs; /* list signatures */ int no_armor; - int list_packets; /* list-packets mode */ + int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/ int def_cipher_algo; int force_v3_sigs; int force_mdc; diff --git a/g10/options.skel b/g10/options.skel index 43c3c0ab2..f2a117e23 100644 --- a/g10/options.skel +++ b/g10/options.skel @@ -48,7 +48,7 @@ force-v3-sigs # Because some mailers change lines starting with "From " to ">From " # it is good to handle such lines in a special way when creating -# cleartext signatures; all other PGP versions it this way too. +# cleartext signatures; all other PGP versions do it this way too. # To enable full OpenPGP compliance you have to remove this option. escape-from-lines @@ -81,12 +81,12 @@ lock-once # GnuPG can import a key from a HKP keyerver if one is missing -# for sercain operations. Is you set this option to a keyserver +# for certain operations. Is you set this option to a keyserver # you will be asked in such a case whether GnuPG should try to # import the key from that server (server do syncronize with each -# others and DNS Round-Robin may give you a random server each time). +# other and DNS Round-Robin may give you a random server each time). # Use "host -l pgp.net | grep www" to figure out a keyserver. -#keyserver wwwkeys.eu.pgp.net +#keyserver wwwkeys.nl.pgp.net # The environment variable http_proxy is only used when the # this option is set. diff --git a/g10/packet.h b/g10/packet.h index a1788336d..034ebdd47 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -178,6 +178,7 @@ typedef struct { int help_key_usage; u32 help_key_expire; int is_primary; + int is_revoked; u32 created; /* according to the self-signature */ char name[1]; } PKT_user_id; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index eca931b16..32b33bec8 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -576,19 +576,23 @@ static int parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) { PKT_symkey_enc *k; + int rc = 0; int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen; if( pktlen < 4 ) { log_error("packet(%d) too short\n", pkttype); + rc = G10ERR_INVALID_PACKET; goto leave; } version = iobuf_get_noeof(inp); pktlen--; if( version != 4 ) { log_error("packet(%d) with unknown version %d\n", pkttype, version); + rc = G10ERR_INVALID_PACKET; goto leave; } if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */ log_error("packet(%d) too large\n", pkttype); + rc = G10ERR_INVALID_PACKET; goto leave; } cipher_algo = iobuf_get_noeof(inp); pktlen--; @@ -610,6 +614,7 @@ parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) } if( minlen > pktlen ) { log_error("packet with S2K %d too short\n", s2kmode ); + rc = G10ERR_INVALID_PACKET; goto leave; } seskeylen = pktlen - minlen; @@ -646,24 +651,27 @@ parse_symkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) leave: skip_rest(inp, pktlen); - return 0; + return rc; } static int parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) { - unsigned n; + unsigned int n; + int rc = 0; int i, ndata; PKT_pubkey_enc *k; k = packet->pkt.pubkey_enc = m_alloc_clear(sizeof *packet->pkt.pubkey_enc); if( pktlen < 12 ) { log_error("packet(%d) too short\n", pkttype); + rc = G10ERR_INVALID_PACKET; goto leave; } k->version = iobuf_get_noeof(inp); pktlen--; if( k->version != 2 && k->version != 3 ) { log_error("packet(%d) with unknown version %d\n", pkttype, k->version); + rc = G10ERR_INVALID_PACKET; goto leave; } k->keyid[0] = read_32(inp); pktlen -= 4; @@ -695,7 +703,7 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) leave: skip_rest(inp, pktlen); - return 0; + return rc; } @@ -1088,6 +1096,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen, is_v4=1; else if( sig->version != 2 && sig->version != 3 ) { log_error("packet(%d) with unknown version %d\n", pkttype, sig->version); + rc = G10ERR_INVALID_PACKET; goto leave; } @@ -1223,14 +1232,17 @@ parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen, PKT_onepass_sig *ops ) { int version; + int rc = 0; if( pktlen < 13 ) { log_error("packet(%d) too short\n", pkttype); + rc = G10ERR_INVALID_PACKET; goto leave; } version = iobuf_get_noeof(inp); pktlen--; if( version != 3 ) { log_error("onepass_sig with unknown version %d\n", version); + rc = G10ERR_INVALID_PACKET; goto leave; } ops->sig_class = iobuf_get_noeof(inp); pktlen--; @@ -1249,7 +1261,7 @@ parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen, leave: skip_rest(inp, pktlen); - return 0; + return rc; } @@ -1289,11 +1301,13 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen, is_v4=1; else if( version != 2 && version != 3 ) { log_error("packet(%d) with unknown version %d\n", pkttype, version); + rc = G10ERR_INVALID_PACKET; goto leave; } if( pktlen < 11 ) { log_error("packet(%d) too short\n", pkttype); + rc = G10ERR_INVALID_PACKET; goto leave; } @@ -1572,6 +1586,12 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) packet->pkt.user_id->len = pktlen; packet->pkt.user_id->photo = NULL; packet->pkt.user_id->photolen = 0; + packet->pkt.user_id->is_primary = 0; + packet->pkt.user_id->is_revoked = 0; + packet->pkt.user_id->created = 0; + packet->pkt.user_id->help_key_usage = 0; + packet->pkt.user_id->help_key_expire = 0; + p = packet->pkt.user_id->name; for( ; pktlen; pktlen--, p++ ) *p = iobuf_get_noeof(inp); @@ -1580,7 +1600,7 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet ) if( list_mode ) { int n = packet->pkt.user_id->len; printf(":user ID packet: \""); - /* fixme: Hey why don't we replace this wioth print_string?? */ + /* fixme: Hey why don't we replace this with print_string?? */ for(p=packet->pkt.user_id->name; n; p++, n-- ) { if( *p >= ' ' && *p <= 'z' ) putchar(*p); @@ -1663,6 +1683,7 @@ static int parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt, int new_ctb ) { + int rc = 0; int mode, namelen; PKT_plaintext *pt; byte *p; @@ -1670,6 +1691,7 @@ parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, if( pktlen && pktlen < 6 ) { log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen); + rc = G10ERR_INVALID_PACKET; goto leave; } mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--; @@ -1709,7 +1731,7 @@ parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, } leave: - return 0; + return rc; } @@ -1738,6 +1760,7 @@ static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt, int new_ctb ) { + int rc = 0; PKT_encrypted *ed; unsigned long orig_pktlen = pktlen; @@ -1757,12 +1780,14 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, log_error("encrypted_mdc packet with unknown version %d\n", version); /*skip_rest(inp, pktlen); should we really do this? */ + rc = G10ERR_INVALID_PACKET; goto leave; } ed->mdc_method = DIGEST_ALGO_SHA1; } if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */ log_error("packet(%d) too short\n", pkttype); + rc = G10ERR_INVALID_PACKET; skip_rest(inp, pktlen); goto leave; } @@ -1779,7 +1804,7 @@ parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, pktlen = 0; leave: - return 0; + return rc; } @@ -1787,6 +1812,7 @@ static int parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt, int new_ctb ) { + int rc = 0; PKT_mdc *mdc; byte *p; @@ -1795,6 +1821,7 @@ parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen, printf(":mdc packet: length=%lu\n", pktlen); if( !new_ctb || pktlen != 20 ) { log_error("mdc_packet with invalid encoding\n"); + rc = G10ERR_INVALID_PACKET; goto leave; } p = mdc->hash; @@ -1802,7 +1829,7 @@ parse_mdc( IOBUF inp, int pkttype, unsigned long pktlen, *p = iobuf_get_noeof(inp); leave: - return 0; + return rc; } diff --git a/g10/sign.c b/g10/sign.c index b99fff6ee..6b603ebf7 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -430,7 +430,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( !(filesize = iobuf_get_filelength(inp)) ) log_info(_("WARNING: `%s' is an empty file\n"), fname ); /* we can't yet encode the length of very large files, - * so we switch to partial lengthn encoding in this case */ + * so we switch to partial length encoding in this case */ if ( filesize >= IOBUF_FILELENGTH_LIMIT ) filesize = 0; diff --git a/g10/signal.c b/g10/signal.c index 9ad194815..512f56368 100644 --- a/g10/signal.c +++ b/g10/signal.c @@ -38,6 +38,36 @@ static volatile int caught_fatal_sig = 0; static volatile int caught_sigusr1 = 0; +static void +init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign ) +{ + #ifndef HAVE_DOSISH_SYSTEM + #if HAVE_SIGACTION + struct sigaction oact, nact; + + if (check_ign) { + /* we don't want to change an IGN handler */ + sigaction (sig, NULL, &oact ); + if (oact.sa_handler == SIG_IGN ) + return; + } + + nact.sa_handler = handler; + sigemptyset (&nact.sa_mask); + nact.sa_flags = 0; + sigaction ( sig, &nact, NULL); + #else + RETSIGTYPE (*ohandler)(int); + + ohandler = signal (sig, handler); + if (check_ign && ohandler == SIG_IGN) { + /* Change it back if it was already set to IGN */ + signal (sig, SIG_IGN); + } + #endif + #endif /*!HAVE_DOSISH_SYSTEM*/ +} + static const char * get_signal_name( int signum ) { @@ -66,18 +96,9 @@ got_fatal_signal( int sig ) s = get_signal_name(sig); write(2, s, strlen(s) ); write(2, " caught ... exiting\n", 21 ); - #ifndef HAVE_DOSISH_SYSTEM - { /* reset action to default action and raise signal again */ - struct sigaction nact; - nact.sa_handler = SIG_DFL; - sigemptyset( &nact.sa_mask ); - nact.sa_flags = 0; - sigaction( sig, &nact, NULL); - } - #endif - + /* reset action to default action and raise signal again */ + init_one_signal (sig, SIG_DFL, 0); remove_lockfiles (); - raise( sig ); } @@ -88,37 +109,18 @@ got_usr_signal( int sig ) caught_sigusr1 = 1; } -#ifndef HAVE_DOSISH_SYSTEM -static void -do_sigaction( int sig, struct sigaction *nact ) -{ - struct sigaction oact; - - sigaction( sig, NULL, &oact ); - if( oact.sa_handler != SIG_IGN ) - sigaction( sig, nact, NULL); -} -#endif void init_signals() { #ifndef HAVE_DOSISH_SYSTEM - struct sigaction nact; - - nact.sa_handler = got_fatal_signal; - sigemptyset( &nact.sa_mask ); - nact.sa_flags = 0; - - do_sigaction( SIGINT, &nact ); - do_sigaction( SIGHUP, &nact ); - do_sigaction( SIGTERM, &nact ); - do_sigaction( SIGQUIT, &nact ); - do_sigaction( SIGSEGV, &nact ); - nact.sa_handler = got_usr_signal; - sigaction( SIGUSR1, &nact, NULL ); - nact.sa_handler = SIG_IGN; - sigaction( SIGPIPE, &nact, NULL ); + init_one_signal (SIGINT, got_fatal_signal, 1 ); + init_one_signal (SIGHUP, got_fatal_signal, 1 ); + init_one_signal (SIGTERM, got_fatal_signal, 1 ); + init_one_signal (SIGQUIT, got_fatal_signal, 1 ); + init_one_signal (SIGSEGV, got_fatal_signal, 1 ); + init_one_signal (SIGUSR1, got_usr_signal, 0 ); + init_one_signal (SIGPIPE, SIG_IGN, 0 ); #endif } @@ -127,6 +129,7 @@ void pause_on_sigusr( int which ) { #ifndef HAVE_DOSISH_SYSTEM + #ifdef HAVE_SIGPROCMASK sigset_t mask, oldmask; assert( which == 1 ); @@ -138,6 +141,14 @@ pause_on_sigusr( int which ) sigsuspend( &oldmask ); caught_sigusr1 = 0; sigprocmask( SIG_UNBLOCK, &mask, NULL ); + #else + assert (which == 1); + sighold (SIGUSR1); + while (!caught_sigusr1) + sigpause(SIGUSR1); + caught_sigusr1 = 0; + sigrelse(SIGUSR1); ???? + #endif /*!HAVE_SIGPROCMASK*/ #endif } @@ -145,12 +156,13 @@ pause_on_sigusr( int which ) static void do_block( int block ) { - #ifndef HAVE_DOSISH_SYSTEM + #ifndef HAVE_DOSISH_SYSTEM static int is_blocked; + #ifdef HAVE_SIGPROCMASK static sigset_t oldmask; if( block ) { - sigset_t newmask; + sigset_t newmask; if( is_blocked ) log_bug("signals are already blocked\n"); @@ -164,7 +176,28 @@ do_block( int block ) sigprocmask( SIG_SETMASK, &oldmask, NULL ); is_blocked = 0; } - #endif /*HAVE_DOSISH_SYSTEM*/ + #else /*!HAVE_SIGPROCMASK*/ + static void (*disposition[MAXSIG])(); + int sig; + + if( block ) { + if( is_blocked ) + log_bug("signals are already blocked\n"); + for (sig=1; sig < MAXSIG; sig++) { + disposition[sig] = sigset (sig, SIG_HOLD); + } + is_blocked = 1; + } + else { + if( !is_blocked ) + log_bug("signals are not blocked\n"); + for (sig=1; sig < MAXSIG; sig++) { + sigset (sig, disposition[sig]); + } + is_blocked = 0; + } + #endif /*!HAVE_SIGPROCMASK*/ + #endif /*HAVE_DOSISH_SYSTEM*/ } @@ -179,4 +212,3 @@ unblock_all_signals() { do_block(0); } - |