Exemplo n.º 1
0
Arquivo: ctx.c Projeto: velter/OpenSC
static void load_reader_driver_options(sc_context_t *ctx)
{
	struct sc_reader_driver *driver = ctx->reader_driver;
	scconf_block *conf_block = NULL;
	sc_reader_t *reader;
	int max_send_size;
	int max_recv_size;

	conf_block = sc_get_conf_block(ctx, "reader_driver", driver->short_name, 1);

	if (conf_block != NULL) {
		max_send_size = scconf_get_int(conf_block, "max_send_size", -1);
		max_recv_size = scconf_get_int(conf_block, "max_recv_size", -1);
		if (max_send_size >= 0 || max_recv_size >= 0) {
			if (list_iterator_start(&ctx->readers)) {
				reader = list_iterator_next(&ctx->readers);
				while (reader) {
					if (max_send_size >= 0)
						reader->max_send_size = max_send_size;
					if (max_recv_size >= 0)
						reader->max_recv_size = max_recv_size;
					reader = list_iterator_next(&ctx->readers);
				}
				list_iterator_stop(&ctx->readers);
			}
		}
	}
}
Exemplo n.º 2
0
static void load_reader_driver_options(sc_context_t *ctx)
{
	struct sc_reader_driver *driver = ctx->reader_driver;
	scconf_block *conf_block = NULL;
	
	driver->max_send_size = 0;
	driver->max_recv_size = 0;

	conf_block = sc_get_conf_block(ctx, "reader_driver", driver->short_name, 1);
	
	if (conf_block != NULL) {
		driver->max_send_size = scconf_get_int(conf_block, "max_send_size", driver->max_send_size);
		driver->max_recv_size = scconf_get_int(conf_block, "max_recv_size", driver->max_recv_size);
	}
}
/*
 * Initialize readers
 *
 * Called during sc_establish_context(), when the driver
 * is loaded
 */
static int
openct_reader_init(sc_context_t *ctx, void **priv_data)
{
	unsigned int	i,max;
	scconf_block *conf_block;

	SC_FUNC_CALLED(ctx, 1);

	max=OPENCT_MAX_READERS; 

        conf_block = sc_get_conf_block(ctx, "reader_driver", "openct", 1);
	if (conf_block) {
		max = scconf_get_int(conf_block, "readers", OPENCT_MAX_READERS);
	}

	for (i = 0; i < max; i++) {
		ct_info_t	info;

		if (ct_reader_info(i, &info) >= 0) {
			openct_add_reader(ctx, i, &info);
		} else if (i < PREALLOCATE) {
			openct_add_reader(ctx, i, NULL);
		}
	}

	return SC_NO_ERROR;
}
Exemplo n.º 4
0
/*
 * Initialize readers
 *
 * Called during sc_establish_context(), when the driver
 * is loaded
 */
