aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-07-01 12:38:17 +0000
committerWerner Koch <[email protected]>2024-07-01 12:38:46 +0000
commit0ed8e9ae3e75e6a08c2ad74fc9b94c48240b58e3 (patch)
treeb7c7c5c1ac9f6cbea64fa3b8806ee07bc542727a
parentagent:daemon: Add an argument to specify requiring socket connection. (diff)
downloadgnupg-0ed8e9ae3e75e6a08c2ad74fc9b94c48240b58e3.tar.gz
gnupg-0ed8e9ae3e75e6a08c2ad74fc9b94c48240b58e3.zip
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 <[email protected]> (cherry picked from commit b3f1f2cd192b71f2c19ec6f871ece0c175d46db0)
-rw-r--r--agent/call-scd.c96
-rw-r--r--scd/app.c2
2 files changed, 97 insertions, 1 deletions
diff --git a/agent/call-scd.c b/agent/call-scd.c
index 918135854..f8b4cb6a1 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -1151,6 +1151,97 @@ pass_data_thru (void *opaque, const void *buffer, size_t length)
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 = FD2INT (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
all status messages back. This command is used as a general quoting
@@ -1166,6 +1257,11 @@ agent_card_scd (ctrl_t ctrl, const char *cmdline,
struct inq_needpin_parm_s inqparm;
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);
if (rc)
return rc;
diff --git a/scd/app.c b/scd/app.c
index 9d838cff0..e78268b50 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -403,7 +403,7 @@ card_list_wait (ctrl_t ctrl)
{
FD_ZERO (&fdset);
FD_SET (FD2INT (fd), &fdset);
- nfd = FD2NUM (fd);
+ nfd = FD2INT (fd);
#ifdef HAVE_W32_SYSTEM
ret = npth_eselect (nfd+1, &fdset, NULL, NULL, NULL,