aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-06-17 17:43:36 +0300
committerJouni Malinen <j@w1.fi>2012-06-17 17:43:36 +0300
commitbde7ba6caf3a2e56b277d9fcf3ff05b0606cb833 (patch)
tree58e7f172c472d1410328d34b040ada38bd568598
parentc2d76aa6247b4769b935f11c902aa3f31278278e (diff)
downloadexternal_wpa_supplicant_8_ti-bde7ba6caf3a2e56b277d9fcf3ff05b0606cb833.zip
external_wpa_supplicant_8_ti-bde7ba6caf3a2e56b277d9fcf3ff05b0606cb833.tar.gz
external_wpa_supplicant_8_ti-bde7ba6caf3a2e56b277d9fcf3ff05b0606cb833.tar.bz2
RADIUS DAS: Validate Event-Timestamp
DAS will now validate Event-Timestamp value to be within an acceptable time window (300 seconds by default; can be set using radius_das_time_window parameter). In addition, Event-Timestamp can be required in Disconnect-Request and CoA-Request messages with radius_das_require_event_timestamp=1. Signed-hostap: Jouni Malinen <j@w1.fi>
-rw-r--r--hostapd/config_file.c5
-rw-r--r--hostapd/hostapd.conf6
-rw-r--r--src/ap/ap_config.c2
-rw-r--r--src/ap/ap_config.h2
-rw-r--r--src/ap/hostapd.c3
-rw-r--r--src/radius/radius_das.c30
-rw-r--r--src/radius/radius_das.h2
7 files changed, 48 insertions, 2 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 6729e5c..b00ed8f 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -1693,6 +1693,11 @@ static int hostapd_config_fill(struct hostapd_config *conf,
"DAS client", line);
errors++;
}
+ } else if (os_strcmp(buf, "radius_das_time_window") == 0) {
+ bss->radius_das_time_window = atoi(pos);
+ } else if (os_strcmp(buf, "radius_das_require_event_timestamp")
+ == 0) {
+ bss->radius_das_require_event_timestamp = atoi(pos);
#endif /* CONFIG_NO_RADIUS */
} else if (os_strcmp(buf, "auth_algs") == 0) {
bss->auth_algs = atoi(pos);
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index 611ce95..a7b8ba6 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -708,6 +708,12 @@ own_ip_addr=127.0.0.1
#
# DAS client (the host that can send Disconnect/CoA requests) and shared secret
#radius_das_client=192.168.1.123 shared secret here
+#
+# DAS Event-Timestamp time window in seconds
+#radius_das_time_window=300
+#
+# DAS require Event-Timestamp
+#radius_das_require_event_timestamp=1
##### RADIUS authentication server configuration ##############################
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index e916f12..d8f55a2 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -87,6 +87,8 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
#ifdef CONFIG_IEEE80211R
bss->ft_over_ds = 1;
#endif /* CONFIG_IEEE80211R */
+
+ bss->radius_das_time_window = 300;
}
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 78c9068..1f35f72 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -187,6 +187,8 @@ struct hostapd_bss_config {
struct hostapd_radius_attr *radius_auth_req_attr;
struct hostapd_radius_attr *radius_acct_req_attr;
int radius_das_port;
+ unsigned int radius_das_time_window;
+ int radius_das_require_event_timestamp;
struct hostapd_ip_addr radius_das_client_addr;
u8 *radius_das_shared_secret;
size_t radius_das_shared_secret_len;
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 9d6fd7b..50239b0 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -639,6 +639,9 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first)
das_conf.shared_secret_len =
hapd->conf->radius_das_shared_secret_len;
das_conf.client_addr = &hapd->conf->radius_das_client_addr;
+ das_conf.time_window = hapd->conf->radius_das_time_window;
+ das_conf.require_event_timestamp =
+ hapd->conf->radius_das_require_event_timestamp;
hapd->radius_das = radius_das_init(&das_conf);
if (hapd->radius_das == NULL) {
wpa_printf(MSG_ERROR, "RADIUS DAS initialization "
diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c
index ae3df89..20c2fc9 100644
--- a/src/radius/radius_das.c
+++ b/src/radius/radius_das.c
@@ -24,6 +24,8 @@ struct radius_das_data {
u8 *shared_secret;
size_t shared_secret_len;
struct hostapd_ip_addr client_addr;
+ unsigned int time_window;
+ int require_event_timestamp;
};
@@ -45,6 +47,8 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx)
struct radius_msg *msg, *reply = NULL;
struct radius_hdr *hdr;
struct wpabuf *rbuf;
+ u32 val;
+ int res;
fromlen = sizeof(from);
len = recvfrom(sock, buf, sizeof(buf), 0,
@@ -81,6 +85,27 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx)
goto fail;
}
+ res = radius_msg_get_attr(msg, RADIUS_ATTR_EVENT_TIMESTAMP,
+ (u8 *) &val, 4);
+ if (res == 4) {
+ u32 timestamp = ntohl(val);
+ struct os_time now;
+
+ os_get_time(&now);
+ if (abs(now.sec - timestamp) > das->time_window) {
+ wpa_printf(MSG_DEBUG, "DAS: Unacceptable "
+ "Event-Timestamp (%u; local time %u) in "
+ "packet from %s:%d - drop",
+ timestamp, (unsigned int) now.sec,
+ abuf, from_port);
+ goto fail;
+ }
+ } else if (das->require_event_timestamp) {
+ wpa_printf(MSG_DEBUG, "DAS: Missing Event-Timestamp in packet "
+ "from %s:%d - drop", abuf, from_port);
+ goto fail;
+ }
+
hdr = radius_msg_get_hdr(msg);
switch (hdr->code) {
@@ -110,8 +135,6 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx)
}
if (reply) {
- int res;
-
wpa_printf(MSG_DEBUG, "DAS: Reply to %s:%d", abuf, from_port);
if (radius_msg_finish_das_resp(reply, das->shared_secret,
@@ -177,6 +200,9 @@ radius_das_init(struct radius_das_conf *conf)
if (das == NULL)
return NULL;
+ das->time_window = conf->time_window;
+ das->require_event_timestamp = conf->require_event_timestamp;
+
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 4e21c6d..c3d501d 100644
--- a/src/radius/radius_das.h
+++ b/src/radius/radius_das.h
@@ -16,6 +16,8 @@ struct radius_das_conf {
const u8 *shared_secret;
size_t shared_secret_len;
const struct hostapd_ip_addr *client_addr;
+ unsigned int time_window;
+ int require_event_timestamp;
};
struct radius_das_data *