1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-05-31 22:18:03 +02:00

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 3b66a256e3)
This commit is contained in:
NIIBE Yutaka 2017-10-26 14:40:38 +09:00 committed by Werner Koch
parent 05cb87276c
commit 4738256f2e
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
2 changed files with 26 additions and 11 deletions

View File

@ -254,6 +254,9 @@ struct server_control_s
/* The current S2K which might be different from the calibrated /* The current S2K which might be different from the calibrated
count. */ count. */
unsigned long s2k_count; unsigned long s2k_count;
/* Recursion level of pinentry. */
int pinentry_level;
}; };

View File

@ -177,15 +177,19 @@ unlock_pinentry (gpg_error_t rc)
} }
} }
entry_ctx = NULL; if (--entry_owner->pinentry_level == 0)
err = npth_mutex_unlock (&entry_lock);
if (err)
{ {
log_error ("failed to release the entry lock: %s\n", strerror (err)); entry_owner = NULL;
if (!rc) entry_ctx = NULL;
rc = gpg_error_from_errno (err); 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; return rc;
} }
@ -288,6 +292,13 @@ start_pinentry (ctrl_t ctrl)
char *flavor_version; char *flavor_version;
int err; int err;
if (entry_owner == ctrl)
{
/* Allow recursive use of pinentry. */
ctrl->pinentry_level++;
return 0;
}
npth_clock_gettime (&abstime); npth_clock_gettime (&abstime);
abstime.tv_sec += LOCK_TIMEOUT; abstime.tv_sec += LOCK_TIMEOUT;
err = npth_mutex_timedlock (&entry_lock, &abstime); 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)); log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
return rc; return rc;
} }
ctrl->pinentry_level = 1;
entry_ctx = ctx;
/* We don't want to log the pinentry communication to make the logs /* 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 easier to read. We might want to add a new debug option to enable
pinentry logging. */ pinentry logging. */
@ -382,17 +397,15 @@ start_pinentry (ctrl_t ctrl)
that atfork is used to change the environment for pinentry. We that atfork is used to change the environment for pinentry. We
start the server in detached mode to suppress the console window start the server in detached mode to suppress the console window
under Windows. */ 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, no_close_list, atfork_cb, ctrl,
ASSUAN_PIPE_CONNECT_DETACHED); ASSUAN_PIPE_CONNECT_DETACHED);
if (rc) if (rc)
{ {
log_error ("can't connect to the PIN entry module '%s': %s\n", log_error ("can't connect to the PIN entry module '%s': %s\n",
full_pgmname, gpg_strerror (rc)); full_pgmname, gpg_strerror (rc));
assuan_release (ctx);
return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY)); return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY));
} }
entry_ctx = ctx;
if (DBG_IPC) if (DBG_IPC)
log_debug ("connection to PIN entry established\n"); 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 /* Thread IDs are opaque, but we try our best here by resetting it
to the same content that a static global variable has. */ to the same content that a static global variable has. */
memset (&popup_tid, '\0', sizeof (popup_tid)); memset (&popup_tid, '\0', sizeof (popup_tid));
entry_owner = NULL;
/* Now we can close the connection. */ /* Now we can close the connection. */
unlock_pinentry (0); unlock_pinentry (0);