summaryrefslogtreecommitdiffstats
path: root/contrib/hostapd
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/hostapd')
-rw-r--r--contrib/hostapd/eap.c29
-rw-r--r--contrib/hostapd/eap.h9
-rw-r--r--contrib/hostapd/eapol_sm.c162
-rw-r--r--contrib/hostapd/ieee802_1x.c221
-rw-r--r--contrib/hostapd/ieee802_1x.h20
-rw-r--r--contrib/hostapd/wpa.c112
6 files changed, 141 insertions, 412 deletions
diff --git a/contrib/hostapd/eap.c b/contrib/hostapd/eap.c
index a20147e..1897856 100644
--- a/contrib/hostapd/eap.c
+++ b/contrib/hostapd/eap.c
@@ -10,6 +10,8 @@
* license.
*
* See README and COPYING for more details.
+ *
+ * $FreeBSD$
*/
#include <stdlib.h>
@@ -24,7 +26,6 @@
#include "sta_info.h"
#include "eap_i.h"
-#define EAP_MAX_AUTH_ROUNDS 50
extern const struct eap_method eap_method_identity;
#ifdef EAP_MD5
@@ -51,12 +52,6 @@ extern const struct eap_method eap_method_ttls;
#ifdef EAP_SIM
extern const struct eap_method eap_method_sim;
#endif /* EAP_SIM */
-#ifdef EAP_PAX
-extern const struct eap_method eap_method_pax;
-#endif /* EAP_PAX */
-#ifdef EAP_PSK
-extern const struct eap_method eap_method_psk;
-#endif /* EAP_PSK */
static const struct eap_method *eap_methods[] =
{
@@ -85,12 +80,6 @@ static const struct eap_method *eap_methods[] =
#ifdef EAP_SIM
&eap_method_sim,
#endif /* EAP_SIM */
-#ifdef EAP_PAX
- &eap_method_pax,
-#endif /* EAP_PAX */
-#ifdef EAP_PSK
- &eap_method_psk,
-#endif /* EAP_PSK */
};
#define NUM_EAP_METHODS (sizeof(eap_methods) / sizeof(eap_methods[0]))
@@ -210,7 +199,6 @@ int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
SM_STATE(EAP, DISABLED)
{
SM_ENTRY(EAP, DISABLED);
- sm->num_rounds = 0;
}
@@ -246,7 +234,6 @@ SM_STATE(EAP, INITIALIZE)
sm->currentId = sm->respId;
}
}
- sm->num_rounds = 0;
}
@@ -303,7 +290,6 @@ SM_STATE(EAP, RECEIVED)
/* parse rxResp, respId, respMethod */
eap_sm_parseEapResp(sm, sm->eapRespData, sm->eapRespDataLen);
- sm->num_rounds++;
}
@@ -519,15 +505,7 @@ SM_STEP(EAP)
SM_ENTER_GLOBAL(EAP, INITIALIZE);
else if (!eapol_get_bool(sm, EAPOL_portEnabled))
SM_ENTER_GLOBAL(EAP, DISABLED);
- else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
- if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
- wpa_printf(MSG_DEBUG, "EAP: more than %d "
- "authentication rounds - abort",
- EAP_MAX_AUTH_ROUNDS);
- sm->num_rounds++;
- SM_ENTER_GLOBAL(EAP, FAILURE);
- }
- } else switch (sm->EAP_state) {
+ else switch (sm->EAP_state) {
case EAP_INITIALIZE:
if (sm->backend_auth) {
if (!sm->rxResp)
@@ -934,7 +912,6 @@ void eap_sm_deinit(struct eap_sm *sm)
free(sm);
}
-
void eap_sm_notify_cached(struct eap_sm *sm)
{
if (sm == NULL)
diff --git a/contrib/hostapd/eap.h b/contrib/hostapd/eap.h
index c5c62eb..c79bffe 100644
--- a/contrib/hostapd/eap.h
+++ b/contrib/hostapd/eap.h
@@ -1,3 +1,5 @@
+/* $FreeBSD$ */
+
#ifndef EAP_H
#define EAP_H
@@ -30,7 +32,6 @@ struct eapol_callbacks {
size_t eapKeyDataLen);
int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
int phase2, struct eap_user *user);
- const char * (*get_eap_req_id_text)(void *ctx, size_t *len);
};
struct eap_config {
@@ -40,7 +41,7 @@ struct eap_config {
};
-#ifdef EAP_SERVER
+#ifdef EAP_AUTHENTICATOR
struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
struct eap_config *eap_conf);
@@ -51,7 +52,7 @@ void eap_set_eapRespData(struct eap_sm *sm, const u8 *eapRespData,
size_t eapRespDataLen);
void eap_sm_notify_cached(struct eap_sm *sm);
-#else /* EAP_SERVER */
+#else /* EAP_AUTHENTICATOR */
static inline struct eap_sm * eap_sm_init(void *eapol_ctx,
struct eapol_callbacks *eapol_cb,
@@ -84,6 +85,6 @@ static inline void eap_sm_notify_cached(struct eap_sm *sm)
{
}
-#endif /* EAP_SERVER */
+#endif /* EAP_AUTHENTICATOR */
#endif /* EAP_H */
diff --git a/contrib/hostapd/eapol_sm.c b/contrib/hostapd/eapol_sm.c
index f2d5ec7..50c645a 100644
--- a/contrib/hostapd/eapol_sm.c
+++ b/contrib/hostapd/eapol_sm.c
@@ -11,6 +11,8 @@
* license.
*
* See README and COPYING for more details.
+ *
+ * $FreeBSD$
*/
#include <stdlib.h>
@@ -66,9 +68,6 @@ static void sm_ ## machine ## _Step(struct eapol_state_machine *sm)
#define SM_STEP_RUN(machine) sm_ ## machine ## _Step(sm)
-static void eapol_sm_step_run(struct eapol_state_machine *sm);
-static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx);
-
/* Port Timers state machine - implemented as a function that will be called
* once a second as a registered event loop timeout */
@@ -77,34 +76,19 @@ static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
{
struct eapol_state_machine *state = timeout_ctx;
- if (state->aWhile > 0) {
+ if (state->aWhile > 0)
state->aWhile--;
- if (state->aWhile == 0) {
- wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
- " - aWhile --> 0",
- MAC2STR(state->addr));
- }
- }
-
- if (state->quietWhile > 0) {
+ if (state->quietWhile > 0)
state->quietWhile--;
- if (state->quietWhile == 0) {
- wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
- " - quietWhile --> 0",
- MAC2STR(state->addr));
- }
- }
-
- if (state->reAuthWhen > 0) {
+ if (state->reAuthWhen > 0)
state->reAuthWhen--;
- if (state->reAuthWhen == 0) {
- wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
- " - reAuthWhen --> 0",
- MAC2STR(state->addr));
- }
- }
- eapol_sm_step_run(state);
+ if (state->hapd->conf->debug >= HOSTAPD_DEBUG_MSGDUMPS)
+ printf("IEEE 802.1X: " MACSTR " Port Timers TICK "
+ "(timers: %d %d %d)\n", MAC2STR(state->addr),
+ state->aWhile, state->quietWhile, state->reAuthWhen);
+
+ eapol_sm_step(state);
eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, state);
}
@@ -375,19 +359,6 @@ SM_STATE(BE_AUTH, REQUEST)
txReq();
sm->be_auth.eapReq = FALSE;
sm->be_auth.backendOtherRequestsToSupplicant++;
-
- /*
- * Clearing eapolEap here is not specified in IEEE Std 802.1X-2004, but
- * it looks like this would be logical thing to do there since the old
- * EAP response would not be valid anymore after the new EAP request
- * was sent out.
- *
- * A race condition has been reported, in which hostapd ended up
- * sending out EAP-Response/Identity as a response to the first
- * EAP-Request from the main EAP method. This can be avoided by
- * clearing eapolEap here.
- */
- sm->eapolEap = FALSE;
}
@@ -734,7 +705,7 @@ eapol_sm_alloc(hostapd *hapd, struct sta_info *sta)
else
sm->portValid = TRUE;
- if (hapd->conf->eap_server) {
+ if (hapd->conf->eap_authenticator) {
struct eap_config eap_conf;
memset(&eap_conf, 0, sizeof(eap_conf));
eap_conf.ssl_ctx = hapd->ssl_ctx;
@@ -758,7 +729,6 @@ void eapol_sm_free(struct eapol_state_machine *sm)
return;
eloop_cancel_timeout(eapol_port_timers_tick, sm->hapd, sm);
- eloop_cancel_timeout(eapol_sm_step_cb, sm, NULL);
if (sm->eap)
eap_sm_deinit(sm->eap);
free(sm);
@@ -775,63 +745,55 @@ static int eapol_sm_sta_entry_alive(struct hostapd_data *hapd, u8 *addr)
}
-static void eapol_sm_step_run(struct eapol_state_machine *sm)
+void eapol_sm_step(struct eapol_state_machine *sm)
{
struct hostapd_data *hapd = sm->hapd;
u8 addr[ETH_ALEN];
int prev_auth_pae, prev_be_auth, prev_reauth_timer, prev_auth_key_tx,
prev_key_rx, prev_ctrl_dir;
- int max_steps = 100;
- memcpy(addr, sm->sta->addr, ETH_ALEN);
+ /* FIX: could re-run eapol_sm_step from registered timeout (after
+ * 0 sec) to make sure that other possible timeouts/events are
+ * processed */
- /*
- * Allow EAPOL state machines to run as long as there are state
- * changes, but exit and return here through event loop if more than
- * 100 steps is needed as a precaution against infinite loops inside
- * eloop callback.
- */
+ memcpy(addr, sm->sta->addr, ETH_ALEN);
restart:
- prev_auth_pae = sm->auth_pae.state;
- prev_be_auth = sm->be_auth.state;
- prev_reauth_timer = sm->reauth_timer.state;
- prev_auth_key_tx = sm->auth_key_tx.state;
- prev_key_rx = sm->key_rx.state;
- prev_ctrl_dir = sm->ctrl_dir.state;
-
- SM_STEP_RUN(AUTH_PAE);
- if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
+ do {
+ prev_auth_pae = sm->auth_pae.state;
+ prev_be_auth = sm->be_auth.state;
+ prev_reauth_timer = sm->reauth_timer.state;
+ prev_auth_key_tx = sm->auth_key_tx.state;
+ prev_key_rx = sm->key_rx.state;
+ prev_ctrl_dir = sm->ctrl_dir.state;
+
+ SM_STEP_RUN(AUTH_PAE);
+ if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
+ break;
SM_STEP_RUN(BE_AUTH);
- if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
+ if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
+ break;
SM_STEP_RUN(REAUTH_TIMER);
- if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
+ if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
+ break;
SM_STEP_RUN(AUTH_KEY_TX);
- if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
+ if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
+ break;
SM_STEP_RUN(KEY_RX);
- if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
+ if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
+ break;
SM_STEP_RUN(CTRL_DIR);
-
- if (prev_auth_pae != sm->auth_pae.state ||
- prev_be_auth != sm->be_auth.state ||
- prev_reauth_timer != sm->reauth_timer.state ||
- prev_auth_key_tx != sm->auth_key_tx.state ||
- prev_key_rx != sm->key_rx.state ||
- prev_ctrl_dir != sm->ctrl_dir.state) {
- if (--max_steps > 0)
- goto restart;
- /* Re-run from eloop timeout */
- eapol_sm_step(sm);
- return;
- }
+ if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
+ break;
+ } while (prev_auth_pae != sm->auth_pae.state ||
+ prev_be_auth != sm->be_auth.state ||
+ prev_reauth_timer != sm->reauth_timer.state ||
+ prev_auth_key_tx != sm->auth_key_tx.state ||
+ prev_key_rx != sm->key_rx.state ||
+ prev_ctrl_dir != sm->ctrl_dir.state);
if (eapol_sm_sta_entry_alive(hapd, addr) && sm->eap) {
- if (eap_sm_step(sm->eap)) {
- if (--max_steps > 0)
- goto restart;
- /* Re-run from eloop timeout */
- eapol_sm_step(sm);
- return;
- }
+ if (eap_sm_step(sm->eap))
+ goto restart;
}
if (eapol_sm_sta_entry_alive(hapd, addr))
@@ -839,34 +801,15 @@ restart:
}
-static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct eapol_state_machine *sm = eloop_ctx;
- eapol_sm_step_run(sm);
-}
-
-
-void eapol_sm_step(struct eapol_state_machine *sm)
-{
- /*
- * Run eapol_sm_step_run from a registered timeout to make sure that
- * other possible timeouts/events are processed and to avoid long
- * function call chains.
- */
-
- eloop_register_timeout(0, 0, eapol_sm_step_cb, sm, NULL);
-}
-
-
void eapol_sm_initialize(struct eapol_state_machine *sm)
{
sm->initializing = TRUE;
/* Initialize the state machines by asserting initialize and then
* deasserting it after one step */
sm->initialize = TRUE;
- eapol_sm_step_run(sm);
+ eapol_sm_step(sm);
sm->initialize = FALSE;
- eapol_sm_step_run(sm);
+ eapol_sm_step(sm);
sm->initializing = FALSE;
/* Start one second tick for port timers state machine */
@@ -1240,14 +1183,6 @@ static int eapol_sm_get_eap_user(void *ctx, const u8 *identity,
}
-static const char * eapol_sm_get_eap_req_id_text(void *ctx, size_t *len)
-{
- struct eapol_state_machine *sm = ctx;
- *len = sm->hapd->conf->eap_req_id_text_len;
- return sm->hapd->conf->eap_req_id_text;
-}
-
-
static struct eapol_callbacks eapol_cb =
{
.get_bool = eapol_sm_get_bool,
@@ -1255,5 +1190,4 @@ static struct eapol_callbacks eapol_cb =
.set_eapReqData = eapol_sm_set_eapReqData,
.set_eapKeyData = eapol_sm_set_eapKeyData,
.get_eap_user = eapol_sm_get_eap_user,
- .get_eap_req_id_text = eapol_sm_get_eap_req_id_text,
};
diff --git a/contrib/hostapd/ieee802_1x.c b/contrib/hostapd/ieee802_1x.c
index fa44d82..ef1bde4 100644
--- a/contrib/hostapd/ieee802_1x.c
+++ b/contrib/hostapd/ieee802_1x.c
@@ -11,6 +11,8 @@
* license.
*
* See README and COPYING for more details.
+ *
+ * $FreeBSD$
*/
#include <stdlib.h>
@@ -133,13 +135,13 @@ void ieee802_1x_request_identity(struct hostapd_data *hapd,
{
u8 *buf;
struct eap_hdr *eap;
- int tlen;
+ int extra, tlen;
u8 *pos;
struct eapol_state_machine *sm = sta->eapol_sm;
- if (hapd->conf->eap_server) {
+ if (hapd->conf->eap_authenticator) {
HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "IEEE 802.1X: Integrated EAP server in "
+ "IEEE 802.1X: Integrated EAP Authenticator in "
"use - do not generate EAP-Request/Identity\n");
return;
}
@@ -149,7 +151,12 @@ void ieee802_1x_request_identity(struct hostapd_data *hapd,
ieee802_1x_new_auth_session(hapd, sta);
- tlen = sizeof(*eap) + 1 + hapd->conf->eap_req_id_text_len;
+ if (hapd->conf->eap_req_id_text)
+ extra = strlen(hapd->conf->eap_req_id_text);
+ else
+ extra = 0;
+
+ tlen = sizeof(*eap) + 1 + extra;
buf = malloc(tlen);
if (buf == NULL) {
@@ -165,10 +172,8 @@ void ieee802_1x_request_identity(struct hostapd_data *hapd,
eap->length = htons(tlen);
pos = (u8 *) (eap + 1);
*pos++ = EAP_TYPE_IDENTITY;
- if (hapd->conf->eap_req_id_text) {
- memcpy(pos, hapd->conf->eap_req_id_text,
- hapd->conf->eap_req_id_text_len);
- }
+ if (hapd->conf->eap_req_id_text)
+ memcpy(pos, hapd->conf->eap_req_id_text, extra);
sm->be_auth.eapReq = TRUE;
free(sm->last_eap_radius);
@@ -419,22 +424,12 @@ static void ieee802_1x_encapsulate_radius(hostapd *hapd, struct sta_info *sta,
goto fail;
}
- if (hapd->conf->own_ip_addr.af == AF_INET &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
- (u8 *) &hapd->conf->own_ip_addr.u.v4, 4)) {
+ if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
+ (u8 *) &hapd->conf->own_ip_addr, 4)) {
printf("Could not add NAS-IP-Address\n");
goto fail;
}
-#ifdef CONFIG_IPV6
- if (hapd->conf->own_ip_addr.af == AF_INET6 &&
- !radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IPV6_ADDRESS,
- (u8 *) &hapd->conf->own_ip_addr.u.v6, 16)) {
- printf("Could not add NAS-IPv6-Address\n");
- goto fail;
- }
-#endif /* CONFIG_IPV6 */
-
if (hapd->conf->nas_identifier &&
!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IDENTIFIER,
(u8 *) hapd->conf->nas_identifier,
@@ -670,8 +665,7 @@ static void handle_eap(hostapd *hapd, struct sta_info *sta, u8 *buf,
/* Process the EAPOL frames from the Supplicant */
-void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
- size_t len)
+void ieee802_1x_receive(hostapd *hapd, u8 *sa, u8 *buf, size_t len)
{
struct sta_info *sta;
struct ieee802_1x_hdr *hdr;
@@ -806,17 +800,20 @@ void ieee802_1x_new_station(hostapd *hapd, struct sta_info *sta)
if (!hapd->conf->ieee802_1x || sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK)
return;
+ if (sta->eapol_sm) {
+ sta->eapol_sm->portEnabled = TRUE;
+ eapol_sm_step(sta->eapol_sm);
+ return;
+ }
+
+ hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
+ HOSTAPD_LEVEL_DEBUG, "start authentication");
+ sta->eapol_sm = eapol_sm_alloc(hapd, sta);
if (sta->eapol_sm == NULL) {
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
- HOSTAPD_LEVEL_DEBUG, "start authentication");
- sta->eapol_sm = eapol_sm_alloc(hapd, sta);
- if (sta->eapol_sm == NULL) {
- hostapd_logger(hapd, sta->addr,
- HOSTAPD_MODULE_IEEE8021X,
- HOSTAPD_LEVEL_INFO,
- "failed to allocate state machine");
- return;
- }
+ HOSTAPD_LEVEL_INFO, "failed to allocate "
+ "state machine");
+ return;
}
sta->eapol_sm->portEnabled = TRUE;
@@ -834,49 +831,7 @@ void ieee802_1x_new_station(hostapd *hapd, struct sta_info *sta)
sta->eapol_sm->authSuccess = TRUE;
if (sta->eapol_sm->eap)
eap_sm_notify_cached(sta->eapol_sm->eap);
- } else
- eapol_sm_step(sta->eapol_sm);
-}
-
-
-void ieee802_1x_free_radius_class(struct radius_class_data *class)
-{
- int i;
- if (class == NULL)
- return;
- for (i = 0; i < class->count; i++)
- free(class->attr[i].data);
- free(class->attr);
- class->attr = NULL;
- class->count = 0;
-}
-
-
-int ieee802_1x_copy_radius_class(struct radius_class_data *dst,
- struct radius_class_data *src)
-{
- size_t i;
-
- if (src->attr == NULL)
- return 0;
-
- dst->attr = malloc(src->count * sizeof(struct radius_attr_data));
- if (dst->attr == NULL)
- return -1;
-
- memset(dst->attr, 0, src->count * sizeof(struct radius_attr_data));
- dst->count = 0;
-
- for (i = 0; i < src->count; i++) {
- dst->attr[i].data = malloc(src->attr[i].len);
- if (dst->attr[i].data == NULL)
- break;
- dst->count++;
- memcpy(dst->attr[i].data, src->attr[i].data, src->attr[i].len);
- dst->attr[i].len = src->attr[i].len;
}
-
- return 0;
}
@@ -899,7 +854,7 @@ void ieee802_1x_free_station(struct sta_info *sta)
free(sm->last_eap_supp);
free(sm->last_eap_radius);
free(sm->identity);
- ieee802_1x_free_radius_class(&sm->radius_class);
+ free(sm->radius_class);
free(sm->eapol_key_sign);
free(sm->eapol_key_crypt);
eapol_sm_free(sm);
@@ -1042,87 +997,31 @@ static void ieee802_1x_store_radius_class(struct hostapd_data *hapd,
u8 *class;
size_t class_len;
struct eapol_state_machine *sm = sta->eapol_sm;
- int count, i;
- struct radius_attr_data *nclass;
- size_t nclass_count;
- if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||
- sm == NULL)
+ if (!hapd->conf->acct_server || hapd->radius == NULL || sm == NULL)
return;
- ieee802_1x_free_radius_class(&sm->radius_class);
- count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
- if (count <= 0)
+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS, &class,
+ &class_len) < 0 ||
+ class_len < 1) {
+ free(sm->radius_class);
+ sm->radius_class = NULL;
+ sm->radius_class_len = 0;
return;
-
- nclass = malloc(count * sizeof(struct radius_attr_data));
- if (nclass == NULL)
- return;
-
- nclass_count = 0;
- memset(nclass, 0, count * sizeof(struct radius_attr_data));
-
- class = NULL;
- for (i = 0; i < count; i++) {
- do {
- if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CLASS,
- &class, &class_len,
- class) < 0) {
- i = count;
- break;
- }
- } while (class_len < 1);
-
- nclass[nclass_count].data = malloc(class_len);
- if (nclass[nclass_count].data == NULL)
- break;
-
- memcpy(nclass[nclass_count].data, class, class_len);
- nclass[nclass_count].len = class_len;
- nclass_count++;
}
- sm->radius_class.attr = nclass;
- sm->radius_class.count = nclass_count;
- HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL, "IEEE 802.1X: Stored %lu RADIUS "
- "Class attributes for " MACSTR "\n",
- (unsigned long) sm->radius_class.count,
- MAC2STR(sta->addr));
-}
-
-
-/* Update sta->identity based on User-Name attribute in Access-Accept */
-static void ieee802_1x_update_sta_identity(struct hostapd_data *hapd,
- struct sta_info *sta,
- struct radius_msg *msg)
-{
- u8 *buf, *identity;
- size_t len;
- struct eapol_state_machine *sm = sta->eapol_sm;
-
- if (sm == NULL)
- return;
-
- if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len,
- NULL) < 0)
- return;
-
- identity = malloc(len + 1);
- if (identity == NULL)
- return;
-
- memcpy(identity, buf, len);
- identity[len] = '\0';
-
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
- HOSTAPD_LEVEL_DEBUG, "old identity '%s' updated with "
- "User-Name from Access-Accept '%s'",
- sm->identity ? (char *) sm->identity : "N/A",
- (char *) identity);
+ if (sm->radius_class == NULL ||
+ sm->radius_class_len < class_len) {
+ free(sm->radius_class);
+ sm->radius_class = malloc(class_len);
+ if (sm->radius_class == NULL) {
+ sm->radius_class_len = 0;
+ return;
+ }
+ }
- free(sm->identity);
- sm->identity = identity;
- sm->identity_len = len;
+ memcpy(sm->radius_class, class, class_len);
+ sm->radius_class_len = class_len;
}
@@ -1167,7 +1066,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
{
struct hostapd_data *hapd = data;
struct sta_info *sta;
- u32 session_timeout = 0, termination_action, acct_interim_interval;
+ u32 session_timeout, termination_action, acct_interim_interval;
int session_timeout_set;
int eap_timeout;
struct eapol_state_machine *sm;
@@ -1192,7 +1091,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
"Access-Reject without Message-Authenticator "
"since it does not include EAP-Message\n");
} else if (radius_msg_verify(msg, shared_secret, shared_secret_len,
- req, 1)) {
+ req)) {
printf("Incoming RADIUS packet did not have correct "
"Message-Authenticator - dropped\n");
return RADIUS_RX_INVALID_AUTHENTICATOR;
@@ -1224,7 +1123,7 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
&termination_action))
termination_action = RADIUS_TERMINATION_ACTION_DEFAULT;
- if (hapd->conf->radius->acct_interim_interval == 0 &&
+ if (hapd->conf->radius_acct_interim_interval == 0 &&
msg->hdr->code == RADIUS_CODE_ACCESS_ACCEPT &&
radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL,
&acct_interim_interval) == 0) {
@@ -1253,13 +1152,12 @@ ieee802_1x_receive_auth(struct radius_msg *msg, struct radius_msg *req,
override_eapReq = 1;
ieee802_1x_get_keys(hapd, sta, msg, req, shared_secret,
shared_secret_len);
- ieee802_1x_store_radius_class(hapd, sta, msg);
- ieee802_1x_update_sta_identity(hapd, sta, msg);
if (sm->keyAvailable) {
pmksa_cache_add(hapd, sta, sm->eapol_key_crypt,
session_timeout_set ?
session_timeout : -1);
}
+ ieee802_1x_store_radius_class(hapd, sta, msg);
break;
case RADIUS_CODE_ACCESS_REJECT:
sm->eapFail = TRUE;
@@ -1301,7 +1199,7 @@ void ieee802_1x_send_resp_to_server(hostapd *hapd, struct sta_info *sta)
if (sm == NULL)
return;
- if (hapd->conf->eap_server) {
+ if (hapd->conf->eap_authenticator) {
eap_set_eapRespData(sm->eap, sm->last_eap_supp,
sm->last_eap_supp_len);
} else {
@@ -1331,6 +1229,9 @@ void ieee802_1x_abort_auth(struct hostapd_data *hapd, struct sta_info *sta)
free(sm->last_eap_radius);
sm->last_eap_radius = NULL;
sm->last_eap_radius_len = 0;
+ free(sm->radius_class);
+ sm->radius_class = NULL;
+ sm->radius_class_len = 0;
}
@@ -1581,15 +1482,13 @@ u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len)
}
-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
- int idx)
+u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len)
{
- if (sm == NULL || sm->radius_class.attr == NULL ||
- idx >= sm->radius_class.count)
+ if (sm == NULL || sm->radius_class == NULL)
return NULL;
- *len = sm->radius_class.attr[idx].len;
- return sm->radius_class.attr[idx].data;
+ *len = sm->radius_class_len;
+ return sm->radius_class;
}
@@ -1609,7 +1508,6 @@ void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm,
if (sm == NULL)
return;
sm->portEnabled = enabled ? TRUE : FALSE;
- eapol_sm_step(sm);
}
@@ -1619,7 +1517,6 @@ void ieee802_1x_notify_port_valid(struct eapol_state_machine *sm,
if (sm == NULL)
return;
sm->portValid = valid ? TRUE : FALSE;
- eapol_sm_step(sm);
}
diff --git a/contrib/hostapd/ieee802_1x.h b/contrib/hostapd/ieee802_1x.h
index 0ac06b2..9d2567a 100644
--- a/contrib/hostapd/ieee802_1x.h
+++ b/contrib/hostapd/ieee802_1x.h
@@ -1,3 +1,5 @@
+/* $FreeBSD$ */
+
#ifndef IEEE802_1X_H
#define IEEE802_1X_H
@@ -10,7 +12,13 @@ struct ieee802_1x_hdr {
/* followed by length octets of data */
} __attribute__ ((packed));
+
+#if defined(IEEE802_1X_EAPOL_VERSION_2)
#define EAPOL_VERSION 2
+#else
+/* Enable support for older Authenticators/Supplicants using EAPOL Version 1 */
+#define EAPOL_VERSION 1
+#endif /* ! IEEE802_1X_EAPOL_VERSION_2 */
enum { IEEE802_1X_TYPE_EAP_PACKET = 0,
IEEE802_1X_TYPE_EAPOL_START = 1,
@@ -47,8 +55,7 @@ enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2,
EAPOL_KEY_TYPE_WPA = 254 };
-void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
- size_t len);
+void ieee802_1x_receive(hostapd *hapd, u8 *sa, u8 *buf, size_t len);
void ieee802_1x_new_station(hostapd *hapd, struct sta_info *sta);
void ieee802_1x_free_station(struct sta_info *sta);
@@ -70,8 +77,7 @@ void ieee802_1x_deinit(hostapd *hapd);
int ieee802_1x_tx_status(hostapd *hapd, struct sta_info *sta, u8 *buf,
size_t len, int ack);
u8 * ieee802_1x_get_identity(struct eapol_state_machine *sm, size_t *len);
-u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
- int idx);
+u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len);
u8 * ieee802_1x_get_key_crypt(struct eapol_state_machine *sm, size_t *len);
void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm,
int enabled);
@@ -85,10 +91,4 @@ void hostapd_get_ntp_timestamp(u8 *buf);
void ieee802_1x_finished(struct hostapd_data *hapd, struct sta_info *sta,
int success);
-struct radius_class_data;
-
-void ieee802_1x_free_radius_class(struct radius_class_data *class);
-int ieee802_1x_copy_radius_class(struct radius_class_data *dst,
- struct radius_class_data *src);
-
#endif /* IEEE802_1X_H */
diff --git a/contrib/hostapd/wpa.c b/contrib/hostapd/wpa.c
index 4bac473..c0948e8 100644
--- a/contrib/hostapd/wpa.c
+++ b/contrib/hostapd/wpa.c
@@ -11,6 +11,8 @@
* license.
*
* See README and COPYING for more details.
+ *
+ * $FreeBSD$
*/
#include <stdlib.h>
@@ -34,8 +36,6 @@
#include "eloop.h"
#include "sta_info.h"
#include "l2_packet.h"
-#include "accounting.h"
-#include "hostap_common.h"
static void wpa_send_eapol_timeout(void *eloop_ctx, void *timeout_ctx);
@@ -103,7 +103,7 @@ static const u8 RSN_KEY_DATA_PMKID[] = { 0x00, 0x0f, 0xac, 4 };
* Authenticated Key Management Suite Count (2 octets, little endian)
* (default: 1)
* Authenticated Key Management Suite List (4 * n octets)
- * (default: unspec 802.1X)
+ * (default: unspec 802.1x)
* WPA Capabilities (2 octets, little endian) (default: 0)
*/
@@ -125,7 +125,7 @@ struct wpa_ie_hdr {
* Authenticated Key Management Suite Count (2 octets, little endian)
* (default: 1)
* Authenticated Key Management Suite List (4 * n octets)
- * (default: unspec 802.1X)
+ * (default: unspec 802.1x)
* RSN Capabilities (2 octets, little endian) (default: 0)
* PMKID Count (2 octets) (default: 0)
* PMKID List (16 * n octets)
@@ -398,8 +398,8 @@ static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
#ifdef CONFIG_RSN_PREAUTH
-static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
- const u8 *buf, size_t len)
+static void rsn_preauth_receive(void *ctx, unsigned char *src_addr,
+ unsigned char *buf, size_t len)
{
struct rsn_preauth_interface *piface = ctx;
struct hostapd_data *hapd = piface->hapd;
@@ -482,12 +482,13 @@ static int rsn_preauth_iface_add(struct hostapd_data *hapd, const char *ifname)
}
piface->l2 = l2_packet_init(piface->ifname, NULL, ETH_P_PREAUTH,
- rsn_preauth_receive, piface, 1);
+ rsn_preauth_receive, piface);
if (piface->l2 == NULL) {
printf("Failed to open register layer 2 access to "
"ETH_P_PREAUTH\n");
goto fail2;
}
+ l2_packet_set_rx_l2_hdr(piface->l2, 1);
piface->next = hapd->preauth_iface;
hapd->preauth_iface = piface;
@@ -552,16 +553,6 @@ static int rsn_preauth_iface_init(struct hostapd_data *hapd)
}
-static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
-{
- struct hostapd_data *hapd = eloop_ctx;
- struct sta_info *sta = timeout_ctx;
- wpa_printf(MSG_DEBUG, "RSN: Removing pre-authentication STA entry for "
- MACSTR, MAC2STR(sta->addr));
- ap_free_sta(hapd, sta);
-}
-
-
void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
int success)
{
@@ -576,11 +567,7 @@ void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
pmksa_cache_add(hapd, sta, key, dot11RSNAConfigPMKLifetime);
}
- /*
- * Finish STA entry removal from timeout in order to avoid freeing
- * STA data before the caller has finished processing.
- */
- eloop_register_timeout(0, 0, rsn_preauth_finished_cb, hapd, sta);
+ ap_free_sta(hapd, sta);
}
@@ -613,8 +600,8 @@ void rsn_preauth_send(struct hostapd_data *hapd, struct sta_info *sta,
ethhdr->h_proto = htons(ETH_P_PREAUTH);
memcpy(ethhdr + 1, buf, len);
- if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
- sizeof(*ethhdr) + len) < 0) {
+ if (l2_packet_send(piface->l2, (u8 *) ethhdr, sizeof(*ethhdr) + len) <
+ 0) {
printf("Failed to send preauth packet using l2_packet_send\n");
}
free(ethhdr);
@@ -631,10 +618,6 @@ static inline void rsn_preauth_iface_deinit(struct hostapd_data *hapd)
{
}
-static void rsn_preauth_finished_cb(void *eloop_ctx, void *timeout_ctx)
-{
-}
-
void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
int success)
{
@@ -826,16 +809,6 @@ static void rsn_pmkid(const u8 *pmk, const u8 *aa, const u8 *spa, u8 *pmkid)
static void pmksa_cache_set_expiration(struct hostapd_data *hapd);
-static void _pmksa_cache_free_entry(struct rsn_pmksa_cache *entry)
-{
- if (entry == NULL)
- return;
- free(entry->identity);
- ieee802_1x_free_radius_class(&entry->radius_class);
- free(entry);
-}
-
-
static void pmksa_cache_free_entry(struct hostapd_data *hapd,
struct rsn_pmksa_cache *entry)
{
@@ -875,7 +848,7 @@ static void pmksa_cache_free_entry(struct hostapd_data *hapd,
prev = pos;
pos = pos->next;
}
- _pmksa_cache_free_entry(entry);
+ free(entry);
}
@@ -911,54 +884,6 @@ static void pmksa_cache_set_expiration(struct hostapd_data *hapd)
}
-static void pmksa_cache_from_eapol_data(struct rsn_pmksa_cache *entry,
- struct eapol_state_machine *eapol)
-{
- if (eapol == NULL)
- return;
-
- if (eapol->identity) {
- entry->identity = malloc(eapol->identity_len);
- if (entry->identity) {
- entry->identity_len = eapol->identity_len;
- memcpy(entry->identity, eapol->identity,
- eapol->identity_len);
- }
- }
-
- ieee802_1x_copy_radius_class(&entry->radius_class,
- &eapol->radius_class);
-}
-
-
-static void pmksa_cache_to_eapol_data(struct rsn_pmksa_cache *entry,
- struct eapol_state_machine *eapol)
-{
- if (entry == NULL || eapol == NULL)
- return;
-
- if (entry->identity) {
- free(eapol->identity);
- eapol->identity = malloc(entry->identity_len);
- if (eapol->identity) {
- eapol->identity_len = entry->identity_len;
- memcpy(eapol->identity, entry->identity,
- entry->identity_len);
- }
- wpa_hexdump_ascii(MSG_DEBUG, "STA identity from PMKSA",
- eapol->identity, eapol->identity_len);
- }
-
- ieee802_1x_free_radius_class(&eapol->radius_class);
- ieee802_1x_copy_radius_class(&eapol->radius_class,
- &entry->radius_class);
- if (eapol->radius_class.attr) {
- wpa_printf(MSG_DEBUG, "Copied %lu Class attribute(s) from "
- "PMKSA", (unsigned long) eapol->radius_class.count);
- }
-}
-
-
void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk,
int session_timeout)
{
@@ -980,7 +905,6 @@ void pmksa_cache_add(struct hostapd_data *hapd, struct sta_info *sta, u8 *pmk,
entry->expiration += dot11RSNAConfigPMKLifetime;
entry->akmp = WPA_KEY_MGMT_IEEE8021X;
memcpy(entry->spa, sta->addr, ETH_ALEN);
- pmksa_cache_from_eapol_data(entry, sta->eapol_sm);
/* Replace an old entry for the same STA (if found) with the new entry
*/
@@ -1037,7 +961,7 @@ static void pmksa_cache_free(struct hostapd_data *hapd)
while (entry) {
prev = entry;
entry = entry->next;
- _pmksa_cache_free_entry(prev);
+ free(prev);
}
eloop_cancel_timeout(pmksa_cache_expire, hapd, NULL);
for (i = 0; i < PMKID_HASH_SIZE; i++)
@@ -1077,7 +1001,7 @@ struct wpa_ie_data {
};
-static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
+static int wpa_parse_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
struct wpa_ie_data *data)
{
struct wpa_ie_hdr *hdr;
@@ -1156,7 +1080,7 @@ static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
}
-static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
+static int wpa_parse_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
struct wpa_ie_data *data)
{
struct rsn_ie_hdr *hdr;
@@ -1250,7 +1174,7 @@ static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
int wpa_validate_wpa_ie(struct hostapd_data *hapd, struct sta_info *sta,
- const u8 *wpa_ie, size_t wpa_ie_len, int version)
+ u8 *wpa_ie, size_t wpa_ie_len, int version)
{
struct wpa_ie_data data;
int ciphers, key_mgmt, res, i;
@@ -1450,7 +1374,6 @@ void wpa_free_station(struct sta_info *sta)
eloop_cancel_timeout(wpa_send_eapol_timeout, sm->hapd, sta);
eloop_cancel_timeout(wpa_sm_call_step, sm->hapd, sta->wpa_sm);
- eloop_cancel_timeout(rsn_preauth_finished_cb, sm->hapd, sta);
free(sm->last_rx_eapol_key);
free(sm);
sta->wpa_sm = NULL;
@@ -2167,7 +2090,6 @@ SM_STATE(WPA_PTK, INITPMK)
if (sm->sta->pmksa) {
wpa_printf(MSG_DEBUG, "WPA: PMK from PMKSA cache");
memcpy(sm->PMK, sm->sta->pmksa->pmk, WPA_PMK_LEN);
- pmksa_cache_to_eapol_data(sm->sta->pmksa, sm->sta->eapol_sm);
} else if ((key = ieee802_1x_get_key_crypt(sm->sta->eapol_sm, &len))) {
wpa_printf(MSG_DEBUG, "WPA: PMK from EAPOL state machine "
"(len=%lu)", (unsigned long) len);
@@ -2374,8 +2296,6 @@ SM_STATE(WPA_PTK, PTKINITDONE)
HOSTAPD_LEVEL_INFO, "pairwise key handshake completed "
"(%s)",
sm->sta->wpa == WPA_VERSION_WPA ? "WPA" : "RSN");
- if (sm->sta->wpa_key_mgmt == WPA_KEY_MGMT_PSK)
- accounting_sta_start(sm->hapd, sm->sta);
}
OpenPOWER on IntegriCloud