summaryrefslogtreecommitdiffstats
path: root/agent
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2017-10-26 07:40:38 +0200
committerWerner Koch <wk@gnupg.org>2017-10-27 14:15:50 +0200
commit4738256f2e0d22302377c9ec7b2ae3999338e6c6 (patch)
treee63e4514bc6757743fb868f4e6379bb5b7df4386 /agent
parentagent, tests: Support --disable-scdaemon build case. (diff)
downloadgnupg2-4738256f2e0d22302377c9ec7b2ae3999338e6c6.tar.xz
gnupg2-4738256f2e0d22302377c9ec7b2ae3999338e6c6.zip
agent: Allow recursive use of pinentry.
* agent/agent.h (struct server_control_s): Add pinentry_level. * agent/call-pinentry.c (agent_popup_message_stop): Not clear ENTRY_CTX here. (unlock_pinentry): Handle recursion. Clear ENTRY_CTX here. (start_pinentry): Allow recursive use. -- GnuPG-bug-id: 3190 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org> (cherry picked from commit 3b66a256e3760e88066ca11b7b49d924e42aa46b)
Diffstat (limited to 'agent')
-rw-r--r--agent/agent.h3
-rw-r--r--agent/call-pinentry.c34
2 files changed, 26 insertions, 11 deletions
diff --git a/agent/agent.h b/agent/agent.h
index f5df75e6e..cde38fe4a 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -254,6 +254,9 @@ struct server_control_s
/* The current S2K which might be different from the calibrated
count. */
unsigned long s2k_count;
+
+ /* Recursion level of pinentry. */
+ int pinentry_level;
};
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 6a5c1fe1e..0fe83454e 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -177,15 +177,19 @@ unlock_pinentry (gpg_error_t rc)
}
}
- entry_ctx = NULL;
- err = npth_mutex_unlock (&entry_lock);
- if (err)
+ if (--entry_owner->pinentry_level == 0)
{
- log_error ("failed to release the entry lock: %s\n", strerror (err));
- if (!rc)
- rc = gpg_error_from_errno (err);
+ entry_owner = NULL;
+ entry_ctx = NULL;
+ err = npth_mutex_unlock (&entry_lock);
+ if (err)
+ {
+ log_error ("failed to release the entry lock: %s\n", strerror (err));
+ if (!rc)
+ rc = gpg_error_from_errno (err);
+ }
+ assuan_release (ctx);
}
- assuan_release (ctx);
return rc;
}
@@ -288,6 +292,13 @@ start_pinentry (ctrl_t ctrl)
char *flavor_version;
int err;
+ if (entry_owner == ctrl)
+ {
+ /* Allow recursive use of pinentry. */
+ ctrl->pinentry_level++;
+ return 0;
+ }
+
npth_clock_gettime (&abstime);
abstime.tv_sec += LOCK_TIMEOUT;
err = npth_mutex_timedlock (&entry_lock, &abstime);
@@ -371,6 +382,10 @@ start_pinentry (ctrl_t ctrl)
log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
return rc;
}
+
+ ctrl->pinentry_level = 1;
+ entry_ctx = ctx;
+
/* We don't want to log the pinentry communication to make the logs
easier to read. We might want to add a new debug option to enable
pinentry logging. */
@@ -382,17 +397,15 @@ start_pinentry (ctrl_t ctrl)
that atfork is used to change the environment for pinentry. We
start the server in detached mode to suppress the console window
under Windows. */
- rc = assuan_pipe_connect (ctx, full_pgmname, argv,
+ rc = assuan_pipe_connect (entry_ctx, full_pgmname, argv,
no_close_list, atfork_cb, ctrl,
ASSUAN_PIPE_CONNECT_DETACHED);
if (rc)
{
log_error ("can't connect to the PIN entry module '%s': %s\n",
full_pgmname, gpg_strerror (rc));
- assuan_release (ctx);
return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
}
- entry_ctx = ctx;
if (DBG_IPC)
log_debug ("connection to PIN entry established\n");
@@ -1551,7 +1564,6 @@ agent_popup_message_stop (ctrl_t ctrl)
/* Thread IDs are opaque, but we try our best here by resetting it
to the same content that a static global variable has. */
memset (&popup_tid, '\0', sizeof (popup_tid));
- entry_owner = NULL;
/* Now we can close the connection. */
unlock_pinentry (0);