예제 #1
0
파일: ctx.c 프로젝트: Hubitronic/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, *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;
}
예제 #2
0
파일: ctx.c 프로젝트: 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;
}
예제 #3
0
mapper_module * mapper_module_init(scconf_block *blk,const char *mapper_name) {
#else
mapper_module * uid_mapper_module_init(scconf_block *blk,const char *mapper_name) {
#endif
	mapper_module *pt;
        if (blk) {
		debug= scconf_get_bool(blk,"debug",0);
	mapfile = scconf_get_str(blk,"mapfile",mapfile);
        ignorecase = scconf_get_bool(blk,"ignorecase",ignorecase);
	} else {
		DBG1("No block declaration for mapper '%s'", mapper_name);
	}
        set_debug_level(debug);
	pt= init_mapper_st(blk,mapper_name);
        if(pt) DBG3("UniqueID mapper started. debug: %d, mapfile: %s, icase: %d",debug,mapfile,ignorecase);
	else DBG("UniqueID mapper initialization failed");
        return pt;
}
예제 #4
0
mapper_module * mapper_module_init(scconf_block *ctx,const char *mapper_name) {
#else
mapper_module * null_mapper_module_init(scconf_block *ctx,const char *mapper_name) {
#endif
	mapper_module *pt= NULL;
	if (ctx) {
	default_user = scconf_get_str( ctx,"default_user",default_user);
	match = scconf_get_bool( ctx,"default_match",0);
		debug = scconf_get_bool( ctx,"debug",0);
	} else {
		DBG1("No block declaration for mapper '%s'", mapper_name);
	}
	set_debug_level(debug);
	pt = init_mapper_st(ctx,mapper_name);
	if (pt) DBG1("Null mapper match set to '%s'",match?"always":"never");
	else DBG("Null mapper initialization failed");
	return pt;
}
예제 #5
0
mapper_module * mapper_module_init(scconf_block *blk,const char *mapper_name) {
#else
mapper_module * krb_mapper_module_init(scconf_block *blk,const char *mapper_name) {
#endif
	mapper_module *pt;
	if( blk) debug = scconf_get_bool(blk,"debug",0);
	set_debug_level(debug);
	pt=init_mapper_st(blk,mapper_name);
	if(pt) DBG("KPN mappper started");
	else DBG("KPN mapper initialization failed");
	return pt;
}
예제 #6
0
파일: dialog.c 프로젝트: securez/opendnie
/**
 * Parse configuration file to extract user consent flags
 */
static int get_user_consent_env(sc_context_t *ctx) {
    int i;
    scconf_block **blocks, *blk;
    for (i = 0; ctx->conf_blocks[i]; i++) {
        blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],"card_driver","dnie");
        if (!blocks) continue;
        blk=blocks[0];
        free(blocks);
        if (blk==NULL) continue;
        user_consent_app = scconf_get_str(blk,"user_consent_app",PIN_ENTRY); 
        user_consent_enabled = scconf_get_bool(blk,"user_consent_enabled",1);
    }
    return SC_SUCCESS;
}
예제 #7
0
파일: misc.c 프로젝트: securez/opendnie
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);
}
예제 #8
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;

}
예제 #9
0
파일: slot.c 프로젝트: llogar/OpenSC
CK_RV card_detect(sc_reader_t *reader)
{
	struct sc_pkcs11_card *p11card = NULL;
	int free_p11card = 0;
	int rc;
	CK_RV rv;
	unsigned int i;
	int j;

	sc_log(context, "%s: Detecting smart card", reader->name);
	/* Check if someone inserted a card */
again:
	rc = sc_detect_card_presence(reader);
	if (rc < 0) {
		sc_log(context, "%s: failed, %s", reader->name, sc_strerror(rc));
		return sc_to_cryptoki_error(rc, NULL);
	}
	if (rc == 0) {
		sc_log(context, "%s: card absent", reader->name);
		card_removed(reader);	/* Release all resources */
		return CKR_TOKEN_NOT_PRESENT;
	}

	/* If the card was changed, disconnect the current one */
	if (rc & SC_READER_CARD_CHANGED) {
		sc_log(context, "%s: Card changed", reader->name);
		/* The following should never happen - but if it
		 * does we'll be stuck in an endless loop.
		 * So better be fussy.
		if (!retry--)
			return CKR_TOKEN_NOT_PRESENT; */
		card_removed(reader);
		goto again;
	}

	/* Locate a slot related to the reader */
	for (i=0; i<list_size(&virtual_slots); i++) {
		sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
		if (slot->reader == reader) {
			p11card = slot->p11card;
			break;
		}
	}

	/* Detect the card if it's not known already */
	if (p11card == NULL) {
		sc_log(context, "%s: First seen the card ", reader->name);
		p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card));
		if (!p11card)
			return CKR_HOST_MEMORY;
		free_p11card = 1;
		p11card->reader = reader;
	}

	if (p11card->card == NULL) {
		sc_log(context, "%s: Connecting ... ", reader->name);
		rc = sc_connect_card(reader, &p11card->card);
		if (rc != SC_SUCCESS) {
			sc_log(context, "%s: SC connect card error %i", reader->name, rc);
			rv = sc_to_cryptoki_error(rc, NULL);
			goto fail;
		}

		/* escape commands are only guaranteed to be working with a card
		 * inserted. That's why by now, after sc_connect_card() the reader's
		 * metadata may have changed. We re-initialize the metadata for every
		 * slot of this reader here. */
		if (reader->flags & SC_READER_ENABLE_ESCAPE) {
			for (i = 0; i<list_size(&virtual_slots); i++) {
				sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
				if (slot->reader == reader)
					init_slot_info(&slot->slot_info, reader);
			}
		}

		sc_log(context, "%s: Connected SC card %p", reader->name, p11card->card);
	}

	/* Detect the framework */
	if (p11card->framework == NULL) {
		struct sc_app_info *app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic");

		sc_log(context, "%s: Detecting Framework. %i on-card applications", reader->name, p11card->card->app_count);
		sc_log(context, "%s: generic application %s", reader->name, app_generic ? app_generic->label : "<none>");

		for (i = 0; frameworks[i]; i++)
			if (frameworks[i]->bind != NULL)
				break;
		/*TODO: only first framework is used: pkcs15init framework is not reachable here */
		if (frameworks[i] == NULL) {
			rv = CKR_GENERAL_ERROR;
			goto fail;
		}

		p11card->framework = frameworks[i];

		/* Initialize framework */
		sc_log(context, "%s: Detected framework %d. Creating tokens.", reader->name, i);
		/* Bind 'generic' application or (emulated?) card without applications */
		if (app_generic || !p11card->card->app_count)   {
			scconf_block *conf_block = NULL;
			int enable_InitToken = 0;

			conf_block = sc_match_atr_block(p11card->card->ctx, NULL,
				&p11card->reader->atr);
			if (!conf_block) /* check default block */
				conf_block = sc_get_conf_block(context,
					"framework", "pkcs15", 1);

			enable_InitToken = scconf_get_bool(conf_block,
				"pkcs11_enable_InitToken", 0);

			sc_log(context, "%s: Try to bind 'generic' token.", reader->name);
			rv = frameworks[i]->bind(p11card, app_generic);
			if (rv == CKR_TOKEN_NOT_RECOGNIZED && enable_InitToken)   {
				sc_log(context, "%s: 'InitToken' enabled -- accept non-binded card", reader->name);
				rv = CKR_OK;
			}
			if (rv != CKR_OK)   {
				sc_log(context,
				       "%s: cannot bind 'generic' token: rv 0x%lX",
				       reader->name, rv);
				goto fail;
			}

			sc_log(context, "%s: Creating 'generic' token.", reader->name);
			rv = frameworks[i]->create_tokens(p11card, app_generic);
			if (rv != CKR_OK)   {
				sc_log(context,
				       "%s: create 'generic' token error 0x%lX",
				       reader->name, rv);
				goto fail;
			}
		}

		/* Now bind the rest of applications that are not 'generic' */
		for (j = 0; j < p11card->card->app_count; j++)   {
			struct sc_app_info *app_info = p11card->card->app[j];
			char *app_name = app_info ? app_info->label : "<anonymous>";

			if (app_generic && app_generic == p11card->card->app[j])
				continue;

			sc_log(context, "%s: Binding %s token.", reader->name, app_name);
			rv = frameworks[i]->bind(p11card, app_info);
			if (rv != CKR_OK)   {
				sc_log(context, "%s: bind %s token error Ox%lX",
				       reader->name, app_name, rv);
				continue;
			}

			sc_log(context, "%s: Creating %s token.", reader->name, app_name);
			rv = frameworks[i]->create_tokens(p11card, app_info);
			if (rv != CKR_OK)   {
				sc_log(context,
				       "%s: create %s token error 0x%lX",
				       reader->name, app_name, rv);
				goto fail;
			}
		}
	}

	sc_log(context, "%s: Detection ended", reader->name);
	return CKR_OK;

