aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Kibbey <[email protected]>2011-09-11 20:55:34 +0000
committerWerner Koch <[email protected]>2011-09-12 07:54:16 +0000
commitfb1cdd7b0ebece16ffe60a30e4d01c5dbb1ca92b (patch)
tree3b5768e1b8efe24ac70e3797638347095cede82a
parentMark component descriptions for translation. (diff)
downloadgnupg-fb1cdd7b0ebece16ffe60a30e4d01c5dbb1ca92b.tar.gz
gnupg-fb1cdd7b0ebece16ffe60a30e4d01c5dbb1ca92b.zip
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.
-rw-r--r--agent/ChangeLog9
-rw-r--r--agent/agent.h3
-rw-r--r--agent/call-pinentry.c41
-rw-r--r--agent/command.c15
-rw-r--r--agent/genkey.c17
5 files changed, 83 insertions, 2 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index ec2dca219..18a94916d 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,12 @@
+2011-09-10 Ben Kibbey <[email protected]>
+
+ * 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 <[email protected]>
* genkey.c (check_passphrase_pattern): Use gpg_strerror instead of
diff --git a/agent/agent.h b/agent/agent.h
index fbd71d51e..b323718fc 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -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);
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 4c30f6dea..d0cfd2b79 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -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);
}
diff --git a/agent/command.c b/agent/command.c
index 6973e78e5..f310a980c 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -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;
+}
diff --git a/agent/genkey.c b/agent/genkey.c
index 09f1c72aa..85ba7023a 100644
--- a/agent/genkey.c
+++ b/agent/genkey.c
@@ -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;