From 2f0a98ad356d8374c6013e035c3accefe3851e97 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Mon, 23 Feb 2004 18:35:05 +0000 Subject: [PATCH] * options.h, g10.c (main), trustdb.c (mark_usable_uid_certs): Add --min-cert-check-level option to specify minimum cert check level. Defaults to 1 (so no sigs are ignored). 0x10 sigs cannot be ignored. * options.h, g10.c (main), plaintext.c (handle_plaintext): Add --max-output option to help people deal with decompression bombs. --- g10/ChangeLog | 10 ++++++ g10/g10.c | 17 ++++++--- g10/options.h | 7 ++-- g10/plaintext.c | 93 +++++++++++++++++++++++++++++++++++++------------ g10/trustdb.c | 7 ++-- 5 files changed, 104 insertions(+), 30 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 6f7cc86bb..48e9277d6 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,13 @@ +2004-02-23 David Shaw + + * options.h, g10.c (main), trustdb.c (mark_usable_uid_certs): Add + --min-cert-check-level option to specify minimum cert check + level. Defaults to 1 (so no sigs are ignored). 0x10 sigs cannot + be ignored. + + * options.h, g10.c (main), plaintext.c (handle_plaintext): Add + --max-output option to help people deal with decompression bombs. + 2004-02-15 David Shaw * build-packet.c (do_user_id): Do not force a header for attribute diff --git a/g10/g10.c b/g10/g10.c index c1049b0d0..6bb068200 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -74,6 +74,7 @@ enum cmd_and_opt_values oCompress = 'z', oSetNotation = 'N', oBatch = 500, + oMaxOutput, oSigNotation, oCertNotation, oShowNotation, @@ -145,6 +146,7 @@ enum cmd_and_opt_values oAnswerYes, oAnswerNo, oDefCertCheckLevel, + oMinCertCheckLevel, oKeyring, oSecretKeyring, oShowKeyring, @@ -401,6 +403,7 @@ static ARGPARSE_OPTS opts[] = { { oAskCertExpire, "ask-cert-expire", 0, "@"}, { oNoAskCertExpire, "no-ask-cert-expire", 0, "@"}, { oOutput, "output", 2, N_("use as output file")}, + { oMaxOutput, "max-output", 16|4, "@" }, { oVerbose, "verbose", 0, N_("verbose") }, { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") }, @@ -530,6 +533,7 @@ static ARGPARSE_OPTS opts[] = { { oCompressKeys, "compress-keys",0, "@"}, { oCompressSigs, "compress-sigs",0, "@"}, { oDefCertCheckLevel, "default-cert-check-level", 1, "@"}, + { oMinCertCheckLevel, "min-cert-check-level", 1, "@"}, { oAlwaysTrust, "always-trust", 0, "@"}, { oTrustModel, "trust-model", 2, "@"}, { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"}, @@ -1320,6 +1324,7 @@ main( int argc, char **argv ) opt.keyserver_options.include_subkeys=1; opt.keyserver_options.include_revoked=1; opt.mangle_dos_filenames = 1; + opt.min_cert_check_level=1; #if defined (_WIN32) set_homedir ( read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" )); @@ -1525,6 +1530,7 @@ main( int argc, char **argv ) case oArmor: opt.armor = 1; opt.no_armor=0; break; case oOutput: opt.outfile = pargs.r.ret_str; break; + case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break; case oQuiet: opt.quiet = 1; break; case oNoTTY: tty_no_terminal(1); break; case oDryRun: opt.dry_run = 1; break; @@ -1592,6 +1598,7 @@ main( int argc, char **argv ) case oNoArmor: opt.no_armor=1; opt.armor=0; break; case oNoDefKeyring: default_keyring = 0; break; case oDefCertCheckLevel: opt.def_cert_check_level=pargs.r.ret_int; break; + case oMinCertCheckLevel: opt.min_cert_check_level=pargs.r.ret_int; break; case oNoGreeting: nogreeting = 1; break; case oNoVerbose: g10_opt_verbose = 0; opt.verbose = 0; opt.list_sigs=0; break; @@ -2124,13 +2131,15 @@ main( int argc, char **argv ) "BZIP2"); #endif if( opt.def_compress_algo < -1 || opt.def_compress_algo > 2 ) - log_error(_("compress algorithm must be in range %d..%d\n"), 0, 2); + log_error(_("compress algorithm must be in range %d..%d\n"), 0, 2); if( opt.completes_needed < 1 ) - log_error(_("completes-needed must be greater than 0\n")); + log_error(_("completes-needed must be greater than 0\n")); if( opt.marginals_needed < 2 ) - log_error(_("marginals-needed must be greater than 1\n")); + log_error(_("marginals-needed must be greater than 1\n")); if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 ) - log_error(_("max-cert-depth must be in range 1 to 255\n")); + log_error(_("max-cert-depth must be in range 1 to 255\n")); + if( opt.min_cert_check_level < 1 || opt.min_cert_check_level > 3 ) + log_error(_("min-cert-check-level must be in the range from 1 to 3\n")); switch( opt.s2k_mode ) { case 0: log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n")); diff --git a/g10/options.h b/g10/options.h index f9be0623d..c12efc109 100644 --- a/g10/options.h +++ b/g10/options.h @@ -1,6 +1,6 @@ /* options.h - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, + * 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -21,6 +21,7 @@ #ifndef G10_OPTIONS_H #define G10_OPTIONS_H +#include #include #include "main.h" #include "packet.h" @@ -44,6 +45,7 @@ struct { int armor; int compress; char *outfile; + off_t max_output; int dry_run; int list_only; int textmode; @@ -73,6 +75,7 @@ struct { char *def_recipient; int def_recipient_self; int def_cert_check_level; + int min_cert_check_level; int sk_comments; int no_version; int marginals_needed; diff --git a/g10/plaintext.c b/g10/plaintext.c index c25f32211..0737fb02c 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -1,5 +1,6 @@ /* plaintext.c - process plaintext packets - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, + * 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -24,6 +25,7 @@ #include #include #include +#include #ifdef HAVE_DOSISH_SYSTEM #include /* for setmode() */ #endif @@ -52,6 +54,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, { char *fname = NULL; FILE *fp = NULL; + off_t count=0; int rc = 0; int c; int convert = pt->mode == 't'; @@ -131,14 +134,23 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, if( c == '\r' ) /* convert to native line ending */ continue; /* fixme: this hack might be too simple */ #endif - if( fp ) { - if( putc( c, fp ) == EOF ) { + if( fp ) + { + if(opt.max_output && (count++)>opt.max_output) + { + log_error("Error writing to `%s': %s\n", + fname,"exceeded --max-output limit\n"); + rc = G10ERR_WRITE_FILE; + goto leave; + } + else if( putc( c, fp ) == EOF ) + { log_error("Error writing to `%s': %s\n", fname, strerror(errno) ); rc = G10ERR_WRITE_FILE; goto leave; - } - } + } + } } } else { /* binary mode */ @@ -155,15 +167,25 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, } if( mfx->md ) md_write( mfx->md, buffer, len ); - if( fp ) { - if( fwrite( buffer, 1, len, fp ) != len ) { + if( fp ) + { + if(opt.max_output && (count+=len)>opt.max_output) + { + log_error("Error writing to `%s': %s\n", + fname,"exceeded --max-output limit\n"); + rc = G10ERR_WRITE_FILE; + m_free( buffer ); + goto leave; + } + else if( fwrite( buffer, 1, len, fp ) != len ) + { log_error("Error writing to `%s': %s\n", fname, strerror(errno) ); rc = G10ERR_WRITE_FILE; m_free( buffer ); goto leave; - } - } + } + } pt->len -= len; } m_free( buffer ); @@ -178,14 +200,23 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, if( convert && c == '\r' ) continue; /* fixme: this hack might be too simple */ #endif - if( fp ) { - if( putc( c, fp ) == EOF ) { + if( fp ) + { + if(opt.max_output && (count++)>opt.max_output) + { + log_error("Error writing to `%s': %s\n", + fname,"exceeded --max-output limit\n"); + rc = G10ERR_WRITE_FILE; + goto leave; + } + else if( putc( c, fp ) == EOF ) + { log_error("Error writing to `%s': %s\n", fname, strerror(errno) ); rc = G10ERR_WRITE_FILE; goto leave; - } - } + } + } } } else { /* binary mode */ @@ -205,15 +236,24 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, eof = 1; if( mfx->md ) md_write( mfx->md, buffer, len ); - if( fp ) { - if( fwrite( buffer, 1, len, fp ) != len ) { + if( fp ) + { + if(opt.max_output && (count+=len)>opt.max_output) + { log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); + fname,"exceeded --max-output limit\n"); rc = G10ERR_WRITE_FILE; m_free( buffer ); goto leave; + } + else if( fwrite( buffer, 1, len, fp ) != len ) { + log_error("Error writing to `%s': %s\n", + fname, strerror(errno) ); + rc = G10ERR_WRITE_FILE; + m_free( buffer ); + goto leave; } - } + } } m_free( buffer ); } @@ -223,14 +263,23 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int state = 0; while( (c = iobuf_get(pt->buf)) != -1 ) { - if( fp ) { - if( putc( c, fp ) == EOF ) { + if( fp ) + { + if(opt.max_output && (count++)>opt.max_output) + { log_error("Error writing to `%s': %s\n", - fname, strerror(errno) ); + fname,"exceeded --max-output limit\n"); rc = G10ERR_WRITE_FILE; goto leave; - } - } + } + else if( putc( c, fp ) == EOF ) + { + log_error("Error writing to `%s': %s\n", + fname, strerror(errno) ); + rc = G10ERR_WRITE_FILE; + goto leave; + } + } if( !mfx->md ) continue; if( state == 2 ) { diff --git a/g10/trustdb.c b/g10/trustdb.c index f24b13bea..db63e53d3 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1,6 +1,6 @@ /* trustdb.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, + * 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1192,6 +1192,9 @@ mark_usable_uid_certs (KBNODE keyblock, KBNODE uidnode, continue; /* ignore self-signatures */ if (!IS_UID_SIG(sig) && !IS_UID_REV(sig)) continue; /* we only look at these signature classes */ + if(sig->sig_class>=0x11 && sig->sig_class<=0x13 && + sig->sig_class-0x10pubkey_algo))