- Fix a long-standing issue for user configured atrs

in the configuration file; free allocated memory
  from the card_driver structures.


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2188 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
aet 2005-02-14 09:12:44 +00:00
parent fcc93f089d
commit 7268799d92
3 changed files with 83 additions and 34 deletions

View File

@ -359,7 +359,7 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
struct sc_context *ctx = reader->ctx; struct sc_context *ctx = reader->ctx;
struct sc_slot_info *slot = _sc_get_slot_info(reader, slot_id); struct sc_slot_info *slot = _sc_get_slot_info(reader, slot_id);
struct sc_card_driver *driver; struct sc_card_driver *driver;
int i, r = 0, connected = 0; int i, r = 0, idx;
assert(card_out != NULL); assert(card_out != NULL);
SC_FUNC_CALLED(ctx, 1); SC_FUNC_CALLED(ctx, 1);
@ -374,7 +374,6 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
r = reader->ops->connect(reader, slot); r = reader->ops->connect(reader, slot);
if (r) if (r)
goto err; goto err;
connected = 1;
card->reader = reader; card->reader = reader;
card->slot = slot; card->slot = slot;
@ -391,10 +390,29 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
/* See if the ATR matches any ATR specified in the config file */ /* See if the ATR matches any ATR specified in the config file */
if ((driver = ctx->forced_driver) == NULL) { if ((driver = ctx->forced_driver) == NULL) {
if (ctx->debug >= 3)
sc_debug(ctx, "matching configured ATRs\n");
for (i = 0; ctx->card_drivers[i] != NULL; i++) { for (i = 0; ctx->card_drivers[i] != NULL; i++) {
driver = ctx->card_drivers[i]; driver = ctx->card_drivers[i];
if (_sc_match_atr(card, driver->atr_map, NULL) >= 0)
if (driver->atr_map == NULL) {
driver = NULL;
continue;
}
if (ctx->debug >= 3)
sc_debug(ctx, "trying driver: %s\n", driver->short_name);
idx = _sc_match_atr(card, driver->atr_map, NULL);
if (idx >= 0) {
struct sc_atr_table *src = &driver->atr_map[idx];
if (ctx->debug >= 3)
sc_debug(ctx, "matched: %s\n", driver->name);
/* It's up to card driver to notice these correctly */
card->name = src->name;
card->type = src->type;
card->flags = src->flags;
break; break;
}
driver = NULL; driver = NULL;
} }
} }
@ -412,31 +430,35 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
goto err; goto err;
} }
} }
} else for (i = 0; ctx->card_drivers[i] != NULL; i++) { } else {
struct sc_card_driver *drv = ctx->card_drivers[i]; if (ctx->debug >= 3)
const struct sc_card_operations *ops = drv->ops; sc_debug(ctx, "matching built-in ATRs\n");
for (i = 0; ctx->card_drivers[i] != NULL; i++) {
struct sc_card_driver *drv = ctx->card_drivers[i];
const struct sc_card_operations *ops = drv->ops;
if (ctx->debug >= 3) if (ctx->debug >= 3)
sc_debug(ctx, "trying driver: %s\n", drv->name); sc_debug(ctx, "trying driver: %s\n", drv->short_name);
if (ops == NULL || ops->match_card == NULL) if (ops == NULL || ops->match_card == NULL)
continue;
if (ops->match_card(card) != 1)
continue;
if (ctx->debug >= 3)
sc_debug(ctx, "matched: %s\n", drv->name);
memcpy(card->ops, ops, sizeof(struct sc_card_operations));
card->driver = drv;
r = ops->init(card);
if (r) {
sc_error(ctx, "driver '%s' init() failed: %s\n", drv->name,
sc_strerror(r));
if (r == SC_ERROR_INVALID_CARD) {
card->driver = NULL;
continue; continue;
if (ops->match_card(card) != 1)
continue;
if (ctx->debug >= 3)
sc_debug(ctx, "matched: %s\n", drv->name);
memcpy(card->ops, ops, sizeof(struct sc_card_operations));
card->driver = drv;
r = ops->init(card);
if (r) {
sc_error(ctx, "driver '%s' init() failed: %s\n", drv->name,
sc_strerror(r));
if (r == SC_ERROR_INVALID_CARD) {
card->driver = NULL;
continue;
}
goto err;
} }
goto err; break;
} }
break;
} }
if (card->driver == NULL) { if (card->driver == NULL) {
sc_error(ctx, "unable to find driver for inserted card\n"); sc_error(ctx, "unable to find driver for inserted card\n");
@ -447,6 +469,7 @@ int sc_connect_card(struct sc_reader *reader, int slot_id,
card->name = card->driver->name; card->name = card->driver->name;
*card_out = card; *card_out = card;
sc_debug(ctx, "card info: %s, %i, 0x%X\n", card->name, card->type, card->flags);
SC_FUNC_RETURN(ctx, 1, 0); SC_FUNC_RETURN(ctx, 1, 0);
err: err:
if (card != NULL) if (card != NULL)
@ -963,7 +986,6 @@ int _sc_match_atr(struct sc_card *card, struct sc_atr_table *table, int *type_ou
return -1; return -1;
} }
/* XXX: temporary, will be rewritten soon */
int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src) int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src)
{ {
struct sc_atr_table *map, *dst; struct sc_atr_table *map, *dst;
@ -994,5 +1016,28 @@ int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc
} }
dst->type = src->type; dst->type = src->type;
dst->flags = src->flags; dst->flags = src->flags;
return 0; return SC_SUCCESS;
}
int _sc_free_atr(struct sc_context *ctx, struct sc_card_driver *driver)
{
unsigned int i;
for (i = 0; i < driver->natrs; i++) {
struct sc_atr_table *src = &driver->atr_map[i];
if (src->atr)
free(src->atr);
if (src->atrmask)
free(src->atrmask);
if (src->name)
free(src->name);
src = NULL;
}
if (driver->atr_map)
free(driver->atr_map);
driver->atr_map = NULL;
driver->natrs = 0;
return SC_SUCCESS;
} }