fail:
	if (free_p11card) {
		if (p11card->framework)
			p11card->framework->unbind(p11card);
		if (p11card->card != NULL)
			sc_disconnect_card(p11card->card);
		free(p11card);
	}

	return rv;
}
static int pcsc_init(sc_context_t *ctx, void **reader_data)
{
	struct pcsc_global_private_data *gpriv;
	scconf_block *conf_block = NULL;
	int ret = SC_ERROR_INTERNAL;

	*reader_data = NULL;

	gpriv = (struct pcsc_global_private_data *) calloc(1, sizeof(struct pcsc_global_private_data));
	if (gpriv == NULL) {
		ret = SC_ERROR_OUT_OF_MEMORY;
		goto out;
	}

	/* Defaults */
	gpriv->connect_reset = 1;
	gpriv->connect_exclusive = 0;
	gpriv->transaction_reset = 0;
	gpriv->enable_pinpad = 0;
	gpriv->provider_library = DEFAULT_PCSC_PROVIDER;
	gpriv->pcsc_ctx = -1;
	
	conf_block = sc_get_conf_block(ctx, "reader_driver", "pcsc", 1);
	if (conf_block) {
		gpriv->connect_reset =
		    scconf_get_bool(conf_block, "connect_reset", gpriv->connect_reset);
		gpriv->connect_exclusive =
		    scconf_get_bool(conf_block, "connect_exclusive", gpriv->connect_exclusive);
		gpriv->transaction_reset =
		    scconf_get_bool(conf_block, "transaction_reset", gpriv->transaction_reset);
		gpriv->enable_pinpad =
		    scconf_get_bool(conf_block, "enable_pinpad", gpriv->enable_pinpad);
		gpriv->provider_library =
		    scconf_get_str(conf_block, "provider_library", gpriv->provider_library);
	}

	gpriv->dlhandle = lt_dlopen(gpriv->provider_library);
	if (gpriv->dlhandle == NULL) {
		ret = SC_ERROR_CANNOT_LOAD_MODULE;
		goto out;
	}

	gpriv->SCardEstablishContext = (SCardEstablishContext_t)lt_dlsym(gpriv->dlhandle, "SCardEstablishContext");
	gpriv->SCardReleaseContext = (SCardReleaseContext_t)lt_dlsym(gpriv->dlhandle, "SCardReleaseContext");
	gpriv->SCardConnect = (SCardConnect_t)lt_dlsym(gpriv->dlhandle, "SCardConnect");
	gpriv->SCardReconnect = (SCardReconnect_t)lt_dlsym(gpriv->dlhandle, "SCardReconnect");
	gpriv->SCardDisconnect = (SCardDisconnect_t)lt_dlsym(gpriv->dlhandle, "SCardDisconnect");
	gpriv->SCardBeginTransaction = (SCardBeginTransaction_t)lt_dlsym(gpriv->dlhandle, "SCardBeginTransaction");
	gpriv->SCardEndTransaction = (SCardEndTransaction_t)lt_dlsym(gpriv->dlhandle, "SCardEndTransaction");
	gpriv->SCardStatus = (SCardStatus_t)lt_dlsym(gpriv->dlhandle, "SCardStatus");
	gpriv->SCardGetStatusChange = (SCardGetStatusChange_t)lt_dlsym(gpriv->dlhandle, "SCardGetStatusChange");
	gpriv->SCardTransmit = (SCardTransmit_t)lt_dlsym(gpriv->dlhandle, "SCardTransmit");
	gpriv->SCardListReaders = (SCardListReaders_t)lt_dlsym(gpriv->dlhandle, "SCardListReaders");

	if (gpriv->SCardConnect == NULL)
		gpriv->SCardConnect = (SCardConnect_t)lt_dlsym(gpriv->dlhandle, "SCardConnectA");
	if (gpriv->SCardStatus == NULL)
		gpriv->SCardStatus = (SCardStatus_t)lt_dlsym(gpriv->dlhandle, "SCardStatusA");
	if (gpriv->SCardGetStatusChange == NULL)
		gpriv->SCardGetStatusChange = (SCardGetStatusChange_t)lt_dlsym(gpriv->dlhandle, "SCardGetStatusChangeA");
	if (gpriv->SCardListReaders == NULL)
		gpriv->SCardListReaders = (SCardListReaders_t)lt_dlsym(gpriv->dlhandle, "SCardListReadersA");
	
	/* If we have SCardGetAttrib it is correct API */
	if (lt_dlsym(gpriv->dlhandle, "SCardGetAttrib") != NULL) {
#ifdef __APPLE__
		gpriv->SCardControl = (SCardControl_t)lt_dlsym(gpriv->dlhandle, "SCardControl132");
#endif
		if (gpriv->SCardControl == NULL) {
			gpriv->SCardControl = (SCardControl_t)lt_dlsym(gpriv->dlhandle, "SCardControl");
		}
	}
	else {
		gpriv->SCardControlOLD = (SCardControlOLD_t)lt_dlsym(gpriv->dlhandle, "SCardControl");
	}

	if (
		gpriv->SCardReleaseContext == NULL ||
		gpriv->SCardConnect == NULL ||
		gpriv->SCardReconnect == NULL ||
		gpriv->SCardDisconnect == NULL ||
		gpriv->SCardBeginTransaction == NULL ||
		gpriv->SCardEndTransaction == NULL ||
		gpriv->SCardStatus == NULL ||
		gpriv->SCardGetStatusChange == NULL ||
		(gpriv->SCardControl == NULL && gpriv->SCardControlOLD == NULL) ||
		gpriv->SCardTransmit == NULL ||
		gpriv->SCardListReaders == NULL
	) {
		ret = SC_ERROR_CANNOT_LOAD_MODULE;
		goto out;
	}

	*reader_data = gpriv;
	gpriv = NULL;
	ret = SC_SUCCESS;

out:
	if (gpriv != NULL) {
		if (gpriv->dlhandle != NULL)
			lt_dlclose(gpriv->dlhandle);
		free(gpriv);
	}

	return ret;
}
예제 #11
0
파일: scconf.c 프로젝트: BradPID/OpenSC
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;
}
예제 #12
0
int sc_pkcs15_bind(sc_card_t *card,
		   struct sc_pkcs15_card **p15card_out)
{
	struct sc_pkcs15_card *p15card = NULL;
	sc_context_t *ctx;
	scconf_block *conf_block = NULL, **blocks;
	int    i, r, emu_first, enable_emu;

	assert(sc_card_valid(card) && p15card_out != NULL);
	ctx = card->ctx;
	SC_FUNC_CALLED(ctx, 1);
	p15card = sc_pkcs15_card_new();
	if (p15card == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	p15card->card = card;

	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
			"framework", "pkcs15");
		if (blocks && blocks[0] != NULL)
			conf_block = blocks[0];
		free(blocks);
	}

	if (conf_block) {
		p15card->opts.use_cache = scconf_get_bool(conf_block, "use_caching", 0);
	}

	r = sc_lock(card);
	if (r) {
		sc_error(ctx, "sc_lock() failed: %s\n", sc_strerror(r));
		sc_pkcs15_card_free(p15card);
		SC_FUNC_RETURN(ctx, 1, r);
	}

	enable_emu = scconf_get_bool(conf_block, "enable_pkcs15_emulation", 1);
	if (enable_emu) {
		emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
		if (emu_first || sc_pkcs15_is_emulation_only(card)) {
			r = sc_pkcs15_bind_synthetic(p15card);
			if (r == SC_SUCCESS)
				goto done;
			r = sc_pkcs15_bind_internal(p15card);
			if (r < 0)
				goto error;
		} else {
			r = sc_pkcs15_bind_internal(p15card);
			if (r == SC_SUCCESS)
				goto done;
			r = sc_pkcs15_bind_synthetic(p15card);
			if (r < 0)
				goto error;
		}
	} else {
		r = sc_pkcs15_bind_internal(p15card);
		if (r < 0)
			goto error;
	}
done:
	*p15card_out = p15card;
	sc_unlock(card);
	return 0;
error:
	sc_unlock(card);
	sc_pkcs15_card_free(p15card);
	SC_FUNC_RETURN(ctx, 1, r);
}
예제 #13
0
int
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
{
	sc_context_t		*ctx = p15card->card->ctx;
	scconf_block		*conf_block, **blocks, *blk;
	sc_pkcs15emu_opt_t	opts;
	int			i, r = SC_ERROR_WRONG_CARD;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	memset(&opts, 0, sizeof(opts));
	conf_block = NULL;

	conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);

	if (!conf_block) {
		/* no conf file found => try bultin drivers  */
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no conf file (or section), trying all builtin emulators\n");
		for (i = 0; builtin_emulators[i].name; i++) {
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", builtin_emulators[i].name);
			r = builtin_emulators[i].handler(p15card, &opts);
			if (r == SC_SUCCESS)
				/* we got a hit */
				goto out;
		}
	} else {
		/* we have a conf file => let's use it */
		int builtin_enabled; 
		const scconf_list *list, *item;

		builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
		list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */

		if (builtin_enabled && list) {
			/* get the list of enabled emulation drivers */
			for (item = list; item; item = item->next) {
				/* go through the list of builtin drivers */
				const char *name = item->data;

				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", name);
				for (i = 0; builtin_emulators[i].name; i++)
					if (!strcmp(builtin_emulators[i].name, name)) {
						r = builtin_emulators[i].handler(p15card, &opts);
						if (r == SC_SUCCESS)
							/* we got a hit */
							goto out;
					}
			}	
		}
		else if (builtin_enabled) {
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no emulator list in config file, trying all builtin emulators\n");
			for (i = 0; builtin_emulators[i].name; i++) {
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", builtin_emulators[i].name);
				r = builtin_emulators[i].handler(p15card, &opts);
				if (r == SC_SUCCESS)
					/* we got a hit */
					goto out;
			}
		}

		/* search for 'emulate foo { ... }' entries in the conf file */
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "searching for 'emulate foo { ... }' blocks\n");
		blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
		for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
			const char *name = blk->name->data;
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", name);
			r = parse_emu_block(p15card, blk);
			if (r == SC_SUCCESS) {
				free(blocks);
				goto out;
			}
		}
		if (blocks)
			free(blocks);
	}
		
	/* Total failure */
	return SC_ERROR_WRONG_CARD;