static int
openct_reader_init(sc_context_t *ctx)
{
	unsigned int	i,max_virtual;
	scconf_block *conf_block;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	max_virtual = 2;
	conf_block = sc_get_conf_block(ctx, "reader_driver", "openct", 1);
	if (conf_block) {
		max_virtual = scconf_get_int(conf_block, "readers", max_virtual);
	}

	for (i = 0; i < OPENCT_MAX_READERS; i++) {
		ct_info_t	info;
		/* XXX: As long as OpenCT has slots, multislot readers should create several instances here. */
		if (ct_reader_info(i, &info) >= 0) {
			openct_add_reader(ctx, i, &info);
		} else if (i < max_virtual) {
			openct_add_reader(ctx, i, NULL);
		}
	}

	return SC_SUCCESS;
}
Exemplo n.º 5
0
static int
openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info)
{
	sc_reader_t	*reader;
	scconf_block *conf_block;
	struct driver_data *data;
	int		rc;

	if (!(reader = calloc(1, sizeof(*reader)))
	 || !(data = (calloc(1, sizeof(*data))))) {
		if (reader)
			free(reader);
		return SC_ERROR_OUT_OF_MEMORY;
	}

	if (info) {
		data->info = *info;
	} else {
		strcpy(data->info.ct_name, "OpenCT reader (detached)");
		data->info.ct_slots = 1;
	}
	data->num = num;

	reader->driver = &openct_reader_driver;
	reader->ops = &openct_ops;
	reader->drv_data = data;
	reader->name = strdup(data->info.ct_name);

	conf_block = sc_get_conf_block(ctx, "reader_driver", "openct", 1);
	if (conf_block) {
		reader->max_send_size = scconf_get_int(conf_block, "max_send_size", reader->max_send_size);
		reader->max_recv_size = scconf_get_int(conf_block, "max_recv_size", reader->max_recv_size);
	}

	if ((rc = _sc_add_reader(ctx, reader)) < 0) {
		free(data);
		free(reader->name);
		free(reader);
		return rc;
	}

	if (data->info.ct_display)
		reader->capabilities |= SC_READER_CAP_DISPLAY;
	if (data->info.ct_keypad)
		reader->capabilities |= SC_READER_CAP_PIN_PAD;
	return 0;
}
Exemplo n.º 6
0
static int
load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts)
{
	int err = 0;
	const scconf_list *list;
	const char *val, *s_internal = "internal";
	int debug;
	int reopen;
#ifdef _WIN32
	char expanded_val[PATH_MAX];
	DWORD expanded_len;
#endif

	reopen = scconf_get_bool(block, "reopen_debug_file", 1);

	debug = scconf_get_int(block, "debug", ctx->debug);
	if (debug > ctx->debug)
		ctx->debug = debug;

	val = scconf_get_str(block, "debug_file", NULL);
	if (val)   {
#ifdef _WIN32
		expanded_len = PATH_MAX;
		expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len);
		if (expanded_len > 0)
			val = expanded_val;
#endif
		if (reopen)
			ctx->debug_filename = strdup(val);

		sc_ctx_log_to_file(ctx, val);
	}

	ctx->paranoid_memory = scconf_get_bool (block, "paranoid-memory",
		ctx->paranoid_memory);

	ctx->enable_default_driver = scconf_get_bool (block, "enable_default_driver",
			ctx->enable_default_driver);

	val = scconf_get_str(block, "force_card_driver", NULL);
	if (val) {
		if (opts->forced_card_driver)
			free(opts->forced_card_driver);
		opts->forced_card_driver = strdup(val);
	}

	list = scconf_find_list(block, "card_drivers");
	if (list != NULL)
		del_drvs(opts);
	while (list != NULL) {
		if (strcmp(list->data, s_internal) == 0)
			add_internal_drvs(opts);
		else
			add_drv(opts, list->data);
		list = list->next;
	}

	return err;
}
Exemplo n.º 7
0
void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
{
	scconf_block *conf_block = NULL;
	char *unblock_style = NULL;

	/* Set defaults */
	conf->plug_and_play = 1;
	conf->max_virtual_slots = 16;
	conf->slots_per_card = 4;
	conf->hide_empty_tokens = 1;
	conf->lock_login = 0;
	conf->soft_keygen_allowed = 0;
	conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED;
	conf->create_puk_slot = 0;
	conf->zero_ckaid_for_ca_certs = 0;

	conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1);
	if (!conf_block)
		return;

	/* contains the defaults, if there is a "pkcs11" config block */
	conf->plug_and_play = scconf_get_bool(conf_block, "plug_and_play", conf->plug_and_play);
	conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots);
	conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card);
	conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens);
	conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login);
	conf->soft_keygen_allowed = scconf_get_bool(conf_block, "soft_keygen_allowed", conf->soft_keygen_allowed);

	unblock_style = (char *)scconf_get_str(conf_block, "user_pin_unblock_style", NULL);
	if (unblock_style && !strcmp(unblock_style, "set_pin_in_unlogged_session"))
		conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN;
	else if (unblock_style && !strcmp(unblock_style, "set_pin_in_specific_context"))
		conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN;
	else if (unblock_style && !strcmp(unblock_style, "init_pin_in_so_session"))
		conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN;
	
	conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot);
	conf->zero_ckaid_for_ca_certs = scconf_get_bool(conf_block, "zero_ckaid_for_ca_certs", conf->zero_ckaid_for_ca_certs);

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d "
		 "hide_empty_tokens=%d lock_login=%d pin_unblock_style=%d zero_ckaid_for_ca_certs=%d",
		 conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card,
		 conf->hide_empty_tokens, conf->lock_login, conf->pin_unblock_style,
		 conf->zero_ckaid_for_ca_certs);
}
Exemplo n.º 8
0
Arquivo: ctx.c Projeto: AktivCo/OpenSC
static int
load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts)
{
	int err = 0;
	const scconf_list *list;
	const char *val;
	int debug;
#ifdef _WIN32
	char expanded_val[PATH_MAX];
	DWORD expanded_len;
#endif

	debug = scconf_get_int(block, "debug", ctx->debug);
	if (debug > ctx->debug)
		ctx->debug = debug;

	val = scconf_get_str(block, "debug_file", NULL);
	if (val)   {
#ifdef _WIN32
		expanded_len = PATH_MAX;
		expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len);
		if (0 < expanded_len && expanded_len < sizeof expanded_val)
			val = expanded_val;
#endif
		sc_ctx_log_to_file(ctx, val);
	}
	else if (ctx->debug)   {
		sc_ctx_log_to_file(ctx, NULL);
	}

	if (scconf_get_bool (block, "disable_popups",
				ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS))
		ctx->flags |= SC_CTX_FLAG_DISABLE_POPUPS;

	if (scconf_get_bool (block, "disable_colors",
				ctx->flags & SC_CTX_FLAG_DISABLE_COLORS))
		ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS;

	if (scconf_get_bool (block, "enable_default_driver",
				ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER))
		ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER;

	list = scconf_find_list(block, "card_drivers");
	set_drivers(opts, list);

	return err;
}
Exemplo n.º 9
0
static int load_parameters(sc_context_t *ctx, scconf_block *block,
			   struct _sc_ctx_options *opts)
{
	int err = 0;
	const scconf_list *list;
	const char *val, *s_internal = "internal";
    const char *debug = NULL;

