mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-14 21:47:19 +02:00
* 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.
This commit is contained in:
parent
3cf45b304e
commit
6b55878912
11 changed files with 178 additions and 70 deletions
147
g10/passphrase.c
147
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 */
|
||||
|
||||
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;
|
||||
}
|
||||
if( read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
|
||||
break;
|
||||
while (!(read (fd, buf, 1) != 1 || *buf == '\n' ))
|
||||
;
|
||||
*buf = 0;
|
||||
return;
|
||||
}
|
||||
pw[i] = 0;
|
||||
if( !opt.batch )
|
||||
tty_printf("\b\b\b \n" );
|
||||
|
||||
m_free( fd_passwd );
|
||||
fd_passwd = pw;
|
||||
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;
|
||||
}
|
||||
if (read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
|
||||
break;
|
||||
}
|
||||
pw[i] = 0;
|
||||
if (!opt.batch)
|
||||
tty_printf("\b\b\b \n" );
|
||||
|
||||
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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue