const struct hostapd_eap_user * hostapd_get_eap_user(struct hostapd_data *hapd, const u8 *identity, size_t identity_len, int phase2) { const struct hostapd_bss_config *conf = hapd->conf; struct hostapd_eap_user *user = conf->eap_user; #ifdef CONFIG_WPS if (conf->wps_state && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) { static struct hostapd_eap_user wsc_enrollee; os_memset(&wsc_enrollee, 0, sizeof(wsc_enrollee)); wsc_enrollee.methods[0].method = eap_server_get_type( "WSC", &wsc_enrollee.methods[0].vendor); return &wsc_enrollee; } if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) { static struct hostapd_eap_user wsc_registrar; os_memset(&wsc_registrar, 0, sizeof(wsc_registrar)); wsc_registrar.methods[0].method = eap_server_get_type( "WSC", &wsc_registrar.methods[0].vendor); wsc_registrar.password = (u8 *) conf->ap_pin; wsc_registrar.password_len = conf->ap_pin ? os_strlen(conf->ap_pin) : 0; return &wsc_registrar; } #endif /* CONFIG_WPS */ while (user) { if (!phase2 && user->identity == NULL) { /* Wildcard match */ break; } if (user->phase2 == !!phase2 && user->wildcard_prefix && identity_len >= user->identity_len && os_memcmp(user->identity, identity, user->identity_len) == 0) { /* Wildcard prefix match */ break; } if (user->phase2 == !!phase2 && user->identity_len == identity_len && os_memcmp(user->identity, identity, identity_len) == 0) break; user = user->next; } #ifdef CONFIG_SQLITE if (user == NULL && conf->eap_user_sqlite) { return eap_user_sqlite_get(hapd, identity, identity_len, phase2); } #endif /* CONFIG_SQLITE */ return user; }
static void set_user_methods(struct hostapd_eap_user *user, const char *methods) { char *buf, *start; int num_methods; buf = os_strdup(methods); if (buf == NULL) return; os_memset(&user->methods, 0, sizeof(user->methods)); num_methods = 0; start = buf; while (*start) { char *pos3 = os_strchr(start, ','); if (pos3) *pos3++ = '\0'; user->methods[num_methods].method = eap_server_get_type(start, &user->methods[num_methods].vendor); if (user->methods[num_methods].vendor == EAP_VENDOR_IETF && user->methods[num_methods].method == EAP_TYPE_NONE) { if (os_strcmp(start, "TTLS-PAP") == 0) { user->ttls_auth |= EAP_TTLS_AUTH_PAP; goto skip_eap; } if (os_strcmp(start, "TTLS-CHAP") == 0) { user->ttls_auth |= EAP_TTLS_AUTH_CHAP; goto skip_eap; } if (os_strcmp(start, "TTLS-MSCHAP") == 0) { user->ttls_auth |= EAP_TTLS_AUTH_MSCHAP; goto skip_eap; } if (os_strcmp(start, "TTLS-MSCHAPV2") == 0) { user->ttls_auth |= EAP_TTLS_AUTH_MSCHAPV2; goto skip_eap; } wpa_printf(MSG_INFO, "DB: Unsupported EAP type '%s'", start); os_free(buf); return; } num_methods++; if (num_methods >= EAP_MAX_METHODS) break; skip_eap: if (pos3 == NULL) break; start = pos3; } os_free(buf); }
/* * 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; }