From 42d30e9ea08c51c95d4c8e53f953ae828e3e3fdc Mon Sep 17 00:00:00 2001 From: Nick Lowe Date: Tue, 26 Jul 2016 19:17:09 +0100 Subject: [PATCH] Add a require_message_authenticator configuration option This can be used to mandate the presence of the Message-Authenticator attribute on CoA/Disconnect-Request packets. Signed-off-by: Nick Lowe --- hostapd/config_file.c | 3 +++ hostapd/hostapd.conf | 3 +++ src/ap/ap_config.h | 1 + src/ap/hostapd.c | 2 ++ src/radius/radius.c | 9 +++++++-- src/radius/radius.h | 3 ++- src/radius/radius_das.c | 11 ++++++++--- src/radius/radius_das.h | 1 + 8 files changed, 27 insertions(+), 6 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 6dc7e8c83..6c53151d7 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -2411,6 +2411,9 @@ static int hostapd_config_fill(struct hostapd_config *conf, 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); + } else if (os_strcmp(buf, "radius_das_require_message_authenticator") == + 0) { + bss->radius_das_require_message_authenticator = 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 c2446240b..a310c0576 100644 --- a/hostapd/hostapd.conf +++ b/hostapd/hostapd.conf @@ -1088,6 +1088,9 @@ own_ip_addr=127.0.0.1 # # DAS require Event-Timestamp #radius_das_require_event_timestamp=1 +# +# DAS require Message-Authenticator +#radius_das_require_message_authenticator=1 ##### RADIUS authentication server configuration ############################## diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h index 0ae9a6e0c..64daf4c81 100644 --- a/src/ap/ap_config.h +++ b/src/ap/ap_config.h @@ -263,6 +263,7 @@ struct hostapd_bss_config { int radius_das_port; unsigned int radius_das_time_window; int radius_das_require_event_timestamp; + int radius_das_require_message_authenticator; 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 30f57f4b0..65f513d1a 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1044,6 +1044,8 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first) das_conf.time_window = conf->radius_das_time_window; das_conf.require_event_timestamp = conf->radius_das_require_event_timestamp; + das_conf.require_message_authenticator = + conf->radius_das_require_message_authenticator; das_conf.ctx = hapd; das_conf.disconnect = hostapd_das_disconnect; hapd->radius_das = radius_das_init(&das_conf); diff --git a/src/radius/radius.c b/src/radius/radius.c index defcd9274..407e4f8b9 100644 --- a/src/radius/radius.c +++ b/src/radius/radius.c @@ -538,7 +538,8 @@ int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret, int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret, - size_t secret_len) + size_t secret_len, + int require_message_authenticator) { const u8 *addr[4]; size_t len[4]; @@ -577,7 +578,11 @@ int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret, } if (attr == NULL) { - /* Message-Authenticator is MAY; not required */ + if (require_message_authenticator) { + wpa_printf(MSG_WARNING, + "Missing Message-Authenticator attribute in RADIUS message"); + return 1; + } return 0; } diff --git a/src/radius/radius.h b/src/radius/radius.h index cba2b9118..cd510d2c8 100644 --- a/src/radius/radius.h +++ b/src/radius/radius.h @@ -242,7 +242,8 @@ void radius_msg_finish_acct_resp(struct radius_msg *msg, const u8 *secret, int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret, size_t secret_len); int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret, - size_t secret_len); + size_t secret_len, + int require_message_authenticator); struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type, const u8 *data, size_t data_len); struct radius_msg * radius_msg_parse(const u8 *data, size_t len); diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c index b7d991bbd..8a3d7e032 100644 --- a/src/radius/radius_das.c +++ b/src/radius/radius_das.c @@ -23,6 +23,7 @@ struct radius_das_data { struct hostapd_ip_addr client_addr; unsigned int time_window; int require_event_timestamp; + int require_message_authenticator; void *ctx; enum radius_das_res (*disconnect)(void *ctx, struct radius_das_attrs *attr); @@ -234,9 +235,11 @@ static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) radius_msg_dump(msg); if (radius_msg_verify_das_req(msg, das->shared_secret, - das->shared_secret_len)) { - wpa_printf(MSG_DEBUG, "DAS: Invalid authenticator in packet " - "from %s:%d - drop", abuf, from_port); + das->shared_secret_len, + das->require_message_authenticator)) { + wpa_printf(MSG_DEBUG, + "DAS: Invalid authenticator or Message-Authenticator in packet from %s:%d - drop", + abuf, from_port); goto fail; } @@ -362,6 +365,8 @@ radius_das_init(struct radius_das_conf *conf) das->time_window = conf->time_window; das->require_event_timestamp = conf->require_event_timestamp; + das->require_message_authenticator = + conf->require_message_authenticator; das->ctx = conf->ctx; das->disconnect = conf->disconnect; diff --git a/src/radius/radius_das.h b/src/radius/radius_das.h index ce731d46a..9863fdc1e 100644 --- a/src/radius/radius_das.h +++ b/src/radius/radius_das.h @@ -44,6 +44,7 @@ struct radius_das_conf { const struct hostapd_ip_addr *client_addr; unsigned int time_window; int require_event_timestamp; + int require_message_authenticator; void *ctx; enum radius_das_res (*disconnect)(void *ctx, struct radius_das_attrs *attr);