/* * read the config section and load all the eap authentication types present. */ static int eap_instantiate(CONF_SECTION *cs, void **instance) { int i, num_types; int has_tls, do_tls; rlm_eap_t *inst; CONF_SECTION *scs; inst = (rlm_eap_t *) malloc(sizeof(*inst)); if (!inst) { return -1; } memset(inst, 0, sizeof(*inst)); if (cf_section_parse(cs, inst, module_config) < 0) { eap_detach(inst); return -1; } /* * Create our own random pool. */ for (i = 0; i < 256; i++) { inst->rand_pool.randrsl[i] = fr_rand(); } fr_randinit(&inst->rand_pool, 1); /* * List of sessions are set to NULL by the memset * of 'inst', above. */ /* * Lookup sessions in the tree. We don't free them in * the tree, as that's taken care of elsewhere... */ inst->session_tree = rbtree_create(eap_handler_cmp, NULL, 0); if (!inst->session_tree) { radlog(L_ERR|L_CONS, "rlm_eap2: Cannot initialize tree"); eap_detach(inst); return -1; } /* * This registers ALL available methods. * * FIXME: we probably want to selectively register * some methods. */ if (eap_server_register_methods() < 0) { eap_detach(inst); return -1; } /* Load all the configured EAP-Types */ num_types = 0; has_tls = do_tls = 0; for (scs=cf_subsection_find_next(cs, NULL, NULL); scs != NULL; scs=cf_subsection_find_next(cs, scs, NULL)) { const char *auth_type; char buffer[64], *p; auth_type = cf_section_name1(scs); if (!auth_type) continue; if (num_types >= EAP_MAX_METHODS) { radlog(L_INFO, "WARNING: Ignoring EAP type %s: too many types defined", auth_type); continue; } /* * Hostapd doesn't do case-insensitive comparisons. * So we mash everything to uppercase for it. */ strlcpy(buffer, auth_type, sizeof(buffer)); for (p = buffer; *p; p++) { if (!islower((int)*p)) continue; *p = toupper((int)*p); } inst->methods[num_types] = eap_server_get_type(buffer, &inst->vendors[num_types]); if (inst->methods[num_types] == EAP_TYPE_NONE) { radlog(L_ERR|L_CONS, "rlm_eap2: Unknown EAP type %s", auth_type); eap_detach(inst); return -1; } switch (inst->methods[num_types]) { case EAP_TYPE_TLS: has_tls = TRUE; /* FALL-THROUGH */ case EAP_TYPE_TTLS: case EAP_TYPE_PEAP: case EAP_TYPE_FAST: do_tls = TRUE; break; default: break; } num_types++; /* successfully loaded one more types */ } inst->num_types = num_types; if (do_tls && !has_tls) { radlog(L_ERR|L_CONS, "rlm_eap2: TLS has not been configured. Cannot do methods that need TLS."); eap_detach(inst); return -1; } if (do_tls) { /* * Initialize TLS. */ if (eap_example_server_init_tls(inst) < 0) { radlog(L_ERR|L_CONS, "rlm_eap2: Cannot initialize TLS"); eap_detach(inst); return -1; } } pthread_mutex_init(&(inst->session_mutex), NULL); *instance = inst; return 0; }
/* * read the config section and load all the eap authentication types present. */ static int eap_instantiate(CONF_SECTION *cs, void **instance) { int i, eap_type; int num_types; CONF_SECTION *scs; rlm_eap_t *inst; inst = (rlm_eap_t *) malloc(sizeof(*inst)); if (!inst) { return -1; } memset(inst, 0, sizeof(*inst)); if (cf_section_parse(cs, inst, module_config) < 0) { eap_detach(inst); return -1; } /* * Create our own random pool. */ for (i = 0; i < 256; i++) { inst->rand_pool.randrsl[i] = fr_rand(); } fr_randinit(&inst->rand_pool, 1); inst->rand_pool.randcnt = 0; inst->xlat_name = cf_section_name2(cs); if (!inst->xlat_name) inst->xlat_name = "EAP"; /* Load all the configured EAP-Types */ num_types = 0; for(scs=cf_subsection_find_next(cs, NULL, NULL); scs != NULL; scs=cf_subsection_find_next(cs, scs, NULL)) { const char *auth_type; auth_type = cf_section_name1(scs); if (!auth_type) continue; if (!strcmp(auth_type, TLS_CONFIG_SECTION)) continue; eap_type = eaptype_name2type(auth_type); if (eap_type < 0) { radlog(L_ERR, "rlm_eap: Unknown EAP type %s", auth_type); eap_detach(inst); return -1; } #ifndef HAVE_OPENSSL_SSL_H /* * This allows the default configuration to be * shipped with EAP-TLS, etc. enabled. If the * system doesn't have OpenSSL, they will be * ignored. * * If the system does have OpenSSL, then this * code will not be used. The administrator will * then have to delete the tls, * etc. configurations from eap.conf in order to * have EAP without the TLS types. */ if ((eap_type == PW_EAP_TLS) || (eap_type == PW_EAP_TTLS) || (eap_type == PW_EAP_PEAP)) { DEBUG2("Ignoring EAP-Type/%s because we do not have OpenSSL support.", auth_type); continue; } #endif /* * Load the type. */ if (eaptype_load(&inst->types[eap_type], eap_type, scs) < 0) { eap_detach(inst); return -1; } num_types++; /* successfully loaded one more types */ } if (num_types == 0) { radlog(L_ERR|L_CONS, "rlm_eap: No EAP type configured, module cannot do anything."); eap_detach(inst); return -1; } /* * Ensure that the default EAP type is loaded. */ eap_type = eaptype_name2type(inst->default_eap_type_name); if (eap_type < 0) { radlog(L_ERR|L_CONS, "rlm_eap: Unknown default EAP type %s", inst->default_eap_type_name); eap_detach(inst); return -1; } if (inst->types[eap_type] == NULL) { radlog(L_ERR|L_CONS, "rlm_eap: No such sub-type for default EAP type %s", inst->default_eap_type_name); eap_detach(inst); return -1; } inst->default_eap_type = eap_type; /* save the numerical type */ /* * List of sessions are set to NULL by the memset * of 'inst', above. */ /* * Lookup sessions in the tree. We don't free them in * the tree, as that's taken care of elsewhere... */ inst->session_tree = rbtree_create(eap_handler_cmp, NULL, 0); if (!inst->session_tree) { radlog(L_ERR|L_CONS, "rlm_eap: Cannot initialize tree"); eap_detach(inst); return -1; } if (fr_debug_flag) { inst->handler_tree = rbtree_create(eap_handler_ptr_cmp, NULL, 0); if (!inst->handler_tree) { radlog(L_ERR|L_CONS, "rlm_eap: Cannot initialize tree"); eap_detach(inst); return -1; } #ifdef HAVE_PTHREAD_H if (pthread_mutex_init(&(inst->handler_mutex), NULL) < 0) { radlog(L_ERR|L_CONS, "rlm_eap: Failed initializing mutex: %s", strerror(errno)); eap_detach(inst); return -1; } #endif } #ifdef HAVE_PTHREAD_H if (pthread_mutex_init(&(inst->session_mutex), NULL) < 0) { radlog(L_ERR|L_CONS, "rlm_eap: Failed initializing mutex: %s", strerror(errno)); eap_detach(inst); return -1; } #endif *instance = inst; return 0; }