From fc2a924a8c984b838a838a08e259fb4fef265152 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 17 Jun 2012 18:14:43 +0300 Subject: [PATCH] RADIUS DAS: Check Disconnect-Request attributes Reject Disconnect-Request if it includes unsupported attributes. Signed-hostap: Jouni Malinen --- src/radius/radius.c | 21 +++++++++++++++++ src/radius/radius.h | 2 ++ src/radius/radius_das.c | 52 +++++++++++++++++++++++++++++++++++------ 3 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/radius/radius.c b/src/radius/radius.c index ed0a9de7d..66e053a14 100644 --- a/src/radius/radius.c +++ b/src/radius/radius.c @@ -1552,3 +1552,24 @@ int radius_copy_class(struct radius_class_data *dst, return 0; } + + +u8 radius_msg_find_unlisted_attr(struct radius_msg *msg, u8 *attrs) +{ + size_t i, j; + struct radius_attr_hdr *attr; + + for (i = 0; i < msg->attr_used; i++) { + attr = radius_get_attr_hdr(msg, i); + + for (j = 0; attrs[j]; j++) { + if (attr->type == attrs[j]) + break; + } + + if (attrs[j] == 0) + return attr->type; /* unlisted attr */ + } + + return 0; +} diff --git a/src/radius/radius.h b/src/radius/radius.h index 8cc611319..2d059df15 100644 --- a/src/radius/radius.h +++ b/src/radius/radius.h @@ -282,4 +282,6 @@ void radius_free_class(struct radius_class_data *c); int radius_copy_class(struct radius_class_data *dst, const struct radius_class_data *src); +u8 radius_msg_find_unlisted_attr(struct radius_msg *msg, u8 *attrs); + #endif /* RADIUS_H */ diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c index 20c2fc969..d3c144a82 100644 --- a/src/radius/radius_das.c +++ b/src/radius/radius_das.c @@ -29,6 +29,50 @@ struct radius_das_data { }; +static struct radius_msg * radius_das_disconnect(struct radius_das_data *das, + struct radius_msg *msg, + const char *abuf, + int from_port) +{ + struct radius_hdr *hdr; + struct radius_msg *reply; + u8 allowed[] = { + RADIUS_ATTR_USER_NAME, + RADIUS_ATTR_CALLING_STATION_ID, + RADIUS_ATTR_ACCT_SESSION_ID, + RADIUS_ATTR_EVENT_TIMESTAMP, + RADIUS_ATTR_MESSAGE_AUTHENTICATOR, + RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, + 0 + }; + int error = 405; + u8 attr; + + hdr = radius_msg_get_hdr(msg); + + attr = radius_msg_find_unlisted_attr(msg, allowed); + if (attr) { + wpa_printf(MSG_INFO, "DAS: Unsupported attribute %u in " + "Disconnect-Request from %s:%d", attr, + abuf, from_port); + error = 401; + goto fail; + } + + /* TODO */ + + goto fail; + +fail: + reply = radius_msg_new(RADIUS_CODE_DISCONNECT_NAK, hdr->identifier); + if (reply == NULL) + return NULL; + + radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, error); + return reply; +} + + static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) { struct radius_das_data *das = eloop_ctx; @@ -110,13 +154,7 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) switch (hdr->code) { case RADIUS_CODE_DISCONNECT_REQUEST: - /* TODO */ - reply = radius_msg_new(RADIUS_CODE_DISCONNECT_NAK, - hdr->identifier); - if (reply == NULL) - break; - - radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, 405); + reply = radius_das_disconnect(das, msg, abuf, from_port); break; case RADIUS_CODE_COA_REQUEST: /* TODO */