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 <j@w1.fi>
This commit is contained in:
parent
95ac3bf49f
commit
e100828b76
5 changed files with 38 additions and 50 deletions
|
@ -1039,9 +1039,8 @@ void ieee802_1x_free_station(struct sta_info *sta)
|
||||||
static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
|
static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
|
||||||
struct sta_info *sta)
|
struct sta_info *sta)
|
||||||
{
|
{
|
||||||
u8 *eap;
|
struct wpabuf *eap;
|
||||||
size_t len;
|
const struct eap_hdr *hdr;
|
||||||
struct eap_hdr *hdr;
|
|
||||||
int eap_type = -1;
|
int eap_type = -1;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
struct radius_msg *msg;
|
struct radius_msg *msg;
|
||||||
|
@ -1055,7 +1054,7 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
|
||||||
|
|
||||||
msg = sm->last_recv_radius;
|
msg = sm->last_recv_radius;
|
||||||
|
|
||||||
eap = radius_msg_get_eap(msg, &len);
|
eap = radius_msg_get_eap(msg);
|
||||||
if (eap == NULL) {
|
if (eap == NULL) {
|
||||||
/* RFC 3579, Chap. 2.6.3:
|
/* RFC 3579, Chap. 2.6.3:
|
||||||
* RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
|
* 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < sizeof(*hdr)) {
|
if (wpabuf_len(eap) < sizeof(*hdr)) {
|
||||||
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
|
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE8021X,
|
||||||
HOSTAPD_LEVEL_WARNING, "too short EAP packet "
|
HOSTAPD_LEVEL_WARNING, "too short EAP packet "
|
||||||
"received from authentication server");
|
"received from authentication server");
|
||||||
os_free(eap);
|
wpabuf_free(eap);
|
||||||
sm->eap_if->aaaEapNoReq = TRUE;
|
sm->eap_if->aaaEapNoReq = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > sizeof(*hdr))
|
if (wpabuf_len(eap) > sizeof(*hdr))
|
||||||
eap_type = eap[sizeof(*hdr)];
|
eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];
|
||||||
|
|
||||||
hdr = (struct eap_hdr *) eap;
|
hdr = wpabuf_head(eap);
|
||||||
switch (hdr->code) {
|
switch (hdr->code) {
|
||||||
case EAP_CODE_REQUEST:
|
case EAP_CODE_REQUEST:
|
||||||
if (eap_type >= 0)
|
if (eap_type >= 0)
|
||||||
|
@ -1114,7 +1113,7 @@ static void ieee802_1x_decapsulate_radius(struct hostapd_data *hapd,
|
||||||
sm->eap_if->aaaEapReq = TRUE;
|
sm->eap_if->aaaEapReq = TRUE;
|
||||||
|
|
||||||
wpabuf_free(sm->eap_if->aaaEapReqData);
|
wpabuf_free(sm->eap_if->aaaEapReqData);
|
||||||
sm->eap_if->aaaEapReqData = wpabuf_alloc_ext_data(eap, len);
|
sm->eap_if->aaaEapReqData = eap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
size_t len, i;
|
||||||
struct radius_attr_hdr *attr;
|
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)
|
if (len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
eap = os_malloc(len);
|
eap = wpabuf_alloc(len);
|
||||||
if (eap == NULL)
|
if (eap == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pos = eap;
|
|
||||||
for (i = 0; i < msg->attr_used; i++) {
|
for (i = 0; i < msg->attr_used; i++) {
|
||||||
attr = radius_get_attr_hdr(msg, i);
|
attr = radius_get_attr_hdr(msg, i);
|
||||||
if (attr->type == RADIUS_ATTR_EAP_MESSAGE) {
|
if (attr->type == RADIUS_ATTR_EAP_MESSAGE) {
|
||||||
int flen = attr->length - sizeof(*attr);
|
int flen = attr->length - sizeof(*attr);
|
||||||
os_memcpy(pos, attr + 1, flen);
|
wpabuf_put_data(eap, attr + 1, flen);
|
||||||
pos += flen;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eap_len)
|
|
||||||
*eap_len = len;
|
|
||||||
|
|
||||||
return eap;
|
return eap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
|
||||||
int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
|
int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
|
||||||
size_t data_len);
|
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,
|
int radius_msg_verify(struct radius_msg *msg, const u8 *secret,
|
||||||
size_t secret_len, struct radius_msg *sent_msg,
|
size_t secret_len, struct radius_msg *sent_msg,
|
||||||
int auth);
|
int auth);
|
||||||
|
|
|
@ -689,8 +689,7 @@ static int radius_server_request(struct radius_server_data *data,
|
||||||
const char *from_addr, int from_port,
|
const char *from_addr, int from_port,
|
||||||
struct radius_session *force_sess)
|
struct radius_session *force_sess)
|
||||||
{
|
{
|
||||||
u8 *eap = NULL;
|
struct wpabuf *eap = NULL;
|
||||||
size_t eap_len;
|
|
||||||
int res, state_included = 0;
|
int res, state_included = 0;
|
||||||
u8 statebuf[4];
|
u8 statebuf[4];
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
|
@ -754,7 +753,7 @@ static int radius_server_request(struct radius_server_data *data,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
eap = radius_msg_get_eap(msg, &eap_len);
|
eap = radius_msg_get_eap(msg);
|
||||||
if (eap == NULL) {
|
if (eap == NULL) {
|
||||||
RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
|
RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
|
||||||
from_addr);
|
from_addr);
|
||||||
|
@ -763,7 +762,7 @@ static int radius_server_request(struct radius_server_data *data,
|
||||||
return -1;
|
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;
|
/* FIX: if Code is Request, Success, or Failure, send Access-Reject;
|
||||||
* RFC3579 Sect. 2.6.2.
|
* 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? */
|
* Or is this already done by the EAP state machine? */
|
||||||
|
|
||||||
wpabuf_free(sess->eap_if->eapRespData);
|
wpabuf_free(sess->eap_if->eapRespData);
|
||||||
sess->eap_if->eapRespData = wpabuf_alloc_ext_data(eap, eap_len);
|
sess->eap_if->eapRespData = eap;
|
||||||
if (sess->eap_if->eapRespData == NULL)
|
|
||||||
os_free(eap);
|
|
||||||
eap = NULL;
|
|
||||||
sess->eap_if->eapResp = TRUE;
|
sess->eap_if->eapResp = TRUE;
|
||||||
eap_server_sm_step(sess->eap);
|
eap_server_sm_step(sess->eap);
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,8 @@ struct eapol_test_data {
|
||||||
struct radius_client_data *radius;
|
struct radius_client_data *radius;
|
||||||
struct hostapd_radius_servers *radius_conf;
|
struct hostapd_radius_servers *radius_conf;
|
||||||
|
|
||||||
u8 *last_eap_radius; /* last received EAP Response from Authentication
|
/* last received EAP Response from Authentication Server */
|
||||||
* Server */
|
struct wpabuf *last_eap_radius;
|
||||||
size_t last_eap_radius_len;
|
|
||||||
|
|
||||||
u8 authenticator_pmk[PMK_LEN];
|
u8 authenticator_pmk[PMK_LEN];
|
||||||
size_t authenticator_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;
|
struct extra_radius_attr *p, *prev;
|
||||||
|
|
||||||
radius_client_deinit(e->radius);
|
radius_client_deinit(e->radius);
|
||||||
os_free(e->last_eap_radius);
|
wpabuf_free(e->last_eap_radius);
|
||||||
radius_msg_free(e->last_recv_radius);
|
radius_msg_free(e->last_recv_radius);
|
||||||
e->last_recv_radius = NULL;
|
e->last_recv_radius = NULL;
|
||||||
os_free(e->eap_identity);
|
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)
|
static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
|
||||||
{
|
{
|
||||||
u8 *eap;
|
struct wpabuf *eap;
|
||||||
size_t len;
|
const struct eap_hdr *hdr;
|
||||||
struct eap_hdr *hdr;
|
|
||||||
int eap_type = -1;
|
int eap_type = -1;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
struct radius_msg *msg;
|
struct radius_msg *msg;
|
||||||
|
@ -591,30 +589,29 @@ static void ieee802_1x_decapsulate_radius(struct eapol_test_data *e)
|
||||||
|
|
||||||
msg = e->last_recv_radius;
|
msg = e->last_recv_radius;
|
||||||
|
|
||||||
eap = radius_msg_get_eap(msg, &len);
|
eap = radius_msg_get_eap(msg);
|
||||||
if (eap == NULL) {
|
if (eap == NULL) {
|
||||||
/* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
|
/* draft-aboba-radius-rfc2869bis-20.txt, Chap. 2.6.3:
|
||||||
* RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
|
* RADIUS server SHOULD NOT send Access-Reject/no EAP-Message
|
||||||
* attribute */
|
* attribute */
|
||||||
wpa_printf(MSG_DEBUG, "could not extract "
|
wpa_printf(MSG_DEBUG, "could not extract "
|
||||||
"EAP-Message from RADIUS message");
|
"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 = NULL;
|
||||||
e->last_eap_radius_len = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len < sizeof(*hdr)) {
|
if (wpabuf_len(eap) < sizeof(*hdr)) {
|
||||||
wpa_printf(MSG_DEBUG, "too short EAP packet "
|
wpa_printf(MSG_DEBUG, "too short EAP packet "
|
||||||
"received from authentication server");
|
"received from authentication server");
|
||||||
os_free(eap);
|
wpabuf_free(eap);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len > sizeof(*hdr))
|
if (wpabuf_len(eap) > sizeof(*hdr))
|
||||||
eap_type = eap[sizeof(*hdr)];
|
eap_type = (wpabuf_head_u8(eap))[sizeof(*hdr)];
|
||||||
|
|
||||||
hdr = (struct eap_hdr *) eap;
|
hdr = wpabuf_head(eap);
|
||||||
switch (hdr->code) {
|
switch (hdr->code) {
|
||||||
case EAP_CODE_REQUEST:
|
case EAP_CODE_REQUEST:
|
||||||
os_snprintf(buf, sizeof(buf), "EAP-Request-%s (%d)",
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
os_strlcpy(buf, "unknown EAP code", sizeof(buf));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
wpa_printf(MSG_DEBUG, "decapsulated EAP packet (code=%d "
|
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; */
|
/* 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 = eap;
|
||||||
e->last_eap_radius_len = len;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ieee802_1x_hdr *dot1x;
|
struct ieee802_1x_hdr *dot1x;
|
||||||
dot1x = os_malloc(sizeof(*dot1x) + len);
|
dot1x = os_malloc(sizeof(*dot1x) + wpabuf_len(eap));
|
||||||
assert(dot1x != NULL);
|
assert(dot1x != NULL);
|
||||||
dot1x->version = EAPOL_VERSION;
|
dot1x->version = EAPOL_VERSION;
|
||||||
dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
|
dot1x->type = IEEE802_1X_TYPE_EAP_PACKET;
|
||||||
dot1x->length = htons(len);
|
dot1x->length = htons(wpabuf_len(eap));
|
||||||
os_memcpy((u8 *) (dot1x + 1), eap, len);
|
os_memcpy((u8 *) (dot1x + 1), wpabuf_head(eap),
|
||||||
|
wpabuf_len(eap));
|
||||||
eapol_sm_rx_eapol(e->wpa_s->eapol, e->wpa_s->bssid,
|
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);
|
os_free(dot1x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue