aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ChangeLog27
-rw-r--r--g10/decrypt.c20
-rw-r--r--g10/encode.c3
-rw-r--r--g10/gpgv.c6
-rw-r--r--g10/keydb.h2
-rw-r--r--g10/keyedit.c6
-rw-r--r--g10/keygen.c13
-rw-r--r--g10/mainproc.c4
-rw-r--r--g10/passphrase.c141
-rw-r--r--g10/seckey-cert.c18
-rw-r--r--g10/sign.c2
11 files changed, 175 insertions, 67 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 95c066908..eb358b1a5 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,30 @@
+2003-04-10 Werner Koch <[email protected]>
+
+ * passphrase.c (read_passphrase_from_fd): Do a dummy read if the
+ agent is to be used. Noted by Ingo Kl�cker.
+ (agent_get_passphrase): Inhibit caching when we have no
+ fingerprint. This is required for key generation as well as for
+ symmetric only encryption.
+
+ * passphrase .c (agent_get_passphrase): New arg CANCELED.
+ (passphrase_to_dek): Ditto. Passed to above. Changed all
+ callers to pass NULL.
+ * seckey-cert.c (do_check): New arg CANCELED.
+ (check_secret_key): Terminate loop when canceled.
+
+ * keyedit.c (change_passphrase): Pass ERRTEXT untranslated to
+ passphrase_to_dek and translate where appropriate.
+ * seckey-cert.c (check_secret_key): Ditto.
+ * keygen.c (ask_passphrase): Ditto.
+ * passphrase.c (agent_get_passphrase): Translate the TRYAGAIN_TEXT.
+ Switch the codeset to utf-8.
+
+2003-04-09 Werner Koch <[email protected]>
+
+ * decrypt.c (decrypt_messages): Fixed error handling; the function
+ used to re-loop with same file after an error. Reported by Joseph
+ Walton.
+
2003-04-08 David Shaw <[email protected]>
* main.h, g10.c (main), import.c (parse_import_options,
diff --git a/g10/decrypt.c b/g10/decrypt.c
index 297ee3418..bea16b728 100644
--- a/g10/decrypt.c
+++ b/g10/decrypt.c
@@ -1,5 +1,5 @@
/* decrypt.c - verify signed data
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -99,12 +99,12 @@ decrypt_messages(int nfiles, char **files)
print_file_status(STATUS_FILE_START, *files, 3);
output = make_outfile_name(*files);
if (!output)
- continue;
+ goto next_file;
fp = iobuf_open(*files);
if (!fp)
{
log_error(_("can't open `%s'\n"), print_fname_stdin(*files));
- continue;
+ goto next_file;
}
if (!opt.no_armor)
{
@@ -122,17 +122,13 @@ decrypt_messages(int nfiles, char **files)
p = get_last_passphrase();
set_next_passphrase(p);
m_free (p);
- files++;
- m_free(output);
+
+ next_file:
+ /* Note that we emit file_done even after an error. */
write_status( STATUS_FILE_DONE );
+ m_free(output);
+ files++;
}
set_next_passphrase(NULL);
}
-
-
-
-
-
-
-
diff --git a/g10/encode.c b/g10/encode.c
index e705a6fad..d1b0cdb11 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -194,7 +194,8 @@ encode_simple( const char *filename, int mode, int compat )
s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
cfx.dek = passphrase_to_dek( NULL, 0,
- default_cipher_algo(), s2k, 2, NULL );
+ default_cipher_algo(), s2k, 2,
+ NULL, NULL);
if( !cfx.dek || !cfx.dek->keylen ) {
rc = G10ERR_PASSPHRASE;
m_free(cfx.dek);
diff --git a/g10/gpgv.c b/g10/gpgv.c
index eba6f8dd0..caa669171 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -314,9 +314,11 @@ check_secret_key( PKT_secret_key *sk, int n )
DEK *
passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode,
- const char *tmp)
+ const char *tmp, int *canceled)
{
- return NULL;
+ if (canceled)
+ *canceled = 0;
+ return NULL;
}
/* Stubs to avoid linking to photoid.c */
diff --git a/g10/keydb.h b/g10/keydb.h
index b506af65d..8395c118f 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -187,7 +187,7 @@ void read_passphrase_from_fd( int fd );
void passphrase_clear_cache ( u32 *keyid, int algo );
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode,
- const char *tryagain_text);
+ const char *tryagain_text, int *canceled);
void set_next_passphrase( const char *s );
char *get_last_passphrase(void);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 9186bd931..2b954e285 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -915,10 +915,10 @@ change_passphrase( KBNODE keyblock )
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
- s2k, 2, errtext);
+ s2k, 2, errtext, NULL);
if( !dek ) {
- errtext = _("passphrase not correctly repeated; try again");
- tty_printf ("%s.\n", errtext);
+ errtext = N_("passphrase not correctly repeated; try again");
+ tty_printf ("%s.\n", _(errtext));
}
else if( !dek->keylen ) {
rc = 0;
diff --git a/g10/keygen.c b/g10/keygen.c
index 3e5bc4fcd..ef4b422dd 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -1479,10 +1479,11 @@ ask_passphrase( STRING2KEY **ret_s2k )
for(;;) {
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2,errtext);
+ dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k,2,
+ errtext, NULL);
if( !dek ) {
- errtext = _("passphrase not correctly repeated; try again");
- tty_printf(_("%s.\n"), errtext);
+ errtext = N_("passphrase not correctly repeated; try again");
+ tty_printf(_("%s.\n"), _(errtext));
}
else if( !dek->keylen ) {
m_free(dek); dek = NULL;
@@ -1809,7 +1810,8 @@ proc_parameter_file( struct para_data_s *para, const char *fname,
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
set_next_passphrase( r->u.value );
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, NULL );
+ dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2,
+ NULL, NULL);
set_next_passphrase( NULL );
assert( dek );
memset( r->u.value, 0, strlen(r->u.value) );
@@ -2476,7 +2478,8 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
set_next_passphrase( passphrase );
- dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, NULL );
+ dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2,
+ NULL, NULL );
}
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 97af59591..1911d0076 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -292,7 +292,7 @@ proc_symkey_enc( CTX c, PACKET *pkt )
c->last_was_session_key = 2;
if ( opt.list_only )
goto leave;
- c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL );
+ c->dek = passphrase_to_dek( NULL, 0, algo, &enc->s2k, 0, NULL, NULL );
if (c->dek)
c->dek->algo_info_printed = 1;
if ( c->dek && enc->seskeylen )
@@ -486,7 +486,7 @@ proc_encrypted( CTX c, PACKET *pkt )
log_info (_("assuming %s encrypted data\n"), "IDEA");
}
- c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL );
+ c->dek = passphrase_to_dek ( NULL, 0, algo, s2k, 0, NULL, NULL );
if (c->dek)
c->dek->algo_info_printed = 1;
}
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 5345fb9b7..769276221 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -1,5 +1,5 @@
/* passphrase.c - Get a passphrase
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -36,6 +36,9 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
#include "util.h"
#include "memory.h"
@@ -144,33 +147,44 @@ get_last_passphrase()
void
read_passphrase_from_fd( int fd )
{
- int i, len;
- char *pw;
+ int i, len;
+ char *pw;
+
+ if ( opt.use_agent )
+ { /* Not used but we have to do a dummy read, so that it won't end
+ up at the begin of the message if the quite usual trick to
+ prepend the passphtrase to the message is used. */
+ char buf[1];
- if ( opt.use_agent )
- return; /* not used here */
+ while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
+ ;
+ *buf = 0;
+ return;
+ }
- if( !opt.batch )
+ if (!opt.batch )
tty_printf("Reading passphrase from file descriptor %d ...", fd );
- for( pw = NULL, i = len = 100; ; i++ ) {
- if( i >= len-1 ) {
- char *pw2 = pw;
- len += 100;
- pw = m_alloc_secure( len );
- if( pw2 )
- memcpy(pw, pw2, i );
- else
- i=0;
+ for (pw = NULL, i = len = 100; ; i++ )
+ {
+ if (i >= len-1 )
+ {
+ char *pw2 = pw;
+ len += 100;
+ pw = m_alloc_secure( len );
+ if( pw2 )
+ memcpy(pw, pw2, i );
+ else
+ i=0;
}
- if( read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
- break;
+ if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
+ break;
}
- pw[i] = 0;
- if( !opt.batch )
- tty_printf("\b\b\b \n" );
+ pw[i] = 0;
+ if (!opt.batch)
+ tty_printf("\b\b\b \n" );
- m_free( fd_passwd );
- fd_passwd = pw;
+ m_free( fd_passwd );
+ fd_passwd = pw;
}
static int
@@ -590,15 +604,20 @@ agent_close ( int fd )
* Mode 0: Allow cached passphrase
* 1: No cached passphrase FIXME: Not really implemented
* 2: Ditto, but change the text to "repeat entry"
+ *
+ * Note that TRYAGAIN_TEXT must not be translated. If canceled is not
+ * NULL, the function does set it to 1 if the user canceled the
+ * operation.
*/
static char *
-agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
+agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text,
+ int *canceled)
{
#if defined(__riscos__)
return NULL;
#else
size_t n;
- char *atext;
+ char *atext = NULL;
char buf[50];
int fd = -1;
int nread;
@@ -606,7 +625,12 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
char *pw = NULL;
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
byte fpr[MAX_FINGERPRINT_LEN];
+ int have_fpr = 0;
int prot;
+ char *orig_codeset = NULL;
+
+ if (canceled)
+ *canceled = 0;
#if MAX_FINGERPRINT_LEN < 20
#error agent needs a 20 byte fingerprint
@@ -619,6 +643,24 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
pk = NULL; /* oops: no key for some reason */
}
+#ifdef ENABLE_NLS
+ /* The Assuan agent protol requires us to trasnmit utf-8 strings */
+ orig_codeset = bind_textdomain_codeset (PACKAGE, NULL);
+#ifdef HAVE_LANGINFO_CODESET
+ if (!orig_codeset)
+ orig_codeset = nl_langinfo (CODESET);
+#endif
+ if (orig_codeset)
+ { /* We only switch when we are able to restore the codeset later. */
+ orig_codeset = m_strdup (orig_codeset);
+ if (!bind_textdomain_codeset (PACKAGE, "utf-8"))
+ orig_codeset = NULL;
+ }
+#endif
+
+ if ( (fd = agent_open (&prot)) == -1 )
+ goto failure;
+
if ( !mode && pk && keyid )
{
char *uid;
@@ -658,6 +700,7 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
{
size_t dummy;
fingerprint_from_pk( pk, fpr, &dummy );
+ have_fpr = 1;
}
}
@@ -666,9 +709,6 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
else
atext = m_strdup ( _("Enter passphrase\n") );
- if ( (fd = agent_open (&prot)) == -1 )
- goto failure;
-
if (!prot)
{ /* old style protocol */
n = 4 + 20 + strlen (atext);
@@ -724,10 +764,19 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
pw[pwlen] = 0; /* make a C String */
agent_close (fd);
free_public_key( pk );
+#ifdef ENABLE_NLS
+ if (orig_codeset)
+ bind_textdomain_codeset (PACKAGE, orig_codeset);
+#endif
+ m_free (orig_codeset);
return pw;
}
else if ( reply == GPGA_PROT_CANCELED )
- log_info ( _("cancelled by user\n") );
+ {
+ log_info ( _("cancelled by user\n") );
+ if (canceled)
+ *canceled = 1;
+ }
else
log_error ( _("problem with the agent: agent returns 0x%lx\n"),
(ulong)reply );
@@ -740,6 +789,8 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
if (!tryagain_text)
tryagain_text = "X";
+ else
+ tryagain_text = _(tryagain_text);
/* We allocate 2 time the needed space for atext so that there
is nenough space for escaping */
@@ -747,7 +798,7 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
+ 3*strlen (tryagain_text) + 3*strlen (atext) + 2);
strcpy (line, "GET_PASSPHRASE ");
p = line+15;
- if (!mode)
+ if (!mode && have_fpr)
{
for (i=0; i < 20; i++, p +=2 )
sprintf (p, "%02X", fpr[i]);
@@ -805,11 +856,20 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
pw[pwlen] = 0; /* make a C String */
agent_close (fd);
free_public_key( pk );
+#ifdef ENABLE_NLS
+ if (orig_codeset)
+ bind_textdomain_codeset (PACKAGE, orig_codeset);
+#endif
+ m_free (orig_codeset);
return pw;
}
else if (nread > 7 && !memcmp (pw, "ERR 111", 7)
&& (pw[7] == ' ' || pw[7] == '\n') )
- log_info (_("cancelled by user\n") );
+ {
+ log_info (_("cancelled by user\n") );
+ if (canceled)
+ *canceled = 1;
+ }
else
{
log_error (_("problem with the agent - disabling agent use\n"));
@@ -819,6 +879,10 @@ agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
failure:
+#ifdef ENABLE_NLS
+ if (orig_codeset)
+ bind_textdomain_codeset (PACKAGE, orig_codeset);
+#endif
m_free (atext);
if ( fd != -1 )
agent_close (fd);
@@ -945,17 +1009,25 @@ passphrase_clear_cache ( u32 *keyid, int algo )
* (only for mode 2)
* a dek->keylen of 0 means: no passphrase entered.
* (only for mode 2)
- * pubkey_algo is only informational.
+ *
+ * pubkey_algo is only informational. Note that TRYAGAIN_TEXT must
+ * not be translated as this is done within this function (required to
+ * switch to utf-8 when the agent is in use). If CANCELED is not
+ * NULL, it is set to 1 if the user choosed to cancel the operation,
+ * otherwise it will be set to 0.
*/
DEK *
passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode,
- const char *tryagain_text)
+ const char *tryagain_text, int *canceled)
{
char *pw = NULL;
DEK *dek;
STRING2KEY help_s2k;
+ if (canceled)
+ *canceled = 0;
+
if( !s2k ) {
/* This is used for the old rfc1991 mode
* Note: This must match the code in encode.c with opt.rfc1991 set */
@@ -1030,7 +1102,8 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
next_pw = NULL;
}
else if ( opt.use_agent ) {
- pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, tryagain_text );
+ pw = agent_get_passphrase ( keyid, mode == 2? 1: 0,
+ tryagain_text, canceled );
if (!pw)
{
if (!opt.use_agent)
@@ -1038,7 +1111,7 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
pw = m_strdup ("");
}
if( *pw && mode == 2 ) {
- char *pw2 = agent_get_passphrase ( keyid, 2, NULL );
+ char *pw2 = agent_get_passphrase ( keyid, 2, NULL, canceled );
if (!pw2)
{
if (!opt.use_agent)
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 4984c888b..32c54498d 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -36,7 +36,8 @@
static int
-do_check( PKT_secret_key *sk, const char *tryagain_text, int mode )
+do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
+ int *canceled )
{
byte *buffer;
u16 csum=0;
@@ -69,7 +70,11 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode )
keyid[3] = sk->main_keyid[1];
}
dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
- &sk->protect.s2k, mode, tryagain_text );
+ &sk->protect.s2k, mode,
+ tryagain_text, canceled );
+ if (!dek && canceled && *canceled)
+ return G10ERR_GENERAL;
+
cipher_hd = cipher_open( sk->protect.algo,
CIPHER_MODE_AUTO_CFB, 1);
cipher_setkey( cipher_hd, dek->key, dek->keylen );
@@ -229,12 +234,13 @@ check_secret_key( PKT_secret_key *sk, int n )
n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */
for(i=0; i < n && rc == G10ERR_BAD_PASS; i++ ) {
+ int canceled = 0;
const char *tryagain = NULL;
if (i) {
- tryagain = _("Invalid passphrase; please try again");
- log_info (_("%s ...\n"), tryagain);
+ tryagain = N_("Invalid passphrase; please try again");
+ log_info (_("%s ...\n"), _(tryagain));
}
- rc = do_check( sk, tryagain, mode );
+ rc = do_check( sk, tryagain, mode, &canceled );
if( rc == G10ERR_BAD_PASS && is_status_enabled() ) {
u32 kid[2];
char buf[50];
@@ -243,7 +249,7 @@ check_secret_key( PKT_secret_key *sk, int n )
sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]);
write_status_text( STATUS_BAD_PASSPHRASE, buf );
}
- if( have_static_passphrase() )
+ if( have_static_passphrase() || canceled)
break;
}
diff --git a/g10/sign.c b/g10/sign.c
index cbc93af2d..9dad9b300 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -1059,7 +1059,7 @@ sign_symencrypt_file (const char *fname, STRLIST locusr)
if (!opt.quiet || !opt.batch)
log_info (_("%s encryption will be used\n"),
cipher_algo_to_string(algo) );
- cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL );
+ cfx.dek = passphrase_to_dek( NULL, 0, algo, s2k, 2, NULL, NULL);
if (!cfx.dek || !cfx.dek->keylen) {
rc = G10ERR_PASSPHRASE;