[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