summaryrefslogtreecommitdiff
path: root/src/eapol_auth/eapol_auth_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eapol_auth/eapol_auth_sm.c')
-rw-r--r--src/eapol_auth/eapol_auth_sm.c107
1 files changed, 91 insertions, 16 deletions
diff --git a/src/eapol_auth/eapol_auth_sm.c b/src/eapol_auth/eapol_auth_sm.c
index c3ccb46bf3832..0df6eb56416b6 100644
--- a/src/eapol_auth/eapol_auth_sm.c
+++ b/src/eapol_auth/eapol_auth_sm.c
@@ -1,6 +1,6 @@
/*
* IEEE 802.1X-2004 Authenticator - EAPOL state machine
- * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -43,6 +43,7 @@ sm->eapol->cb.set_port_authorized(sm->eapol->conf.ctx, sm->sta, 0)
static void eapol_sm_step_run(struct eapol_state_machine *sm);
static void eapol_sm_step_cb(void *eloop_ctx, void *timeout_ctx);
static void eapol_auth_initialize(struct eapol_state_machine *sm);
+static void eapol_auth_conf_free(struct eapol_auth_config *conf);
static void eapol_auth_logger(struct eapol_authenticator *eapol,
@@ -219,7 +220,8 @@ SM_STATE(AUTH_PAE, DISCONNECTED)
sm->eapolLogoff = FALSE;
if (!from_initialize) {
sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 0,
- sm->flags & EAPOL_SM_PREAUTH);
+ sm->flags & EAPOL_SM_PREAUTH,
+ sm->remediation);
}
}
@@ -276,7 +278,7 @@ SM_STATE(AUTH_PAE, HELD)
eap_server_get_name(0, sm->eap_type_supp));
}
sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 0,
- sm->flags & EAPOL_SM_PREAUTH);
+ sm->flags & EAPOL_SM_PREAUTH, sm->remediation);
}
@@ -302,7 +304,7 @@ SM_STATE(AUTH_PAE, AUTHENTICATED)
eap_server_get_name(0, sm->eap_type_authsrv),
extra);
sm->eapol->cb.finished(sm->eapol->conf.ctx, sm->sta, 1,
- sm->flags & EAPOL_SM_PREAUTH);
+ sm->flags & EAPOL_SM_PREAUTH, sm->remediation);
}
@@ -830,6 +832,9 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
eap_conf.fragment_size = eapol->conf.fragment_size;
eap_conf.pwd_group = eapol->conf.pwd_group;
eap_conf.pbc_in_m1 = eapol->conf.pbc_in_m1;
+ eap_conf.server_id = eapol->conf.server_id;
+ eap_conf.server_id_len = eapol->conf.server_id_len;
+ eap_conf.erp = eapol->conf.erp;
sm->eap = eap_server_sm_init(sm, &eapol_cb, &eap_conf);
if (sm->eap == NULL) {
eapol_auth_free(sm);
@@ -848,6 +853,11 @@ eapol_auth_alloc(struct eapol_authenticator *eapol, const u8 *addr,
sm->radius_cui = wpabuf_alloc_copy(radius_cui,
os_strlen(radius_cui));
+ sm->acct_multi_session_id_lo = eapol->acct_multi_session_id_lo++;
+ if (eapol->acct_multi_session_id_lo == 0)
+ eapol->acct_multi_session_id_hi++;
+ sm->acct_multi_session_id_hi = eapol->acct_multi_session_id_hi;
+
return sm;
}
@@ -999,8 +1009,13 @@ static int eapol_sm_get_eap_user(void *ctx, const u8 *identity,
struct eap_user *user)
{
struct eapol_state_machine *sm = ctx;
- return sm->eapol->cb.get_eap_user(sm->eapol->conf.ctx, identity,
- identity_len, phase2, user);
+ int ret;
+
+ ret = sm->eapol->cb.get_eap_user(sm->eapol->conf.ctx, identity,
+ identity_len, phase2, user);
+ if (user->remediation)
+ sm->remediation = 1;
+ return ret;
}
@@ -1012,10 +1027,44 @@ static const char * eapol_sm_get_eap_req_id_text(void *ctx, size_t *len)
}
+static int eapol_sm_get_erp_send_reauth_start(void *ctx)
+{
+ struct eapol_state_machine *sm = ctx;
+ return sm->eapol->conf.erp_send_reauth_start;
+}
+
+
+static const char * eapol_sm_get_erp_domain(void *ctx)
+{
+ struct eapol_state_machine *sm = ctx;
+ return sm->eapol->conf.erp_domain;
+}
+
+
+static struct eap_server_erp_key * eapol_sm_erp_get_key(void *ctx,
+ const char *keyname)
+{
+ struct eapol_state_machine *sm = ctx;
+ return sm->eapol->cb.erp_get_key(sm->eapol->conf.ctx, keyname);
+}
+
+
+static int eapol_sm_erp_add_key(void *ctx, struct eap_server_erp_key *erp)
+{
+ struct eapol_state_machine *sm = ctx;
+ return sm->eapol->cb.erp_add_key(sm->eapol->conf.ctx, erp);
+}
+
+
static struct eapol_callbacks eapol_cb =
{
eapol_sm_get_eap_user,
- eapol_sm_get_eap_req_id_text
+ eapol_sm_get_eap_req_id_text,
+ NULL,
+ eapol_sm_get_erp_send_reauth_start,
+ eapol_sm_get_erp_domain,
+ eapol_sm_erp_get_key,
+ eapol_sm_erp_add_key,
};
@@ -1045,6 +1094,8 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
os_free(dst->eap_req_id_text);
dst->pwd_group = src->pwd_group;
dst->pbc_in_m1 = src->pbc_in_m1;
+ dst->server_id = src->server_id;
+ dst->server_id_len = src->server_id_len;
if (src->eap_req_id_text) {
dst->eap_req_id_text = os_malloc(src->eap_req_id_text_len);
if (dst->eap_req_id_text == NULL)
@@ -1058,16 +1109,16 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
}
if (src->pac_opaque_encr_key) {
dst->pac_opaque_encr_key = os_malloc(16);
+ if (dst->pac_opaque_encr_key == NULL)
+ goto fail;
os_memcpy(dst->pac_opaque_encr_key, src->pac_opaque_encr_key,
16);
} else
dst->pac_opaque_encr_key = NULL;
if (src->eap_fast_a_id) {
dst->eap_fast_a_id = os_malloc(src->eap_fast_a_id_len);
- if (dst->eap_fast_a_id == NULL) {
- os_free(dst->eap_req_id_text);
- return -1;
- }
+ if (dst->eap_fast_a_id == NULL)
+ goto fail;
os_memcpy(dst->eap_fast_a_id, src->eap_fast_a_id,
src->eap_fast_a_id_len);
dst->eap_fast_a_id_len = src->eap_fast_a_id_len;
@@ -1075,11 +1126,8 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
dst->eap_fast_a_id = NULL;
if (src->eap_fast_a_id_info) {
dst->eap_fast_a_id_info = os_strdup(src->eap_fast_a_id_info);
- if (dst->eap_fast_a_id_info == NULL) {
- os_free(dst->eap_req_id_text);
- os_free(dst->eap_fast_a_id);
- return -1;
- }
+ if (dst->eap_fast_a_id_info == NULL)
+ goto fail;
} else
dst->eap_fast_a_id_info = NULL;
dst->eap_fast_prov = src->eap_fast_prov;
@@ -1089,7 +1137,23 @@ static int eapol_auth_conf_clone(struct eapol_auth_config *dst,
dst->tnc = src->tnc;
dst->wps = src->wps;
dst->fragment_size = src->fragment_size;
+
+ os_free(dst->erp_domain);
+ if (src->erp_domain) {
+ dst->erp_domain = os_strdup(src->erp_domain);
+ if (dst->erp_domain == NULL)
+ goto fail;
+ } else {
+ dst->erp_domain = NULL;
+ }
+ dst->erp_send_reauth_start = src->erp_send_reauth_start;
+ dst->erp = src->erp;
+
return 0;
+
+fail:
+ eapol_auth_conf_free(dst);
+ return -1;
}
@@ -1103,6 +1167,8 @@ static void eapol_auth_conf_free(struct eapol_auth_config *conf)
conf->eap_fast_a_id = NULL;
os_free(conf->eap_fast_a_id_info);
conf->eap_fast_a_id_info = NULL;
+ os_free(conf->erp_domain);
+ conf->erp_domain = NULL;
}
@@ -1110,6 +1176,7 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
struct eapol_auth_cb *cb)
{
struct eapol_authenticator *eapol;
+ struct os_time now;
eapol = os_zalloc(sizeof(*eapol));
if (eapol == NULL)
@@ -1135,6 +1202,14 @@ struct eapol_authenticator * eapol_auth_init(struct eapol_auth_config *conf,
eapol->cb.abort_auth = cb->abort_auth;
eapol->cb.tx_key = cb->tx_key;
eapol->cb.eapol_event = cb->eapol_event;
+ eapol->cb.erp_get_key = cb->erp_get_key;
+ eapol->cb.erp_add_key = cb->erp_add_key;
+
+ /* Acct-Multi-Session-Id should be unique over reboots. If reliable
+ * clock is not available, this could be replaced with reboot counter,
+ * etc. */
+ os_get_time(&now);
+ eapol->acct_multi_session_id_hi = now.sec;
return eapol;
}