mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-19 09:02:22 +02:00
scd: Fix card removal/reset on multiple contexts.
* scd/app.c (application_notify_card_reset): Add message for debug. *scd/command.c (update_card_removed): Call release_application and set SLOT -1 here. (struct server_local_s): Remove app_ctx_marked_for_release. (do_reset): Don't mark release but call release_application here. (open_card): Remove app_ctx_marked_for_release handling. (update_reader_status_file): Don't set SLOT here, so that it can be released the APP by application_notify_card_reset in update_card_removed. -- Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
270f7f7b8b
commit
1598a44764
@ -168,8 +168,12 @@ application_notify_card_reset (int slot)
|
|||||||
/* Release the APP, as it's not reusable any more. */
|
/* Release the APP, as it's not reusable any more. */
|
||||||
if (lock_table[slot].app)
|
if (lock_table[slot].app)
|
||||||
{
|
{
|
||||||
|
if (lock_table[slot].app->ref_count)
|
||||||
|
log_bug ("trying to release active context\n");
|
||||||
|
|
||||||
deallocate_app (lock_table[slot].app);
|
deallocate_app (lock_table[slot].app);
|
||||||
lock_table[slot].app = NULL;
|
lock_table[slot].app = NULL;
|
||||||
|
log_debug ("application has been released\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
unlock_reader (slot);
|
unlock_reader (slot);
|
||||||
|
@ -129,10 +129,6 @@ struct server_local_s
|
|||||||
continue operation. */
|
continue operation. */
|
||||||
int card_removed;
|
int card_removed;
|
||||||
|
|
||||||
/* Flag indicating that the application context needs to be released
|
|
||||||
at the next opportunity. */
|
|
||||||
int app_ctx_marked_for_release;
|
|
||||||
|
|
||||||
/* A disconnect command has been sent. */
|
/* A disconnect command has been sent. */
|
||||||
int disconnect_allowed;
|
int disconnect_allowed;
|
||||||
|
|
||||||
@ -209,14 +205,28 @@ update_card_removed (int vrdr, int value)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
for (sl=session_list; sl; sl = sl->next_session)
|
for (sl=session_list; sl; sl = sl->next_session)
|
||||||
if (sl->ctrl_backlink
|
{
|
||||||
&& sl->ctrl_backlink->server_local->vreader_idx == vrdr)
|
ctrl_t ctrl = sl->ctrl_backlink;
|
||||||
|
|
||||||
|
if (ctrl && ctrl->server_local->vreader_idx == vrdr)
|
||||||
{
|
{
|
||||||
sl->card_removed = value;
|
sl->card_removed = value;
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
struct app_ctx_s *app = ctrl->app_ctx;
|
||||||
|
ctrl->app_ctx = NULL;
|
||||||
|
release_application (app);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Let the card application layer know about the removal. */
|
/* Let the card application layer know about the removal. */
|
||||||
if (value)
|
if (value)
|
||||||
|
{
|
||||||
|
log_debug ("Removal of a card: %d\n", vrdr);
|
||||||
application_notify_card_reset (vreader_slot (vrdr));
|
application_notify_card_reset (vreader_slot (vrdr));
|
||||||
|
vreader_table[vrdr].slot = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -266,22 +276,30 @@ do_reset (ctrl_t ctrl, int send_reset)
|
|||||||
if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
|
if (!(vrdr == -1 || (vrdr >= 0 && vrdr < DIM(vreader_table))))
|
||||||
BUG ();
|
BUG ();
|
||||||
|
|
||||||
/* If there is an active application, release it. Tell all other
|
/* If there is an active application, release it. */
|
||||||
sessions using the same application to release the
|
|
||||||
application. */
|
|
||||||
if (app)
|
if (app)
|
||||||
{
|
{
|
||||||
ctrl->app_ctx = NULL;
|
ctrl->app_ctx = NULL;
|
||||||
release_application (app);
|
release_application (app);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the same application which is used by other sessions. */
|
||||||
if (send_reset)
|
if (send_reset)
|
||||||
{
|
{
|
||||||
struct server_local_s *sl;
|
struct server_local_s *sl;
|
||||||
|
|
||||||
for (sl=session_list; sl; sl = sl->next_session)
|
for (sl=session_list; sl; sl = sl->next_session)
|
||||||
if (sl->ctrl_backlink
|
|
||||||
&& sl->ctrl_backlink->server_local->vreader_idx == vrdr)
|
|
||||||
{
|
{
|
||||||
sl->app_ctx_marked_for_release = 1;
|
ctrl_t c = sl->ctrl_backlink;
|
||||||
|
|
||||||
|
if (c && c != ctrl && c->server_local->vreader_idx == vrdr)
|
||||||
|
{
|
||||||
|
struct app_ctx_s *app0 = c->app_ctx;
|
||||||
|
if (app0)
|
||||||
|
{
|
||||||
|
c->app_ctx = NULL;
|
||||||
|
release_application (app0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,7 +319,7 @@ do_reset (ctrl_t ctrl, int send_reset)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
apdu_close_reader (slot);
|
apdu_close_reader (slot);
|
||||||
vreader_table[vrdr].slot = slot = -1;
|
vreader_table[vrdr].slot = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -427,16 +445,6 @@ open_card (ctrl_t ctrl, const char *apptype)
|
|||||||
if ( IS_LOCKED (ctrl) )
|
if ( IS_LOCKED (ctrl) )
|
||||||
return gpg_error (GPG_ERR_LOCKED);
|
return gpg_error (GPG_ERR_LOCKED);
|
||||||
|
|
||||||
/* If the application has been marked for release do it now. We
|
|
||||||
can't do it immediately in do_reset because the application may
|
|
||||||
still be in use. */
|
|
||||||
if (ctrl->server_local->app_ctx_marked_for_release)
|
|
||||||
{
|
|
||||||
ctrl->server_local->app_ctx_marked_for_release = 0;
|
|
||||||
release_application (ctrl->app_ctx);
|
|
||||||
ctrl->app_ctx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we are already initialized for one specific application we
|
/* If we are already initialized for one specific application we
|
||||||
need to check that the client didn't requested a specific
|
need to check that the client didn't requested a specific
|
||||||
application different from the one in use before we continue. */
|
application different from the one in use before we continue. */
|
||||||
@ -2031,14 +2039,10 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
|||||||
session_list = ctrl->server_local;
|
session_list = ctrl->server_local;
|
||||||
ctrl->server_local->ctrl_backlink = ctrl;
|
ctrl->server_local->ctrl_backlink = ctrl;
|
||||||
ctrl->server_local->assuan_ctx = ctx;
|
ctrl->server_local->assuan_ctx = ctx;
|
||||||
ctrl->server_local->vreader_idx = -1;
|
|
||||||
|
|
||||||
/* We open the reader right at startup so that the ticker is able to
|
/* We open the reader right at startup so that the ticker is able to
|
||||||
update the status file. */
|
update the status file. */
|
||||||
if (ctrl->server_local->vreader_idx == -1)
|
|
||||||
{
|
|
||||||
ctrl->server_local->vreader_idx = get_current_reader ();
|
ctrl->server_local->vreader_idx = get_current_reader ();
|
||||||
}
|
|
||||||
|
|
||||||
/* Command processing loop. */
|
/* Command processing loop. */
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -2256,9 +2260,7 @@ update_reader_status_file (int set_card_removed_flag)
|
|||||||
if (sw_apdu == SW_HOST_NO_READER)
|
if (sw_apdu == SW_HOST_NO_READER)
|
||||||
{
|
{
|
||||||
/* Most likely the _reader_ has been unplugged. */
|
/* Most likely the _reader_ has been unplugged. */
|
||||||
application_notify_card_reset (vr->slot);
|
|
||||||
apdu_close_reader (vr->slot);
|
apdu_close_reader (vr->slot);
|
||||||
vr->slot = -1;
|
|
||||||
status = 0;
|
status = 0;
|
||||||
changed = vr->changed;
|
changed = vr->changed;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user