From e100828b76f2e6a9ba7c387ad9532710497ee5da Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 7 Aug 2012 18:14:42 +0300 Subject: [PATCH] Return wpabuf from radius_msg_get_eap() This simplifies the implementation by using the buffer type to which the returned data will be converted anyway. This avoids one memory allocation for each processed RADIUS message. Signed-hostap: Jouni Malinen --- src/ap/ieee802_1x.c | 19 ++++++++--------- src/radius/radius.c | 13 ++++-------- src/radius/radius.h | 2 +- src/radius/radius_server.c | 12 ++++------- wpa_supplicant/eapol_test.c | 42 ++++++++++++++++++------------------- 5 files changed, 38 insertions(+), 50 deletions(-) diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c index 25b5065cb..e7009a7c0 100644 --- a/src/ap/ieee802_1x.c +++ b/src/ap/ieee802_1x.c @@ -1039,9 +1039,8 @@ void ieee802_1x_free_station(struct sta_info *sta) static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd, struct sta_info *sta) { - u8 *eap; - size_t len; - struct eap_hdr *hdr; + struct wpabuf *eap; + const struct eap_hdr *hdr; int eap_type = -1; char buf[64]; struct radius_msg *msg; @@ -1055,7 +1054,7 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd, msg = sm->last_recv_radius; - eap = radius_msg_get_eap(msg, &len); + eap = radius_msg_get_eap(msg); if (eap == NULL) { /* RFC 3579, Chap. 2.6.3: * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message @@ -1067,19 +1066,19 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd, return; } - if (len < sizeof(*hdr)) { + if (wpabuf_len(eap) < sizeof(*hdr)) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X, HOSTAPD_LEVEL_WARNING, "too short EAP packet " "received from authentication server"); - os_free(eap); + wpabuf_free(eap); sm->eap_if->aaaEapNoReq = TRUE; return; } - if (len > sizeof(*hdr)) - eap_type = eap[sizeof(*hdr)]; + if (wpabuf_len(eap) > sizeof(*hdr)) + eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; - hdr = (struct eap_hdr *) eap; + hdr = wpabuf_head(eap); switch (hdr->code) { case EAP_CODE_REQUEST: if (eap_type >= 0) @@ -1114,7 +1113,7 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd, sm->eap_if->aaaEapReq = TRUE; wpabuf_free(sm->eap_if->aaaEapReqData); - sm->eap_if->aaaEapReqData = wpabuf_alloc_ext_data(eap, len); + sm->eap_if->aaaEapReqData = eap; } diff --git a/src/radius/radius.c b/src/radius/radius.c index 2b9cbcaa0..ba5f979e0 100644 --- a/src/radius/radius.c +++ b/src/radius/radius.c @@ -707,9 +707,9 @@ int radius_msg_add_eap(struct radius_msg *msg, const u8 *data, size_t data_len) } -u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *eap_len) +struct wpabuf * radius_msg_get_eap(struct radius_msg *msg) { - u8 *eap, *pos; + struct wpabuf *eap; size_t len, i; struct radius_attr_hdr *attr; @@ -726,23 +726,18 @@ u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *eap_len) if (len == 0) return NULL; - eap = os_malloc(len); + eap = wpabuf_alloc(len); if (eap == NULL) return NULL; - pos = eap; for (i = 0; i < msg->attr_used; i++) { attr = radius_get_attr_hdr(msg, i); if (attr->type == RADIUS_ATTR_EAP_MESSAGE) { int flen = attr->length - sizeof(*attr); - os_memcpy(pos, attr + 1, flen); - pos += flen; + wpabuf_put_data(eap, attr + 1, flen); } } - if (eap_len) - *eap_len = len; - return eap; } diff --git a/src/radius/radius.h b/src/radius/radius.h index 2d059df15..fcbb27567 100644 --- a/src/radius/radius.h +++ b/src/radius/radius.h @@ -213,7 +213,7 @@ struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type, struct radius_msg * radius_msg_parse(const u8 *data, size_t len); int radius_msg_add_eap(struct radius_msg *msg, const u8 *data, size_t data_len); -u8 *radius_msg_get_eap(struct radius_msg *msg, size_t *len); +struct wpabuf * radius_msg_get_eap(struct radius_msg *msg); int radius_msg_verify(struct radius_msg *msg, const u8 *secret, size_t secret_len, struct radius_msg *sent_msg, int auth); diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c index 123c59b70..5b2d71111 100644 --- a/src/radius/radius_server.c +++ b/src/radius/radius_server.c @@ -689,8 +689,7 @@ static int radius_server_request(struct radius_server_data *data, const char *from_addr, int from_port, struct radius_session *force_sess) { - u8 *eap = NULL; - size_t eap_len; + struct wpabuf *eap = NULL; int res, state_included = 0; u8 statebuf[4]; unsigned int state; @@ -754,7 +753,7 @@ static int radius_server_request(struct radius_server_data *data, return -1; } - eap = radius_msg_get_eap(msg, &eap_len); + eap = radius_msg_get_eap(msg); if (eap == NULL) { RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s", from_addr); @@ -763,7 +762,7 @@ static int radius_server_request(struct radius_server_data *data, return -1; } - RADIUS_DUMP("Received EAP data", eap, eap_len); + RADIUS_DUMP("Received EAP data", wpabuf_head(eap), wpabuf_len(eap)); /* FIX: if Code is Request, Success, or Failure, send Access-Reject; * RFC3579 Sect. 2.6.2. @@ -773,10 +772,7 @@ static int radius_server_request(struct radius_server_data *data, * Or is this already done by the EAP state machine? */ wpabuf_free(sess->eap_if->eapRespData); - sess->eap_if->eapRespData = wpabuf_alloc_ext_data(eap, eap_len); - if (sess->eap_if->eapRespData == NULL) - os_free(eap); - eap = NULL; + sess->eap_if->eapRespData = eap; sess->eap_if->eapResp = TRUE; eap_server_sm_step(sess->eap); diff --git a/wpa_supplicant/eapol_test.c b/wpa_supplicant/eapol_test.c index 825e2b9db..7d63c1b42 100644 --- a/wpa_supplicant/eapol_test.c +++ b/wpa_supplicant/eapol_test.c @@ -56,9 +56,8 @@ struct eapol_test_data { struct radius_client_data *radius; struct hostapd_radius_servers *radius_conf; - u8 *last_eap_radius; /* last received EAP Response from Authentication - * Server */ - size_t last_eap_radius_len; + /* last received EAP Response from Authentication Server */ + struct wpabuf *last_eap_radius; u8 authenticator_pmk[PMK_LEN]; size_t authenticator_pmk_len; @@ -489,7 +488,7 @@ static void test_eapol_clean(struct eapol_test_data *e, struct extra_radius_attr *p, *prev; radius_client_deinit(e->radius); - os_free(e->last_eap_radius); + wpabuf_free(e->last_eap_radius); radius_msg_free(e->last_recv_radius); e->last_recv_radius = NULL; os_free(e->eap_identity); @@ -579,9 +578,8 @@ static char *eap_type_text(u8 type) static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) { - u8 *eap; - size_t len; - struct eap_hdr *hdr; + struct wpabuf *eap; + const struct eap_hdr *hdr; int eap_type = -1; char buf[64]; struct radius_msg *msg; @@ -591,30 +589,29 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) msg = e->last_recv_radius; - eap = radius_msg_get_eap(msg, &len); + eap = radius_msg_get_eap(msg); if (eap == NULL) { /* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3: * RADIUS server SHOULD NOT send Access-Reject/no EAP-Message * attribute */ wpa_printf(MSG_DEBUG, "could not extract " "EAP-Message from RADIUS message"); - os_free(e->last_eap_radius); + wpabuf_free(e->last_eap_radius); e->last_eap_radius = NULL; - e->last_eap_radius_len = 0; return; } - if (len < sizeof(*hdr)) { + if (wpabuf_len(eap) < sizeof(*hdr)) { wpa_printf(MSG_DEBUG, "too short EAP packet " "received from authentication server"); - os_free(eap); + wpabuf_free(eap); return; } - if (len > sizeof(*hdr)) - eap_type = eap[sizeof(*hdr)]; + if (wpabuf_len(eap) > sizeof(*hdr)) + eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)]; - hdr = (struct eap_hdr *) eap; + hdr = wpabuf_head(eap); switch (hdr->code) { case EAP_CODE_REQUEST: os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)", @@ -637,7 +634,7 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) break; default: os_strlcpy(buf, "unknown EAP code", sizeof(buf)); - wpa_hexdump(MSG_DEBUG, "Decapsulated EAP packet", eap, len); + wpa_hexdump_buf(MSG_DEBUG, "Decapsulated EAP packet", eap); break; } wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d " @@ -646,20 +643,21 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e) /* sta->eapol_sm->be_auth.idFromServer = hdr->identifier; */ - os_free(e->last_eap_radius); + wpabuf_free(e->last_eap_radius); e->last_eap_radius = eap; - e->last_eap_radius_len = len; { struct ieee802_1x_hdr *dot1x; - dot1x = os_malloc(sizeof(*dot1x) + len); + dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap)); assert(dot1x != NULL); dot1x->version = EAPOL_VERSION; dot1x->type = IEEE802_1X_TYPE_EAP_PACKET; - dot1x->length = htons(len); - os_memcpy((u8 *) (dot1x + 1), eap, len); + dot1x->length = htons(wpabuf_len(eap)); + os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap), + wpabuf_len(eap)); eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid, - (u8 *) dot1x, sizeof(*dot1x) + len); + (u8 *) dot1x, + sizeof(*dot1x) + wpabuf_len(eap)); os_free(dot1x); } }