aboutsummaryrefslogtreecommitdiffstats
path: root/g10/passphrase.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2003-04-10 09:56:47 +0000
committerWerner Koch <[email protected]>2003-04-10 09:56:47 +0000
commit6b5587891221213706b131e262f95072b5ff6a63 (patch)
treef7ad6f0ea7eb77469d8e79cfc79e934087009bcd /g10/passphrase.c
parent* main.h, g10.c (main), import.c (parse_import_options, (diff)
downloadgnupg-6b5587891221213706b131e262f95072b5ff6a63.tar.gz
gnupg-6b5587891221213706b131e262f95072b5ff6a63.zip
* 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.
Diffstat (limited to 'g10/passphrase.c')
-rw-r--r--g10/passphrase.c141
1 files changed, 107 insertions, 34 deletions
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)