1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

agent: Handle SCD DEVINFO --watch command in a special way.

* agent/call-scd.c (devinfo_watch_thread): New.
(agent_card_devinfo): New.
(agent_card_scd): Call agent_card_devinfo when it's
DEVINFO_WATCH_COMMAND.

--

GnuPG-bug-id: 7151
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2024-06-27 15:29:01 +09:00
parent 5d980802ac
commit b3f1f2cd19
No known key found for this signature in database
GPG Key ID: 640114AF89DE6054

View File

@ -1155,6 +1155,97 @@ pass_data_thru (void *opaque, const void *buffer, size_t length)
return 0; return 0;
} }
#define DEVINFO_WATCH_COMMAND "DEVINFO --watch"
struct devinfo_watch_thread {
ctrl_t ctrl;
void *assuan_context;
};
static void *
devinfo_watch_thread (void *arg)
{
struct devinfo_watch_thread *d = arg;
assuan_set_flag (daemon_ctx (d->ctrl), ASSUAN_CONVEY_COMMENTS, 1);
assuan_transact (daemon_ctx (d->ctrl), DEVINFO_WATCH_COMMAND,
pass_data_thru, d->assuan_context,
NULL, NULL,
pass_status_thru, d->assuan_context);
return NULL;
}
static int
agent_card_devinfo (ctrl_t ctrl, void *assuan_context)
{
npth_t thread;
struct devinfo_watch_thread dwt;
gpg_error_t err = 0;
npth_attr_t tattr;
assuan_context_t scd_ctx;
gnupg_fd_t scd_fds[2];
gnupg_fd_t client_input;
gnupg_fd_t scd_sock;
int rc;
gnupg_fd_t client_fds[2];
rc = daemon_start (DAEMON_SCD, ctrl, 1);
if (rc)
return rc;
dwt.ctrl = ctrl;
dwt.assuan_context = assuan_context;
scd_ctx = daemon_ctx (ctrl);
err = npth_attr_init (&tattr);
if (err)
return err;
npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
err = npth_create (&thread, &tattr, devinfo_watch_thread, &dwt);
npth_attr_destroy (&tattr);
if (err)
{
log_error ("error spawning devinfo_watch_thread: %s\n", strerror (err));
return err;
}
assuan_get_active_fds (assuan_context, 0, client_fds, 2);
client_input = client_fds[0];
assuan_get_active_fds (scd_ctx, 0, scd_fds, 2);
scd_sock = scd_fds[0];
while (1)
{
fd_set fdset;
int nfd;
int ret;
FD_ZERO (&fdset);
FD_SET (FD2INT (client_input), &fdset);
nfd = FD2NUM (client_input);
ret = npth_select (nfd+1, &fdset, NULL, NULL, NULL);
if (ret == 1)
break;
}
/* Forcibly close the socket connection to scdaemon. */
#ifdef HAVE_W32_SYSTEM
# if _WIN64
shutdown ((uintptr_t)scd_sock, SD_BOTH);
# else
shutdown ((unsigned int)scd_sock, SD_BOTH);
# endif
#else
shutdown (scd_sock, SHUT_RDWR);
#endif
/* Then, join the thread. */
npth_join (thread, NULL);
return unlock_scd (ctrl, rc);
}
/* Send the line CMDLINE with command for the SCDdaemon to it and send /* Send the line CMDLINE with command for the SCDdaemon to it and send
all status messages back. This command is used as a general quoting all status messages back. This command is used as a general quoting
@ -1170,6 +1261,11 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
struct inq_needpin_parm_s inqparm; struct inq_needpin_parm_s inqparm;
int saveflag; int saveflag;
/* This is a layer violation, but it's needed that because DEVINFO
--watch is so special. */
if (!strcmp (cmdline, DEVINFO_WATCH_COMMAND))
return agent_card_devinfo (ctrl, assuan_context);
rc = start_scd (ctrl); rc = start_scd (ctrl);
if (rc) if (rc)
return rc; return rc;