}
-static int eap_fast_process_version(struct eap_fast_data *data,
+static int eap_fast_process_version(struct eap_sm *sm, void *priv,
int peer_version)
{
+ struct eap_fast_data *data = priv;
+
data->peer_version = peer_version;
if (data->force_version >= 0 && peer_version != data->force_version) {
wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
" version (forced=%d peer=%d) - reject",
data->force_version, peer_version);
- eap_fast_state(data, FAILURE);
return -1;
}
}
-static void eap_fast_process(struct eap_sm *sm, void *priv,
- struct wpabuf *respData)
+static void eap_fast_process_msg(struct eap_sm *sm, void *priv,
+ const struct wpabuf *respData)
{
struct eap_fast_data *data = priv;
- const u8 *pos;
- u8 flags;
- size_t left;
- int ret;
-
- pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData,
- &left);
- if (pos == NULL || left < 1)
- return;
- flags = *pos++;
- left--;
- wpa_printf(MSG_DEBUG, "EAP-FAST: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
- flags);
-
- if (eap_fast_process_version(data, flags & EAP_TLS_VERSION_MASK))
- return;
-
- ret = eap_server_tls_reassemble(&data->ssl, flags, &pos, &left);
- if (ret < 0) {
- eap_fast_state(data, FAILURE);
- return;
- } else if (ret == 1)
- return;
switch (data->state) {
case PHASE1:
data->state, __func__);
break;
}
+}
- if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
- wpa_printf(MSG_INFO, "EAP-FAST: Locally detected fatal error "
- "in TLS processing");
- eap_fast_state(data, FAILURE);
- }
- eap_server_tls_free_in_buf(&data->ssl);
+static void eap_fast_process(struct eap_sm *sm, void *priv,
+ struct wpabuf *respData)
+{
+ struct eap_fast_data *data = priv;
+ if (eap_server_tls_process(sm, &data->ssl, respData, data,
+ EAP_TYPE_FAST, eap_fast_process_version,
+ eap_fast_process_msg) < 0)
+ eap_fast_state(data, FAILURE);
}
static void eap_peap_process_phase2(struct eap_sm *sm,
struct eap_peap_data *data,
const struct wpabuf *respData,
- const u8 *in_data, size_t in_len)
+ struct wpabuf *in_buf)
{
struct wpabuf *in_decrypted;
int len_decrypted;
const struct eap_hdr *hdr;
size_t buf_len, len;
+ u8 *in_data;
+ size_t in_len;
+
+ in_data = wpabuf_mhead(in_buf);
+ in_len = wpabuf_len(in_buf);
wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for"
" Phase 2", (unsigned long) in_len);
}
-static void eap_peap_process(struct eap_sm *sm, void *priv,
- struct wpabuf *respData)
+static int eap_peap_process_version(struct eap_sm *sm, void *priv,
+ int peer_version)
{
struct eap_peap_data *data = priv;
- const u8 *pos;
- u8 flags;
- size_t left;
- int peer_version;
- int ret;
- pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PEAP, respData,
- &left);
- if (pos == NULL || left < 1)
- return;
- flags = *pos++;
- left--;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
- flags);
- data->recv_version = peer_version = flags & EAP_TLS_VERSION_MASK;
+ data->recv_version = peer_version;
if (data->force_version >= 0 && peer_version != data->force_version) {
wpa_printf(MSG_INFO, "EAP-PEAP: peer did not select the forced"
" version (forced=%d peer=%d) - reject",
data->force_version, peer_version);
- eap_peap_state(data, FAILURE);
- return;
+ return -1;
}
if (peer_version < data->peap_version) {
wpa_printf(MSG_DEBUG, "EAP-PEAP: peer ver=%d, own ver=%d; "
data->peap_version = peer_version;
}
- ret = eap_server_tls_reassemble(&data->ssl, flags, &pos, &left);
- if (ret < 0) {
- eap_peap_state(data, FAILURE);
- return;
- } else if (ret == 1)
- return;
+ return 0;
+}
+
+
+static void eap_peap_process_msg(struct eap_sm *sm, void *priv,
+ const struct wpabuf *respData)
+{
+ struct eap_peap_data *data = priv;
switch (data->state) {
case PHASE1:
case PHASE2_METHOD:
case PHASE2_SOH:
case PHASE2_TLV:
- eap_peap_process_phase2(sm, data, respData, pos, left);
+ eap_peap_process_phase2(sm, data, respData, data->ssl.in_buf);
break;
case SUCCESS_REQ:
eap_peap_state(data, SUCCESS);
data->state, __func__);
break;
}
+}
- if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
- wpa_printf(MSG_INFO, "EAP-PEAP: Locally detected fatal error "
- "in TLS processing");
- eap_peap_state(data, FAILURE);
- }
- eap_server_tls_free_in_buf(&data->ssl);
+static void eap_peap_process(struct eap_sm *sm, void *priv,
+ struct wpabuf *respData)
+{
+ struct eap_peap_data *data = priv;
+ if (eap_server_tls_process(sm, &data->ssl, respData, data,
+ EAP_TYPE_PEAP, eap_peap_process_version,
+ eap_peap_process_msg) < 0)
+ eap_peap_state(data, FAILURE);
}
}
-static void eap_tls_process(struct eap_sm *sm, void *priv,
- struct wpabuf *respData)
+static void eap_tls_process_msg(struct eap_sm *sm, void *priv,
+ const struct wpabuf *respData)
{
struct eap_tls_data *data = priv;
- const u8 *pos;
- u8 flags;
- size_t left;
- int ret;
-
- pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLS, respData, &left);
- if (pos == NULL || left < 1)
- return; /* Should not happen - frame already validated */
- flags = *pos++;
- left--;
- wpa_printf(MSG_DEBUG, "EAP-TLS: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
- flags);
-
- ret = eap_server_tls_reassemble(&data->ssl, flags, &pos, &left);
- if (ret < 0) {
- data->state = FAILURE;
- return;
- } else if (ret == 1)
- return;
-
if (eap_server_tls_phase1(sm, &data->ssl) < 0)
data->state = FAILURE;
+}
- if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
- wpa_printf(MSG_INFO, "EAP-TLS: Locally detected fatal error "
- "in TLS processing");
- data->state = FAILURE;
- }
- eap_server_tls_free_in_buf(&data->ssl);
+static void eap_tls_process(struct eap_sm *sm, void *priv,
+ struct wpabuf *respData)
+{
+ struct eap_tls_data *data = priv;
+ if (eap_server_tls_process(sm, &data->ssl, respData, data,
+ EAP_TYPE_TLS, NULL, eap_tls_process_msg) <
+ 0)
+ data->state = FAILURE;
}
}
-int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags,
- const u8 **pos, size_t *left)
+static int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags,
+ const u8 **pos, size_t *left)
{
unsigned int tls_msg_len = 0;
const u8 *end = *pos + *left;
}
-void eap_server_tls_free_in_buf(struct eap_ssl_data *data)
+static void eap_server_tls_free_in_buf(struct eap_ssl_data *data)
{
if (data->in_buf != &data->tmpbuf)
wpabuf_free(data->in_buf);
return buf;
}
+
+
+int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data,
+ struct wpabuf *respData, void *priv, int eap_type,
+ int (*proc_version)(struct eap_sm *sm, void *priv,
+ int peer_version),
+ void (*proc_msg)(struct eap_sm *sm, void *priv,
+ const struct wpabuf *respData))
+{
+ const u8 *pos;
+ u8 flags;
+ size_t left;
+ int ret, res = 0;
+
+ pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, &left);
+ if (pos == NULL || left < 1)
+ return 0; /* Should not happen - frame already validated */
+ flags = *pos++;
+ left--;
+ wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x",
+ (unsigned long) wpabuf_len(respData), flags);
+
+ if (proc_version &&
+ proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0)
+ return -1;
+
+ ret = eap_server_tls_reassemble(data, flags, &pos, &left);
+ if (ret < 0) {
+ res = -1;
+ goto done;
+ } else if (ret == 1)
+ return 0;
+
+ if (proc_msg)
+ proc_msg(sm, priv, respData);
+
+ if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) {
+ wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in "
+ "TLS processing");
+ res = -1;
+ }
+
+done:
+ eap_server_tls_free_in_buf(data);
+
+ return res;
+}
int eap_type, int version, u8 id);
struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version);
int eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data);
-int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags,
- const u8 **pos, size_t *left);
-void eap_server_tls_free_in_buf(struct eap_ssl_data *data);
struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm,
struct eap_ssl_data *data,
const u8 *plain, size_t plain_len);
+int eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data,
+ struct wpabuf *respData, void *priv, int eap_type,
+ int (*proc_version)(struct eap_sm *sm, void *priv,
+ int peer_version),
+ void (*proc_msg)(struct eap_sm *sm, void *priv,
+ const struct wpabuf *respData));
#endif /* EAP_TLS_COMMON_H */
}
-static void eap_ttls_process_version(struct eap_sm *sm,
- struct eap_ttls_data *data,
- int peer_version)
+static int eap_ttls_process_version(struct eap_sm *sm, void *priv,
+ int peer_version)
{
+ struct eap_ttls_data *data = priv;
if (peer_version < data->ttls_version) {
wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
"use version %d",
if (tls_connection_set_ia(sm->ssl_ctx, data->ssl.conn, 1)) {
wpa_printf(MSG_INFO, "EAP-TTLS: Failed to enable "
"TLS/IA");
- eap_ttls_state(data, FAILURE);
- return;
+ return -1;
}
data->tls_ia_configured = 1;
}
+
+ return 0;
}
-static void eap_ttls_process(struct eap_sm *sm, void *priv,
- struct wpabuf *respData)
+static void eap_ttls_process_msg(struct eap_sm *sm, void *priv,
+ const struct wpabuf *respData)
{
struct eap_ttls_data *data = priv;
- const u8 *pos;
- u8 flags;
- size_t left;
- int ret;
-
- pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData,
- &left);
- if (pos == NULL || left < 1)
- return;
- flags = *pos++;
- left--;
- wpa_printf(MSG_DEBUG, "EAP-TTLS: Received packet(len=%lu) - "
- "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
- flags);
-
- eap_ttls_process_version(sm, data, flags & EAP_TLS_VERSION_MASK);
-
- ret = eap_server_tls_reassemble(&data->ssl, flags, &pos, &left);
- if (ret < 0) {
- eap_ttls_state(data, FAILURE);
- return;
- } else if (ret == 1)
- return;
switch (data->state) {
case PHASE1:
eap_ttls_start_tnc(sm, data);
break;
case PHASE2_MSCHAPV2_RESP:
- if (data->mschapv2_resp_ok && left == 0) {
+ if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.in_buf) ==
+ 0) {
wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
"acknowledged response");
eap_ttls_state(data, data->ttls_version > 0 ?
wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
"frame from peer (payload len %lu, "
"expected empty frame)",
- (unsigned long) left);
+ (unsigned long)
+ wpabuf_len(data->ssl.in_buf));
eap_ttls_state(data, FAILURE);
}
eap_ttls_start_tnc(sm, data);
data->state, __func__);
break;
}
+}
- if (tls_connection_get_write_alerts(sm->ssl_ctx, data->ssl.conn) > 1) {
- wpa_printf(MSG_INFO, "EAP-TTLS: Locally detected fatal error "
- "in TLS processing");
- eap_ttls_state(data, FAILURE);
- }
- eap_server_tls_free_in_buf(&data->ssl);
+static void eap_ttls_process(struct eap_sm *sm, void *priv,
+ struct wpabuf *respData)
+{
+ struct eap_ttls_data *data = priv;
+ if (eap_server_tls_process(sm, &data->ssl, respData, data,
+ EAP_TYPE_TTLS, eap_ttls_process_version,
+ eap_ttls_process_msg) < 0)
+ eap_ttls_state(data, FAILURE);
}