/** * rsn_preauth_init - Start new RSN pre-authentication * @sm: Pointer to WPA state machine data from wpa_sm_init() * @dst: Authenticator address (BSSID) with which to preauthenticate * @eap_conf: Current EAP configuration * Returns: 0 on success, -1 on another pre-authentication is in progress, * -2 on layer 2 packet initialization failure, -3 on EAPOL state machine * initialization failure, -4 on memory allocation failure * * This function request an RSN pre-authentication with a given destination * address. This is usually called for PMKSA candidates found from scan results * or from driver reports. In addition, ctrl_iface PREAUTH command can trigger * pre-authentication. */ int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst, struct eap_peer_config *eap_conf) { struct eapol_config eapol_conf; struct eapol_ctx *ctx; if (sm->preauth_eapol) return -1; wpa_msg(sm->ctx->ctx, MSG_DEBUG, "RSN: starting pre-authentication " "with " MACSTR, MAC2STR(dst)); sm->l2_preauth = l2_packet_init(sm->ifname, sm->own_addr, ETH_P_RSN_PREAUTH, rsn_preauth_receive, sm, 0); if (sm->l2_preauth == NULL) { wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 packet " "processing for pre-authentication"); return -2; } if (sm->bridge_ifname) { sm->l2_preauth_br = l2_packet_init(sm->bridge_ifname, sm->own_addr, ETH_P_RSN_PREAUTH, rsn_preauth_receive, sm, 0); if (sm->l2_preauth_br == NULL) { wpa_printf(MSG_WARNING, "RSN: Failed to initialize L2 " "packet processing (bridge) for " "pre-authentication"); return -2; } } ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) { wpa_printf(MSG_WARNING, "Failed to allocate EAPOL context."); return -4; } ctx->ctx = sm->ctx->ctx; ctx->msg_ctx = sm->ctx->ctx; ctx->preauth = 1; ctx->cb = rsn_preauth_eapol_cb; ctx->cb_ctx = sm; ctx->scard_ctx = sm->scard_ctx; ctx->eapol_send = rsn_preauth_eapol_send; ctx->eapol_send_ctx = sm; ctx->set_config_blob = sm->ctx->set_config_blob; ctx->get_config_blob = sm->ctx->get_config_blob; sm->preauth_eapol = eapol_sm_init(ctx); if (sm->preauth_eapol == NULL) { os_free(ctx); wpa_printf(MSG_WARNING, "RSN: Failed to initialize EAPOL " "state machines for pre-authentication"); return -3; } os_memset(&eapol_conf, 0, sizeof(eapol_conf)); eapol_conf.accept_802_1x_keys = 0; eapol_conf.required_keys = 0; eapol_conf.fast_reauth = sm->fast_reauth; eapol_conf.workaround = sm->eap_workaround; eapol_sm_notify_config(sm->preauth_eapol, eap_conf, &eapol_conf); /* * Use a shorter startPeriod with preauthentication since the first * preauth EAPOL-Start frame may end up being dropped due to race * condition in the AP between the data receive and key configuration * after the 4-Way Handshake. */ eapol_sm_configure(sm->preauth_eapol, -1, -1, 5, 6); os_memcpy(sm->preauth_bssid, dst, ETH_ALEN); eapol_sm_notify_portValid(sm->preauth_eapol, TRUE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(sm->preauth_eapol, TRUE); eloop_register_timeout(sm->dot11RSNAConfigSATimeout, 0, rsn_preauth_timeout, sm, NULL); return 0; }
static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { struct eapol_config eapol_conf; struct eapol_ctx *ctx; struct wpa_sm_ctx *wctx; ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) { printf("Failed to allocate EAPOL context.\n"); return -1; } ctx->ctx = e; ctx->msg_ctx = wpa_s; ctx->scard_ctx = wpa_s->scard; ctx->cb = eapol_sm_cb; ctx->cb_ctx = e; ctx->eapol_send_ctx = wpa_s; ctx->preauth = 0; ctx->eapol_done_cb = eapol_test_eapol_done_cb; ctx->eapol_send = eapol_test_eapol_send; ctx->set_config_blob = eapol_test_set_config_blob; ctx->get_config_blob = eapol_test_get_config_blob; ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path; ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path; ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path; ctx->openssl_ciphers = wpa_s->conf->openssl_ciphers; ctx->eap_param_needed = eapol_test_eap_param_needed; ctx->cert_cb = eapol_test_cert_cb; ctx->cert_in_cb = 1; ctx->set_anon_id = eapol_test_set_anon_id; wpa_s->eapol = eapol_sm_init(ctx); if (wpa_s->eapol == NULL) { os_free(ctx); printf("Failed to initialize EAPOL state machines.\n"); return -1; } wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA; wctx = os_zalloc(sizeof(*wctx)); if (wctx == NULL) { os_free(ctx); return -1; } wctx->ctx = e; wctx->msg_ctx = wpa_s; wctx->get_state = eapol_test_get_state; wpa_s->wpa = wpa_sm_init(wctx); if (!wpa_s->wpa) { os_free(ctx); os_free(wctx); return -1; } if (!ssid) return 0; wpa_s->current_ssid = ssid; os_memset(&eapol_conf, 0, sizeof(eapol_conf)); eapol_conf.accept_802_1x_keys = 1; eapol_conf.required_keys = 0; eapol_conf.fast_reauth = wpa_s->conf->fast_reauth; eapol_conf.workaround = ssid->eap_workaround; eapol_conf.external_sim = wpa_s->conf->external_sim; eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf); eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); return 0; }