View File

@ -52,8 +52,6 @@ struct _sc_driver_entry {
char *name; char *name;
void *func; void *func;
char *libpath; char *libpath;
struct sc_atr_table *atrs;
unsigned int natrs;
}; };
static const struct _sc_driver_entry internal_card_drivers[] = { static const struct _sc_driver_entry internal_card_drivers[] = {
@ -477,6 +475,9 @@ static int load_card_drivers(struct sc_context *ctx,
ctx->card_drivers[drv_count] = func(); ctx->card_drivers[drv_count] = func();
ctx->card_drivers[drv_count]->dll = dll; ctx->card_drivers[drv_count]->dll = dll;
ctx->card_drivers[drv_count]->atr_map = NULL;
ctx->card_drivers[drv_count]->natrs = 0;
load_card_driver_options(ctx, ctx->card_drivers[drv_count]); load_card_driver_options(ctx, ctx->card_drivers[drv_count]);
drv_count++; drv_count++;
} }
@ -600,6 +601,8 @@ int sc_release_context(struct sc_context *ctx)
struct sc_card_driver *drv = ctx->card_drivers[i]; struct sc_card_driver *drv = ctx->card_drivers[i];
if (drv->dll) if (drv->dll)
scdl_close(drv->dll); scdl_close(drv->dll);
if (drv->atr_map)
_sc_free_atr(ctx, drv);
} }
if (ctx->debug_file && ctx->debug_file != stdout) if (ctx->debug_file && ctx->debug_file != stdout)
fclose(ctx->debug_file); fclose(ctx->debug_file);

View File

@ -40,12 +40,12 @@ extern "C" {
#define SC_CTX_MAGIC 0x0A550335 #define SC_CTX_MAGIC 0x0A550335
struct sc_atr_table { struct sc_atr_table {
const char *atr; /* The atr fields are required to char *atr; /* The atr fields are required to
be in aa:bb:cc hex format. */ be in aa:bb:cc hex format. */
const char *atrmask; /* The atrmask is logically AND'd with an char *atrmask; /* The atrmask is logically AND'd with an
card atr prior to comparison with the card atr prior to comparison with the
atr reference value above. */ atr reference value above. */
const char *name; char *name;
int type; int type;
unsigned long flags; unsigned long flags;
}; };
@ -60,6 +60,7 @@ struct sc_slot_info * _sc_get_slot_info(struct sc_reader *reader, int slot_id);
/* Add an ATR to the card driver's struct sc_atr_table */ /* Add an ATR to the card driver's struct sc_atr_table */
int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src); int _sc_add_atr(struct sc_context *ctx, struct sc_card_driver *driver, struct sc_atr_table *src);
int _sc_free_atr(struct sc_context *ctx, struct sc_card_driver *driver);
/* Returns an index number if a match was found, -1 otherwise. table has to /* Returns an index number if a match was found, -1 otherwise. table has to
* be null terminated. */ * be null terminated. */