summaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2006-03-07 05:51:52 +0000
committersam <sam@FreeBSD.org>2006-03-07 05:51:52 +0000
commit7ec4eb033d83d1150a5d461349c32d7113770a57 (patch)
tree4c08a6b60d0fad8945a0348eb843f0d8b2bd8d9d /contrib
parent8410a7ea6cb51f8974a9d5506dacff8d565158f5 (diff)
downloadFreeBSD-src-7ec4eb033d83d1150a5d461349c32d7113770a57.zip
FreeBSD-src-7ec4eb033d83d1150a5d461349c32d7113770a57.tar.gz
resolve merge conflicts
MFC after: 2 weeks
Diffstat (limited to 'contrib')
-rw-r--r--contrib/hostapd/FREEBSD-Xlist4
-rw-r--r--contrib/hostapd/FREEBSD-upgrade8
-rw-r--r--contrib/hostapd/eap.c27
-rw-r--r--contrib/hostapd/eap.h7
-rw-r--r--contrib/hostapd/eapol_sm.c160
-rw-r--r--contrib/hostapd/hostapd_ctrl.c188
-rw-r--r--contrib/hostapd/hostapd_ctrl.h18
-rw-r--r--contrib/hostapd/ieee802_1x.c219
-rw-r--r--contrib/hostapd/ieee802_1x.h18
-rw-r--r--contrib/hostapd/wpa.c110
10 files changed, 419 insertions, 340 deletions
diff --git a/contrib/hostapd/FREEBSD-Xlist b/contrib/hostapd/FREEBSD-Xlist
index cba8df0..00330b3 100644
--- a/contrib/hostapd/FREEBSD-Xlist
+++ b/contrib/hostapd/FREEBSD-Xlist
@@ -4,7 +4,9 @@ driver.c
driver_bsd.c
driver_madwifi.c
driver_prism54.c
-l2_packet.c
+l2_packet_freebsd.c
+l2_packet_linux.c
+l2_packet_pcap.c
prism54.h
priv_netlink.h
wireless_copy.h
diff --git a/contrib/hostapd/FREEBSD-upgrade b/contrib/hostapd/FREEBSD-upgrade
index 5efe2f5..8286ce4 100644
--- a/contrib/hostapd/FREEBSD-upgrade
+++ b/contrib/hostapd/FREEBSD-upgrade
@@ -6,12 +6,12 @@ WPA/802.1x Authenticator
For the import files and directories were pruned by:
- tar -X FREEBSD-Xlist -zxf hostapd-0.3.7.tar.gz
+ tar -X FREEBSD-Xlist -zxf hostapd-0.4.8.tar.gz
then imported by:
- cvs import -m 'Import of hostapd 0.3.7' \
- src/contrib/hostapd MALINEN v0_3_7
+ cvs import -m 'Import of hostapd 0.4.8' \
+ src/contrib/hostapd MALINEN v0_4_8
To make local changes to hostapd, simply patch and commit to the
main branch (aka HEAD). Never make local changes on the vendor
@@ -21,4 +21,4 @@ All local changes should be submitted to Jouni Malinen for inclusion in
the next vendor release.
sam@FreeBSD.org
-4-June-2005
+6-March-2006
diff --git a/contrib/hostapd/eap.c b/contrib/hostapd/eap.c
index 1897856..b321ea6 100644
--- a/contrib/hostapd/eap.c
+++ b/contrib/hostapd/eap.c
@@ -26,6 +26,7 @@
#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
@@ -52,6 +53,12 @@ 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[] =
{
@@ -80,6 +87,12 @@ 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]))
@@ -199,6 +212,7 @@ 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;
}
@@ -234,6 +248,7 @@ SM_STATE(EAP, INITIALIZE)
sm->currentId = sm->respId;
}
}
+ sm->num_rounds = 0;
}
@@ -290,6 +305,7 @@ SM_STATE(EAP, RECEIVED)
/* parse rxResp, respId, respMethod */
eap_sm_parseEapResp(sm, sm->eapRespData, sm->eapRespDataLen);
+ sm->num_rounds++;
}
@@ -505,7 +521,15 @@ SM_STEP(EAP)
SM_ENTER_GLOBAL(EAP, INITIALIZE);
else if (!eapol_get_bool(sm, EAPOL_portEnabled))
SM_ENTER_GLOBAL(EAP, DISABLED);
- else switch (sm->EAP_state) {
+ 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) {
case EAP_INITIALIZE:
if (sm->backend_auth) {
if (!sm->rxResp)
@@ -912,6 +936,7 @@ 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 c79bffe..ce49b07 100644
--- a/contrib/hostapd/eap.h
+++ b/contrib/hostapd/eap.h
@@ -32,6 +32,7 @@ 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 {
@@ -41,7 +42,7 @@ struct eap_config {
};
-#ifdef EAP_AUTHENTICATOR
+#ifdef EAP_SERVER
struct eap_sm * eap_sm_init(void *eapol_ctx, struct eapol_callbacks *eapol_cb,
struct eap_config *eap_conf);
@@ -52,7 +53,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_AUTHENTICATOR */
+#else /* EAP_SERVER */
static inline struct eap_sm * eap_sm_init(void *eapol_ctx,
struct eapol_callbacks *eapol_cb,
@@ -85,6 +86,6 @@ static inline void eap_sm_notify_cached(struct eap_sm *sm)
{
}
-#endif /* EAP_AUTHENTICATOR */
+#endif /* EAP_SERVER */
#endif /* EAP_H */
diff --git a/contrib/hostapd/eapol_sm.c b/contrib/hostapd/eapol_sm.c
index 50c645a..4ded7e7 100644
--- a/contrib/hostapd/eapol_sm.c
+++ b/contrib/hostapd/eapol_sm.c
@@ -68,6 +68,9 @@ 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 */
@@ -76,19 +79,34 @@ 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->quietWhile > 0)
+ if (state->aWhile == 0) {
+ wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
+ " - aWhile --> 0",
+ MAC2STR(state->addr));
+ }
+ }
+
+ if (state->quietWhile > 0) {
state->quietWhile--;
- if (state->reAuthWhen > 0)
- state->reAuthWhen--;
+ if (state->quietWhile == 0) {
+ wpa_printf(MSG_DEBUG, "IEEE 802.1X: " MACSTR
+ " - quietWhile --> 0",
+ MAC2STR(state->addr));
+ }
+ }
- 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);
+ 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(state);
+ eapol_sm_step_run(state);
eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, state);
}
@@ -359,6 +377,19 @@ 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;
}
@@ -705,7 +736,7 @@ eapol_sm_alloc(hostapd *hapd, struct sta_info *sta)
else
sm->portValid = TRUE;
- if (hapd->conf->eap_authenticator) {
+ if (hapd->conf->eap_server) {
struct eap_config eap_conf;
memset(&eap_conf, 0, sizeof(eap_conf));
eap_conf.ssl_ctx = hapd->ssl_ctx;
@@ -729,6 +760,7 @@ 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);
@@ -745,55 +777,63 @@ static int eapol_sm_sta_entry_alive(struct hostapd_data *hapd, u8 *addr)
}
-void eapol_sm_step(struct eapol_state_machine *sm)
+static void eapol_sm_step_run(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;
-
- /* FIX: could re-run eapol_sm_step from registered timeout (after
- * 0 sec) to make sure that other possible timeouts/events are
- * processed */
+ int max_steps = 100;
memcpy(addr, sm->sta->addr, ETH_ALEN);
+
+ /*
+ * 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.
+ */
restart:
- 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;
+ 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))
SM_STEP_RUN(BE_AUTH);
- if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
- break;
+ if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
SM_STEP_RUN(REAUTH_TIMER);
- if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
- break;
+ if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
SM_STEP_RUN(AUTH_KEY_TX);
- if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
- break;
+ if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
SM_STEP_RUN(KEY_RX);
- if (!sm->initializing && !eapol_sm_sta_entry_alive(hapd, addr))
- break;
+ if (sm->initializing || eapol_sm_sta_entry_alive(hapd, addr))
SM_STEP_RUN(CTRL_DIR);
- 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 (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 (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 (eapol_sm_sta_entry_alive(hapd, addr))
@@ -801,15 +841,34 @@ 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(sm);
+ eapol_sm_step_run(sm);
sm->initialize = FALSE;
- eapol_sm_step(sm);
+ eapol_sm_step_run(sm);
sm->initializing = FALSE;
/* Start one second tick for port timers state machine */
@@ -1183,6 +1242,14 @@ 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,
@@ -1190,4 +1257,5 @@ 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/hostapd_ctrl.c b/contrib/hostapd/hostapd_ctrl.c
deleted file mode 100644
index 55b6904..0000000
--- a/contrib/hostapd/hostapd_ctrl.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * hostapd - hostapd control interface library
- * Copyright (c) 2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/un.h>
-
-#include "hostapd_ctrl.h"
-
-
-struct hostapd_ctrl {
- int s;
- struct sockaddr_un local;
- struct sockaddr_un dest;
-};
-
-
-struct hostapd_ctrl * hostapd_ctrl_open(const char *ctrl_path)
-{
- struct hostapd_ctrl *ctrl;
- static int counter = 0;
-
- ctrl = malloc(sizeof(*ctrl));
- if (ctrl == NULL)
- return NULL;
- memset(ctrl, 0, sizeof(*ctrl));
-
- ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
- if (ctrl->s < 0) {
- free(ctrl);
- return NULL;
- }
-
- ctrl->local.sun_family = AF_UNIX;
- snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
- "/tmp/hostapd_ctrl_%d-%d", getpid(), counter++);
- if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
- sizeof(ctrl->local.sun_family) +
- strlen(ctrl->local.sun_path)) < 0) {
- close(ctrl->s);
- free(ctrl);
- return NULL;
- }
-
- ctrl->dest.sun_family = AF_UNIX;
- strncpy(ctrl->dest.sun_path, ctrl_path, sizeof(ctrl->dest.sun_path));
- if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
- sizeof(ctrl->dest.sun_family) +
- strlen(ctrl->dest.sun_path)) < 0) {
- close(ctrl->s);
- unlink(ctrl->local.sun_path);
- free(ctrl);
- return NULL;
- }
-
- return ctrl;
-}
-
-
-void hostapd_ctrl_close(struct hostapd_ctrl *ctrl)
-{
- unlink(ctrl->local.sun_path);
- close(ctrl->s);
- free(ctrl);
-}
-
-
-int hostapd_ctrl_request(struct hostapd_ctrl *ctrl, char *cmd, size_t cmd_len,
- char *reply, size_t *reply_len,
- void (*msg_cb)(char *msg, size_t len))
-{
- struct timeval tv;
- int res;
- fd_set rfds;
-
- if (send(ctrl->s, cmd, cmd_len, 0) < 0)
- return -1;
-
- for (;;) {
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_SET(ctrl->s, &rfds);
- res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
- if (FD_ISSET(ctrl->s, &rfds)) {
- res = recv(ctrl->s, reply, *reply_len, 0);
- if (res < 0)
- return res;
- if (res > 0 && reply[0] == '<') {
- /* This is an unsolicited message from
- * wpa_supplicant, not the reply to the
- * request. Use msg_cb to report this to the
- * caller. */
- if (msg_cb) {
- /* Make sure the message is nul
- * terminated. */
- if (res == *reply_len)
- res = (*reply_len) - 1;
- reply[res] = '\0';
- msg_cb(reply, res);
- }
- continue;
- }
- *reply_len = res;
- break;
- } else {
- return -2;
- }
- }
- return 0;
-}
-
-
-static int hostapd_ctrl_attach_helper(struct hostapd_ctrl *ctrl, int attach)
-{
- char buf[10];
- int ret;
- size_t len = 10;
-
- ret = hostapd_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
- buf, &len, NULL);
- if (ret < 0)
- return ret;
- if (len == 3 && memcmp(buf, "OK\n", 3) == 0)
- return 0;
- return -1;
-}
-
-
-int hostapd_ctrl_attach(struct hostapd_ctrl *ctrl)
-{
- return hostapd_ctrl_attach_helper(ctrl, 1);
-}
-
-
-int hostapd_ctrl_detach(struct hostapd_ctrl *ctrl)
-{
- return hostapd_ctrl_attach_helper(ctrl, 0);
-}
-
-
-int hostapd_ctrl_recv(struct hostapd_ctrl *ctrl, char *reply,
- size_t *reply_len)
-{
- int res;
-
- res = recv(ctrl->s, reply, *reply_len, 0);
- if (res < 0)
- return res;
- *reply_len = res;
- return 0;
-}
-
-
-int hostapd_ctrl_pending(struct hostapd_ctrl *ctrl)
-{
- struct timeval tv;
- int res;
- fd_set rfds;
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_SET(ctrl->s, &rfds);
- res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
- return FD_ISSET(ctrl->s, &rfds);
-}
-
-
-int hostapd_ctrl_get_fd(struct hostapd_ctrl *ctrl)
-{
- return ctrl->s;
-}
diff --git a/contrib/hostapd/hostapd_ctrl.h b/contrib/hostapd/hostapd_ctrl.h
deleted file mode 100644
index 7ba221e..0000000
--- a/contrib/hostapd/hostapd_ctrl.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef HOSTAPD_CTRL_H
-#define HOSTAPD_CTRL_H
-
-struct hostapd_ctrl;
-
-struct hostapd_ctrl * hostapd_ctrl_open(const char *ctrl_path);
-void hostapd_ctrl_close(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_request(struct hostapd_ctrl *ctrl, char *cmd, size_t cmd_len,
- char *reply, size_t *reply_len,
- void (*msg_cb)(char *msg, size_t len));
-int hostapd_ctrl_attach(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_detach(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_recv(struct hostapd_ctrl *ctrl, char *reply,
- size_t *reply_len);
-int hostapd_ctrl_pending(struct hostapd_ctrl *ctrl);
-int hostapd_ctrl_get_fd(struct hostapd_ctrl *ctrl);
-
-#endif /* HOSTAPD_CTRL_H */
diff --git a/contrib/hostapd/ieee802_1x.c b/contrib/hostapd/ieee802_1x.c
index ef1bde4..c8b1602 100644
--- a/contrib/hostapd/ieee802_1x.c
+++ b/contrib/hostapd/ieee802_1x.c
@@ -135,13 +135,13 @@ void ieee802_1x_request_identity(struct hostapd_data *hapd,
{
u8 *buf;
struct eap_hdr *eap;
- int extra, tlen;
+ int tlen;
u8 *pos;
struct eapol_state_machine *sm = sta->eapol_sm;
- if (hapd->conf->eap_authenticator) {
+ if (hapd->conf->eap_server) {
HOSTAPD_DEBUG(HOSTAPD_DEBUG_MINIMAL,
- "IEEE 802.1X: Integrated EAP Authenticator in "
+ "IEEE 802.1X: Integrated EAP server in "
"use - do not generate EAP-Request/Identity\n");
return;
}
@@ -151,12 +151,7 @@ void ieee802_1x_request_identity(struct hostapd_data *hapd,
ieee802_1x_new_auth_session(hapd, sta);
- if (hapd->conf->eap_req_id_text)
- extra = strlen(hapd->conf->eap_req_id_text);
- else
- extra = 0;
-
- tlen = sizeof(*eap) + 1 + extra;
+ tlen = sizeof(*eap) + 1 + hapd->conf->eap_req_id_text_len;
buf = malloc(tlen);
if (buf == NULL) {
@@ -172,8 +167,10 @@ 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, extra);
+ if (hapd->conf->eap_req_id_text) {
+ memcpy(pos, hapd->conf->eap_req_id_text,
+ hapd->conf->eap_req_id_text_len);
+ }
sm->be_auth.eapReq = TRUE;
free(sm->last_eap_radius);
@@ -424,12 +421,22 @@ static void ieee802_1x_encapsulate_radius(hostapd *hapd, struct sta_info *sta,
goto fail;
}
- if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
- (u8 *) &hapd->conf->own_ip_addr, 4)) {
+ 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)) {
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,
@@ -665,7 +672,8 @@ static void handle_eap(hostapd *hapd, struct sta_info *sta, u8 *buf,
/* Process the EAPOL frames from the Supplicant */
-void ieee802_1x_receive(hostapd *hapd, u8 *sa, u8 *buf, size_t len)
+void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
+ size_t len)
{
struct sta_info *sta;
struct ieee802_1x_hdr *hdr;
@@ -800,20 +808,17 @@ 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_INFO, "failed to allocate "
- "state machine");
- return;
+ 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;
+ }
}
sta->eapol_sm->portEnabled = TRUE;
@@ -831,7 +836,49 @@ 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;
}
@@ -854,7 +901,7 @@ void ieee802_1x_free_station(struct sta_info *sta)
free(sm->last_eap_supp);
free(sm->last_eap_radius);
free(sm->identity);
- free(sm->radius_class);
+ ieee802_1x_free_radius_class(&sm->radius_class);
free(sm->eapol_key_sign);
free(sm->eapol_key_crypt);
eapol_sm_free(sm);
@@ -997,31 +1044,87 @@ 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->acct_server || hapd->radius == NULL || sm == NULL)
+ if (!hapd->conf->radius->acct_server || hapd->radius == NULL ||
+ sm == NULL)
return;
- 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;
+ ieee802_1x_free_radius_class(&sm->radius_class);
+ count = radius_msg_count_attr(msg, RADIUS_ATTR_CLASS, 1);
+ if (count <= 0)
return;
- }
- 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;
- }
+ 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++;
}
- memcpy(sm->radius_class, class, class_len);
- sm->radius_class_len = class_len;
+ 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);
+
+ free(sm->identity);
+ sm->identity = identity;
+ sm->identity_len = len;
}
@@ -1066,7 +1169,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, termination_action, acct_interim_interval;
+ u32 session_timeout = 0, termination_action, acct_interim_interval;
int session_timeout_set;
int eap_timeout;
struct eapol_state_machine *sm;
@@ -1091,7 +1194,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)) {
+ req, 1)) {
printf("Incoming RADIUS packet did not have correct "
"Message-Authenticator - dropped\n");
return RADIUS_RX_INVALID_AUTHENTICATOR;
@@ -1123,7 +1226,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) {
@@ -1152,12 +1255,13 @@ 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;
@@ -1199,7 +1303,7 @@ void ieee802_1x_send_resp_to_server(hostapd *hapd, struct sta_info *sta)
if (sm == NULL)
return;
- if (hapd->conf->eap_authenticator) {
+ if (hapd->conf->eap_server) {
eap_set_eapRespData(sm->eap, sm->last_eap_supp,
sm->last_eap_supp_len);
} else {
@@ -1229,9 +1333,6 @@ 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;
}
@@ -1482,13 +1583,15 @@ 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)
+u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
+ int idx)
{
- if (sm == NULL || sm->radius_class == NULL)
+ if (sm == NULL || sm->radius_class.attr == NULL ||
+ idx >= sm->radius_class.count)
return NULL;
- *len = sm->radius_class_len;
- return sm->radius_class;
+ *len = sm->radius_class.attr[idx].len;
+ return sm->radius_class.attr[idx].data;
}
@@ -1508,6 +1611,7 @@ void ieee802_1x_notify_port_enabled(struct eapol_state_machine *sm,
if (sm == NULL)
return;
sm->portEnabled = enabled ? TRUE : FALSE;
+ eapol_sm_step(sm);
}
@@ -1517,6 +1621,7 @@ 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 9d2567a..90cc2ce 100644
--- a/contrib/hostapd/ieee802_1x.h
+++ b/contrib/hostapd/ieee802_1x.h
@@ -12,13 +12,7 @@ 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,
@@ -55,7 +49,8 @@ enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2,
EAPOL_KEY_TYPE_WPA = 254 };
-void ieee802_1x_receive(hostapd *hapd, u8 *sa, u8 *buf, size_t len);
+void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const 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);
@@ -77,7 +72,8 @@ 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);
+u8 * ieee802_1x_get_radius_class(struct eapol_state_machine *sm, size_t *len,
+ int idx);
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);
@@ -91,4 +87,10 @@ 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 c0948e8..ec07b35 100644
--- a/contrib/hostapd/wpa.c
+++ b/contrib/hostapd/wpa.c
@@ -36,6 +36,8 @@
#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 +105,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 +127,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 +400,8 @@ static void wpa_rekey_gtk(void *eloop_ctx, void *timeout_ctx)
#ifdef CONFIG_RSN_PREAUTH
-static void rsn_preauth_receive(void *ctx, unsigned char *src_addr,
- unsigned char *buf, size_t len)
+static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
+ const u8 *buf, size_t len)
{
struct rsn_preauth_interface *piface = ctx;
struct hostapd_data *hapd = piface->hapd;
@@ -482,13 +484,12 @@ 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);
+ rsn_preauth_receive, piface, 1);
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;
@@ -553,6 +554,16 @@ 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)
{
@@ -567,7 +578,11 @@ void rsn_preauth_finished(struct hostapd_data *hapd, struct sta_info *sta,
pmksa_cache_add(hapd, sta, key, dot11RSNAConfigPMKLifetime);
}
- ap_free_sta(hapd, sta);
+ /*
+ * 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);
}
@@ -600,8 +615,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, (u8 *) ethhdr, sizeof(*ethhdr) + len) <
- 0) {
+ if (l2_packet_send(piface->l2, sta->addr, ETH_P_PREAUTH, (u8 *) ethhdr,
+ sizeof(*ethhdr) + len) < 0) {
printf("Failed to send preauth packet using l2_packet_send\n");
}
free(ethhdr);
@@ -618,6 +633,10 @@ 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)
{
@@ -809,6 +828,16 @@ 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)
{
@@ -848,7 +877,7 @@ static void pmksa_cache_free_entry(struct hostapd_data *hapd,
prev = pos;
pos = pos->next;
}
- free(entry);
+ _pmksa_cache_free_entry(entry);
}
@@ -884,6 +913,54 @@ 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)
{
@@ -905,6 +982,7 @@ 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
*/
@@ -961,7 +1039,7 @@ static void pmksa_cache_free(struct hostapd_data *hapd)
while (entry) {
prev = entry;
entry = entry->next;
- free(prev);
+ _pmksa_cache_free_entry(prev);
}
eloop_cancel_timeout(pmksa_cache_expire, hapd, NULL);
for (i = 0; i < PMKID_HASH_SIZE; i++)
@@ -1001,7 +1079,7 @@ struct wpa_ie_data {
};
-static int wpa_parse_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
+static int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
struct wpa_ie_data *data)
{
struct wpa_ie_hdr *hdr;
@@ -1080,7 +1158,7 @@ static int wpa_parse_wpa_ie_wpa(u8 *wpa_ie, size_t wpa_ie_len,
}
-static int wpa_parse_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
+static int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
struct wpa_ie_data *data)
{
struct rsn_ie_hdr *hdr;
@@ -1174,7 +1252,7 @@ static int wpa_parse_wpa_ie_rsn(u8 *rsn_ie, size_t rsn_ie_len,
int wpa_validate_wpa_ie(struct hostapd_data *hapd, struct sta_info *sta,
- u8 *wpa_ie, size_t wpa_ie_len, int version)
+ const u8 *wpa_ie, size_t wpa_ie_len, int version)
{
struct wpa_ie_data data;
int ciphers, key_mgmt, res, i;
@@ -1374,6 +1452,7 @@ 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;
@@ -2090,6 +2169,7 @@ 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);
@@ -2296,6 +2376,8 @@ 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