Handle pinentry-mode=loopback.

When this mode is set an inquire will be sent to the client to retrieve
the passphrase. This adds a new inquire keyword "NEW_PASSPHRASE" that the
GENKEY and PASSWD commands use when generating a new key.
This commit is contained in:
Ben Kibbey 2011-09-11 16:55:34 -04:00 committed by Werner Koch
parent bea3b7c93f
commit fb1cdd7b0e
5 changed files with 83 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2011-09-10 Ben Kibbey <bjk@luxsci.net>
* agent.h (pinentry_loopback): New prototype.
* command.c (pinentry_loopback): New function to inquire a passphrase
from the client. For use with pinentry-mode=loopback.
* call-pinentry.c (agent_askpin): Handle PINENTRY_MODE_LOOPBACK.
* call-pinentry.c (agent_get_passphrase): Ditto.
* genkey.c (agent_ask_new_passphrase): Ditto.
2011-08-10 Werner Koch <wk@g10code.com>
* genkey.c (check_passphrase_pattern): Use gpg_strerror instead of

View File

@ -252,6 +252,9 @@ gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...)
void bump_key_eventcounter (void);
void bump_card_eventcounter (void);
void start_command_handler (ctrl_t, gnupg_fd_t, gnupg_fd_t);
gpg_error_t pinentry_loopback(ctrl_t, const char *keyword,
unsigned char **buffer, size_t *size,
size_t max_length);
/*-- command-ssh.c --*/
void start_command_handler_ssh (ctrl_t, gnupg_fd_t);

View File

@ -746,8 +746,29 @@ agent_askpin (ctrl_t ctrl,
{
if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
return gpg_error (GPG_ERR_CANCELED);
/*FIXME: Implement loopback mode. */
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
{
unsigned char *passphrase;
size_t size;
*pininfo->pin = 0; /* Reset the PIN. */
rc = pinentry_loopback(ctrl, "PASSPHRASE", &passphrase, &size,
pininfo->max_length);
if (rc)
return rc;
memcpy(&pininfo->pin, passphrase, size);
xfree(passphrase);
pininfo->pin[size] = 0;
if (pininfo->check_cb)
{
/* More checks by utilizing the optional callback. */
pininfo->cb_errtext = NULL;
rc = pininfo->check_cb (pininfo);
}
return rc;
}
return gpg_error(GPG_ERR_NO_PIN_ENTRY);
}
if (!pininfo || pininfo->max_length < 1)
@ -908,6 +929,22 @@ agent_get_passphrase (ctrl_t ctrl,
if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
return gpg_error (GPG_ERR_CANCELED);
if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
{
size_t size;
size_t len = ASSUAN_LINELENGTH/2;
unsigned char *buffer = gcry_malloc_secure (len);
rc = pinentry_loopback(ctrl, "PASSPHRASE", &buffer, &size, len);
if (rc)
xfree(buffer);
else
{
buffer[size] = 0;
*retpass = buffer;
}
return rc;
}
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
}

View File

@ -2731,3 +2731,18 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
xfree (ctrl->server_local);
ctrl->server_local = NULL;
}
gpg_error_t
pinentry_loopback(ctrl_t ctrl, const char *keyword,
unsigned char **buffer, size_t *size,
size_t max_length)
{
gpg_error_t rc;
assuan_context_t ctx = ctrl->server_local->assuan_ctx;
assuan_begin_confidential (ctx);
rc = assuan_inquire (ctx, keyword, buffer, size, max_length);
assuan_end_confidential (ctx);
return rc;
}

View File

@ -304,6 +304,23 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt,
*r_passphrase = NULL;
if (ctrl->pinentry_mode == PINENTRY_MODE_LOOPBACK)
{
size_t size;
size_t len = 100;
unsigned char *buffer;
err = pinentry_loopback(ctrl, "NEW_PASSPHRASE", &buffer, &size, len);
if (err)
xfree(buffer);
else
{
buffer[size] = 0;
*r_passphrase = buffer;
}
return err;
}
pi = gcry_calloc_secure (2, sizeof (*pi) + 100);
pi2 = pi + (sizeof *pi + 100);
pi->max_length = 100;