	ctx->debug = scconf_get_int(block, "debug", ctx->debug);
	debug = getenv("OPENSC_DEBUG");
	if (debug)
		ctx->debug = atoi(debug);

	val = scconf_get_str(block, "debug_file", NULL);
	if (val)
		sc_ctx_log_to_file(ctx, val);

	val = scconf_get_str(block, "force_card_driver", NULL);
	if (val) {
		if (opts->forced_card_driver)
			free(opts->forced_card_driver);
		opts->forced_card_driver = strdup(val);
	}

	list = scconf_find_list(block, "card_drivers");
	if (list != NULL)
		del_drvs(opts);
	while (list != NULL) {
		if (strcmp(list->data, s_internal) == 0)
			add_internal_drvs(opts);
		else
			add_drv(opts, list->data);
		list = list->next;
	}

	return err;
}
Exemplo n.º 10
0
static int read_config(scconf_block *blk) {
	int debug = scconf_get_bool(blk,"debug",0);
	const char *ssltls;

	ldaphost = scconf_get_str(blk,"ldaphost",ldaphost);
	ldapport = scconf_get_int(blk,"ldapport",ldapport);
	ldapURI = scconf_get_str(blk,"uri",ldapURI);
	scope = scconf_get_int(blk,"scope",scope);
	binddn = scconf_get_str(blk,"binddn",binddn);
	passwd = scconf_get_str(blk,"passwd",passwd);
	base = scconf_get_str(blk,"base",base);
	attribute = scconf_get_str(blk,"attribute",attribute);
	filter = scconf_get_str(blk,"filter",filter);
	ignorecase = scconf_get_bool(blk,"ignorecase",ignorecase);
	searchtimeout = scconf_get_int(blk,"searchtimeout",searchtimeout);

	ssltls =  scconf_get_str(blk,"ssl","off");
	if (! strncasecmp (ssltls, "tls", 3))
		ssl_on = SSL_START_TLS;
	else if( ! strncasecmp (ssltls, "on", 2))
		ssl_on = SSL_LDAPS;
	else if( ! strncasecmp (ssltls, "ssl", 3))
		ssl_on = SSL_LDAPS;

#if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS))
	/* TLS specific options */
	tls_randfile = scconf_get_str(blk,"tls_randfile",tls_randfile);
	tls_cacertfile = scconf_get_str(blk,"tls_cacertfile",tls_cacertfile);
	tls_cacertdir = scconf_get_str(blk,"tls_cacertdir",tls_cacertdir);
	tls_checkpeer=scconf_get_int(blk,"tls_checkpeer",tls_checkpeer);
	tls_ciphers = scconf_get_str(blk,"tls_ciphers",tls_ciphers);
	tls_cert = scconf_get_str(blk,"tls_cert",tls_cert);
	tls_key = scconf_get_str(blk,"tls_key",tls_key);
#endif


	set_debug_level(debug);
DBG1("test ssltls = %s", ssltls);

	DBG("LDAP mapper started.");
	DBG1("debug         = %d", debug);
	DBG1("ignorecase    = %d", ignorecase);
	DBG1("ldaphost      = %s", ldaphost);
	DBG1("ldapport      = %d", ldapport);
	DBG1("ldapURI       = %s", ldapURI);
	DBG1("scope         = %d", scope);
	DBG1("binddn        = %s", binddn);
	DBG1("passwd        = %s", passwd);
	DBG1("base          = %s", base);
	DBG1("attribute     = %s", attribute);
	DBG1("filter        = %s", filter);
	DBG1("searchtimeout = %d", searchtimeout);
	DBG1("ssl_on        = %d", ssl_on);
#if defined HAVE_LDAP_START_TLS_S || (defined(HAVE_LDAP_SET_OPTION) && defined(LDAP_OPT_X_TLS))
	DBG1("tls_randfile  = %s", tls_randfile);
	DBG1("tls_cacertfile= %s", tls_cacertfile);
	DBG1("tls_cacertdir = %s", tls_cacertdir);
	DBG1("tls_checkpeer = %d", tls_checkpeer);
	DBG1("tls_ciphers   = %s", tls_ciphers);
	DBG1("tls_cert      = %s", tls_cert);
	DBG1("tls_key       = %s", tls_key);
#endif
	return 1;

}
Exemplo n.º 11
0
static int load_card_atrs(sc_context_t *ctx)
{
	struct sc_card_driver *driver;
	scconf_block **blocks;
	int i, j, k;

	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_atr", NULL);
		if (!blocks)
			continue;
		for (j = 0; blocks[j] != NULL; j++) {
			scconf_block *b = blocks[j];
			char *atr = b->name->data;
			const scconf_list *list;
			struct sc_atr_table t;
			const char *dname;

			driver = NULL;

			if (strlen(atr) < 4)
				continue;

			/* The interesting part. If there's no card
			 * driver assigned for the ATR, add it to
			 * the default driver. This will reduce the
			 * amount of code required to process things
			 * related to card_atr blocks in situations,
			 * where the code is not exactly related to
			 * card driver settings, but for example
			 * forcing a protocol at the reader driver.
			 */
			dname = scconf_get_str(b, "driver", "default");

			/* Find the card driver structure according to dname */
			for (k = 0; ctx->card_drivers[k] != NULL; k++) {
				driver = ctx->card_drivers[k];
				if (!strcmp(dname, driver->short_name))
					break;
				driver = NULL;
			}

			if (!driver)
				continue;

			memset(&t, 0, sizeof(struct sc_atr_table));
			t.atr = atr;
			t.atrmask = (char *) scconf_get_str(b, "atrmask", NULL);
			t.name = (char *) scconf_get_str(b, "name", NULL);
			t.type = scconf_get_int(b, "type", SC_CARD_TYPE_UNKNOWN);
			list = scconf_find_list(b, "flags");
			while (list != NULL) {
				unsigned int flags;

				if (!list->data) {
					list = list->next;
					continue;
				}
				flags = 0;
				if (!strcmp(list->data, "rng")) {
					flags = SC_CARD_FLAG_RNG;
				} else {
					if (sscanf(list->data, "%x", &flags) != 1)
						flags = 0;
				}
				t.flags |= flags;
				list = list->next;
			}
			t.card_atr = b;
			_sc_add_atr(ctx, driver, &t);
		}
		free(blocks);
	}
	return SC_SUCCESS;
}
Exemplo n.º 12
0
static int parse_type(const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth)
{
	void *parm = entry->parm;
	size_t *len = (size_t *) entry->arg;
	int (*callback_func) (const scconf_context * config, const scconf_block * block, scconf_entry * entry, int depth) =
	(int (*)(const scconf_context *, const scconf_block *, scconf_entry *, int)) parm;
	int r = 0;

	if (config->debug) {
		fprintf(stderr, "decoding '%s'\n", entry->name);
	}
	switch (entry->type) {
	case SCCONF_CALLBACK:
		if (parm) {
			r = callback_func(config, block, entry, depth);
		}
		break;
	case SCCONF_BLOCK:
		if (parm) {
			r = parse_entries(config, block, (scconf_entry *) parm, depth + 1);
		}
		break;
	case SCCONF_LIST:
		{
			const scconf_list *val = scconf_find_list(block, entry->name);

			if (!val) {
				r = 1;
				break;
			}
			if (parm) {
				if (entry->flags & SCCONF_ALLOC) {
					scconf_list *dest = NULL;

					for (; val != NULL; val = val->next) {
						if (!scconf_list_add(&dest, val->data)) {
							r = 1;
							break;
						}
					}
					*((scconf_list **) parm) = dest;
				} else {
					*((const scconf_list **) parm) = val;
				}
			}
			if (entry->flags & SCCONF_VERBOSE) {
				char *buf = scconf_list_strdup(val, ", ");
				printf("%s = %s\n", entry->name, buf);
				free(buf);
			}
		}
		break;
	case SCCONF_BOOLEAN:
		{
			int val = scconf_get_bool(block, entry->name, 0);

			if (parm) {
				*((int *) parm) = val;
			}
			if (entry->flags & SCCONF_VERBOSE) {
				printf("%s = %s\n", entry->name, val == 0 ? "false" : "true");
			}
		}
		break;
	case SCCONF_INTEGER:
		{
			int val = scconf_get_int(block, entry->name, 0);

			if (parm) {
				*((int *) parm) = val;
			}
			if (entry->flags & SCCONF_VERBOSE) {
				printf("%s = %i\n", entry->name, val);
			}
		}
		break;
	case SCCONF_STRING:
		{
			const char *val = scconf_get_str(block, entry->name, NULL);
			int vallen = val ? strlen(val) : 0;

			if (!vallen) {
				r = 1;
				break;
			}
			if (parm) {
				if (entry->flags & SCCONF_ALLOC) {
					char **buf = (char **) parm;
					*buf = malloc(vallen + 1);
					if (*buf == NULL) {
						r = 1;
						break;
					}
					memset(*buf, 0, vallen + 1);
					if (len) {
						*len = vallen;
					}
					parm = *buf;
				}
				memcpy((char *) parm, val, vallen);
			}
			if (entry->flags & SCCONF_VERBOSE) {
				printf("%s = %s\n", entry->name, val);
			}
		}
		break;
	default:
		fprintf(stderr, "invalid configuration type: %d\n", entry->type);
	}
	if (r) {
		fprintf(stderr, "decoding of configuration entry '%s' failed.\n", entry->name);
		return r;
	}
	entry->flags |= SCCONF_PRESENT;
	return 0;
}
Exemplo n.º 13
0
static int ctapi_load_module(sc_context_t *ctx,
		struct ctapi_global_private_data *gpriv, scconf_block *conf)
{
	const char *val;
	struct ctapi_functions funcs;
	struct ctapi_module *mod;
	const scconf_list *list;
	scconf_block *conf_block = NULL;
	void *dlh;
	int r, i, NumUnits;
	u8 cmd[5], rbuf[256], sad, dad;
	unsigned short lr;

