aboutsummaryrefslogtreecommitdiffstats
path: root/src/radius
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-06-17 19:30:01 +0300
committerJouni Malinen <j@w1.fi>2012-06-17 19:30:01 +0300
commit8047a958099516f570eca35dc6f3885a5809633a (patch)
treec128227aa07a905e63dc7ec42c4f2aa80698a453 /src/radius
parentfc2a924a8c984b838a838a08e259fb4fef265152 (diff)
downloadexternal_wpa_supplicant_8_ti-8047a958099516f570eca35dc6f3885a5809633a.zip
external_wpa_supplicant_8_ti-8047a958099516f570eca35dc6f3885a5809633a.tar.gz
external_wpa_supplicant_8_ti-8047a958099516f570eca35dc6f3885a5809633a.tar.bz2
RADIUS DAS: Add support for Disconnect-Request
Calling-Station-Id, Acct-Session-Id, and User-Name attributes in a Disconnect-Request message can now be used to indicate which station is to be disconnected. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'src/radius')
-rw-r--r--src/radius/radius_das.c66
-rw-r--r--src/radius/radius_das.h17
2 files changed, 79 insertions, 4 deletions
diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c
index d3c144a..61e3518 100644
--- a/src/radius/radius_das.c
+++ b/src/radius/radius_das.c
@@ -26,6 +26,9 @@ struct radius_das_data {
struct hostapd_ip_addr client_addr;
unsigned int time_window;
int require_event_timestamp;
+ void *ctx;
+ enum radius_das_res (*disconnect)(void *ctx,
+ struct radius_das_attrs *attr);
};
@@ -47,6 +50,12 @@ static struct radius_msg * radius_das_disconnect(struct radius_das_data *das,
};
int error = 405;
u8 attr;
+ enum radius_das_res res;
+ struct radius_das_attrs attrs;
+ u8 *buf;
+ size_t len;
+ char tmp[100];
+ u8 sta_addr[ETH_ALEN];
hdr = radius_msg_get_hdr(msg);
@@ -59,16 +68,63 @@ static struct radius_msg * radius_das_disconnect(struct radius_das_data *das,
goto fail;
}
- /* TODO */
+ os_memset(&attrs, 0, sizeof(attrs));
+
+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_CALLING_STATION_ID,
+ &buf, &len, NULL) == 0) {
+ if (len >= sizeof(tmp))
+ len = sizeof(tmp) - 1;
+ os_memcpy(tmp, buf, len);
+ tmp[len] = '\0';
+ if (hwaddr_aton2(tmp, sta_addr) < 0) {
+ wpa_printf(MSG_INFO, "DAS: Invalid Calling-Station-Id "
+ "'%s' from %s:%d", tmp, abuf, from_port);
+ error = 407;
+ goto fail;
+ }
+ attrs.sta_addr = sta_addr;
+ }
+
+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME,
+ &buf, &len, NULL) == 0) {
+ attrs.user_name = buf;
+ attrs.user_name_len = len;
+ }
+
+ if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_ACCT_SESSION_ID,
+ &buf, &len, NULL) == 0) {
+ attrs.acct_session_id = buf;
+ attrs.acct_session_id_len = len;
+ }
- goto fail;
+ res = das->disconnect(das->ctx, &attrs);
+ switch (res) {
+ case RADIUS_DAS_NAS_MISMATCH:
+ wpa_printf(MSG_INFO, "DAS: NAS mismatch from %s:%d",
+ abuf, from_port);
+ error = 403;
+ break;
+ case RADIUS_DAS_SESSION_NOT_FOUND:
+ wpa_printf(MSG_INFO, "DAS: Session not found for request from "
+ "%s:%d", abuf, from_port);
+ error = 503;
+ break;
+ case RADIUS_DAS_SUCCESS:
+ error = 0;
+ break;
+ }
fail:
- reply = radius_msg_new(RADIUS_CODE_DISCONNECT_NAK, hdr->identifier);
+ reply = radius_msg_new(error ? RADIUS_CODE_DISCONNECT_NAK :
+ RADIUS_CODE_DISCONNECT_ACK, hdr->identifier);
if (reply == NULL)
return NULL;
- radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE, error);
+ if (error) {
+ radius_msg_add_attr_int32(reply, RADIUS_ATTR_ERROR_CAUSE,
+ error);
+ }
+
return reply;
}
@@ -240,6 +296,8 @@ radius_das_init(struct radius_das_conf *conf)
das->time_window = conf->time_window;
das->require_event_timestamp = conf->require_event_timestamp;
+ das->ctx = conf->ctx;
+ das->disconnect = conf->disconnect;
os_memcpy(&das->client_addr, conf->client_addr,
sizeof(das->client_addr));
diff --git a/src/radius/radius_das.h b/src/radius/radius_das.h
index c3d501d..d0719ed 100644
--- a/src/radius/radius_das.h
+++ b/src/radius/radius_das.h
@@ -11,6 +11,20 @@
struct radius_das_data;
+enum radius_das_res {
+ RADIUS_DAS_SUCCESS,
+ RADIUS_DAS_NAS_MISMATCH,
+ RADIUS_DAS_SESSION_NOT_FOUND
+};
+
+struct radius_das_attrs {
+ const u8 *sta_addr;
+ const u8 *user_name;
+ size_t user_name_len;
+ const u8 *acct_session_id;
+ size_t acct_session_id_len;
+};
+
struct radius_das_conf {
int port;
const u8 *shared_secret;
@@ -18,6 +32,9 @@ struct radius_das_conf {
const struct hostapd_ip_addr *client_addr;
unsigned int time_window;
int require_event_timestamp;
+ void *ctx;
+ enum radius_das_res (*disconnect)(void *ctx,
+ struct radius_das_attrs *attr);
};
struct radius_das_data *