mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-22 09:06:27 +00:00
wpa_supplicant: Add WPS registrar support for softAP mode
This commit is contained in:
@@ -11,9 +11,9 @@
|
||||
|
||||
#include "common/defs.h"
|
||||
#include "utils/list.h"
|
||||
#include "eap_common/eap_defs.h"
|
||||
#include "eap_peer/eap_defs.h"
|
||||
#include "eap_server/eap_methods.h"
|
||||
#include "wpabuf.h"
|
||||
#include "utils/wpabuf.h"
|
||||
|
||||
struct eap_sm;
|
||||
|
||||
@@ -66,6 +66,7 @@ struct eap_eapol_interface {
|
||||
size_t eapSessionIdLen;
|
||||
bool eapKeyAvailable; /* called keyAvailable in IEEE 802.1X-2004 */
|
||||
|
||||
#ifndef ESP_SUPPLICANT
|
||||
/* AAA interface to full authenticator variables */
|
||||
bool aaaEapReq;
|
||||
bool aaaEapNoReq;
|
||||
@@ -82,6 +83,7 @@ struct eap_eapol_interface {
|
||||
struct wpabuf *aaaEapRespData;
|
||||
/* aaaIdentity -> eap_get_identity() */
|
||||
bool aaaTimeout;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct eap_server_erp_key {
|
||||
|
@@ -9,9 +9,9 @@
|
||||
#ifndef EAP_I_H
|
||||
#define EAP_I_H
|
||||
|
||||
#include "wpabuf.h"
|
||||
#include "utils/wpabuf.h"
|
||||
#include "eap_server/eap.h"
|
||||
#include "eap_common/eap_common.h"
|
||||
#include "eap_peer/eap_common.h"
|
||||
|
||||
/* RFC 4137 - EAP Standalone Authenticator */
|
||||
|
||||
|
@@ -9,7 +9,7 @@
|
||||
#ifndef EAP_SERVER_METHODS_H
|
||||
#define EAP_SERVER_METHODS_H
|
||||
|
||||
#include "eap_common/eap_defs.h"
|
||||
#include "eap_peer/eap_defs.h"
|
||||
|
||||
const struct eap_method * eap_server_get_eap_method(int vendor,
|
||||
enum eap_type method);
|
||||
|
@@ -29,7 +29,9 @@ static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
|
||||
int eapSRTT, int eapRTTVAR,
|
||||
int methodTimeout);
|
||||
static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp);
|
||||
#ifndef ESP_SUPPLICANT
|
||||
static int eap_sm_getId(const struct wpabuf *data);
|
||||
#endif
|
||||
static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id);
|
||||
static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id);
|
||||
static int eap_sm_nextId(struct eap_sm *sm, int id);
|
||||
@@ -43,8 +45,6 @@ static bool eap_sm_Policy_doPickUp(struct eap_sm *sm, enum eap_type method);
|
||||
|
||||
static int eap_get_erp_send_reauth_start(struct eap_sm *sm)
|
||||
{
|
||||
if (sm->eapol_cb->get_erp_send_reauth_start)
|
||||
return sm->eapol_cb->get_erp_send_reauth_start(sm->eapol_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src)
|
||||
}
|
||||
|
||||
|
||||
#ifndef ESP_SUPPLICANT
|
||||
static int eap_copy_data(u8 **dst, size_t *dst_len,
|
||||
const u8 *src, size_t src_len)
|
||||
{
|
||||
@@ -137,6 +138,7 @@ static int eap_copy_data(u8 **dst, size_t *dst_len,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define EAP_COPY(dst, src) \
|
||||
eap_copy_data((dst), (dst ## Len), (src), (src ## Len))
|
||||
@@ -994,6 +996,7 @@ fail:
|
||||
#endif /* CONFIG_ERP */
|
||||
|
||||
|
||||
#ifndef ESP_SUPPLICANT
|
||||
SM_STATE(EAP, INITIALIZE_PASSTHROUGH)
|
||||
{
|
||||
SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);
|
||||
@@ -1161,6 +1164,7 @@ SM_STATE(EAP, SUCCESS2)
|
||||
wpa_msg(sm->cfg->msg_ctx, MSG_INFO, WPA_EVENT_EAP_SUCCESS2 MACSTR,
|
||||
MAC2STR(sm->peer_addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
SM_STEP(EAP)
|
||||
@@ -1346,8 +1350,10 @@ SM_STEP(EAP)
|
||||
SM_ENTER(EAP, FAILURE);
|
||||
else if (sm->decision == DECISION_SUCCESS)
|
||||
SM_ENTER(EAP, SUCCESS);
|
||||
#ifndef ESP_SUPPLICANT
|
||||
else if (sm->decision == DECISION_PASSTHROUGH)
|
||||
SM_ENTER(EAP, INITIALIZE_PASSTHROUGH);
|
||||
#endif
|
||||
else if (sm->decision == DECISION_INITIATE_REAUTH_START)
|
||||
SM_ENTER(EAP, INITIATE_REAUTH_START);
|
||||
#ifdef CONFIG_ERP
|
||||
@@ -1370,7 +1376,7 @@ SM_STEP(EAP)
|
||||
break;
|
||||
case EAP_SUCCESS:
|
||||
break;
|
||||
|
||||
#ifndef ESP_SUPPLICANT
|
||||
case EAP_INITIALIZE_PASSTHROUGH:
|
||||
if (sm->currentId == -1)
|
||||
SM_ENTER(EAP, AAA_IDLE);
|
||||
@@ -1423,6 +1429,10 @@ SM_STEP(EAP)
|
||||
break;
|
||||
case EAP_SUCCESS2:
|
||||
break;
|
||||
#else
|
||||
default:
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1545,6 +1555,7 @@ static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp)
|
||||
}
|
||||
|
||||
|
||||
#ifndef ESP_SUPPLICANT
|
||||
static int eap_sm_getId(const struct wpabuf *data)
|
||||
{
|
||||
const struct eap_hdr *hdr;
|
||||
@@ -1556,7 +1567,7 @@ static int eap_sm_getId(const struct wpabuf *data)
|
||||
wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier);
|
||||
return hdr->identifier;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id)
|
||||
{
|
||||
@@ -1873,6 +1884,7 @@ struct eap_sm * eap_server_sm_init(void *eapol_ctx,
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
sm->tls_test_flags = sess->tls_test_flags;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
sm->eap_if.portEnabled = 1;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
|
||||
|
||||
@@ -1901,9 +1913,11 @@ void eap_server_sm_deinit(struct eap_sm *sm)
|
||||
wpabuf_free(sm->eap_if.eapRespData);
|
||||
os_free(sm->identity);
|
||||
os_free(sm->serial_num);
|
||||
#ifndef ESP_SUPPLICANT
|
||||
wpabuf_free(sm->eap_if.aaaEapReqData);
|
||||
wpabuf_free(sm->eap_if.aaaEapRespData);
|
||||
bin_clear_free(sm->eap_if.aaaEapKeyData, sm->eap_if.aaaEapKeyDataLen);
|
||||
#endif
|
||||
eap_user_free(sm->user);
|
||||
wpabuf_free(sm->assoc_wps_ie);
|
||||
wpabuf_free(sm->assoc_p2p_ie);
|
||||
|
@@ -123,7 +123,7 @@ static void eap_identity_process(struct eap_sm *sm, void *priv,
|
||||
buf = os_malloc(len * 4 + 1);
|
||||
if (buf) {
|
||||
printf_encode(buf, len * 4 + 1, pos, len);
|
||||
eap_log_msg(sm, "EAP-Response/Identity '%s'", buf);
|
||||
wpa_printf(MSG_DEBUG, "EAP-Response/Identity '%s'", buf);
|
||||
os_free(buf);
|
||||
}
|
||||
if (sm->identity)
|
||||
|
@@ -12,12 +12,12 @@
|
||||
#include "eloop.h"
|
||||
#include "eap_i.h"
|
||||
#include "eap_common/eap_wsc_common.h"
|
||||
#include "p2p/p2p.h"
|
||||
#include "wps/wps.h"
|
||||
#include "esp_wps_i.h"
|
||||
|
||||
|
||||
struct eap_wsc_data {
|
||||
enum { START, MESG, FRAG_ACK, WAIT_FRAG_ACK, DONE, FAIL } state;
|
||||
enum { START, MESG, FRAG_ACK, WAIT_FRAG_ACK, DONE, WSC_FAIL } state;
|
||||
int registrar;
|
||||
struct wpabuf *in_buf;
|
||||
struct wpabuf *out_buf;
|
||||
@@ -28,8 +28,7 @@ struct eap_wsc_data {
|
||||
int ext_reg_timeout;
|
||||
};
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_STDOUT_DEBUG
|
||||
#ifdef DEBUG_PRINT
|
||||
static const char * eap_wsc_state_txt(int state)
|
||||
{
|
||||
switch (state) {
|
||||
@@ -43,14 +42,13 @@ static const char * eap_wsc_state_txt(int state)
|
||||
return "WAIT_FRAG_ACK";
|
||||
case DONE:
|
||||
return "DONE";
|
||||
case FAIL:
|
||||
case WSC_FAIL:
|
||||
return "FAIL";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
||||
|
||||
#endif
|
||||
|
||||
static void eap_wsc_state(struct eap_wsc_data *data, int state)
|
||||
{
|
||||
@@ -61,26 +59,10 @@ static void eap_wsc_state(struct eap_wsc_data *data, int state)
|
||||
}
|
||||
|
||||
|
||||
static void eap_wsc_ext_reg_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
struct eap_sm *sm = eloop_ctx;
|
||||
struct eap_wsc_data *data = timeout_ctx;
|
||||
|
||||
if (sm->method_pending != METHOD_PENDING_WAIT)
|
||||
return;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Timeout while waiting for an External "
|
||||
"Registrar");
|
||||
data->ext_reg_timeout = 1;
|
||||
eap_sm_pending_cb(sm);
|
||||
}
|
||||
|
||||
|
||||
static void * eap_wsc_init(struct eap_sm *sm)
|
||||
{
|
||||
struct eap_wsc_data *data;
|
||||
int registrar;
|
||||
struct wps_config cfg;
|
||||
|
||||
if (sm->identity && sm->identity_len == WSC_ID_REGISTRAR_LEN &&
|
||||
os_memcmp(sm->identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) ==
|
||||
@@ -102,52 +84,13 @@ static void * eap_wsc_init(struct eap_sm *sm)
|
||||
data->state = registrar ? START : MESG;
|
||||
data->registrar = registrar;
|
||||
|
||||
os_memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.wps = sm->cfg->wps;
|
||||
cfg.registrar = registrar;
|
||||
if (registrar) {
|
||||
if (!sm->cfg->wps || !sm->cfg->wps->registrar) {
|
||||
wpa_printf(MSG_INFO, "EAP-WSC: WPS Registrar not "
|
||||
"initialized");
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (sm->user == NULL || sm->user->password == NULL) {
|
||||
/*
|
||||
* In theory, this should not really be needed, but
|
||||
* Windows 7 uses Registrar mode to probe AP's WPS
|
||||
* capabilities before trying to use Enrollee and fails
|
||||
* if the AP does not allow that probing to happen..
|
||||
*/
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: No AP PIN (password) "
|
||||
"configured for Enrollee functionality - "
|
||||
"allow for probing capabilities (M1)");
|
||||
} else {
|
||||
cfg.pin = sm->user->password;
|
||||
cfg.pin_len = sm->user->password_len;
|
||||
}
|
||||
}
|
||||
cfg.assoc_wps_ie = sm->assoc_wps_ie;
|
||||
cfg.peer_addr = sm->peer_addr;
|
||||
#ifdef CONFIG_P2P
|
||||
if (sm->assoc_p2p_ie) {
|
||||
if (!sm->cfg->wps->use_passphrase) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-WSC: Prefer PSK format for non-6 GHz P2P client");
|
||||
cfg.use_psk_key = 1;
|
||||
}
|
||||
cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie);
|
||||
}
|
||||
#endif /* CONFIG_P2P */
|
||||
cfg.pbc_in_m1 = sm->cfg->pbc_in_m1;
|
||||
data->wps = wps_init(&cfg);
|
||||
struct wps_sm *wps_sm = wps_sm_get();
|
||||
data->wps = wps_sm->wps;
|
||||
if (data->wps == NULL) {
|
||||
os_free(data);
|
||||
return NULL;
|
||||
}
|
||||
data->fragment_size = sm->cfg->fragment_size > 0 ?
|
||||
sm->cfg->fragment_size : WSC_FRAGMENT_SIZE;
|
||||
data->fragment_size = WSC_FRAGMENT_SIZE;
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -156,7 +99,6 @@ static void * eap_wsc_init(struct eap_sm *sm)
|
||||
static void eap_wsc_reset(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_wsc_data *data = priv;
|
||||
eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
|
||||
wpabuf_free(data->in_buf);
|
||||
wpabuf_free(data->out_buf);
|
||||
wps_deinit(data->wps);
|
||||
@@ -297,13 +239,13 @@ static int eap_wsc_process_cont(struct eap_wsc_data *data,
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d in "
|
||||
"fragment (expected %d)",
|
||||
op_code, data->in_op_code);
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > wpabuf_tailroom(data->in_buf)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment overflow");
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -358,9 +300,8 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
|
||||
enum wps_process_res res;
|
||||
struct wpabuf tmpbuf;
|
||||
|
||||
eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
|
||||
if (data->ext_reg_timeout) {
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -397,7 +338,7 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
|
||||
if (op_code != WSC_FRAG_ACK) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
|
||||
"in WAIT_FRAG_ACK state", op_code);
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
return;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment acknowledged");
|
||||
@@ -409,13 +350,13 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
|
||||
op_code != WSC_Done) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
|
||||
op_code);
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data->in_buf &&
|
||||
eap_wsc_process_cont(data, pos, end - pos, op_code) < 0) {
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -423,7 +364,7 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
|
||||
if (eap_wsc_process_fragment(data, flags, op_code,
|
||||
message_length, pos, end - pos) <
|
||||
0)
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
else
|
||||
eap_wsc_state(data, FRAG_ACK);
|
||||
return;
|
||||
@@ -440,21 +381,20 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
|
||||
case WPS_DONE:
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing completed "
|
||||
"successfully - report EAP failure");
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
break;
|
||||
case WPS_CONTINUE:
|
||||
eap_wsc_state(data, MESG);
|
||||
break;
|
||||
case WPS_FAILURE:
|
||||
wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing failed");
|
||||
eap_wsc_state(data, FAIL);
|
||||
eap_wsc_state(data, WSC_FAIL);
|
||||
break;
|
||||
case WPS_PENDING:
|
||||
eap_wsc_state(data, MESG);
|
||||
sm->method_pending = METHOD_PENDING_WAIT;
|
||||
eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
|
||||
eloop_register_timeout(5, 0, eap_wsc_ext_reg_timeout,
|
||||
sm, data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -467,7 +407,7 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
|
||||
static bool eap_wsc_isDone(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_wsc_data *data = priv;
|
||||
return data->state == FAIL;
|
||||
return data->state == WSC_FAIL;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user