aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2018-10-11 06:41:49 +0000
committerNIIBE Yutaka <[email protected]>2018-12-18 01:18:23 +0000
commitffe31f405f9b5e4929e95c3d66c613052cb7727e (patch)
tree150e13ed4fbb7312c510751d73c610eab0eb84f1
parentagent: Support --ack option for POPUPPINPADPROMPT. (diff)
downloadgnupg-ffe31f405f9b5e4929e95c3d66c613052cb7727e.tar.gz
gnupg-ffe31f405f9b5e4929e95c3d66c613052cb7727e.zip
scd: Support "acknowledge button" feature.
* scd/apdu.c (set_prompt_cb): New member function. (set_prompt_cb_ccid_reader): New function. (open_ccid_reader): Initialize with set_prompt_cb_ccid_reader. (apdu_set_prompt_cb): New. * scd/app.c (lock_app, unlock_app): Add call to apdu_set_prompt_cb. * ccid-driver.c (ccid_set_prompt_cb): New. (bulk_in): Call ->prompt_cb when timer extension. * scd/command.c (popup_prompt): New. -- Cherry-picked master commit of: 7a5a4c4cac8709f7c413e94cd0b40f4123baa1e5 Signed-off-by: NIIBE Yutaka <[email protected]>
Diffstat (limited to '')
-rw-r--r--scd/apdu.c34
-rw-r--r--scd/apdu.h1
-rw-r--r--scd/app.c2
-rw-r--r--scd/ccid-driver.c30
-rw-r--r--scd/ccid-driver.h2
-rw-r--r--scd/command.c28
-rw-r--r--scd/scdaemon.h1
7 files changed, 97 insertions, 1 deletions
diff --git a/scd/apdu.c b/scd/apdu.c
index 9e3594b1c..7ed0b978b 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -105,6 +105,7 @@ struct reader_table_s {
int (*check_pinpad)(int, int, pininfo_t *);
void (*dump_status_reader)(int);
int (*set_progress_cb)(int, gcry_handler_progress_t, void*);
+ int (*set_prompt_cb)(int, void (*) (void *, int), void*);
int (*pinpad_verify)(int, int, int, int, int, pininfo_t *);
int (*pinpad_modify)(int, int, int, int, int, pininfo_t *);
@@ -444,6 +445,7 @@ new_reader_slot (void)
reader_table[reader].check_pinpad = check_pcsc_pinpad;
reader_table[reader].dump_status_reader = NULL;
reader_table[reader].set_progress_cb = NULL;
+ reader_table[reader].set_prompt_cb = NULL;
reader_table[reader].pinpad_verify = pcsc_pinpad_verify;
reader_table[reader].pinpad_modify = pcsc_pinpad_modify;
@@ -1403,6 +1405,14 @@ set_progress_cb_ccid_reader (int slot, gcry_handler_progress_t cb, void *cb_arg)
return ccid_set_progress_cb (slotp->ccid.handle, cb, cb_arg);
}
+static int
+set_prompt_cb_ccid_reader (int slot, void (*cb) (void *, int ), void *cb_arg)
+{
+ reader_table_t slotp = reader_table + slot;
+
+ return ccid_set_prompt_cb (slotp->ccid.handle, cb, cb_arg);
+}
+
static int
get_status_ccid (int slot, unsigned int *status, int on_wire)
@@ -1542,6 +1552,7 @@ open_ccid_reader (struct dev_list *dl)
reader_table[slot].check_pinpad = check_ccid_pinpad;
reader_table[slot].dump_status_reader = dump_ccid_reader_status;
reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader;
+ reader_table[slot].set_prompt_cb = set_prompt_cb_ccid_reader;
reader_table[slot].pinpad_verify = ccid_pinpad_operation;
reader_table[slot].pinpad_modify = ccid_pinpad_operation;
/* Our CCID reader code does not support T=0 at all, thus reset the
@@ -2381,6 +2392,29 @@ apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg)
}
+int
+apdu_set_prompt_cb (int slot, void (*cb) (void *, int), void *cb_arg)
+{
+ int sw;
+
+ if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
+ return SW_HOST_NO_DRIVER;
+
+ if (reader_table[slot].set_prompt_cb)
+ {
+ sw = lock_slot (slot);
+ if (!sw)
+ {
+ sw = reader_table[slot].set_prompt_cb (slot, cb, cb_arg);
+ unlock_slot (slot);
+ }
+ }
+ else
+ sw = 0;
+ return sw;
+}
+
+
/* Do a reset for the card in reader at SLOT. */
int
apdu_reset (int slot)
diff --git a/scd/apdu.h b/scd/apdu.h
index 6751e8c9b..f7bc0bcee 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -116,6 +116,7 @@ int apdu_connect (int slot);
int apdu_disconnect (int slot);
int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg);
+int apdu_set_prompt_cb (int slot, void (*cb) (void *, int), void *cb_arg);
int apdu_reset (int slot);
int apdu_get_status (int slot, int hang, unsigned int *status);
diff --git a/scd/app.c b/scd/app.c
index f3f1205f8..a82db26cd 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -67,6 +67,7 @@ lock_app (app_t app, ctrl_t ctrl)
}
apdu_set_progress_cb (app->slot, print_progress_line, ctrl);
+ apdu_set_prompt_cb (app->slot, popup_prompt, ctrl);
return 0;
}
@@ -76,6 +77,7 @@ static void
unlock_app (app_t app)
{
apdu_set_progress_cb (app->slot, NULL, NULL);
+ apdu_set_prompt_cb (app->slot, NULL, NULL);
if (npth_mutex_unlock (&app->lock))
{
diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c
index ae40f0118..6b0833b2c 100644
--- a/scd/ccid-driver.c
+++ b/scd/ccid-driver.c
@@ -255,6 +255,9 @@ struct ccid_driver_s
void (*progress_cb)(void *, const char *, int, int, int);
void *progress_cb_arg;
+ void (*prompt_cb)(void *, int);
+ void *prompt_cb_arg;
+
unsigned char intr_buf[64];
struct libusb_transfer *transfer;
};
@@ -1802,6 +1805,19 @@ ccid_set_progress_cb (ccid_driver_t handle,
}
+int
+ccid_set_prompt_cb (ccid_driver_t handle,
+ void (*cb)(void *, int), void *cb_arg)
+{
+ if (!handle)
+ return CCID_DRIVER_ERR_INV_VALUE;
+
+ handle->prompt_cb = cb;
+ handle->prompt_cb_arg = cb_arg;
+ return 0;
+}
+
+
/* Close the reader HANDLE. */
int
ccid_close_reader (ccid_driver_t handle)
@@ -1930,6 +1946,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
{
int rc;
int msglen;
+ int notified = 0;
/* Fixme: The next line for the current Valgrind without support
for USB IOCTLs. */
@@ -1982,14 +1999,25 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
we got the expected message type. This is in particular required
for the Cherry keyboard which sends a time extension request for
each key hit. */
- if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80)
+ if (!(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80)
{
/* Card present and active, time extension requested. */
DEBUGOUT_2 ("time extension requested (%02X,%02X)\n",
buffer[7], buffer[8]);
+
+ /* Gnuk enhancement to prompt user input by ack button */
+ if (buffer[8] == 0xff && !notified)
+ {
+ notified = 1;
+ handle->prompt_cb (handle->prompt_cb_arg, 1);
+ }
+
goto retry;
}
+ if (notified)
+ handle->prompt_cb (handle->prompt_cb_arg, 0);
+
if (buffer[0] != expected_type && buffer[0] != RDR_to_PC_SlotStatus)
{
DEBUGOUT_1 ("unexpected bulk-in msg type (%02x)\n", buffer[0]);
diff --git a/scd/ccid-driver.h b/scd/ccid-driver.h
index c31c25fa7..1550b3eba 100644
--- a/scd/ccid-driver.h
+++ b/scd/ccid-driver.h
@@ -126,6 +126,8 @@ int ccid_open_reader (const char *spec_reader_name,
int ccid_set_progress_cb (ccid_driver_t handle,
void (*cb)(void *, const char *, int, int, int),
void *cb_arg);
+int ccid_set_prompt_cb (ccid_driver_t handle, void (*cb)(void *, int),
+ void *cb_arg);
int ccid_shutdown_reader (ccid_driver_t handle);
int ccid_close_reader (ccid_driver_t handle);
int ccid_get_atr (ccid_driver_t handle,
diff --git a/scd/command.c b/scd/command.c
index 66d9fb971..0a9654693 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -1898,6 +1898,34 @@ send_status_direct (ctrl_t ctrl, const char *keyword, const char *args)
}
+void
+popup_prompt (void *opaque, int on)
+{
+ ctrl_t ctrl = opaque;
+
+ if (ctrl)
+ {
+ assuan_context_t ctx = ctrl->server_local->assuan_ctx;
+
+ if (ctx)
+ {
+ const char *cmd;
+ gpg_error_t err;
+ unsigned char *value;
+ size_t valuelen;
+
+ if (on)
+ cmd = "POPUPPINPADPROMPT --ack";
+ else
+ cmd = "DISMISSPINPADPROMPT";
+ err = assuan_inquire (ctx, cmd, &value, &valuelen, 100);
+ if (!err)
+ xfree (value);
+ }
+ }
+}
+
+
/* Helper to send the clients a status change notification. */
void
send_client_notifications (app_t app, int removal)
diff --git a/scd/scdaemon.h b/scd/scdaemon.h
index 4797f3df0..238e6a8fd 100644
--- a/scd/scdaemon.h
+++ b/scd/scdaemon.h
@@ -123,6 +123,7 @@ int scd_command_handler (ctrl_t, int);
void send_status_info (ctrl_t ctrl, const char *keyword, ...)
GPGRT_ATTR_SENTINEL(1);
void send_status_direct (ctrl_t ctrl, const char *keyword, const char *args);
+void popup_prompt (void *opaque, int on);
void send_client_notifications (app_t app, int removal);
void scd_kick_the_loop (void);
int get_active_connection_count (void);