mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +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>
|
||||
|
||||
* agent.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER.
|
||||
|
@ -378,8 +378,10 @@ start_scd (ctrl_t ctrl)
|
||||
char buf[100];
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
snprintf (buf, sizeof buf, "OPTION event-signal=%lx",
|
||||
(unsigned long)get_agent_scd_notify_event ());
|
||||
/* 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 ());
|
||||
#else
|
||||
snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
|
||||
#endif
|
||||
|
@ -1268,12 +1268,34 @@ get_agent_scd_notify_event (void)
|
||||
|
||||
if (!the_event)
|
||||
{
|
||||
HANDLE h, h2;
|
||||
SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), NULL, TRUE};
|
||||
|
||||
the_event = CreateEvent ( &sa, FALSE, FALSE, NULL);
|
||||
if (!the_event)
|
||||
/* We need to use manual reset evet object due to the way our
|
||||
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) );
|
||||
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;
|
||||
}
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
@ -226,7 +226,7 @@ checked right before it is used.
|
||||
@opindex delete-keys
|
||||
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
|
||||
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
|
||||
``keygrip'' line and delete the file consisting of these hex-digits
|
||||
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>
|
||||
|
||||
* scdaemon.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER.
|
||||
|
1018
scd/apdu.c
1018
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_NO_READER = 0x1000c,
|
||||
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)
|
||||
|
||||
|
||||
/* 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. */
|
||||
int apdu_open_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);
|
||||
|
||||
|
||||
/* 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_reset (int slot);
|
||||
|
@ -102,8 +102,12 @@ struct server_local_s
|
||||
/* The Assuan context used by this session/server. */
|
||||
assuan_context_t assuan_ctx;
|
||||
|
||||
int event_signal; /* Or 0 if not used. */
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
unsigned long event_signal; /* Or 0 if not used. */
|
||||
#else
|
||||
int event_signal; /* Or 0 if not used. */
|
||||
#endif
|
||||
|
||||
/* True if the card has been removed and a reset is required to
|
||||
continue operation. */
|
||||
int card_removed;
|
||||
@ -165,6 +169,7 @@ update_card_removed (int slot, int value)
|
||||
{
|
||||
sl->card_removed = value;
|
||||
}
|
||||
/* Let the card application layer know about the removal. */
|
||||
if (value)
|
||||
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"))
|
||||
{
|
||||
/* 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;
|
||||
if (i < 0)
|
||||
return gpg_error (GPG_ERR_ASS_PARAMETER);
|
||||
ctrl->server_local->event_signal = i;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -389,7 +400,15 @@ open_card (ctrl_t ctrl, const char *apptype)
|
||||
if (slot == -1)
|
||||
err = gpg_error (GPG_ERR_CARD);
|
||||
else
|
||||
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
|
||||
{
|
||||
/* 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
|
||||
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
|
||||
}
|
||||
|
||||
TEST_CARD_REMOVAL (ctrl, err);
|
||||
return err;
|
||||
@ -1774,7 +1793,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = assuan_init_socket_server_ext (&ctx, fd, 2);
|
||||
rc = assuan_init_socket_server_ext (&ctx, INT2FD(fd), 2);
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
@ -1911,6 +1930,11 @@ update_reader_status_file (void)
|
||||
int idx;
|
||||
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
|
||||
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
|
||||
@ -2007,11 +2031,20 @@ update_reader_status_file (void)
|
||||
if (sl->event_signal && 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;
|
||||
|
||||
log_info ("client pid is %d, sending signal %d\n",
|
||||
pid, signo);
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
if (pid != (pid_t)(-1) && pid && signo > 0)
|
||||
kill (pid, signo);
|
||||
#endif
|
||||
|
@ -142,6 +142,8 @@ main (int argc, char **argv )
|
||||
slot = apdu_open_reader (reader_port);
|
||||
if (slot == -1)
|
||||
exit (1);
|
||||
if (apdu_connect (slot))
|
||||
exit (1);
|
||||
|
||||
/* FIXME: Use select_application. */
|
||||
appbuf.slot = slot;
|
||||
|
@ -148,15 +148,18 @@ static ARGPARSE_OPTS opts[] = {
|
||||
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
|
||||
#endif
|
||||
|
||||
/* The timer tick used for housekeeping stuff. For Windows we use a
|
||||
longer period as the SetWaitableTimer seems to signal earlier than
|
||||
the 2 seconds. */
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#define TIMERTICK_INTERVAL (4)
|
||||
#else
|
||||
#define TIMERTICK_INTERVAL (2) /* Seconds. */
|
||||
#endif
|
||||
/* The timer tick used for housekeeping stuff. We poll every 250ms to
|
||||
let the user immediately know a status change.
|
||||
|
||||
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. */
|
||||
static int shutdown_pending;
|
||||
@ -1107,7 +1110,8 @@ handle_connections (int listen_fd)
|
||||
/* Create a timeout event if needed. */
|
||||
if (!time_ev)
|
||||
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,
|
||||
thus a simple assignment is fine to copy the entire set. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user