1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

* gpg-agent.c (handle_connections): Need to check for events if

select returns with -1.

* tools.texi (gpg-connect-agent): New.

* app-openpgp.c (get_one_do): Never try to get a non cacheable
object from the cache.
(get_one_do): Add new arg to return an error code.  Changed all
callers.
(do_getattr): Let it return a proper error code.

* app.c (select_application): Return an error code and the
application context in an new arg.
* command.c (open_card): Adjusted for that.  Don't use the
fallback if no card is present.  Return an error if the card has
been removed without a reset.
(do_reset, cmd_serialno): Clear that error flag.
(TEST_CARD_REMOVAL): New. Use it with all command handlers.

* scdaemon.c (ticker_thread): Termintate if a shutdown is pending.

* apdu.c: Added some PCSC error codes.
(pcsc_error_to_sw): New.
(reset_pcsc_reader, pcsc_get_status, pcsc_send_apdu)
(open_pcsc_reader): Do proper error code mapping.

* gpg-connect-agent.c: New.
* Makefile.am: Add it.
This commit is contained in:
Werner Koch 2005-02-24 17:36:11 +00:00
parent 4e5bf2fd93
commit 3af261572b
18 changed files with 839 additions and 239 deletions

View file

@ -45,10 +45,24 @@ static ctrl_t primary_connection;
#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
/* Macro to flag a a removed card. */
#define TEST_CARD_REMOVAL(c,r) \
do { \
int _r = (r); \
if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \
|| gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \
(c)->server_local->card_removed = 1; \
} while (0)
/* Data used to associate an Assuan context with local server data */
struct server_local_s {
ASSUAN_CONTEXT assuan_ctx;
assuan_context_t assuan_ctx;
int event_signal; /* Or 0 if not used. */
int card_removed; /* True if the card has been removed and a
reset is required to continue
operation. */
};
@ -89,6 +103,7 @@ do_reset (ctrl_t ctrl, int do_close)
ctrl->reader_slot = -1;
}
}
ctrl->server_local->card_removed = 0;
}
@ -122,11 +137,18 @@ option_handler (ASSUAN_CONTEXT ctx, const char *key, const char *value)
/* If the card has not yet been opened, do it. Note that this
function returns an Assuan error, so don't map the error a second
time */
static AssuanError
static assuan_error_t
open_card (ctrl_t ctrl, const char *apptype)
{
gpg_error_t err;
int slot;
/* If we ever got a card not present error code, return that. Only
the SERIALNO command and a reset are able to clear from that
state. */
if (ctrl->server_local->card_removed)
return map_to_assuan_status (gpg_error (GPG_ERR_CARD_REMOVED));
if (ctrl->app_ctx)
return 0; /* Already initialized for one specific application. */
if (ctrl->card_ctx)
@ -137,24 +159,28 @@ open_card (ctrl_t ctrl, const char *apptype)
else
slot = apdu_open_reader (opt.reader_port);
ctrl->reader_slot = slot;
if (slot != -1)
ctrl->app_ctx = select_application (ctrl, slot, apptype);
if (!ctrl->app_ctx)
{ /* No application found - fall back to old mode. */
if (slot == -1)
err = gpg_error (GPG_ERR_CARD);
else
err = select_application (ctrl, slot, apptype, &ctrl->app_ctx);
if (!ctrl->app_ctx
&& gpg_err_code (err) != GPG_ERR_CARD_NOT_PRESENT)
{
/* No application found - fall back to old mode. */
/* Note that we should rework the old code to use the
application paradigma too. */
int rc;
/* If an APPTYPE was requested and it is not pkcs#15, we return
an error here. */
if (apptype && !(!strcmp (apptype, "P15") || !strcmp (apptype, "p15")))
rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
else
rc = card_open (&ctrl->card_ctx);
if (rc)
return map_to_assuan_status (rc);
err = card_open (&ctrl->card_ctx);
}
return 0;
if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
ctrl->server_local->card_removed = 1;
return map_to_assuan_status (err);
}
@ -215,12 +241,15 @@ percent_plus_unescape (unsigned char *string)
static int
cmd_serialno (ASSUAN_CONTEXT ctx, char *line)
{
CTRL ctrl = assuan_get_pointer (ctx);
ctrl_t ctrl = assuan_get_pointer (ctx);
int rc = 0;
char *serial_and_stamp;
char *serial;
time_t stamp;
/* Clear the remove flag so that the open_card is able to reread it. */
ctrl->server_local->card_removed = 0;
if ((rc = open_card (ctrl, *line? line:NULL)))
return rc;
@ -443,6 +472,7 @@ cmd_learn (ASSUAN_CONTEXT ctx, char *line)
if (rc == -1)
rc = 0;
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -485,6 +515,7 @@ cmd_readcert (ASSUAN_CONTEXT ctx, char *line)
return rc;
}
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -575,6 +606,7 @@ cmd_readkey (assuan_context_t ctx, char *line)
leave:
ksba_cert_release (kc);
xfree (cert);
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -697,6 +729,7 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
return rc; /* that is already an assuan error code */
}
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -743,6 +776,7 @@ cmd_pkauth (ASSUAN_CONTEXT ctx, char *line)
return rc; /* that is already an assuan error code */
}
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -789,6 +823,7 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
return rc; /* that is already an assuan error code */
}
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -824,6 +859,7 @@ cmd_getattr (ASSUAN_CONTEXT ctx, char *line)
rc = app_getattr (ctrl->app_ctx, ctrl, keyword);
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -871,6 +907,7 @@ cmd_setattr (ASSUAN_CONTEXT ctx, char *orig_line)
rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, line, nbytes);
xfree (linebuf);
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -927,6 +964,8 @@ cmd_genkey (ASSUAN_CONTEXT ctx, char *line)
return ASSUAN_Out_Of_Core;
rc = app_genkey (ctrl->app_ctx, ctrl, keyno, force? 1:0, pin_cb, ctx);
xfree (keyno);
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -966,6 +1005,7 @@ cmd_random (ASSUAN_CONTEXT ctx, char *line)
}
xfree (buffer);
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -1010,6 +1050,8 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
if (rc)
log_error ("command passwd failed: %s\n", gpg_strerror (rc));
xfree (chvnostr);
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -1044,6 +1086,7 @@ cmd_checkpin (ASSUAN_CONTEXT ctx, char *line)
if (rc)
log_error ("app_check_pin failed: %s\n", gpg_strerror (rc));
TEST_CARD_REMOVAL (ctrl, rc);
return map_to_assuan_status (rc);
}
@ -1226,7 +1269,9 @@ send_status_info (CTRL ctrl, const char *keyword, ...)
}
/* This fucntion is called by the ticker thread to check for changes
of the reader stati. It updates the reader status files and if
requested by the caller also send a signal to the caller. */
void
scd_update_reader_status_file (void)
{
@ -1239,10 +1284,10 @@ scd_update_reader_status_file (void)
int used;
unsigned int status, changed;
/* Note, that we only try to get the status, becuase 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
so busy working with the card, delays in the status file updated
are should be acceptable. */
busy working with a card, delays in the status file update should
be acceptable. */
for (slot=0; (slot < DIM(last)
&&!apdu_enum_reader (slot, &used)); slot++)
if (used && !apdu_get_status (slot, 0, &status, &changed))