diff options
author | Werner Koch <[email protected]> | 2003-04-10 09:56:47 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2003-04-10 09:56:47 +0000 |
commit | 6b5587891221213706b131e262f95072b5ff6a63 (patch) | |
tree | f7ad6f0ea7eb77469d8e79cfc79e934087009bcd /g10/passphrase.c | |
parent | * main.h, g10.c (main), import.c (parse_import_options, (diff) | |
download | gnupg-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.c | 141 |
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) |