diff --git a/agent/agent.h b/agent/agent.h index 7ffbd5cc2..ae2ae5004 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -709,7 +709,7 @@ gpg_error_t agent_card_ecc_kem (ctrl_t ctrl, const unsigned char *ecc_ct, size_t ecc_point_len, unsigned char *ecc_ecdh); /*-- call-daemon.c --*/ -gpg_error_t daemon_start (enum daemon_type type, ctrl_t ctrl); +gpg_error_t daemon_start (enum daemon_type type, ctrl_t ctrl, int req_sock); assuan_context_t daemon_type_ctx (enum daemon_type type, ctrl_t ctrl); gpg_error_t daemon_unlock (enum daemon_type type, ctrl_t ctrl, gpg_error_t rc); void initialize_module_daemon (void); diff --git a/agent/call-daemon.c b/agent/call-daemon.c index 337bee3c2..cf5a0c85f 100644 --- a/agent/call-daemon.c +++ b/agent/call-daemon.c @@ -211,7 +211,7 @@ atfork_cb (void *opaque, int where) * caller must call unlock_daemon after this function has returned * success and the actual Assuan transaction been done. */ gpg_error_t -daemon_start (enum daemon_type type, ctrl_t ctrl) +daemon_start (enum daemon_type type, ctrl_t ctrl, int require_socket) { gpg_error_t err = 0; const char *pgmname; @@ -243,6 +243,7 @@ daemon_start (enum daemon_type type, ctrl_t ctrl) return gpg_error (GPG_ERR_INTERNAL); } + again: /* We need to serialize the access to scd_local_list and primary_scd_ctx. */ rc = npth_mutex_lock (&start_daemon_lock); if (rc) @@ -275,7 +276,7 @@ daemon_start (enum daemon_type type, ctrl_t ctrl) /* Check whether the pipe server has already been started and in this case either reuse a lingering pipe connection or establish a new socket based one. */ - if (g->primary_ctx && g->primary_ctx_reusable) + if (g->primary_ctx && g->primary_ctx_reusable && !require_socket) { ctx = g->primary_ctx; g->primary_ctx_reusable = 0; @@ -466,6 +467,7 @@ daemon_start (enum daemon_type type, ctrl_t ctrl) leave: xfree (abs_homedir); + abs_homedir = NULL; if (err) { rc = npth_mutex_unlock (&start_daemon_lock); @@ -482,6 +484,12 @@ daemon_start (enum daemon_type type, ctrl_t ctrl) rc = npth_mutex_unlock (&start_daemon_lock); if (rc) log_error ("failed to release the start_daemon lock: %s\n", strerror (rc)); + + if (require_socket && g->primary_ctx == ctx) + { + daemon_unlock (type, ctrl, 0); + goto again; + } } return err; } diff --git a/agent/call-scd.c b/agent/call-scd.c index 6e3f4ef26..048c5d306 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -94,7 +94,7 @@ struct inq_needpin_parm_s static int start_scd (ctrl_t ctrl) { - return daemon_start (DAEMON_SCD, ctrl); + return daemon_start (DAEMON_SCD, ctrl, 0); } diff --git a/agent/call-tpm2d.c b/agent/call-tpm2d.c index 1048c7d63..3f6ca7b52 100644 --- a/agent/call-tpm2d.c +++ b/agent/call-tpm2d.c @@ -16,7 +16,7 @@ static int start_tpm2d (ctrl_t ctrl) { - return daemon_start (DAEMON_TPM2D, ctrl); + return daemon_start (DAEMON_TPM2D, ctrl, 0); } static int