[PATCH 2/3] radius: add extended attributes support

michael-dev at fami-braun.de michael-dev at fami-braun.de
Fri Apr 16 07:13:44 BST 2021


From: Michael Braun <michael-dev at fami-braun.de>

Signed-off-by: Michael Braun <michael-dev at fami-braun.de>
---
 src/radius/radius.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
 src/radius/radius.h |  9 +++++++
 2 files changed, 73 insertions(+)

diff --git a/src/radius/radius.c b/src/radius/radius.c
index fe4d23a5d..d58394397 100644
--- a/src/radius/radius.c
+++ b/src/radius/radius.c
@@ -14,6 +14,9 @@
 #include "crypto/crypto.h"
 #include "radius.h"
 
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
 
 /**
  * struct radius_msg - RADIUS message structure for new and parsed messages
@@ -1295,6 +1298,67 @@ int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
 }
 
 
+// RFC 6929
+int radius_msg_add_extended_vsa(struct radius_msg *msg, u8 type, u8 subtype,
+				const u8 *data, size_t len, u32 vendor)
+{
+	const u8 *bufptr[2];
+	size_t buflen[2];
+	size_t offset = 0;
+
+	u8 evs[5];
+	WPA_PUT_BE32(evs, vendor);
+	evs[4] = subtype;
+
+	bufptr[1] = evs;
+	buflen[1] = sizeof(evs);
+
+	do {
+		u8 hdr[2];
+		size_t hdrlen = 1;
+		size_t fraglen;
+		struct radius_attr_hdr *attr;
+
+		hdr[0] = RADIUS_ATTR_VENDOR_SPECIFIC; // independently defined as 26 by RFC 6929
+
+		switch (type) {
+			case RADIUS_ATTR_EXTENDED_1:
+			case RADIUS_ATTR_EXTENDED_2:
+			case RADIUS_ATTR_EXTENDED_3:
+			case RADIUS_ATTR_EXTENDED_4:
+				if (hdrlen + len - offset > RADIUS_MAX_ATTR_LEN) {
+					wpa_printf(MSG_ERROR, "WARNING: attr data too exceeds maximum size of extended attribute");
+					return 0;
+				}
+				fraglen = len - offset;
+				break;
+			case RADIUS_ATTR_EXTENDED_5:
+			case RADIUS_ATTR_EXTENDED_6:
+				hdr[1] = 0;
+				hdrlen++;
+
+				fraglen = MIN(len - offset, RADIUS_MAX_ATTR_LEN - hdrlen);
+				if (fraglen < len - offset)
+					hdr[1] |= RADIUS_LONGEXT_FLAG_MORE;
+				break;
+			default:
+				wpa_printf(MSG_ERROR, "WARNING: Invalid attr type %d used with %s", type, __FUNCTION__);
+				return 0;
+		}
+
+		bufptr[0] = hdr;
+		buflen[0] = hdrlen;
+
+		attr = radius_msg_add_attr_frag(msg, type, offset > 0 ? 1 : 2, bufptr, buflen, data + offset, fraglen);
+		if (attr == NULL)
+			return 0;
+
+		offset += fraglen;
+	} while (offset < len);
+
+	return 1;
+}
+
 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 3dc73bdc5..0f2420567 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -113,6 +113,12 @@ 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_EXTENDED_1 = 241,
+       RADIUS_ATTR_EXTENDED_2 = 242,
+       RADIUS_ATTR_EXTENDED_3 = 243,
+       RADIUS_ATTR_EXTENDED_4 = 244,
+       RADIUS_ATTR_EXTENDED_5 = 245, // long extended
+       RADIUS_ATTR_EXTENDED_6 = 246, // long extended
 };
 
 
@@ -172,6 +178,7 @@ enum { RADIUS_ATTR_USER_NAME = 1,
 #define RADIUS_TUNNEL_MEDIUM_TYPE_IPV6 2
 #define RADIUS_TUNNEL_MEDIUM_TYPE_802 6
 
+#define RADIUS_LONGEXT_FLAG_MORE 0x80
 
 struct radius_attr_vendor {
 	u8 vendor_type;
@@ -290,6 +297,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_extended_vsa(struct radius_msg *msg, u8 type, u8 subtype,
+				const u8 *data, size_t len, u32 vendor);
 int radius_user_password_hide(struct radius_msg *msg,
 			      const u8 *data, size_t data_len,
 			      const u8 *secret, size_t secret_len,
-- 
2.20.1




More information about the Hostap mailing list