mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
Fix psk2-radius feature
Add psk2-radius functionality in hostapd and fix config via netifd. Fixes WIFI-13183 Signed-off-by: Arif Alam <arif.alam@netexperience.com>
This commit is contained in:
@@ -0,0 +1,459 @@
|
||||
From 1c3438fec4bad13a676617915ff56af54e7b4542 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 2 Apr 2022 13:12:43 +0300
|
||||
Subject: [PATCH] RADIUS ACL/PSK check during 4-way handshake
|
||||
|
||||
Add an alternative sequence for performing the RADIUS ACL check and PSK
|
||||
fetch. The previously used (macaddr_acl=2, wpa_psk_radius=2) combination
|
||||
does this during IEEE 802.11 Authentication frame exchange while the new
|
||||
option (wpa_psk_radius=3) does this during the 4-way handshake. This
|
||||
allows some more information to be provided to the RADIUS authentication
|
||||
server.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
hostapd/config_file.c | 3 +-
|
||||
hostapd/hostapd.conf | 5 ++-
|
||||
src/ap/ap_config.c | 4 ++-
|
||||
src/ap/ap_config.h | 5 +--
|
||||
src/ap/ieee802_11.c | 5 ++-
|
||||
src/ap/ieee802_11.h | 2 ++
|
||||
src/ap/ieee802_11_auth.c | 76 ++++++++++++++++++++++++++++++++++++----
|
||||
src/ap/ieee802_11_auth.h | 5 ++-
|
||||
src/ap/wpa_auth.c | 51 ++++++++++++++++++++++++++-
|
||||
src/ap/wpa_auth.h | 9 ++++-
|
||||
src/ap/wpa_auth_glue.c | 25 ++++++++++++-
|
||||
src/ap/wpa_auth_i.h | 1 +
|
||||
12 files changed, 172 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -2858,7 +2858,8 @@ static int hostapd_config_fill(struct ho
|
||||
bss->wpa_psk_radius = atoi(pos);
|
||||
if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
|
||||
bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
|
||||
- bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_REQUIRED &&
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Line %d: unknown wpa_psk_radius %d",
|
||||
line, bss->wpa_psk_radius);
|
||||
--- a/hostapd/hostapd.conf
|
||||
+++ b/hostapd/hostapd.conf
|
||||
@@ -1635,12 +1635,15 @@ own_ip_addr=127.0.0.1
|
||||
#wpa_psk_file=/etc/hostapd.wpa_psk
|
||||
|
||||
# Optionally, WPA passphrase can be received from RADIUS authentication server
|
||||
-# This requires macaddr_acl to be set to 2 (RADIUS)
|
||||
+# This requires macaddr_acl to be set to 2 (RADIUS) for wpa_psk_radius values
|
||||
+# 1 and 2.
|
||||
# 0 = disabled (default)
|
||||
# 1 = optional; use default passphrase/psk if RADIUS server does not include
|
||||
# Tunnel-Password
|
||||
# 2 = required; reject authentication if RADIUS server does not include
|
||||
# Tunnel-Password
|
||||
+# 3 = ask RADIUS server during 4-way handshake if there is no locally
|
||||
+# configured PSK/passphrase for the STA
|
||||
#wpa_psk_radius=0
|
||||
|
||||
# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
|
||||
--- a/src/ap/ap_config.c
|
||||
+++ b/src/ap/ap_config.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / Configuration helper functions
|
||||
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -1245,6 +1245,7 @@ static int hostapd_config_check_bss(stru
|
||||
|
||||
if (full_config && bss->wpa &&
|
||||
bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS &&
|
||||
bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
|
||||
wpa_printf(MSG_ERROR, "WPA-PSK using RADIUS enabled, but no "
|
||||
"RADIUS checking (macaddr_acl=2) enabled.");
|
||||
@@ -1254,6 +1255,7 @@ static int hostapd_config_check_bss(stru
|
||||
if (full_config && bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
|
||||
bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
|
||||
bss->ssid.wpa_psk_file == NULL &&
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS &&
|
||||
(bss->wpa_psk_radius != PSK_RADIUS_REQUIRED ||
|
||||
bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH)) {
|
||||
wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / Configuration definitions and helpers functions
|
||||
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -367,7 +367,8 @@ struct hostapd_bss_config {
|
||||
enum {
|
||||
PSK_RADIUS_IGNORED = 0,
|
||||
PSK_RADIUS_ACCEPTED = 1,
|
||||
- PSK_RADIUS_REQUIRED = 2
|
||||
+ PSK_RADIUS_REQUIRED = 2,
|
||||
+ PSK_RADIUS_DURING_4WAY_HS = 3,
|
||||
} wpa_psk_radius;
|
||||
int wpa_pairwise;
|
||||
int group_cipher; /* wpa_group value override from configuation */
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -2348,9 +2348,8 @@ static int ieee802_11_allowed_address(st
|
||||
}
|
||||
|
||||
|
||||
-static int
|
||||
-ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
- int res, struct radius_sta *info)
|
||||
+int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
+ int res, struct radius_sta *info)
|
||||
{
|
||||
u32 session_timeout = info->session_timeout;
|
||||
u32 acct_interim_interval = info->acct_interim_interval;
|
||||
--- a/src/ap/ieee802_11.h
|
||||
+++ b/src/ap/ieee802_11.h
|
||||
@@ -220,4 +220,6 @@ void auth_sae_process_commit(void *eloop
|
||||
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
|
||||
u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len);
|
||||
u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len);
|
||||
+int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
+ int res, struct radius_sta *info);
|
||||
#endif /* IEEE802_11_H */
|
||||
--- a/src/ap/ieee802_11_auth.c
|
||||
+++ b/src/ap/ieee802_11_auth.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 authentication (ACL)
|
||||
- * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_drv_ops.h"
|
||||
+#include "sta_info.h"
|
||||
+#include "wpa_auth.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "ieee802_11_auth.h"
|
||||
@@ -43,6 +45,8 @@ struct hostapd_acl_query_data {
|
||||
u8 *auth_msg; /* IEEE 802.11 authentication frame from station */
|
||||
size_t auth_msg_len;
|
||||
struct hostapd_acl_query_data *next;
|
||||
+ bool radius_psk;
|
||||
+ int akm;
|
||||
};
|
||||
|
||||
|
||||
@@ -153,6 +157,13 @@ static int hostapd_radius_acl_query(stru
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (query->akm &&
|
||||
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_AKM_SUITE,
|
||||
+ wpa_akm_to_suite(query->akm))) {
|
||||
+ wpa_printf(MSG_DEBUG, "Could not add WLAN-AKM-Suite");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
|
||||
goto fail;
|
||||
return 0;
|
||||
@@ -566,17 +577,40 @@ hostapd_acl_recv_radius(struct radius_ms
|
||||
cache->next = hapd->acl_cache;
|
||||
hapd->acl_cache = cache;
|
||||
|
||||
+ if (query->radius_psk) {
|
||||
+ struct sta_info *sta;
|
||||
+ bool success = cache->accepted == HOSTAPD_ACL_ACCEPT;
|
||||
+
|
||||
+ sta = ap_get_sta(hapd, query->addr);
|
||||
+ if (!sta || !sta->wpa_sm) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "No STA/SM entry found for the RADIUS PSK response");
|
||||
+ goto done;
|
||||
+ }
|
||||
+#ifdef NEED_AP_MLME
|
||||
+ if (success &&
|
||||
+ (ieee802_11_set_radius_info(hapd, sta, cache->accepted,
|
||||
+ info) < 0 ||
|
||||
+ ap_sta_bind_vlan(hapd, sta) < 0))
|
||||
+ success = false;
|
||||
+#endif /* NEED_AP_MLME */
|
||||
+ wpa_auth_sta_radius_psk_resp(sta->wpa_sm, success);
|
||||
+ } else {
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||
- hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
|
||||
- info->session_timeout);
|
||||
+ hostapd_drv_set_radius_acl_auth(hapd, query->addr,
|
||||
+ cache->accepted,
|
||||
+ info->session_timeout);
|
||||
#else /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
#ifdef NEED_AP_MLME
|
||||
- /* Re-send original authentication frame for 802.11 processing */
|
||||
- wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
|
||||
- "successful RADIUS ACL query");
|
||||
- ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL);
|
||||
+ /* Re-send original authentication frame for 802.11 processing
|
||||
+ */
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "Re-sending authentication frame after successful RADIUS ACL query");
|
||||
+ ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len,
|
||||
+ NULL);
|
||||
#endif /* NEED_AP_MLME */
|
||||
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
+ }
|
||||
|
||||
done:
|
||||
if (prev == NULL)
|
||||
@@ -658,3 +692,31 @@ void hostapd_free_psk_list(struct hostap
|
||||
os_free(prev);
|
||||
}
|
||||
}
|
||||
+
|
||||
+
|
||||
+#ifndef CONFIG_NO_RADIUS
|
||||
+void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
|
||||
+ int key_mgmt, const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len)
|
||||
+{
|
||||
+ struct hostapd_acl_query_data *query;
|
||||
+
|
||||
+ query = os_zalloc(sizeof(*query));
|
||||
+ if (!query)
|
||||
+ return;
|
||||
+
|
||||
+ query->radius_psk = true;
|
||||
+ query->akm = key_mgmt;
|
||||
+ os_get_reltime(&query->timestamp);
|
||||
+ os_memcpy(query->addr, addr, ETH_ALEN);
|
||||
+ if (hostapd_radius_acl_query(hapd, addr, query)) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "Failed to send Access-Request for RADIUS PSK/ACL query");
|
||||
+ hostapd_acl_query_free(query);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ query->next = hapd->acl_queries;
|
||||
+ hapd->acl_queries = query;
|
||||
+}
|
||||
+#endif /* CONFIG_NO_RADIUS */
|
||||
--- a/src/ap/ieee802_11_auth.h
|
||||
+++ b/src/ap/ieee802_11_auth.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 authentication (ACL)
|
||||
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -36,5 +36,8 @@ void hostapd_free_psk_list(struct hostap
|
||||
void hostapd_acl_expire(struct hostapd_data *hapd);
|
||||
void hostapd_copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
|
||||
struct hostapd_sta_wpa_psk_short *src);
|
||||
+void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
|
||||
+ int key_mgmt, const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len);
|
||||
|
||||
#endif /* IEEE802_11_AUTH_H */
|
||||
--- a/src/ap/wpa_auth.c
|
||||
+++ b/src/ap/wpa_auth.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IEEE 802.11 RSN / WPA Authenticator
|
||||
- * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -1465,6 +1465,12 @@ static void wpa_send_eapol_timeout(void
|
||||
struct wpa_authenticator *wpa_auth = eloop_ctx;
|
||||
struct wpa_state_machine *sm = timeout_ctx;
|
||||
|
||||
+ if (sm->waiting_radius_psk) {
|
||||
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
|
||||
+ "Ignore EAPOL-Key timeout while waiting for RADIUS PSK");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
sm->pending_1_of_4_timeout = 0;
|
||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout");
|
||||
sm->TimeoutEvt = true;
|
||||
@@ -3003,6 +3009,19 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (!ok && wpa_key_mgmt_wpa_psk_no_sae(sm->wpa_key_mgmt) &&
|
||||
+ wpa_auth->conf.radius_psk && wpa_auth->cb->request_radius_psk &&
|
||||
+ !sm->waiting_radius_psk) {
|
||||
+ wpa_printf(MSG_DEBUG, "No PSK available - ask RADIUS server");
|
||||
+ wpa_auth->cb->request_radius_psk(wpa_auth->cb_ctx, sm->addr,
|
||||
+ sm->wpa_key_mgmt,
|
||||
+ sm->ANonce,
|
||||
+ sm->last_rx_eapol_key,
|
||||
+ sm->last_rx_eapol_key_len);
|
||||
+ sm->waiting_radius_psk = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!ok) {
|
||||
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
|
||||
"invalid MIC in msg 2/4 of 4-Way Handshake");
|
||||
@@ -3758,6 +3777,11 @@ SM_STEP(WPA_PTK)
|
||||
} else if (wpa_auth_uses_sae(sm) && sm->pmksa) {
|
||||
SM_ENTER(WPA_PTK, PTKSTART);
|
||||
#endif /* CONFIG_SAE */
|
||||
+ } else if (wpa_key_mgmt_wpa_psk_no_sae(sm->wpa_key_mgmt) &&
|
||||
+ wpa_auth->conf.radius_psk) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "INITPSK: No PSK yet available for STA - use RADIUS later");
|
||||
+ SM_ENTER(WPA_PTK, PTKSTART);
|
||||
} else {
|
||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||
"no PSK configured for the STA");
|
||||
@@ -5661,3 +5685,28 @@ void wpa_auth_set_ocv_override_freq(stru
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
+
|
||||
+
|
||||
+void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success)
|
||||
+{
|
||||
+ if (!sm->waiting_radius_psk) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "Ignore RADIUS PSK response for " MACSTR
|
||||
+ " that did not wait one",
|
||||
+ MAC2STR(sm->addr));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "RADIUS PSK response for " MACSTR " (%s)",
|
||||
+ MAC2STR(sm->addr), success ? "success" : "fail");
|
||||
+ sm->waiting_radius_psk = 0;
|
||||
+
|
||||
+ if (success) {
|
||||
+ /* Try to process the EAPOL-Key msg 2/4 again */
|
||||
+ sm->EAPOLKeyReceived = true;
|
||||
+ } else {
|
||||
+ sm->Disconnect = true;
|
||||
+ }
|
||||
+
|
||||
+ eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
|
||||
+}
|
||||
--- a/src/ap/wpa_auth.h
|
||||
+++ b/src/ap/wpa_auth.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd - IEEE 802.11i-2004 / WPA Authenticator
|
||||
- * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -273,6 +273,8 @@ struct wpa_auth_config {
|
||||
* PTK derivation regardless of advertised capabilities.
|
||||
*/
|
||||
bool force_kdk_derivation;
|
||||
+
|
||||
+ bool radius_psk;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -320,6 +322,9 @@ struct wpa_auth_callbacks {
|
||||
void (*store_ptksa)(void *ctx, const u8 *addr, int cipher,
|
||||
u32 life_time, const struct wpa_ptk *ptk);
|
||||
void (*clear_ptksa)(void *ctx, const u8 *addr, int cipher);
|
||||
+ void (*request_radius_psk)(void *ctx, const u8 *addr, int key_mgmt,
|
||||
+ const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len);
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
|
||||
int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
|
||||
@@ -567,4 +572,6 @@ void wpa_auth_set_ocv_override_freq(stru
|
||||
enum wpa_auth_ocv_override_frame frame,
|
||||
unsigned int freq);
|
||||
|
||||
+void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success);
|
||||
+
|
||||
#endif /* WPA_AUTH_H */
|
||||
--- a/src/ap/wpa_auth_glue.c
|
||||
+++ b/src/ap/wpa_auth_glue.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / WPA authenticator glue code
|
||||
- * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "ap_drv_ops.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_11.h"
|
||||
+#include "ieee802_11_auth.h"
|
||||
#include "pmksa_cache_auth.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "wpa_auth_glue.h"
|
||||
@@ -214,6 +215,8 @@ static void hostapd_wpa_auth_conf(struct
|
||||
wconf->force_kdk_derivation = conf->force_kdk_derivation;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
#endif /* CONFIG_PASN */
|
||||
+
|
||||
+ wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1435,6 +1438,23 @@ static void hostapd_wpa_unregister_ft_ou
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
|
||||
|
||||
+#ifndef CONFIG_NO_RADIUS
|
||||
+static void hostapd_request_radius_psk(void *ctx, const u8 *addr, int key_mgmt,
|
||||
+ const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len)
|
||||
+{
|
||||
+ struct hostapd_data *hapd = ctx;
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "RADIUS PSK request for " MACSTR " key_mgmt=0x%x",
|
||||
+ MAC2STR(addr), key_mgmt);
|
||||
+ wpa_hexdump(MSG_DEBUG, "ANonce", anonce, WPA_NONCE_LEN);
|
||||
+ wpa_hexdump(MSG_DEBUG, "EAPOL", eapol, eapol_len);
|
||||
+ hostapd_acl_req_radius_psk(hapd, addr, key_mgmt, anonce, eapol,
|
||||
+ eapol_len);
|
||||
+}
|
||||
+#endif /* CONFIG_NO_RADIUS */
|
||||
+
|
||||
+
|
||||
int hostapd_setup_wpa(struct hostapd_data *hapd)
|
||||
{
|
||||
struct wpa_auth_config _conf;
|
||||
@@ -1478,6 +1498,9 @@ int hostapd_setup_wpa(struct hostapd_dat
|
||||
.set_session_timeout = hostapd_wpa_auth_set_session_timeout,
|
||||
.get_session_timeout = hostapd_wpa_auth_get_session_timeout,
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
+#ifndef CONFIG_NO_RADIUS
|
||||
+ .request_radius_psk = hostapd_request_radius_psk,
|
||||
+#endif /* CONFIG_NO_RADIUS */
|
||||
};
|
||||
const u8 *wpa_ie;
|
||||
size_t wpa_ie_len;
|
||||
--- a/src/ap/wpa_auth_i.h
|
||||
+++ b/src/ap/wpa_auth_i.h
|
||||
@@ -89,6 +89,7 @@ struct wpa_state_machine {
|
||||
unsigned int rx_eapol_key_secure:1;
|
||||
unsigned int update_snonce:1;
|
||||
unsigned int alt_snonce_valid:1;
|
||||
+ unsigned int waiting_radius_psk:1;
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
unsigned int ft_completed:1;
|
||||
unsigned int pmk_r1_name_valid:1;
|
||||
@@ -0,0 +1,350 @@
|
||||
From 24763e3cd0a564eb71f3c501bbb4fbb0d7070762 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Fri, 15 Apr 2022 17:31:48 +0300
|
||||
Subject: [PATCH] RADIUS: Attributes with Extended Types (RFC 6929)
|
||||
|
||||
Supported extended types for RADIUS attributes for the cases defined in
|
||||
RFC 6929.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/radius/radius.c | 195 ++++++++++++++++++++++++++++++++++++++------
|
||||
src/radius/radius.h | 26 +++++-
|
||||
2 files changed, 193 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/src/radius/radius.c b/src/radius/radius.c
|
||||
index be16e27b9..a64228067 100644
|
||||
--- a/src/radius/radius.c
|
||||
+++ b/src/radius/radius.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* RADIUS message processing
|
||||
- * Copyright (c) 2002-2009, 2011-2015, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2002-2009, 2011-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -159,7 +159,8 @@ static const char *radius_code_string(u8 code)
|
||||
|
||||
|
||||
struct radius_attr_type {
|
||||
- u8 type;
|
||||
+ u16 type; /* 0..255 for basic types;
|
||||
+ * (241 << 8) | <ext-type> for extended types */
|
||||
char *name;
|
||||
enum {
|
||||
RADIUS_ATTR_UNDIST, RADIUS_ATTR_TEXT, RADIUS_ATTR_IP,
|
||||
@@ -260,11 +261,31 @@ static const struct radius_attr_type radius_attrs[] =
|
||||
RADIUS_ATTR_HEXDUMP },
|
||||
{ RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER, "WLAN-Group-Mgmt-Pairwise-Cipher",
|
||||
RADIUS_ATTR_HEXDUMP },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_1, "Extended-Type-1", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_2, "Extended-Type-2", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_3, "Extended-Type-3", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_4, "Extended-Type-4", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_LONG_EXT_TYPE_1, "Long-Extended-Type-1",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_LONG_EXT_TYPE_2, "Long-Extended-Type-2",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_1, "Extended-Vendor-Specific-1",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_2, "Extended-Vendor-Specific-2",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_3, "Extended-Vendor-Specific-3",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_4, "Extended-Vendor-Specific-4",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5, "Extended-Vendor-Specific-5",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_6, "Extended-Vendor-Specific-6",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
};
|
||||
#define RADIUS_ATTRS ARRAY_SIZE(radius_attrs)
|
||||
|
||||
|
||||
-static const struct radius_attr_type *radius_get_attr_type(u8 type)
|
||||
+static const struct radius_attr_type * radius_get_attr_type(u16 type)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -277,23 +298,60 @@ static const struct radius_attr_type *radius_get_attr_type(u8 type)
|
||||
}
|
||||
|
||||
|
||||
+static bool radius_is_long_ext_type(u8 type)
|
||||
+{
|
||||
+ return type == RADIUS_ATTR_LONG_EXT_TYPE_1 ||
|
||||
+ type == RADIUS_ATTR_LONG_EXT_TYPE_2;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static bool radius_is_ext_type(u8 type)
|
||||
+{
|
||||
+ return type >= RADIUS_ATTR_EXT_TYPE_1 &&
|
||||
+ type <= RADIUS_ATTR_LONG_EXT_TYPE_2;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static void radius_msg_dump_attr(struct radius_attr_hdr *hdr)
|
||||
{
|
||||
+ struct radius_attr_hdr_ext *ext = NULL;
|
||||
const struct radius_attr_type *attr;
|
||||
int len;
|
||||
unsigned char *pos;
|
||||
char buf[1000];
|
||||
|
||||
- attr = radius_get_attr_type(hdr->type);
|
||||
+ if (hdr->length < sizeof(struct radius_attr_hdr))
|
||||
+ return;
|
||||
|
||||
- wpa_printf(MSG_INFO, " Attribute %d (%s) length=%d",
|
||||
- hdr->type, attr ? attr->name : "?Unknown?", hdr->length);
|
||||
+ if (radius_is_ext_type(hdr->type)) {
|
||||
+ if (hdr->length < 4) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ " Invalid attribute %d (too short for extended type)",
|
||||
+ hdr->type);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (attr == NULL || hdr->length < sizeof(struct radius_attr_hdr))
|
||||
- return;
|
||||
+ ext = (struct radius_attr_hdr_ext *) hdr;
|
||||
+ }
|
||||
+
|
||||
+ if (ext) {
|
||||
+ attr = radius_get_attr_type((ext->type << 8) | ext->ext_type);
|
||||
+ wpa_printf(MSG_INFO, " Attribute %d.%d (%s) length=%d",
|
||||
+ ext->type, ext->ext_type,
|
||||
+ attr ? attr->name : "?Unknown?", ext->length);
|
||||
+ pos = (unsigned char *) (ext + 1);
|
||||
+ len = ext->length - sizeof(struct radius_attr_hdr_ext);
|
||||
+ } else {
|
||||
+ attr = radius_get_attr_type(hdr->type);
|
||||
+ wpa_printf(MSG_INFO, " Attribute %d (%s) length=%d",
|
||||
+ hdr->type, attr ? attr->name : "?Unknown?",
|
||||
+ hdr->length);
|
||||
+ pos = (unsigned char *) (hdr + 1);
|
||||
+ len = hdr->length - sizeof(struct radius_attr_hdr);
|
||||
+ }
|
||||
|
||||
- len = hdr->length - sizeof(struct radius_attr_hdr);
|
||||
- pos = (unsigned char *) (hdr + 1);
|
||||
+ if (!attr)
|
||||
+ return;
|
||||
|
||||
switch (attr->data_type) {
|
||||
case RADIUS_ATTR_TEXT:
|
||||
@@ -627,22 +685,54 @@ static int radius_msg_add_attr_to_array(struct radius_msg *msg,
|
||||
}
|
||||
|
||||
|
||||
-struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
|
||||
- const u8 *data, size_t data_len)
|
||||
+struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u16 type,
|
||||
+ const u8 *data, size_t data_len)
|
||||
{
|
||||
- size_t buf_needed;
|
||||
- struct radius_attr_hdr *attr;
|
||||
+ size_t buf_needed, max_len;
|
||||
+ struct radius_attr_hdr *attr = NULL;
|
||||
+ struct radius_attr_hdr_ext *ext;
|
||||
+ u8 ext_type = 0;
|
||||
|
||||
if (TEST_FAIL())
|
||||
return NULL;
|
||||
|
||||
- if (data_len > RADIUS_MAX_ATTR_LEN) {
|
||||
- wpa_printf(MSG_ERROR, "radius_msg_add_attr: too long attribute (%lu bytes)",
|
||||
- (unsigned long) data_len);
|
||||
- return NULL;
|
||||
+ if (type > 255) {
|
||||
+ if (!radius_is_ext_type(type >> 8)) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "%s: Undefined extended type %d.%d",
|
||||
+ __func__, type >> 8, type & 0xff);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ ext_type = type & 0xff;
|
||||
+ type >>= 8;
|
||||
+ } else if (radius_is_ext_type(type)) {
|
||||
+ wpa_printf(MSG_ERROR, "%s: Unexpected extended type use for %d",
|
||||
+ __func__, type);
|
||||
}
|
||||
|
||||
- buf_needed = sizeof(*attr) + data_len;
|
||||
+ if (radius_is_long_ext_type(type)) {
|
||||
+ size_t hdr_len = sizeof(struct radius_attr_hdr_ext) + 1;
|
||||
+ size_t plen = 255 - hdr_len;
|
||||
+ size_t num;
|
||||
+
|
||||
+ max_len = 4096;
|
||||
+ num = (data_len + plen - 1) / plen;
|
||||
+ if (num == 0)
|
||||
+ num = 1;
|
||||
+ buf_needed = num * hdr_len + data_len;
|
||||
+ } else if (radius_is_ext_type(type)) {
|
||||
+ max_len = RADIUS_MAX_EXT_ATTR_LEN;
|
||||
+ buf_needed = sizeof(struct radius_attr_hdr_ext) + data_len;
|
||||
+ } else {
|
||||
+ max_len = RADIUS_MAX_ATTR_LEN;
|
||||
+ buf_needed = sizeof(*attr) + data_len;
|
||||
+ }
|
||||
+ if (data_len > max_len) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "%s: too long attribute (%zu > %zu bytes)",
|
||||
+ __func__, data_len, max_len);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
if (wpabuf_tailroom(msg->buf) < buf_needed) {
|
||||
/* allocate more space for message buffer */
|
||||
@@ -651,13 +741,44 @@ struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
|
||||
msg->hdr = wpabuf_mhead(msg->buf);
|
||||
}
|
||||
|
||||
- attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
|
||||
- attr->type = type;
|
||||
- attr->length = sizeof(*attr) + data_len;
|
||||
- wpabuf_put_data(msg->buf, data, data_len);
|
||||
-
|
||||
- if (radius_msg_add_attr_to_array(msg, attr))
|
||||
- return NULL;
|
||||
+ if (radius_is_long_ext_type(type)) {
|
||||
+ size_t plen = 255 - sizeof(struct radius_attr_hdr_ext) - 1;
|
||||
+ size_t alen;
|
||||
+
|
||||
+ do {
|
||||
+ alen = data_len > plen ? plen : data_len;
|
||||
+ ext = wpabuf_put(msg->buf,
|
||||
+ sizeof(struct radius_attr_hdr_ext));
|
||||
+ if (!attr)
|
||||
+ attr = (struct radius_attr_hdr *) ext;
|
||||
+ ext->type = type;
|
||||
+ ext->length = sizeof(*ext) + 1 + alen;
|
||||
+ ext->ext_type = ext_type;
|
||||
+ wpabuf_put_u8(msg->buf, data_len > alen ? 0x80 : 0);
|
||||
+ wpabuf_put_data(msg->buf, data, data_len);
|
||||
+ data += alen;
|
||||
+ data_len -= alen;
|
||||
+ if (radius_msg_add_attr_to_array(
|
||||
+ msg, (struct radius_attr_hdr *) ext))
|
||||
+ return NULL;
|
||||
+ } while (data_len > 0);
|
||||
+ } else if (radius_is_ext_type(type)) {
|
||||
+ ext = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr_ext));
|
||||
+ attr = (struct radius_attr_hdr *) ext;
|
||||
+ ext->type = type;
|
||||
+ ext->length = sizeof(*ext) + data_len;
|
||||
+ ext->ext_type = ext_type;
|
||||
+ wpabuf_put_data(msg->buf, data, data_len);
|
||||
+ if (radius_msg_add_attr_to_array(msg, attr))
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
|
||||
+ attr->type = type;
|
||||
+ attr->length = sizeof(*attr) + data_len;
|
||||
+ wpabuf_put_data(msg->buf, data, data_len);
|
||||
+ if (radius_msg_add_attr_to_array(msg, attr))
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
return attr;
|
||||
}
|
||||
@@ -1285,6 +1406,28 @@ int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
|
||||
}
|
||||
|
||||
|
||||
+int radius_msg_add_ext_vs(struct radius_msg *msg, u16 type, u32 vendor_id,
|
||||
+ u8 vendor_type, const u8 *data, size_t len)
|
||||
+{
|
||||
+ struct radius_attr_hdr *attr;
|
||||
+ u8 *buf, *pos;
|
||||
+ size_t alen;
|
||||
+
|
||||
+ alen = 4 + 1 + len;
|
||||
+ buf = os_malloc(alen);
|
||||
+ if (!buf)
|
||||
+ return 0;
|
||||
+ pos = buf;
|
||||
+ WPA_PUT_BE32(pos, vendor_id);
|
||||
+ pos += 4;
|
||||
+ *pos++ = vendor_type;
|
||||
+ os_memcpy(pos, data, len);
|
||||
+ attr = radius_msg_add_attr(msg, type, buf, alen);
|
||||
+ os_free(buf);
|
||||
+ return attr != NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int radius_user_password_hide(struct radius_msg *msg,
|
||||
const u8 *data, size_t data_len,
|
||||
const u8 *secret, size_t secret_len,
|
||||
diff --git a/src/radius/radius.h b/src/radius/radius.h
|
||||
index fb8148180..490c8d1f6 100644
|
||||
--- a/src/radius/radius.h
|
||||
+++ b/src/radius/radius.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* RADIUS message processing
|
||||
- * Copyright (c) 2002-2009, 2012, 2014-2015, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2002-2009, 2012, 2014-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -46,7 +46,15 @@ struct radius_attr_hdr {
|
||||
/* followed by length-2 octets of attribute value */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
+struct radius_attr_hdr_ext {
|
||||
+ u8 type;
|
||||
+ u8 length; /* including this header */
|
||||
+ u8 ext_type;
|
||||
+ /* followed by length-3 octets of attribute value */
|
||||
+} STRUCT_PACKED;
|
||||
+
|
||||
#define RADIUS_MAX_ATTR_LEN (255 - sizeof(struct radius_attr_hdr))
|
||||
+#define RADIUS_MAX_EXT_ATTR_LEN (255 - sizeof(struct radius_attr_hdr_ext))
|
||||
|
||||
enum { RADIUS_ATTR_USER_NAME = 1,
|
||||
RADIUS_ATTR_USER_PASSWORD = 2,
|
||||
@@ -113,6 +121,18 @@ enum { RADIUS_ATTR_USER_NAME = 1,
|
||||
RADIUS_ATTR_WLAN_GROUP_CIPHER = 187,
|
||||
RADIUS_ATTR_WLAN_AKM_SUITE = 188,
|
||||
RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER = 189,
|
||||
+ RADIUS_ATTR_EXT_TYPE_1 = 241,
|
||||
+ RADIUS_ATTR_EXT_TYPE_2 = 242,
|
||||
+ RADIUS_ATTR_EXT_TYPE_3 = 243,
|
||||
+ RADIUS_ATTR_EXT_TYPE_4 = 244,
|
||||
+ RADIUS_ATTR_LONG_EXT_TYPE_1 = 245,
|
||||
+ RADIUS_ATTR_LONG_EXT_TYPE_2 = 246,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_1 = (241 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_2 = (242 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_3 = (243 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_4 = (244 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5 = (245 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_6 = (246 << 8) | 26,
|
||||
};
|
||||
|
||||
|
||||
@@ -257,7 +277,7 @@ 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,
|
||||
int require_message_authenticator);
|
||||
-struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
|
||||
+struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u16 type,
|
||||
const u8 *data, size_t data_len);
|
||||
struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
|
||||
int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
|
||||
@@ -284,6 +304,8 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg,
|
||||
const u8 *recv_key, size_t recv_key_len);
|
||||
int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
|
||||
size_t len);
|
||||
+int radius_msg_add_ext_vs(struct radius_msg *msg, u16 type, u32 vendor_id,
|
||||
+ u8 vendor_type, const u8 *data, size_t len);
|
||||
int radius_user_password_hide(struct radius_msg *msg,
|
||||
const u8 *data, size_t data_len,
|
||||
const u8 *secret, size_t secret_len,
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
From b94371af8402f60218716552e571ca72cff4e3c0 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Fri, 15 Apr 2022 17:36:25 +0300
|
||||
Subject: [PATCH] RADIUS attributes for EAPOL-Key message details
|
||||
|
||||
Use vendor specific RADIUS attributes for sending ANonce and EAPOL-Key
|
||||
msg 2/4 for the wpa_psk_radius=3 case. The vendor specific attributes
|
||||
for this are defined in FreeRADIUS as follows:
|
||||
|
||||
BEGIN-VENDOR FreeRADIUS format=Extended-Vendor-Specific-5
|
||||
ATTRIBUTE FreeRADIUS-802.1X-Anonce 1 octets[32]
|
||||
ATTRIBUTE FreeRADIUS-802.1X-EAPoL-Key-Msg 2 octets
|
||||
END-VENDOR FreeRADIUS
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/ap/ieee802_11_auth.c | 29 +++++++++++++++++++++++++++++
|
||||
src/radius/radius.h | 7 +++++++
|
||||
2 files changed, 36 insertions(+)
|
||||
|
||||
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
|
||||
index a54d7616e..4277d82cb 100644
|
||||
--- a/src/ap/ieee802_11_auth.c
|
||||
+++ b/src/ap/ieee802_11_auth.c
|
||||
@@ -47,6 +47,9 @@ struct hostapd_acl_query_data {
|
||||
struct hostapd_acl_query_data *next;
|
||||
bool radius_psk;
|
||||
int akm;
|
||||
+ u8 *anonce;
|
||||
+ u8 *eapol;
|
||||
+ size_t eapol_len;
|
||||
};
|
||||
|
||||
|
||||
@@ -102,6 +105,8 @@ static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
|
||||
if (!query)
|
||||
return;
|
||||
os_free(query->auth_msg);
|
||||
+ os_free(query->anonce);
|
||||
+ os_free(query->eapol);
|
||||
os_free(query);
|
||||
}
|
||||
|
||||
@@ -164,6 +169,24 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (query->anonce &&
|
||||
+ !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
|
||||
+ RADIUS_VENDOR_ID_FREERADIUS,
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE,
|
||||
+ query->anonce, WPA_NONCE_LEN)) {
|
||||
+ wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-Anonce");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (query->eapol &&
|
||||
+ !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
|
||||
+ RADIUS_VENDOR_ID_FREERADIUS,
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG,
|
||||
+ query->eapol, query->eapol_len)) {
|
||||
+ wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-EAPoL-Key-Msg");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
|
||||
goto fail;
|
||||
return 0;
|
||||
@@ -703,6 +726,12 @@ void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
|
||||
query->akm = key_mgmt;
|
||||
os_get_reltime(&query->timestamp);
|
||||
os_memcpy(query->addr, addr, ETH_ALEN);
|
||||
+ if (anonce)
|
||||
+ query->anonce = os_memdup(anonce, WPA_NONCE_LEN);
|
||||
+ if (eapol) {
|
||||
+ query->eapol = os_memdup(eapol, eapol_len);
|
||||
+ query->eapol_len = eapol_len;
|
||||
+ }
|
||||
if (hostapd_radius_acl_query(hapd, addr, query)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Failed to send Access-Request for RADIUS PSK/ACL query");
|
||||
diff --git a/src/radius/radius.h b/src/radius/radius.h
|
||||
index 490c8d1f6..177c64a66 100644
|
||||
--- a/src/radius/radius.h
|
||||
+++ b/src/radius/radius.h
|
||||
@@ -208,6 +208,13 @@ enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
|
||||
RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
|
||||
};
|
||||
|
||||
+/* FreeRADIUS vendor-specific attributes */
|
||||
+#define RADIUS_VENDOR_ID_FREERADIUS 11344
|
||||
+/* Extended-Vendor-Specific-5 (245.26; long extended header) */
|
||||
+enum {
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE = 1,
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG = 2,
|
||||
+};
|
||||
|
||||
/* Hotspot 2.0 - WFA Vendor-specific RADIUS Attributes */
|
||||
#define RADIUS_VENDOR_ID_WFA 40808
|
||||
--
|
||||
2.25.1
|
||||
|
||||
32
patches/0077-netifd-add-psk2-radius.patch
Normal file
32
patches/0077-netifd-add-psk2-radius.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From d1e6c2041e21cccdd4fd30b28b3b48765825f976 Mon Sep 17 00:00:00 2001
|
||||
From: Arif Alam <arif.alam@netexperience.com>
|
||||
Date: Sun, 24 Mar 2024 12:18:11 -0400
|
||||
Subject: [PATCH] netifd: add psk2-radius
|
||||
|
||||
Signed-off-by: Arif Alam <arif.alam@netexperience.com>
|
||||
---
|
||||
.../config/netifd/patches/005-psk2-radius.patch | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
create mode 100644 package/network/config/netifd/patches/005-psk2-radius.patch
|
||||
|
||||
diff --git a/package/network/config/netifd/patches/005-psk2-radius.patch b/package/network/config/netifd/patches/005-psk2-radius.patch
|
||||
new file mode 100644
|
||||
index 0000000000..f6dab51c8a
|
||||
--- /dev/null
|
||||
+++ b/package/network/config/netifd/patches/005-psk2-radius.patch
|
||||
@@ -0,0 +1,12 @@
|
||||
+--- a/scripts/netifd-wireless.sh
|
||||
++++ b/scripts/netifd-wireless.sh
|
||||
+@@ -266,6 +266,9 @@ wireless_vif_parse_encryption() {
|
||||
+ wpa3*)
|
||||
+ auth_type=eap2
|
||||
+ ;;
|
||||
++ psk2-radius*)
|
||||
++ auth_type=psk2-radius
|
||||
++ ;;
|
||||
+ psk3-mixed*|sae-mixed*)
|
||||
+ auth_type=psk-sae
|
||||
+ ;;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
Reference in New Issue
Block a user