aboutsummaryrefslogtreecommitdiffstats
path: root/g10/passphrase.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/passphrase.c')
-rw-r--r--g10/passphrase.c70
1 files changed, 58 insertions, 12 deletions
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 12a507692..64a43d4eb 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -371,6 +371,7 @@ agent_open (int *ret_prot)
infostr = getenv ( "GPG_AGENT_INFO" );
if ( !infostr ) {
log_error (_("gpg-agent is not available in this session\n"));
+ opt.use_agent = 0;
return -1;
}
infostr = m_strdup ( infostr );
@@ -378,6 +379,7 @@ agent_open (int *ret_prot)
|| (p-infostr)+1 >= sizeof client_addr.sun_path ) {
log_error( _("malformed GPG_AGENT_INFO environment variable\n"));
m_free (infostr );
+ opt.use_agent = 0;
return -1;
}
*p++ = 0;
@@ -390,6 +392,7 @@ agent_open (int *ret_prot)
if ( prot < 0 || prot > 1) {
log_error (_("gpg-agent protocol version %d is not supported\n"),prot);
m_free (infostr );
+ opt.use_agent = 0;
return -1;
}
*ret_prot = prot;
@@ -397,6 +400,7 @@ agent_open (int *ret_prot)
if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) {
log_error ("can't create socket: %s\n", strerror(errno) );
m_free (infostr );
+ opt.use_agent = 0;
return -1;
}
@@ -411,6 +415,7 @@ agent_open (int *ret_prot)
infostr, strerror (errno) );
m_free (infostr );
close (fd );
+ opt.use_agent = 0;
return -1;
}
m_free (infostr);
@@ -430,6 +435,7 @@ agent_open (int *ret_prot)
&& (line[2] == '\n' || line[2] == ' ')) ) {
log_error ( _("communication problem with gpg-agent\n"));
close (fd );
+ opt.use_agent = 0;
return -1;
}
@@ -460,7 +466,7 @@ agent_close ( int fd )
* 2: Ditto, but change the text to "repeat entry"
*/
static char *
-agent_get_passphrase ( u32 *keyid, int mode )
+agent_get_passphrase ( u32 *keyid, int mode, const char *tryagain_text )
{
#if defined(__riscos__)
return NULL;
@@ -602,15 +608,35 @@ agent_get_passphrase ( u32 *keyid, int mode )
char *line, *p;
int i;
+ if (!tryagain_text)
+ tryagain_text = "X";
+
/* We allocate 2 time the needed space for atext so that there
is nenough space for escaping */
- line = m_alloc (15 + 46 + 3*strlen (atext) + 2);
+ line = m_alloc (15 + 46
+ + 3*strlen (tryagain_text) + 3*strlen (atext) + 2);
strcpy (line, "GET_PASSPHRASE ");
p = line+15;
- for (i=0; i < 20; i++, p +=2 )
- sprintf (p, "%02X", fpr[i]);
+ if (!mode)
+ {
+ for (i=0; i < 20; i++, p +=2 )
+ sprintf (p, "%02X", fpr[i]);
+ }
+ else
+ *p++ = 'X'; /* no caching */
*p++ = ' ';
- *p++ = 'X'; /* No error prompt */
+ for (i=0; tryagain_text[i]; i++)
+ {
+ if (tryagain_text[i] < ' ' || tryagain_text[i] == '+')
+ {
+ sprintf (p, "%%%02X", tryagain_text[i]);
+ p += 3;
+ }
+ else if (tryagain_text[i] == ' ')
+ *p++ = '+';
+ else
+ *p++ = tryagain_text[i];
+ }
*p++ = ' ';
*p++ = 'X'; /* Use the standard prompt */
*p++ = ' ';
@@ -655,7 +681,10 @@ agent_get_passphrase ( u32 *keyid, int mode )
&& (pw[7] == ' ' || pw[7] == '\n') )
log_info (_("cancelled by user\n") );
else
- log_error (_("problem with the agent\n"));
+ {
+ log_error (_("problem with the agent - disabling agent use\n"));
+ opt.use_agent = 0;
+ }
}
@@ -760,7 +789,10 @@ passphrase_clear_cache ( u32 *keyid, int algo )
if (buf[0] == 'O' && buf[1] == 'K' && (buf[2] == ' ' || buf[2] == '\n'))
;
else
- log_error (_("problem with the agent\n"));
+ {
+ log_error (_("problem with the agent - disabling agent use\n"));
+ opt.use_agent = 0;
+ }
}
failure:
@@ -786,7 +818,8 @@ passphrase_clear_cache ( u32 *keyid, int algo )
*/
DEK *
passphrase_to_dek( u32 *keyid, int pubkey_algo,
- int cipher_algo, STRING2KEY *s2k, int mode )
+ int cipher_algo, STRING2KEY *s2k, int mode,
+ const char *tryagain_text)
{
char *pw = NULL;
DEK *dek;
@@ -863,18 +896,31 @@ passphrase_to_dek( u32 *keyid, int pubkey_algo,
free_public_key( pk );
}
+ agent_died:
if( next_pw ) {
pw = next_pw;
next_pw = NULL;
}
else if ( opt.use_agent ) {
- pw = agent_get_passphrase ( keyid, mode == 2? 1: 0 );
- if ( !pw )
+ pw = agent_get_passphrase ( keyid, mode == 2? 1: 0, tryagain_text );
+ if (!pw)
+ {
+ if (!opt.use_agent)
+ goto agent_died;
pw = m_strdup ("");
+ }
if( *pw && mode == 2 ) {
- char *pw2 = agent_get_passphrase ( keyid, 2 );
- if ( !pw2 )
+ char *pw2 = agent_get_passphrase ( keyid, 2, NULL );
+ if (!pw2)
+ {
+ if (!opt.use_agent)
+ {
+ m_free (pw);
+ pw = NULL;
+ goto agent_died;
+ }
pw2 = m_strdup ("");
+ }
if( strcmp(pw, pw2) ) {
m_free(pw2);
m_free(pw);