out:	if (r == SC_SUCCESS) {
		p15card->magic  = SC_PKCS15_CARD_MAGIC;
		p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
	} else if (r != SC_ERROR_WRONG_CARD) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to load card emulator: %s\n",
				sc_strerror(r));
	}

	return r;
}
예제 #14
0
static int belpic_init(sc_card_t *card)
{
	struct belpic_priv_data *priv = NULL;
	scconf_block *conf_block;
#ifdef BELPIC_PIN_PAD
	int r;
#endif

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Belpic V%s", BELPIC_VERSION);
#ifdef HAVE_GUI
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with GUI support");
#endif
#ifdef BELPIC_PIN_PAD
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, " with support for pin pad reader libs");
#endif
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "\n");

	if (card->type < 0)
		card->type = SC_CARD_TYPE_BELPIC_EID;	/* Unknown card: assume it's the Belpic Card */

	priv = calloc(1, sizeof(struct belpic_priv_data));
	if (priv == NULL)
		return SC_ERROR_OUT_OF_MEMORY;
	card->drv_data = priv;
	card->cla = 0x00;
	if (card->type == SC_CARD_TYPE_BELPIC_EID) {
		_sc_card_add_rsa_alg(card, 1024,
				     SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE, 0);
	}

	/* V1 applets have a problem: if the card sends a 6C XX (only XX bytes available),
	 * and we resend the command too soon (i.e. the reader is too fast), the card
	 * doesn't respond. So we build in a delay. */
	card->wait_resend_apdu = 40;

	/* State that we have an RNG */
	card->caps |= SC_CARD_CAP_RNG;
	/* State that we don't return FCI (no file type, no file size, ...) */
	card->caps |= SC_CARD_CAP_NO_FCI;

	/* Language prefences */
	priv->lang = -1;
	conf_block = get_belpic_conf(card->ctx, "belpic_general");
	if (conf_block != NULL) {
		char *lang = (char *) scconf_get_str(conf_block, "force_language", NULL);
		if (lang != NULL && strlen(lang) == 2)
			priv->lang = str2lang(card->ctx, lang);
	}
#ifdef GET_LANG_FROM_CARD
	if (priv->lang == -1)
		priv->lang = get_language(card);
#endif

	card->max_pin_len = BELPIC_MAX_USER_PIN_LEN;

#ifdef HAVE_GUI
	r = scgui_init();
	if (r != 0)
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_init() returned error %d\n", i);
#endif

#ifdef BELPIC_PIN_PAD
	r = belpic_detect_pin_pad(card, priv);
	if (r == 1)
		card->reader->capabilities |= SC_READER_CAP_PIN_PAD;
	else if (r < 0)
		return r;	/* error loading/initing pin pad lib */

	conf_block = get_belpic_conf(card->ctx, "belpic_pin_pad");
	if (conf_block != NULL) {
		if (scconf_get_bool(conf_block, "msg_auth_pin", 1))
			priv->options |= PP_MSG_AUTH_PIN;
		if (scconf_get_bool(conf_block, "msg_wrong_pin", 1))
			priv->options |= PP_MSG_WRONG_PIN;
		if (scconf_get_bool(conf_block, "msg_changepin_mismatch", 1))
			priv->options |= PP_MSG_CHANGEPIN_MISMATCH;
		if (scconf_get_bool(conf_block, "msg_pin_blocked", 1))
			priv->options |= PP_MSG_PIN_BLOCKED;
	}
#endif

	return 0;
}
예제 #15
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;
}
예제 #16
0
파일: misc.c 프로젝트: Ecordonnier/OpenSC
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);
}