diff --git a/g10/ChangeLog b/g10/ChangeLog index ce2c0b410..0579504da 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,22 @@ +2002-06-20 David Shaw + + * keydb.h, pkclist.c (select_algo_from_prefs): Allow passing a + suggested algorithm which will be used if available. + + * encode.c (encode_crypt, encrypt_filter), sign.c (sign_file): Use + new select_algo_from_prefs feature to check if forcing an + algorithm would violate the recipient preferences. + + * photoid.c (get_default_photo_command, show_photos): Use + different default viewers on different platforms. Currently we + have Win 9x, Win NT (2k, xp), Mac OSX, RISC OS, and "everybody + else". These are #ifdefs as much as possible to avoid clutter. + + * g10.c (strusage, build_list), keyedit.c (show_prefs), main.h, + misc.c (compress_algo_to_string, check_compress_algo), pkclist.c + (algo_available), keygen.c (keygen_set_std_prefs): New + algo_to_string and check functions for compress algorithms. + 2002-06-20 Werner Koch * misc.c (setsysinfo): Removed a #warning for Alpha's uniligedn diff --git a/g10/encode.c b/g10/encode.c index 9c5075f74..80a9039ec 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -387,7 +387,7 @@ encode_crypt( const char *filename, STRLIST remusr ) /* create a session key */ cfx.dek = m_alloc_secure_clear (sizeof *cfx.dek); if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ - cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM, NULL ); + cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL); /* The only way select_algo_from_prefs can fail here is when mixing v3 and v4 keys, as v4 keys have an implicit preference entry for 3DES, and the pk_list cannot be empty. @@ -406,8 +406,17 @@ encode_crypt( const char *filename, STRLIST remusr ) } } } - else - cfx.dek->algo = opt.def_cipher_algo; + else { + if(!opt.expert && + select_algo_from_prefs(pk_list,PREFTYPE_SYM, + opt.def_cipher_algo,NULL)!=opt.def_cipher_algo) + log_info(_("forcing symmetric cipher %s (%d) " + "violates recipient preferences\n"), + cipher_algo_to_string(opt.def_cipher_algo), + opt.def_cipher_algo); + + cfx.dek->algo = opt.def_cipher_algo; + } cfx.dek->use_mdc = select_mdc_from_pklist (pk_list); make_session_key( cfx.dek ); @@ -467,9 +476,15 @@ encode_crypt( const char *filename, STRLIST remusr ) if(compr_algo==-1) { if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,NULL))==-1) + select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) compr_algo=DEFAULT_COMPRESS_ALGO; } + else if(!opt.expert && + select_algo_from_prefs(pk_list,PREFTYPE_ZIP, + compr_algo,NULL)!=compr_algo) + log_info(_("forcing compression algorithm %s (%d) " + "violates recipient preferences\n"), + compress_algo_to_string(compr_algo),compr_algo); /* algo 0 means no compression */ if( compr_algo ) @@ -537,15 +552,25 @@ encrypt_filter( void *opaque, int control, if( !opt.def_cipher_algo ) { /* try to get it from the prefs */ efx->cfx.dek->algo = - select_algo_from_prefs( efx->pk_list, PREFTYPE_SYM, NULL ); + select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM,-1,NULL); if( efx->cfx.dek->algo == -1 ) { /* because 3DES is implicitly in the prefs, this can only * happen if we do not have any public keys in the list */ efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; } } - else - efx->cfx.dek->algo = opt.def_cipher_algo; + else { + if(!opt.expert && + select_algo_from_prefs(efx->pk_list,PREFTYPE_SYM, + opt.def_cipher_algo, + NULL)!=opt.def_cipher_algo) + log_info(_("forcing symmetric cipher %s (%d) " + "violates recipient preferences\n"), + cipher_algo_to_string(opt.def_cipher_algo), + opt.def_cipher_algo); + + efx->cfx.dek->algo = opt.def_cipher_algo; + } efx->cfx.dek->use_mdc = select_mdc_from_pklist (efx->pk_list); diff --git a/g10/g10.c b/g10/g10.c index 6a897bceb..33aa164af 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -607,7 +607,7 @@ const char *__dynamic_da_name = "GnuPG Heap"; const char * strusage( int level ) { - static char *digests, *pubkeys, *ciphers; + static char *digests, *pubkeys, *ciphers, *zips; const char *p; switch( level ) { case 11: p = "gpg (GnuPG)"; @@ -653,13 +653,12 @@ strusage( int level ) p = digests; break; case 37: - if(opt.verbose) - p = "Compress: Uncompressed (Z0), ZIP (Z1), ZLIB (Z2)\n"; - else - p = "Compress: Uncompressed, ZIP, ZLIB\n"; + if( !zips ) + zips = build_list("Compress: ",'Z',compress_algo_to_string, + check_compress_algo); + p = zips; break; - default: p = default_strusage(level); } return p; @@ -678,11 +677,11 @@ build_list( const char *text, char letter, if( maybe_setuid ) secmem_init( 0 ); /* drop setuid */ - for(i=1; i <= 110; i++ ) + for(i=0; i <= 110; i++ ) if( !chkf(i) && (s=mapf(i)) ) n += strlen(s) + 7 + 2; list = m_alloc( 21 + n ); *list = 0; - for(p=NULL, i=1; i <= 110; i++ ) { + for(p=NULL, i=0; i <= 110; i++ ) { if( !chkf(i) && (s=mapf(i)) ) { if( !p ) { p = stpcpy( list, text ); diff --git a/g10/keydb.h b/g10/keydb.h index 13106955d..34d02d702 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -166,7 +166,8 @@ void show_revocation_reason( PKT_public_key *pk, int mode ); int check_signatures_trust( PKT_signature *sig ); void release_pk_list( PK_LIST pk_list ); int build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ); -int select_algo_from_prefs( PK_LIST pk_list, int preftype, void *hint ); +int select_algo_from_prefs( PK_LIST pk_list, int preftype, + int request, void *hint ); int select_mdc_from_pklist (PK_LIST pk_list); /*-- skclist.c --*/ diff --git a/g10/keyedit.c b/g10/keyedit.c index 6462b1d13..db811ac0c 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1503,21 +1503,7 @@ show_prefs (PKT_user_id *uid, int verbose) tty_printf ("\n Compression: "); for(i=any=0; prefs[i].type; i++ ) { if( prefs[i].type == PREFTYPE_ZIP ) { - const char *s=NULL; - switch(prefs[i].value) - { - case 0: - s="Uncompressed"; - break; - - case 1: - s="ZIP"; - break; - - case 2: - s="ZLIB"; - break; - } + const char *s=compress_algo_to_string(prefs[i].value); if (any) tty_printf (", "); @@ -1534,9 +1520,11 @@ show_prefs (PKT_user_id *uid, int verbose) if (!uncomp_seen) { if (any) tty_printf (", "); - else - tty_printf ("ZIP, "); - tty_printf ("Uncompressed"); + else { + tty_printf ("%s",compress_algo_to_string(1)); + tty_printf (", "); + } + tty_printf ("%s",compress_algo_to_string(0)); } tty_printf ("\n Features: "); if(uid->mdc_feature) diff --git a/g10/keygen.c b/g10/keygen.c index 4f9becbfe..b8398b88a 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -198,11 +198,6 @@ set_one_pref (ulong val, int type, int (*cf)(int), byte *buf, int *nbuf) return 0; } -static int -check_zip_algo (int algo) -{ - return algo < 0 || algo > 2; -} /* * Parse the supplied string and use it to set the standard preferences. @@ -252,7 +247,7 @@ keygen_set_std_prefs (const char *string,int personal) } else if ((*s=='z' || *s == 'Z') && isdigit(s[1]) ) { val = strtoul (++s, (char**)&s2, 10); - if (set_one_pref (val, 'Z', check_zip_algo, zip, &nzip)) + if (set_one_pref (val, 'Z', check_compress_algo, zip, &nzip)) rc = -1; } else if (ascii_strcasecmp(s,"mdc")==0) { diff --git a/g10/main.h b/g10/main.h index 6946362f4..e7153bd55 100644 --- a/g10/main.h +++ b/g10/main.h @@ -85,6 +85,8 @@ char *pct_expando(const char *string,struct expando_args *args); int hextobyte( const char *s ); void deprecated_warning(const char *configname,unsigned int configlineno, const char *option,const char *repl1,const char *repl2); +const char *compress_algo_to_string(int algo); +int check_compress_algo(int algo); /*-- helptext.c --*/ void display_online_help( const char *keyword ); diff --git a/g10/misc.c b/g10/misc.c index 1fb635d83..c2330d959 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -657,3 +657,35 @@ deprecated_warning(const char *configname,unsigned int configlineno, log_info(_("please use \"%s%s\" instead\n"),repl1,repl2); } + +const char * +compress_algo_to_string(int algo) +{ + const char *s="?"; + + switch(algo) + { + case 0: + s="Uncompressed"; + break; + + case 1: + s="ZIP"; + break; + + case 2: + s="ZLIB"; + break; + } + + return s; +} + +int +check_compress_algo(int algo) +{ + if(algo>=0 && algo<=2) + return 0; + + return G10ERR_COMPR_ALGO; +} diff --git a/g10/photoid.c b/g10/photoid.c index 13e4cd1c7..66240ecc2 100644 --- a/g10/photoid.c +++ b/g10/photoid.c @@ -22,7 +22,9 @@ #include #include #include - +#ifdef HAVE_DOSISH_SYSTEM +#include +#endif #include "packet.h" #include "status.h" #include "exec.h" @@ -35,12 +37,6 @@ #include "main.h" #include "photoid.h" -#ifdef HAVE_DOSISH_SYSTEM -#define DEFAULT_PHOTO_COMMAND "start /w %i" -#else -#define DEFAULT_PHOTO_COMMAND "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin" -#endif - /* Generate a new photo id packet, or return NULL if canceled */ PKT_user_id *generate_photo_id(PKT_public_key *pk) { @@ -219,6 +215,29 @@ char *image_type_to_string(byte type,int style) return string; } +static const char *get_default_photo_command(void) +{ +#if defined(HAVE_DOSISH_SYSTEM) + OSVERSIONINFO osvi; + + memset(&osvi,0,sizeof(osvi)); + osvi.dwOSVersionInfoSize=sizeof(osvi); + GetVersionEx(&osvi); + + if(osvi.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) + return "start /w %i"; + else + return "cmd /c start /w %i"; +#elif defined(__APPLE__) + /* OS X. This really needs more than just __APPLE__. */ + return "open %I"; +#elif defined(__riscos__) + return "Filer_Run %I"; +#else + return "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin"; +#endif +} + void show_photos(const struct user_attribute *attrs, int count,PKT_public_key *pk,PKT_secret_key *sk) { @@ -244,9 +263,11 @@ void show_photos(const struct user_attribute *attrs, struct exec_info *spawn; int offset=attrs[i].len-len; + if(!opt.photo_viewer) + opt.photo_viewer=get_default_photo_command(); + /* make command grow */ - command=pct_expando(opt.photo_viewer? - opt.photo_viewer:DEFAULT_PHOTO_COMMAND,&args); + command=pct_expando(opt.photo_viewer,&args); if(!command) goto fail; diff --git a/g10/pkclist.c b/g10/pkclist.c index 70e551fad..671b56879 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -1058,7 +1058,7 @@ algo_available( int preftype, int algo, void *hint ) if ( ( opt.pgp6 || opt.pgp7 ) && ( algo !=0 && algo != 1) ) return 0; - return !algo || algo == 1 || algo == 2; + return !check_compress_algo( algo ); } else return 0; @@ -1070,7 +1070,7 @@ algo_available( int preftype, int algo, void *hint ) * Return -1 if we could not find an algorithm. */ int -select_algo_from_prefs( PK_LIST pk_list, int preftype, void *hint ) +select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint) { PK_LIST pkr; u32 bits[8]; @@ -1189,6 +1189,11 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype, void *hint ) } } } + + /* Can we use the requested algorithm? */ + if(request>-1 && request==i) + return i; + #if 0 log_debug("prefs of type %d: selected %d\n", preftype, i ); #endif diff --git a/g10/sign.c b/g10/sign.c index cfab80066..6a8ce2991 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -679,24 +679,39 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, /* If we're encrypting and signing, it is reasonable to pick the hash algorithm to use out of the recepient key prefs. */ - if(pk_list && !opt.def_digest_algo) + if(pk_list) { - int hashlen=0,algo; + if(opt.def_digest_algo) + { + if(!opt.expert && + select_algo_from_prefs(pk_list,PREFTYPE_HASH, + opt.def_digest_algo, + NULL)!=opt.def_digest_algo) + log_info(_("forcing digest algorithm %s (%d) " + "violates recipient preferences\n"), + digest_algo_to_string(opt.def_digest_algo), + opt.def_digest_algo); + } + else + { + int hashlen=0,algo; - /* Of course, if the recipient asks for something unreasonable - (like a non-160-bit hash for DSA, for example), then don't - do it. Check all sk's - if any are DSA, then the hash must - be 160-bit. In the future this can be more complex with - different hashes for each sk, but so long as there is only - one signing algorithm with hash restrictions, this is - ok. -dms */ + /* Of course, if the recipient asks for something + unreasonable (like a non-160-bit hash for DSA, for + example), then don't do it. Check all sk's - if any + are DSA, then the hash must be 160-bit. In the future + this can be more complex with different hashes for each + sk, but so long as there is only one signing algorithm + with hash restrictions, this is ok. -dms */ - for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) - if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA) - hashlen=20; + for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) + if(sk_rover->sk->pubkey_algo==PUBKEY_ALGO_DSA) + hashlen=20; - if((algo=select_algo_from_prefs(pk_list,PREFTYPE_HASH,&hashlen))>0) - recipient_digest_algo=algo; + if((algo= + select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,&hashlen))>0) + recipient_digest_algo=algo; + } } for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { @@ -724,19 +739,25 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, int compr_algo=opt.def_compress_algo; /* If not forced by user */ - if(compr_algo==-1) + if(compr_algo==-1) { /* If we're not encrypting, then select_algo_from_prefs - will fail and we'll end up with the default. If we are - encrypting, select_algo_from_prefs cannot fail since - there is an assumed preference for uncompressed data. - Still, if it did fail, we'll also end up with the - default. */ - + will fail and we'll end up with the default. If we are + encrypting, select_algo_from_prefs cannot fail since + there is an assumed preference for uncompressed data. + Still, if it did fail, we'll also end up with the + default. */ + if((compr_algo= - select_algo_from_prefs(pk_list,PREFTYPE_ZIP,NULL))==-1) + select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1) compr_algo=DEFAULT_COMPRESS_ALGO; } + else if(!opt.expert && + select_algo_from_prefs(pk_list,PREFTYPE_ZIP, + compr_algo,NULL)!=compr_algo) + log_info(_("forcing compression algorithm %s (%d) " + "violates recipient preferences\n"), + compress_algo_to_string(compr_algo),compr_algo); /* algo 0 means no compression */ if( compr_algo )