diff options
Diffstat (limited to 'contrib/hostapd')
-rw-r--r-- | contrib/hostapd/eap.c | 29 | ||||
-rw-r--r-- | contrib/hostapd/eap.h | 9 | ||||
-rw-r--r-- | contrib/hostapd/eapol_sm.c | 162 | ||||
-rw-r--r-- | contrib/hostapd/ieee802_1x.c | 221 | ||||
-rw-r--r-- | contrib/hostapd/ieee802_1x.h | 20 | ||||
-rw-r--r-- | contrib/hostapd/wpa.c | 112 |
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); } |