diff options
Diffstat (limited to 'src/radius')
| -rw-r--r-- | src/radius/radius.c | 124 | ||||
| -rw-r--r-- | src/radius/radius.h | 19 | ||||
| -rw-r--r-- | src/radius/radius_client.c | 150 | ||||
| -rw-r--r-- | src/radius/radius_client.h | 3 | ||||
| -rw-r--r-- | src/radius/radius_das.c | 11 | ||||
| -rw-r--r-- | src/radius/radius_das.h | 1 |
6 files changed, 219 insertions, 89 deletions
diff --git a/src/radius/radius.c b/src/radius/radius.c index 1ebfd11f3b9a2..407e4f8b96149 100644 --- a/src/radius/radius.c +++ b/src/radius/radius.c @@ -1,6 +1,6 @@ /* * RADIUS message processing - * Copyright (c) 2002-2009, 2011-2014, Jouni Malinen <j@w1.fi> + * Copyright (c) 2002-2009, 2011-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -173,6 +173,8 @@ static const struct radius_attr_type radius_attrs[] = { RADIUS_ATTR_USER_PASSWORD, "User-Password", RADIUS_ATTR_UNDIST }, { RADIUS_ATTR_NAS_IP_ADDRESS, "NAS-IP-Address", RADIUS_ATTR_IP }, { RADIUS_ATTR_NAS_PORT, "NAS-Port", RADIUS_ATTR_INT32 }, + { RADIUS_ATTR_SERVICE_TYPE, "Service-Type", RADIUS_ATTR_INT32 }, + { RADIUS_ATTR_FRAMED_IP_ADDRESS, "Framed-IP-Address", RADIUS_ATTR_IP }, { RADIUS_ATTR_FRAMED_MTU, "Framed-MTU", RADIUS_ATTR_INT32 }, { RADIUS_ATTR_REPLY_MESSAGE, "Reply-Message", RADIUS_ATTR_TEXT }, { RADIUS_ATTR_STATE, "State", RADIUS_ATTR_UNDIST }, @@ -214,6 +216,7 @@ static const struct radius_attr_type radius_attrs[] = RADIUS_ATTR_INT32 }, { RADIUS_ATTR_EVENT_TIMESTAMP, "Event-Timestamp", RADIUS_ATTR_INT32 }, + { RADIUS_ATTR_EGRESS_VLANID, "EGRESS-VLANID", RADIUS_ATTR_HEXDUMP }, { RADIUS_ATTR_NAS_PORT_TYPE, "NAS-Port-Type", RADIUS_ATTR_INT32 }, { RADIUS_ATTR_TUNNEL_TYPE, "Tunnel-Type", RADIUS_ATTR_HEXDUMP }, { RADIUS_ATTR_TUNNEL_MEDIUM_TYPE, "Tunnel-Medium-Type", @@ -535,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]; @@ -574,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; } @@ -703,7 +711,7 @@ struct radius_msg * radius_msg_parse(const u8 *data, size_t len) attr = (struct radius_attr_hdr *) pos; - if (pos + attr->length > end || attr->length < sizeof(*attr)) + if (attr->length > end - pos || attr->length < sizeof(*attr)) goto fail; /* TODO: check that attr->length is suitable for attr->type */ @@ -815,8 +823,9 @@ int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret, os_memcpy(msg->hdr->authenticator, req_auth, sizeof(msg->hdr->authenticator)); } - hmac_md5(secret, secret_len, wpabuf_head(msg->buf), - wpabuf_len(msg->buf), auth); + if (hmac_md5(secret, secret_len, wpabuf_head(msg->buf), + wpabuf_len(msg->buf), auth) < 0) + return 1; os_memcpy(attr + 1, orig, MD5_MAC_LEN); if (req_auth) { os_memcpy(msg->hdr->authenticator, orig_authenticator, @@ -859,8 +868,8 @@ int radius_msg_verify(struct radius_msg *msg, const u8 *secret, len[2] = wpabuf_len(msg->buf) - sizeof(struct radius_hdr); addr[3] = secret; len[3] = secret_len; - md5_vector(4, addr, len, hash); - if (os_memcmp_const(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) { + if (md5_vector(4, addr, len, hash) < 0 || + os_memcmp_const(hash, msg->hdr->authenticator, MD5_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "Response Authenticator invalid!"); return 1; } @@ -892,25 +901,11 @@ int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src, /* Create Request Authenticator. The value should be unique over the lifetime * of the shared secret between authenticator and authentication server. - * Use one-way MD5 hash calculated from current timestamp and some data given - * by the caller. */ -void radius_msg_make_authenticator(struct radius_msg *msg, - const u8 *data, size_t len) + */ +int radius_msg_make_authenticator(struct radius_msg *msg) { - struct os_time tv; - long int l; - const u8 *addr[3]; - size_t elen[3]; - - os_get_time(&tv); - l = os_random(); - addr[0] = (u8 *) &tv; - elen[0] = sizeof(tv); - addr[1] = data; - elen[1] = len; - addr[2] = (u8 *) &l; - elen[2] = sizeof(l); - md5_vector(3, addr, elen, msg->hdr->authenticator); + return os_get_random((u8 *) &msg->hdr->authenticator, + sizeof(msg->hdr->authenticator)); } @@ -1028,7 +1023,10 @@ static u8 * decrypt_ms_key(const u8 *key, size_t len, addr[1] = pos - MD5_MAC_LEN; elen[1] = MD5_MAC_LEN; } - md5_vector(first ? 3 : 2, addr, elen, hash); + if (md5_vector(first ? 3 : 2, addr, elen, hash) < 0) { + os_free(plain); + return NULL; + } first = 0; for (i = 0; i < MD5_MAC_LEN; i++) @@ -1210,7 +1208,11 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg, vhdr = (struct radius_attr_vendor *) pos; vhdr->vendor_type = RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY; pos = (u8 *) (vhdr + 1); - salt = os_random() | 0x8000; + if (os_get_random((u8 *) &salt, sizeof(salt)) < 0) { + os_free(buf); + return 0; + } + salt |= 0x8000; WPA_PUT_BE16(pos, salt); pos += 2; encrypt_ms_key(send_key, send_key_len, salt, req_authenticator, secret, @@ -1422,12 +1424,30 @@ struct radius_tunnel_attrs { }; +static int cmp_int(const void *a, const void *b) +{ + int x, y; + + x = *((int *) a); + y = *((int *) b); + return (x - y); +} + + /** * radius_msg_get_vlanid - Parse RADIUS attributes for VLAN tunnel information + * The k tagged vlans found are sorted by vlan_id and stored in the first k + * items of tagged. + * * @msg: RADIUS message - * Returns: VLAN ID for the first tunnel configuration or 0 if none is found + * @untagged: Pointer to store untagged vid + * @numtagged: Size of tagged + * @tagged: Pointer to store tagged list + * + * Returns: 0 if neither tagged nor untagged configuration is found, 1 otherwise */ -int radius_msg_get_vlanid(struct radius_msg *msg) +int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged, + int *tagged) { struct radius_tunnel_attrs tunnel[RADIUS_TUNNEL_TAGS], *tun; size_t i; @@ -1435,8 +1455,12 @@ int radius_msg_get_vlanid(struct radius_msg *msg) const u8 *data; char buf[10]; size_t dlen; + int j, taggedidx = 0, vlan_id; os_memset(&tunnel, 0, sizeof(tunnel)); + for (j = 0; j < numtagged; j++) + tagged[j] = 0; + *untagged = 0; for (i = 0; i < msg->attr_used; i++) { attr = radius_get_attr_hdr(msg, i); @@ -1473,21 +1497,44 @@ int radius_msg_get_vlanid(struct radius_msg *msg) break; os_memcpy(buf, data, dlen); buf[dlen] = '\0'; + vlan_id = atoi(buf); + if (vlan_id <= 0) + break; tun->tag_used++; - tun->vlanid = atoi(buf); + tun->vlanid = vlan_id; + break; + case RADIUS_ATTR_EGRESS_VLANID: /* RFC 4675 */ + if (attr->length != 6) + break; + vlan_id = WPA_GET_BE24(data + 1); + if (vlan_id <= 0) + break; + if (data[0] == 0x32) + *untagged = vlan_id; + else if (data[0] == 0x31 && tagged && + taggedidx < numtagged) + tagged[taggedidx++] = vlan_id; break; } } + /* Use tunnel with the lowest tag for untagged VLAN id */ for (i = 0; i < RADIUS_TUNNEL_TAGS; i++) { tun = &tunnel[i]; if (tun->tag_used && tun->type == RADIUS_TUNNEL_TYPE_VLAN && tun->medium_type == RADIUS_TUNNEL_MEDIUM_TYPE_802 && - tun->vlanid > 0) - return tun->vlanid; + tun->vlanid > 0) { + *untagged = tun->vlanid; + break; + } } + if (taggedidx) + qsort(tagged, taggedidx, sizeof(int), cmp_int); + + if (*untagged > 0 || taggedidx) + return 1; return 0; } @@ -1669,3 +1716,14 @@ u8 radius_msg_find_unlisted_attr(struct radius_msg *msg, u8 *attrs) return 0; } + + +int radius_gen_session_id(u8 *id, size_t len) +{ + /* + * Acct-Session-Id and Acct-Multi-Session-Id should be globally and + * temporarily unique. A high quality random number is required + * therefore. This could be be improved by switching to a GUID. + */ + return os_get_random(id, len); +} diff --git a/src/radius/radius.h b/src/radius/radius.h index 5977339e08d2b..cd510d2c88e22 100644 --- a/src/radius/radius.h +++ b/src/radius/radius.h @@ -1,6 +1,6 @@ /* * RADIUS message processing - * Copyright (c) 2002-2009, 2012, 2014, Jouni Malinen <j@w1.fi> + * Copyright (c) 2002-2009, 2012, 2014-2015, Jouni Malinen <j@w1.fi> * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -52,6 +52,8 @@ enum { RADIUS_ATTR_USER_NAME = 1, RADIUS_ATTR_USER_PASSWORD = 2, RADIUS_ATTR_NAS_IP_ADDRESS = 4, RADIUS_ATTR_NAS_PORT = 5, + RADIUS_ATTR_SERVICE_TYPE = 6, + RADIUS_ATTR_FRAMED_IP_ADDRESS = 8, RADIUS_ATTR_FRAMED_MTU = 12, RADIUS_ATTR_REPLY_MESSAGE = 18, RADIUS_ATTR_STATE = 24, @@ -79,6 +81,7 @@ enum { RADIUS_ATTR_USER_NAME = 1, RADIUS_ATTR_ACCT_INPUT_GIGAWORDS = 52, RADIUS_ATTR_ACCT_OUTPUT_GIGAWORDS = 53, RADIUS_ATTR_EVENT_TIMESTAMP = 55, + RADIUS_ATTR_EGRESS_VLANID = 56, RADIUS_ATTR_NAS_PORT_TYPE = 61, RADIUS_ATTR_TUNNEL_TYPE = 64, RADIUS_ATTR_TUNNEL_MEDIUM_TYPE = 65, @@ -108,6 +111,9 @@ enum { RADIUS_ATTR_USER_NAME = 1, }; +/* Service-Type values (RFC 2865, 5.6) */ +#define RADIUS_SERVICE_TYPE_FRAMED 2 + /* Termination-Action */ #define RADIUS_TERMINATION_ACTION_DEFAULT 0 #define RADIUS_TERMINATION_ACTION_RADIUS_REQUEST 1 @@ -236,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); @@ -250,8 +257,7 @@ int radius_msg_verify_msg_auth(struct radius_msg *msg, const u8 *secret, size_t secret_len, const u8 *req_auth); int radius_msg_copy_attr(struct radius_msg *dst, struct radius_msg *src, u8 type); -void radius_msg_make_authenticator(struct radius_msg *msg, - const u8 *data, size_t len); +int radius_msg_make_authenticator(struct radius_msg *msg); struct radius_ms_mppe_keys * radius_msg_get_ms_keys(struct radius_msg *msg, struct radius_msg *sent_msg, const u8 *secret, size_t secret_len); @@ -274,7 +280,8 @@ radius_msg_add_attr_user_password(struct radius_msg *msg, const u8 *data, size_t data_len, const u8 *secret, size_t secret_len); int radius_msg_get_attr(struct radius_msg *msg, u8 type, u8 *buf, size_t len); -int radius_msg_get_vlanid(struct radius_msg *msg); +int radius_msg_get_vlanid(struct radius_msg *msg, int *untagged, int numtagged, + int *tagged); char * radius_msg_get_tunnel_password(struct radius_msg *msg, int *keylen, const u8 *secret, size_t secret_len, struct radius_msg *sent_msg, size_t n); @@ -319,4 +326,6 @@ int radius_copy_class(struct radius_class_data *dst, u8 radius_msg_find_unlisted_attr(struct radius_msg *msg, u8 *attrs); +int radius_gen_session_id(u8 *id, size_t len); + #endif /* RADIUS_H */ diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c index 693f61ea04552..06c804d132fd5 100644 --- a/src/radius/radius_client.c +++ b/src/radius/radius_client.c @@ -226,6 +226,16 @@ struct radius_client_data { * next_radius_identifier - Next RADIUS message identifier to use */ u8 next_radius_identifier; + + /** + * interim_error_cb - Interim accounting error callback + */ + void (*interim_error_cb)(const u8 *addr, void *ctx); + + /** + * interim_error_cb_ctx - interim_error_cb() context data + */ + void *interim_error_cb_ctx; }; @@ -297,6 +307,25 @@ int radius_client_register(struct radius_client_data *radius, } +/** + * radius_client_set_interim_erro_cb - Register an interim acct error callback + * @radius: RADIUS client context from radius_client_init() + * @addr: Station address from the failed message + * @cb: Handler for interim accounting errors + * @ctx: Context pointer for handler callbacks + * + * This function is used to register a handler for processing failed + * transmission attempts of interim accounting update messages. + */ +void radius_client_set_interim_error_cb(struct radius_client_data *radius, + void (*cb)(const u8 *addr, void *ctx), + void *ctx) +{ + radius->interim_error_cb = cb; + radius->interim_error_cb_ctx = ctx; +} + + /* * Returns >0 if message queue was flushed (i.e., the message that triggered * the error is not available anymore) @@ -308,7 +337,7 @@ static int radius_client_handle_send_error(struct radius_client_data *radius, int _errno = errno; wpa_printf(MSG_INFO, "send[RADIUS,s=%d]: %s", s, strerror(errno)); if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL || - _errno == EBADF || _errno == ENETUNREACH) { + _errno == EBADF || _errno == ENETUNREACH || _errno == EACCES) { hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "Send failed - maybe interface status changed -" @@ -336,6 +365,8 @@ static int radius_client_retransmit(struct radius_client_data *radius, int s; struct wpabuf *buf; size_t prev_num_msgs; + u8 *acct_delay_time; + size_t acct_delay_time_len; if (entry->msg_type == RADIUS_ACCT || entry->msg_type == RADIUS_ACCT_INTERIM) { @@ -371,12 +402,52 @@ static int radius_client_retransmit(struct radius_client_data *radius, conf->auth_server->retransmissions++; } } + + if (entry->msg_type == RADIUS_ACCT_INTERIM) { + wpa_printf(MSG_DEBUG, + "RADIUS: Failed to transmit interim accounting update to " + MACSTR " - drop message and request a new update", + MAC2STR(entry->addr)); + if (radius->interim_error_cb) + radius->interim_error_cb(entry->addr, + radius->interim_error_cb_ctx); + return 1; + } + if (s < 0) { wpa_printf(MSG_INFO, "RADIUS: No valid socket for retransmission"); return 1; } + if (entry->msg_type == RADIUS_ACCT && + radius_msg_get_attr_ptr(entry->msg, RADIUS_ATTR_ACCT_DELAY_TIME, + &acct_delay_time, &acct_delay_time_len, + NULL) == 0 && + acct_delay_time_len == 4) { + struct radius_hdr *hdr; + u32 delay_time; + + /* + * Need to assign a new identifier since attribute contents + * changes. + */ + hdr = radius_msg_get_hdr(entry->msg); + hdr->identifier = radius_client_get_id(radius); + + /* Update Acct-Delay-Time to show wait time in queue */ + delay_time = now - entry->first_try; + WPA_PUT_BE32(acct_delay_time, delay_time); + + wpa_printf(MSG_DEBUG, + "RADIUS: Updated Acct-Delay-Time to %u for retransmission", + delay_time); + radius_msg_finish_acct(entry->msg, entry->shared_secret, + entry->shared_secret_len); + if (radius->conf->msg_dumps) + radius_msg_dump(entry->msg); + } + /* retransmit; remove entry if too many attempts */ entry->attempts++; hostapd_logger(radius->ctx, entry->addr, HOSTAPD_MODULE_RADIUS, @@ -407,7 +478,6 @@ static int radius_client_retransmit(struct radius_client_data *radius, static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) { struct radius_client_data *radius = eloop_ctx; - struct hostapd_radius_servers *conf = radius->conf; struct os_reltime now; os_time_t first; struct radius_msg_list *entry, *prev, *tmp; @@ -476,10 +546,10 @@ static void radius_client_timer(void *eloop_ctx, void *timeout_ctx) (long int) (first - now.sec)); } - if (auth_failover && conf->num_auth_servers > 1) + if (auth_failover) radius_client_auth_failover(radius); - if (acct_failover && conf->num_acct_servers > 1) + if (acct_failover) radius_client_acct_failover(radius); } @@ -625,39 +695,6 @@ static void radius_client_list_add(struct radius_client_data *radius, } -static void radius_client_list_del(struct radius_client_data *radius, - RadiusType msg_type, const u8 *addr) -{ - struct radius_msg_list *entry, *prev, *tmp; - - if (addr == NULL) - return; - - entry = radius->msgs; - prev = NULL; - while (entry) { - if (entry->msg_type == msg_type && - os_memcmp(entry->addr, addr, ETH_ALEN) == 0) { - if (prev) - prev->next = entry->next; - else - radius->msgs = entry->next; - tmp = entry; - entry = entry->next; - hostapd_logger(radius->ctx, addr, - HOSTAPD_MODULE_RADIUS, - HOSTAPD_LEVEL_DEBUG, - "Removing matching RADIUS message"); - radius_client_msg_free(tmp); - radius->num_msgs--; - continue; - } - prev = entry; - entry = entry->next; - } -} - - /** * radius_client_send - Send a RADIUS request * @radius: RADIUS client context from radius_client_init() @@ -669,16 +706,19 @@ static void radius_client_list_del(struct radius_client_data *radius, * This function is used to transmit a RADIUS authentication (RADIUS_AUTH) or * accounting request (RADIUS_ACCT or RADIUS_ACCT_INTERIM). The only difference * between accounting and interim accounting messages is that the interim - * message will override any pending interim accounting updates while a new - * accounting message does not remove any pending messages. + * message will not be retransmitted. Instead, a callback is used to indicate + * that the transmission failed for the specific station @addr so that a new + * interim accounting update message can be generated with up-to-date session + * data instead of trying to resend old information. * * The message is added on the retransmission queue and will be retransmitted * automatically until a response is received or maximum number of retries - * (RADIUS_CLIENT_MAX_RETRIES) is reached. + * (RADIUS_CLIENT_MAX_RETRIES) is reached. No such retries are used with + * RADIUS_ACCT_INTERIM, i.e., such a pending message is removed from the queue + * automatically on transmission failure. * * The related device MAC address can be used to identify pending messages that - * can be removed with radius_client_flush_auth() or with interim accounting - * updates. + * can be removed with radius_client_flush_auth(). */ int radius_client_send(struct radius_client_data *radius, struct radius_msg *msg, RadiusType msg_type, @@ -691,11 +731,6 @@ int radius_client_send(struct radius_client_data *radius, int s, res; struct wpabuf *buf; - if (msg_type == RADIUS_ACCT_INTERIM) { - /* Remove any pending interim acct update for the same STA. */ - radius_client_list_del(radius, msg_type, addr); - } - if (msg_type == RADIUS_ACCT || msg_type == RADIUS_ACCT_INTERIM) { if (conf->acct_server && radius->acct_sock < 0) radius_client_init_acct(radius); @@ -1015,6 +1050,9 @@ radius_change_server(struct radius_client_data *radius, int sel_sock; struct radius_msg_list *entry; struct hostapd_radius_servers *conf = radius->conf; + struct sockaddr_in disconnect_addr = { + .sin_family = AF_UNSPEC, + }; hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, @@ -1023,6 +1061,12 @@ radius_change_server(struct radius_client_data *radius, hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)), nserv->port); + if (oserv && oserv == nserv) { + /* Reconnect to same server, flush */ + if (auth) + radius_client_flush(radius, 1); + } + if (oserv && oserv != nserv && (nserv->shared_secret_len != oserv->shared_secret_len || os_memcmp(nserv->shared_secret, oserv->shared_secret, @@ -1125,6 +1169,11 @@ radius_change_server(struct radius_client_data *radius, } } + /* Force a reconnect by disconnecting the socket first */ + if (connect(sel_sock, (struct sockaddr *) &disconnect_addr, + sizeof(disconnect_addr)) < 0) + wpa_printf(MSG_INFO, "disconnect[radius]: %s", strerror(errno)); + if (connect(sel_sock, addr, addrlen) < 0) { wpa_printf(MSG_INFO, "connect[radius]: %s", strerror(errno)); return -1; @@ -1587,11 +1636,16 @@ static int radius_client_dump_acct_server(char *buf, size_t buflen, int radius_client_get_mib(struct radius_client_data *radius, char *buf, size_t buflen) { - struct hostapd_radius_servers *conf = radius->conf; + struct hostapd_radius_servers *conf; int i; struct hostapd_radius_server *serv; int count = 0; + if (!radius) + return 0; + + conf = radius->conf; + if (conf->auth_servers) { for (i = 0; i < conf->num_auth_servers; i++) { serv = &conf->auth_servers[i]; diff --git a/src/radius/radius_client.h b/src/radius/radius_client.h index 3db16aa282ba7..8ca0874db498a 100644 --- a/src/radius/radius_client.h +++ b/src/radius/radius_client.h @@ -241,6 +241,9 @@ int radius_client_register(struct radius_client_data *radius, const u8 *shared_secret, size_t shared_secret_len, void *data), void *data); +void radius_client_set_interim_error_cb(struct radius_client_data *radius, + void (*cb)(const u8 *addr, void *ctx), + void *ctx); int radius_client_send(struct radius_client_data *radius, struct radius_msg *msg, RadiusType msg_type, const u8 *addr); diff --git a/src/radius/radius_das.c b/src/radius/radius_das.c index b7d991bbd0979..8a3d7e0324bc2 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 ce731d46a9ace..9863fdc1eaca0 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); |
