summaryrefslogtreecommitdiff
path: root/src/eap_server
diff options
context:
space:
mode:
Diffstat (limited to 'src/eap_server')
-rw-r--r--src/eap_server/.gitignore1
-rw-r--r--src/eap_server/eap.c15
-rw-r--r--src/eap_server/eap_fast.c77
-rw-r--r--src/eap_server/eap_gpsk.c2
-rw-r--r--src/eap_server/eap_i.h2
-rw-r--r--src/eap_server/eap_tls_common.c2
-rw-r--r--src/eap_server/eap_tnc.c2
-rw-r--r--src/eap_server/eap_ttls.c13
8 files changed, 84 insertions, 30 deletions
diff --git a/src/eap_server/.gitignore b/src/eap_server/.gitignore
deleted file mode 100644
index a4383358ec72f..0000000000000
--- a/src/eap_server/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.d
diff --git a/src/eap_server/eap.c b/src/eap_server/eap.c
index dea91e635d2f4..897adc3b1a2aa 100644
--- a/src/eap_server/eap.c
+++ b/src/eap_server/eap.c
@@ -573,6 +573,13 @@ SM_STATE(EAP, SUCCESS2)
}
sm->eap_if.eapSuccess = TRUE;
+
+ /*
+ * Start reauthentication with identity request even though we know the
+ * previously used identity. This is needed to get reauthentication
+ * started properly.
+ */
+ sm->start_reauth = TRUE;
}
@@ -1070,7 +1077,7 @@ static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor)
static int eap_sm_Policy_getDecision(struct eap_sm *sm)
{
- if (!sm->eap_server && sm->identity) {
+ if (!sm->eap_server && sm->identity && !sm->start_reauth) {
wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");
return DECISION_PASSTHROUGH;
}
@@ -1091,7 +1098,8 @@ static int eap_sm_Policy_getDecision(struct eap_sm *sm)
return DECISION_FAILURE;
}
- if ((sm->user == NULL || sm->update_user) && sm->identity) {
+ if ((sm->user == NULL || sm->update_user) && sm->identity &&
+ !sm->start_reauth) {
/*
* Allow Identity method to be started once to allow identity
* selection hint to be sent from the authentication server,
@@ -1118,6 +1126,7 @@ static int eap_sm_Policy_getDecision(struct eap_sm *sm)
}
sm->update_user = FALSE;
}
+ sm->start_reauth = FALSE;
if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
(sm->user->methods[sm->user_eap_method_index].vendor !=
@@ -1252,7 +1261,7 @@ void eap_server_sm_deinit(struct eap_sm *sm)
sm->m->reset(sm, sm->eap_method_priv);
wpabuf_free(sm->eap_if.eapReqData);
os_free(sm->eap_if.eapKeyData);
- os_free(sm->lastReqData);
+ wpabuf_free(sm->lastReqData);
wpabuf_free(sm->eap_if.eapRespData);
os_free(sm->identity);
os_free(sm->pac_opaque_encr_key);
diff --git a/src/eap_server/eap_fast.c b/src/eap_server/eap_fast.c
index b474c99a1ff3d..c06f396ffd675 100644
--- a/src/eap_server/eap_fast.c
+++ b/src/eap_server/eap_fast.c
@@ -73,6 +73,10 @@ struct eap_fast_data {
};
+static int eap_fast_process_phase2_start(struct eap_sm *sm,
+ struct eap_fast_data *data);
+
+
static const char * eap_fast_state_txt(int state)
{
switch (state) {
@@ -804,11 +808,48 @@ static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
}
+static int eap_fast_encrypt_phase2(struct eap_sm *sm,
+ struct eap_fast_data *data,
+ struct wpabuf *plain, int piggyback)
+{
+ struct wpabuf *encr;
+
+ wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
+ plain);
+ encr = eap_server_tls_encrypt(sm, &data->ssl, wpabuf_mhead(plain),
+ wpabuf_len(plain));
+ wpabuf_free(plain);
+
+ if (data->ssl.out_buf && piggyback) {
+ wpa_printf(MSG_DEBUG, "EAP-FAST: Piggyback Phase 2 data "
+ "(len=%d) with last Phase 1 Message (len=%d "
+ "used=%d)",
+ (int) wpabuf_len(encr),
+ (int) wpabuf_len(data->ssl.out_buf),
+ (int) data->ssl.out_used);
+ if (wpabuf_resize(&data->ssl.out_buf, wpabuf_len(encr)) < 0) {
+ wpa_printf(MSG_WARNING, "EAP-FAST: Failed to resize "
+ "output buffer");
+ wpabuf_free(encr);
+ return -1;
+ }
+ wpabuf_put_buf(data->ssl.out_buf, encr);
+ wpabuf_free(encr);
+ } else {
+ wpabuf_free(data->ssl.out_buf);
+ data->ssl.out_used = 0;
+ data->ssl.out_buf = encr;
+ }
+
+ return 0;
+}
+
+
static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
struct eap_fast_data *data = priv;
struct wpabuf *req = NULL;
- struct wpabuf *encr;
+ int piggyback = 0;
if (data->ssl.state == FRAG_ACK) {
return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
@@ -827,6 +868,19 @@ static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
if (eap_fast_phase1_done(sm, data) < 0)
return NULL;
+ if (data->state == PHASE2_START) {
+ /*
+ * Try to generate Phase 2 data to piggyback
+ * with the end of Phase 1 to avoid extra
+ * roundtrip.
+ */
+ wpa_printf(MSG_DEBUG, "EAP-FAST: Try to start "
+ "Phase 2");
+ if (eap_fast_process_phase2_start(sm, data))
+ break;
+ req = eap_fast_build_phase2_req(sm, data, id);
+ piggyback = 1;
+ }
}
break;
case PHASE2_ID:
@@ -856,18 +910,9 @@ static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
return NULL;
}
- if (req) {
- wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 "
- "TLVs", req);
- encr = eap_server_tls_encrypt(sm, &data->ssl,
- wpabuf_mhead(req),
- wpabuf_len(req));
- wpabuf_free(req);
-
- wpabuf_free(data->ssl.out_buf);
- data->ssl.out_used = 0;
- data->ssl.out_buf = encr;
- }
+ if (req &&
+ eap_fast_encrypt_phase2(sm, data, req, piggyback) < 0)
+ return NULL;
return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_FAST,
data->fast_version, id);
@@ -1443,8 +1488,8 @@ static int eap_fast_process_phase1(struct eap_sm *sm,
}
-static void eap_fast_process_phase2_start(struct eap_sm *sm,
- struct eap_fast_data *data)
+static int eap_fast_process_phase2_start(struct eap_sm *sm,
+ struct eap_fast_data *data)
{
u8 next_type;
@@ -1474,7 +1519,7 @@ static void eap_fast_process_phase2_start(struct eap_sm *sm,
next_type = EAP_TYPE_IDENTITY;
}
- eap_fast_phase2_init(sm, data, next_type);
+ return eap_fast_phase2_init(sm, data, next_type);
}
diff --git a/src/eap_server/eap_gpsk.c b/src/eap_server/eap_gpsk.c
index c87d4526884af..d0c7559d758b4 100644
--- a/src/eap_server/eap_gpsk.c
+++ b/src/eap_server/eap_gpsk.c
@@ -1,5 +1,5 @@
/*
- * hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt) server
+ * hostapd / EAP-GPSK (RFC 5433) server
* Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/eap_server/eap_i.h b/src/eap_server/eap_i.h
index 61f564d5c49f3..d52b86f9558f0 100644
--- a/src/eap_server/eap_i.h
+++ b/src/eap_server/eap_i.h
@@ -183,6 +183,8 @@ struct eap_sm {
int tnc;
struct wps_context *wps;
struct wpabuf *assoc_wps_ie;
+
+ Boolean start_reauth;
};
int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
diff --git a/src/eap_server/eap_tls_common.c b/src/eap_server/eap_tls_common.c
index befc1bf80f83d..bda1184c02bd2 100644
--- a/src/eap_server/eap_tls_common.c
+++ b/src/eap_server/eap_tls_common.c
@@ -344,7 +344,7 @@ struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm,
size_t buf_len;
/* reserve some extra room for encryption overhead */
- buf_len = plain_len + 200;
+ buf_len = plain_len + 300;
buf = wpabuf_alloc(buf_len);
if (buf == NULL)
return NULL;
diff --git a/src/eap_server/eap_tnc.c b/src/eap_server/eap_tnc.c
index 834685bb7dc27..4cb3ecfb05655 100644
--- a/src/eap_server/eap_tnc.c
+++ b/src/eap_server/eap_tnc.c
@@ -500,7 +500,7 @@ static void eap_tnc_process(struct eap_sm *sm, void *priv,
static Boolean eap_tnc_isDone(struct eap_sm *sm, void *priv)
{
struct eap_tnc_data *data = priv;
- return data->state == DONE;
+ return data->state == DONE || data->state == FAIL;
}
diff --git a/src/eap_server/eap_ttls.c b/src/eap_server/eap_ttls.c
index b097ab2ea0b67..21e4b21b15db6 100644
--- a/src/eap_server/eap_ttls.c
+++ b/src/eap_server/eap_ttls.c
@@ -954,7 +954,7 @@ static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
sm->init_phase2 = 1;
data->phase2_priv = data->phase2_method->init(sm);
sm->init_phase2 = 0;
- return 0;
+ return data->phase2_priv == NULL ? -1 : 0;
}
@@ -1045,6 +1045,11 @@ static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
next_type = sm->user->methods[0].method;
sm->user_eap_method_index = 1;
wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
+ if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
+ wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize "
+ "EAP type %d", next_type);
+ eap_ttls_state(data, FAILURE);
+ }
break;
case PHASE2_METHOD:
if (data->ttls_version > 0) {
@@ -1066,12 +1071,6 @@ static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
__func__, data->state);
break;
}
-
- if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize EAP "
- "type %d", next_type);
- eap_ttls_state(data, FAILURE);
- }
}