	list = scconf_find_list(conf, "ports");
	if (list == NULL) {
		sc_log(ctx, "No ports configured.");
		return -1;
	}

	val = conf->name->data;
	dlh = sc_dlopen(val);
	if (!dlh) {
		sc_log(ctx, "Unable to open shared library '%s': %s", val, sc_dlerror());
		return -1;
	}

	funcs.CT_init = (CT_INIT_TYPE *) sc_dlsym(dlh, "CT_init");
	if (!funcs.CT_init)
		goto symerr;
	funcs.CT_close = (CT_CLOSE_TYPE *) sc_dlsym(dlh, "CT_close");
	if (!funcs.CT_close)
		goto symerr;
	funcs.CT_data = (CT_DATA_TYPE *) sc_dlsym(dlh, "CT_data");
	if (!funcs.CT_data)
		goto symerr;

	mod = add_module(gpriv, val, dlh);
	if (!mod)
		goto symerr;
	for (; list != NULL; list = list->next) {
		int port;
		char namebuf[128];
		char rv;
		sc_reader_t *reader;
		struct ctapi_private_data *priv;

		if (sscanf(list->data, "%d", &port) != 1) {
			sc_log(ctx, "Port '%s' is not a number.", list->data);
			continue;
		}
		rv = funcs.CT_init((unsigned short)mod->ctn_count, (unsigned short)port);
		if (rv) {
			sc_log(ctx, "CT_init() failed with %d", rv);
			continue;
		}

		reader = calloc(1, sizeof(sc_reader_t));
		priv = calloc(1, sizeof(struct ctapi_private_data));
		if (!priv || !reader) {
			free(reader);
			free(priv);
			return SC_ERROR_OUT_OF_MEMORY;
		}
		reader->drv_data = priv;
		reader->ops = &ctapi_ops;
		reader->driver = &ctapi_drv;
		snprintf(namebuf, sizeof(namebuf), "CT-API %s, port %d", mod->name, port);
		reader->name = strdup(namebuf);
		priv->funcs = funcs;
		priv->ctn = mod->ctn_count;

		reader->max_send_size = SC_READER_SHORT_APDU_MAX_SEND_SIZE;
		reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;

		conf_block = sc_get_conf_block(ctx, "reader_driver", "ctapi", 1);
		if (conf_block) {
			reader->max_send_size = scconf_get_int(conf_block, "max_send_size", reader->max_send_size);
			reader->max_recv_size = scconf_get_int(conf_block, "max_recv_size", reader->max_recv_size);
			if (scconf_get_bool(conf_block, "enable_escape", 0))
				reader->flags |= SC_READER_ENABLE_ESCAPE;
		}

		r = _sc_add_reader(ctx, reader);
		if (r) {
			funcs.CT_close((unsigned short)mod->ctn_count);
			free(priv);
			free(reader->name);
			free(reader);
			break;
		}

		/* Detect functional units of the reader according to CT-BCS spec version 1.0
		(14.04.2004, http://www.teletrust.de/down/mct1-0_t4.zip) */
		cmd[0] = CTBCS_CLA;
		cmd[1] = CTBCS_INS_STATUS;
		cmd[2] = CTBCS_P1_CT_KERNEL;
		cmd[3] = CTBCS_P2_STATUS_TFU;
		cmd[4] = 0x00;
		dad = 1;
		sad = 2;
		lr = 256;

		rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
		if (rv || (lr < 4) || (rbuf[lr-2] != 0x90)) {
			sc_log(reader->ctx, "Error getting status of terminal: %d, using defaults", rv);
		}
		if (rbuf[0] != CTBCS_P2_STATUS_TFU) {
			/* Number of slots might also detected by using CTBCS_P2_STATUS_ICC.
			   If you think that's important please do it... ;) */
			sc_log(reader->ctx, "Invalid data object returned on CTBCS_P2_STATUS_TFU: 0x%x", rbuf[0]);
		}
		NumUnits = rbuf[1];
		if (NumUnits + 4 > lr) {
			sc_log(reader->ctx, "Invalid data returned: %d functional units, size %d", NumUnits, rv);
		}
		priv->ctapi_functional_units = 0;
		for(i = 0; i < NumUnits; i++) {
			switch(rbuf[i+2]) {
				case CTBCS_P1_INTERFACE1:
				case CTBCS_P1_INTERFACE2:
				case CTBCS_P1_INTERFACE3:
				case CTBCS_P1_INTERFACE4:
				case CTBCS_P1_INTERFACE5:
				case CTBCS_P1_INTERFACE6:
				case CTBCS_P1_INTERFACE7:
				case CTBCS_P1_INTERFACE8:
				case CTBCS_P1_INTERFACE9:
				case CTBCS_P1_INTERFACE10:
				case CTBCS_P1_INTERFACE11:
				case CTBCS_P1_INTERFACE12:
				case CTBCS_P1_INTERFACE13:
				case CTBCS_P1_INTERFACE14:
				/* Maybe a weak point here if multiple interfaces are present and not returned
				   in the "canonical" order. This is not forbidden by the specs, but why should
				   anyone want to do that? */
					sc_log(reader->ctx, "Found slot id 0x%x", rbuf[i+2]);
					break;

				case CTBCS_P1_DISPLAY:
					priv->ctapi_functional_units |= CTAPI_FU_DISPLAY;
					sc_log(reader->ctx, "Display detected");
					break;

				case CTBCS_P1_KEYPAD:
					priv->ctapi_functional_units |= CTAPI_FU_KEYBOARD;
					sc_log(reader->ctx, "Keypad detected");
					break;

				case CTBCS_P1_PRINTER:
					priv->ctapi_functional_units |= CTAPI_FU_PRINTER;
					sc_log(reader->ctx, "Printer detected");
					break;

				case CTBCS_P1_FINGERPRINT:
				case CTBCS_P1_VOICEPRINT:
				case CTBCS_P1_DSV:
				case CTBCS_P1_FACE_RECOGNITION:
				case CTBCS_P1_IRISSCAN:
					priv->ctapi_functional_units |= CTAPI_FU_BIOMETRIC;
					sc_log(reader->ctx, "Biometric sensor detected");
					break;

				default:
					sc_log(reader->ctx, "Unknown functional unit 0x%x", rbuf[i+2]);
			}
		}
		/* CT-BCS does not define Keyboard/Display for each slot, so I assume
		those additional units can be used for each slot */
		if (priv->ctapi_functional_units) {
			if (priv->ctapi_functional_units & CTAPI_FU_KEYBOARD)
				reader->capabilities |= SC_READER_CAP_PIN_PAD;
			if (priv->ctapi_functional_units & CTAPI_FU_DISPLAY)
				reader->capabilities |= SC_READER_CAP_DISPLAY;
		}

		ctapi_reset(reader);
		refresh_attributes(reader);
		mod->ctn_count++;
	}
	return 0;
symerr:
	sc_log(ctx, "Unable to resolve CT-API symbols.");
	sc_dlclose(dlh);
	return -1;
}
Exemplo n.º 14
0
void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t * ctx)
{
	scconf_block *conf_block = NULL;
	char *unblock_style = NULL;
	char *create_slots_for_pins = NULL, *op, *tmp;

	/* Set defaults */
	conf->plug_and_play = 1;
	conf->max_virtual_slots = 16;
	if (strcmp(ctx->app_name, "onepin-opensc-pkcs11") == 0) {
		conf->slots_per_card = 1;
	} else {
		conf->slots_per_card = 4;
	}
	conf->hide_empty_tokens = 1;
	conf->lock_login = 0;
	conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_NOT_ALLOWED;
	conf->create_puk_slot = 0;
	conf->zero_ckaid_for_ca_certs = 0;
	conf->create_slots_flags = SC_PKCS11_SLOT_CREATE_ALL;

	conf_block = sc_get_conf_block(ctx, "pkcs11", NULL, 1);
	if (!conf_block)
		return;

	/* contains the defaults, if there is a "pkcs11" config block */
	conf->plug_and_play = scconf_get_bool(conf_block, "plug_and_play", conf->plug_and_play);
	conf->max_virtual_slots = scconf_get_int(conf_block, "max_virtual_slots", conf->max_virtual_slots);
	conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card);
	conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens);
	conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login);

	unblock_style = (char *)scconf_get_str(conf_block, "user_pin_unblock_style", NULL);
	if (unblock_style && !strcmp(unblock_style, "set_pin_in_unlogged_session"))
		conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_UNLOGGED_SETPIN;
	else if (unblock_style && !strcmp(unblock_style, "set_pin_in_specific_context"))
		conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SCONTEXT_SETPIN;
	else if (unblock_style && !strcmp(unblock_style, "init_pin_in_so_session"))
		conf->pin_unblock_style = SC_PKCS11_PIN_UNBLOCK_SO_LOGGED_INITPIN;

	conf->create_puk_slot = scconf_get_bool(conf_block, "create_puk_slot", conf->create_puk_slot);
	conf->zero_ckaid_for_ca_certs = scconf_get_bool(conf_block, "zero_ckaid_for_ca_certs", conf->zero_ckaid_for_ca_certs);

	create_slots_for_pins = (char *)scconf_get_str(conf_block, "create_slots_for_pins", "all");
	conf->create_slots_flags = 0;
	tmp = strdup(create_slots_for_pins);
	op = strtok(tmp, " ,");
	while (op) {
		if (!strcmp(op, "user"))
			conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_PIN_USER;
		else if (!strcmp(op, "sign"))
			conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_PIN_SIGN;
		else if (!strcmp(op, "application"))
			conf->create_slots_flags |= SC_PKCS11_SLOT_FOR_APPLICATION;
		else if (!strcmp(op, "all"))
			conf->create_slots_flags |= SC_PKCS11_SLOT_CREATE_ALL;
		op = strtok(NULL, " ,");
	}
        free(tmp);

	sc_log(ctx, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d "
		 "hide_empty_tokens=%d lock_login=%d pin_unblock_style=%d "
		 "zero_ckaid_for_ca_certs=%d create_slots_flags=0x%X",
		 conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card,
		 conf->hide_empty_tokens, conf->lock_login, conf->pin_unblock_style,
		 conf->zero_ckaid_for_ca_certs, conf->create_slots_flags);
}