mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
SCD changes for PC/SC under W32.
This commit is contained in:
parent
c1329ec7c6
commit
d0ca953014
@ -1,3 +1,8 @@
|
|||||||
|
2008-10-14 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gpg-agent.c (get_agent_scd_notify_event): Need to use a manual
|
||||||
|
reset event.
|
||||||
|
|
||||||
2008-09-29 Werner Koch <wk@g10code.com>
|
2008-09-29 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* agent.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER.
|
* agent.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER.
|
||||||
|
@ -378,7 +378,9 @@ start_scd (ctrl_t ctrl)
|
|||||||
char buf[100];
|
char buf[100];
|
||||||
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
snprintf (buf, sizeof buf, "OPTION event-signal=%lx",
|
/* Use estream snprintf due to a bug in mingw32 related to the l
|
||||||
|
modifier. */
|
||||||
|
estream_snprintf (buf, sizeof buf, "OPTION event-signal=%lx",
|
||||||
(unsigned long)get_agent_scd_notify_event ());
|
(unsigned long)get_agent_scd_notify_event ());
|
||||||
#else
|
#else
|
||||||
snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
|
snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
|
||||||
|
@ -1268,12 +1268,34 @@ get_agent_scd_notify_event (void)
|
|||||||
|
|
||||||
if (!the_event)
|
if (!the_event)
|
||||||
{
|
{
|
||||||
|
HANDLE h, h2;
|
||||||
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
|
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
|
||||||
|
|
||||||
the_event = CreateEvent ( &sa, FALSE, FALSE, NULL);
|
/* We need to use manual reset evet object due to the way our
|
||||||
if (!the_event)
|
w32-pth wait function works: If we would use an automatic
|
||||||
|
reset event we are not able to figure out which handle has
|
||||||
|
been signaled because at the time we single out the signaled
|
||||||
|
handles using WFSO the event has already been reset due to
|
||||||
|
the WFMO. */
|
||||||
|
h = CreateEvent (&sa, TRUE, FALSE, NULL);
|
||||||
|
if (!h)
|
||||||
log_error ("can't create scd notify event: %s\n", w32_strerror (-1) );
|
log_error ("can't create scd notify event: %s\n", w32_strerror (-1) );
|
||||||
|
else if (!DuplicateHandle (GetCurrentProcess(), h,
|
||||||
|
GetCurrentProcess(), &h2,
|
||||||
|
EVENT_MODIFY_STATE|SYNCHRONIZE, TRUE, 0))
|
||||||
|
{
|
||||||
|
log_error ("setting syncronize for scd notify event failed: %s\n",
|
||||||
|
w32_strerror (-1) );
|
||||||
|
CloseHandle (h);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CloseHandle (h);
|
||||||
|
the_event = h2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug ("returning notify handle %p\n", the_event);
|
||||||
return the_event;
|
return the_event;
|
||||||
}
|
}
|
||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
@ -226,7 +226,7 @@ checked right before it is used.
|
|||||||
@opindex delete-keys
|
@opindex delete-keys
|
||||||
Delete the keys matching @var{pattern}. Note that there is no command
|
Delete the keys matching @var{pattern}. Note that there is no command
|
||||||
to delete the secret part of the key directly. In case you need to do
|
to delete the secret part of the key directly. In case you need to do
|
||||||
this, you should run the command @code{gpg --dump-secret-keys KEYID}
|
this, you should run the command @code{gpgsm --dump-secret-keys KEYID}
|
||||||
before you delete the key, copy the string of hex-digits in the
|
before you delete the key, copy the string of hex-digits in the
|
||||||
``keygrip'' line and delete the file consisting of these hex-digits
|
``keygrip'' line and delete the file consisting of these hex-digits
|
||||||
and the suffix @code{.key} from the @file{private-keys-v1.d} directory
|
and the suffix @code{.key} from the @file{private-keys-v1.d} directory
|
||||||
|
698
po/pt_BR.po
698
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
696
po/zh_CN.po
696
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
697
po/zh_TW.po
697
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,45 @@
|
|||||||
|
2008-10-14 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
|
||||||
|
* apdu.c (reader_table_s): Add fields connect_card and
|
||||||
|
disconnect_card.
|
||||||
|
(new_reader_slot): Set them to NULL.
|
||||||
|
(apdu_connect, apdu_disconnect): New.
|
||||||
|
(apdu_close_reader, apdu_shutdown_reader): Call apdu_disconnect.
|
||||||
|
(connect_pcsc_card, disconnect_pcsc_card): new.
|
||||||
|
(reset_pcsc_reader_direct): Implement in terms of
|
||||||
|
disconnect_pcsc_card and connect_pcsc_card.
|
||||||
|
(apdu_get_atr): Return NULL if there is no ATR.
|
||||||
|
* sc-copykeys.c (main): Add call to apdu_connect.
|
||||||
|
* command.c (open_card): Ditto.
|
||||||
|
|
||||||
|
* apdu.h (SW_HOST_ALREADY_CONNECTED): New.
|
||||||
|
(APDU_CARD_USABLE, APDU_CARD_PRESENT, APDU_CARD_ACTIVE): New.
|
||||||
|
* apdu.c: Replace constants by the new macros.
|
||||||
|
(open_pcsc_reader): Factor code out to ...
|
||||||
|
(open_pcsc_reader_direct, open_pcsc_reader_wrapped): New.
|
||||||
|
(reset_pcsc_reader): Factor code out to ...
|
||||||
|
(reset_pcsc_reader_direct, reset_pcsc_reader_wrapped): New.
|
||||||
|
(pcsc_get_status): Factor code out to ...
|
||||||
|
(pcsc_get_status_direct, pcsc_get_status_wrapped): New.
|
||||||
|
(pcsc_send_apdu): Factor code out to ...
|
||||||
|
(pcsc_send_apdu_direct, pcsc_send_apdu_wrapped): New.
|
||||||
|
(close_pcsc_reader): Factor code out to ...
|
||||||
|
(close_pcsc_reader_direct, close_pcsc_reader_wrapped): New.
|
||||||
|
|
||||||
|
* command.c (update_reader_status_file): Open the reader if not
|
||||||
|
yet done.
|
||||||
|
|
||||||
|
* scdaemon.c (TIMERTICK_INTERVAL_SEC, TIMERTICK_INTERVAL_USEC):
|
||||||
|
New to replace TIMERTICK_INTERVAL. Chnage from 2s (4 under W32)
|
||||||
|
to 250ms.
|
||||||
|
|
||||||
|
2008-10-13 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* command.c (option_handler) [W32]: Use strtoul with base 16.
|
||||||
|
(update_reader_status_file) [W32]: Set Event.
|
||||||
|
(scd_command_handler): Use INT2FD to silent warning.
|
||||||
|
|
||||||
2008-09-29 Werner Koch <wk@g10code.com>
|
2008-09-29 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* scdaemon.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER.
|
* scdaemon.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER.
|
||||||
|
976
scd/apdu.c
976
scd/apdu.c
File diff suppressed because it is too large
Load Diff
14
scd/apdu.h
14
scd/apdu.h
@ -65,13 +65,20 @@ enum {
|
|||||||
SW_HOST_GENERAL_ERROR = 0x1000b,
|
SW_HOST_GENERAL_ERROR = 0x1000b,
|
||||||
SW_HOST_NO_READER = 0x1000c,
|
SW_HOST_NO_READER = 0x1000c,
|
||||||
SW_HOST_ABORTED = 0x1000d,
|
SW_HOST_ABORTED = 0x1000d,
|
||||||
SW_HOST_NO_KEYPAD = 0x1000e
|
SW_HOST_NO_KEYPAD = 0x1000e,
|
||||||
|
SW_HOST_ALREADY_CONNECTED = 0x1000f
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define SW_EXACT_LENGTH_P(a) (((a)&~0xff) == SW_EXACT_LENGTH)
|
#define SW_EXACT_LENGTH_P(a) (((a)&~0xff) == SW_EXACT_LENGTH)
|
||||||
|
|
||||||
|
|
||||||
|
/* Bit flags for the card status. */
|
||||||
|
#define APDU_CARD_USABLE (1) /* Card is present and ready for use. */
|
||||||
|
#define APDU_CARD_PRESENT (2) /* Card is just present. */
|
||||||
|
#define APDU_CARD_ACTIVE (4) /* Card is active. */
|
||||||
|
|
||||||
|
|
||||||
/* Note , that apdu_open_reader returns no status word but -1 on error. */
|
/* Note , that apdu_open_reader returns no status word but -1 on error. */
|
||||||
int apdu_open_reader (const char *portstr);
|
int apdu_open_reader (const char *portstr);
|
||||||
int apdu_open_remote_reader (const char *portstr,
|
int apdu_open_remote_reader (const char *portstr,
|
||||||
@ -92,7 +99,10 @@ unsigned char *apdu_get_atr (int slot, size_t *atrlen);
|
|||||||
const char *apdu_strerror (int rc);
|
const char *apdu_strerror (int rc);
|
||||||
|
|
||||||
|
|
||||||
/* These apdu functions do return status words. */
|
/* These APDU functions return status words. */
|
||||||
|
|
||||||
|
int apdu_connect (int slot);
|
||||||
|
int apdu_disconnect (int slot);
|
||||||
|
|
||||||
int apdu_activate (int slot);
|
int apdu_activate (int slot);
|
||||||
int apdu_reset (int slot);
|
int apdu_reset (int slot);
|
||||||
|
@ -102,7 +102,11 @@ struct server_local_s
|
|||||||
/* The Assuan context used by this session/server. */
|
/* The Assuan context used by this session/server. */
|
||||||
assuan_context_t assuan_ctx;
|
assuan_context_t assuan_ctx;
|
||||||
|
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
unsigned long event_signal; /* Or 0 if not used. */
|
||||||
|
#else
|
||||||
int event_signal; /* Or 0 if not used. */
|
int event_signal; /* Or 0 if not used. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* True if the card has been removed and a reset is required to
|
/* True if the card has been removed and a reset is required to
|
||||||
continue operation. */
|
continue operation. */
|
||||||
@ -165,6 +169,7 @@ update_card_removed (int slot, int value)
|
|||||||
{
|
{
|
||||||
sl->card_removed = value;
|
sl->card_removed = value;
|
||||||
}
|
}
|
||||||
|
/* Let the card application layer know about the removal. */
|
||||||
if (value)
|
if (value)
|
||||||
application_notify_card_removed (slot);
|
application_notify_card_removed (slot);
|
||||||
}
|
}
|
||||||
@ -319,10 +324,16 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
|
|||||||
if (!strcmp (key, "event-signal"))
|
if (!strcmp (key, "event-signal"))
|
||||||
{
|
{
|
||||||
/* A value of 0 is allowed to reset the event signal. */
|
/* A value of 0 is allowed to reset the event signal. */
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
if (!*value)
|
||||||
|
return gpg_error (GPG_ERR_ASS_PARAMETER);
|
||||||
|
ctrl->server_local->event_signal = strtoul (value, NULL, 16);
|
||||||
|
#else
|
||||||
int i = *value? atoi (value) : -1;
|
int i = *value? atoi (value) : -1;
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
return gpg_error (GPG_ERR_ASS_PARAMETER);
|
return gpg_error (GPG_ERR_ASS_PARAMETER);
|
||||||
ctrl->server_local->event_signal = i;
|
ctrl->server_local->event_signal = i;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -388,8 +399,16 @@ open_card (ctrl_t ctrl, const char *apptype)
|
|||||||
ctrl->reader_slot = slot;
|
ctrl->reader_slot = slot;
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
err = gpg_error (GPG_ERR_CARD);
|
err = gpg_error (GPG_ERR_CARD);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Fixme: We should move the apdu_connect call to
|
||||||
|
select_application. */
|
||||||
|
int sw = apdu_connect (slot);
|
||||||
|
if (sw && sw != SW_HOST_ALREADY_CONNECTED)
|
||||||
|
err = gpg_error (GPG_ERR_CARD);
|
||||||
else
|
else
|
||||||
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
|
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CARD_REMOVAL (ctrl, err);
|
TEST_CARD_REMOVAL (ctrl, err);
|
||||||
return err;
|
return err;
|
||||||
@ -1774,7 +1793,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = assuan_init_socket_server_ext (&ctx, fd, 2);
|
rc = assuan_init_socket_server_ext (&ctx, INT2FD(fd), 2);
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -1911,6 +1930,11 @@ update_reader_status_file (void)
|
|||||||
int idx;
|
int idx;
|
||||||
unsigned int status, changed;
|
unsigned int status, changed;
|
||||||
|
|
||||||
|
/* Make sure that the reader has been opened. Like get_reader_slot,
|
||||||
|
this part of the code assumes that there is only one reader. */
|
||||||
|
if (!slot_table[0].valid)
|
||||||
|
(void)get_reader_slot ();
|
||||||
|
|
||||||
/* Note, that we only try to get the status, because it does not
|
/* Note, that we only try to get the status, because it does not
|
||||||
make sense to wait here for a operation to complete. If we are
|
make sense to wait here for a operation to complete. If we are
|
||||||
busy working with a card, delays in the status file update should
|
busy working with a card, delays in the status file update should
|
||||||
@ -2007,11 +2031,20 @@ update_reader_status_file (void)
|
|||||||
if (sl->event_signal && sl->assuan_ctx)
|
if (sl->event_signal && sl->assuan_ctx)
|
||||||
{
|
{
|
||||||
pid_t pid = assuan_get_pid (sl->assuan_ctx);
|
pid_t pid = assuan_get_pid (sl->assuan_ctx);
|
||||||
|
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
HANDLE handle = (void *)sl->event_signal;
|
||||||
|
|
||||||
|
log_info ("client pid is %d, triggering event %lx (%p)\n",
|
||||||
|
pid, sl->event_signal, handle);
|
||||||
|
if (!SetEvent (handle))
|
||||||
|
log_error ("SetEvent(%lx) failed: %s\n",
|
||||||
|
sl->event_signal, w32_strerror (-1));
|
||||||
|
#else
|
||||||
int signo = sl->event_signal;
|
int signo = sl->event_signal;
|
||||||
|
|
||||||
log_info ("client pid is %d, sending signal %d\n",
|
log_info ("client pid is %d, sending signal %d\n",
|
||||||
pid, signo);
|
pid, signo);
|
||||||
#ifndef HAVE_W32_SYSTEM
|
|
||||||
if (pid != (pid_t)(-1) && pid && signo > 0)
|
if (pid != (pid_t)(-1) && pid && signo > 0)
|
||||||
kill (pid, signo);
|
kill (pid, signo);
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,6 +142,8 @@ main (int argc, char **argv )
|
|||||||
slot = apdu_open_reader (reader_port);
|
slot = apdu_open_reader (reader_port);
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
exit (1);
|
exit (1);
|
||||||
|
if (apdu_connect (slot))
|
||||||
|
exit (1);
|
||||||
|
|
||||||
/* FIXME: Use select_application. */
|
/* FIXME: Use select_application. */
|
||||||
appbuf.slot = slot;
|
appbuf.slot = slot;
|
||||||
|
@ -148,15 +148,18 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
|
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* The timer tick used for housekeeping stuff. For Windows we use a
|
/* The timer tick used for housekeeping stuff. We poll every 250ms to
|
||||||
longer period as the SetWaitableTimer seems to signal earlier than
|
let the user immediately know a status change.
|
||||||
the 2 seconds. */
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
|
||||||
#define TIMERTICK_INTERVAL (4)
|
|
||||||
#else
|
|
||||||
#define TIMERTICK_INTERVAL (2) /* Seconds. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
This is not too good for power saving but given that there is no
|
||||||
|
easy way to block on card status changes it is the best we can do.
|
||||||
|
For PC/SC we could in theory use an extra thread to wait for status
|
||||||
|
changes but that requires a native thread because there is no way
|
||||||
|
to make the underlying PC/SC card change function block using a Pth
|
||||||
|
mechanism. Given that a native thread could only be used under W32
|
||||||
|
we don't do that at all. */
|
||||||
|
#define TIMERTICK_INTERVAL_SEC (0)
|
||||||
|
#define TIMERTICK_INTERVAL_USEC (250000)
|
||||||
|
|
||||||
/* Flag to indicate that a shutdown was requested. */
|
/* Flag to indicate that a shutdown was requested. */
|
||||||
static int shutdown_pending;
|
static int shutdown_pending;
|
||||||
@ -1107,7 +1110,8 @@ handle_connections (int listen_fd)
|
|||||||
/* Create a timeout event if needed. */
|
/* Create a timeout event if needed. */
|
||||||
if (!time_ev)
|
if (!time_ev)
|
||||||
time_ev = pth_event (PTH_EVENT_TIME,
|
time_ev = pth_event (PTH_EVENT_TIME,
|
||||||
pth_timeout (TIMERTICK_INTERVAL, 0));
|
pth_timeout (TIMERTICK_INTERVAL_SEC,
|
||||||
|
TIMERTICK_INTERVAL_USEC));
|
||||||
|
|
||||||
/* POSIX says that fd_set should be implemented as a structure,
|
/* POSIX says that fd_set should be implemented as a structure,
|
||||||
thus a simple assignment is fine to copy the entire set. */
|
thus a simple assignment is fine to copy the entire set. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user