[PATCH 1/2] RADIUS server: add accounting message callback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Adds a configurable callback for incoming Accounting-Request messages to
integrated RADIUS server. This approach allows different implementation by
hostapd itself and other binaries built on top of hostap -- for example --
OpenWrt's RADIUS server.

Signed-off-by: Dávid Benko <davidbenko@xxxxxxxxxxxxxx>
---
 src/radius/radius_server.c | 42 ++++++++++++++++++++++++++++++++++++--
 src/radius/radius_server.h | 26 ++++++++++++++++++++++-
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index 715b6d928..bbb493b41 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -146,7 +146,8 @@ struct radius_server_data {
 	/**
 	 * conf_ctx - Context pointer for callbacks
 	 *
-	 * This is used as the ctx argument in get_eap_user() calls.
+	 * This is used as the ctx argument in get_eap_user() and acct_req_cb()
+	 * calls.
 	 */
 	void *conf_ctx;
 
@@ -193,6 +194,27 @@ struct radius_server_data {
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);
 
+	/**
+	 * acct_req_cb - Callback for processing received RADIUS accounting
+	 * requests
+	 * @ctx: Context data from conf_ctx
+	 * @msg: Received RADIUS accounting request
+	 * @status_type: Status type from the message (parsed Acct-Status-Type
+	 * attribute)
+	 * Returns: 0 on success, -1 on failure
+	 *
+	 * This can be used to log accounting information into file, database,
+	 * syslog server, etc.
+	 * Callback should not modify the message.
+	 * If 0 is returned, response is automatically created. Otherwise,
+	 * no response is created.
+	 *
+	 * acct_req_cb can be set to null to omit any custom processing of
+	 * account requests. Statistics counters will be incremented in any
+	 * case.
+	 */
+	int (*acct_req_cb)(void *ctx, struct radius_msg *msg, u32 status_type);
+
 	/**
 	 * eap_req_id_text - Optional data for EAP-Request/Identity
 	 *
@@ -1674,7 +1696,22 @@ static void radius_server_receive_acct(int sock, void *eloop_ctx,
 		goto fail;
 	}
 
-	/* TODO: Write accounting information to a file or database */
+	/* Parse Acct-Status-Type from Accounting-Request */
+	u32 status_type = 0;
+	if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_ACCT_STATUS_TYPE,
+				      &status_type) != 0) {
+		RADIUS_DEBUG("Unable to parse Acct-Status-Type from %s", abuf);
+		goto fail;
+	}
+
+	/* Process accounting information by configured callback */
+	if (data->acct_req_cb != NULL &&
+	    data->acct_req_cb(data->conf_ctx, msg, status_type) != 0) {
+		RADIUS_DEBUG("Accounting request callback returned non-zero "
+			     "code indicating processing failure (from %s)",
+			     abuf);
+		goto fail;
+	}
 
 	hdr = radius_msg_get_hdr(msg);
 
@@ -1999,6 +2036,7 @@ radius_server_init(struct radius_server_conf *conf)
 	conf->eap_cfg->eap_server = 1;
 	data->ipv6 = conf->ipv6;
 	data->get_eap_user = conf->get_eap_user;
+	data->acct_req_cb = conf->acct_req_cb;
 	if (conf->eap_req_id_text) {
 		data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
 		if (!data->eap_req_id_text)
diff --git a/src/radius/radius_server.h b/src/radius/radius_server.h
index 2a6f56796..9124b91f2 100644
--- a/src/radius/radius_server.h
+++ b/src/radius/radius_server.h
@@ -9,6 +9,8 @@
 #ifndef RADIUS_SERVER_H
 #define RADIUS_SERVER_H
 
+#include "radius.h"
+
 struct radius_server_data;
 struct eap_user;
 
@@ -47,7 +49,8 @@ struct radius_server_conf {
 	/**
 	 * conf_ctx - Context pointer for callbacks
 	 *
-	 * This is used as the ctx argument in get_eap_user() calls.
+	 * This is used as the ctx argument in get_eap_user() and acct_req_cb()
+	 * calls.
 	 */
 	void *conf_ctx;
 
@@ -75,6 +78,27 @@ struct radius_server_conf {
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);
 
+	/**
+	 * acct_req_cb - Callback for processing received RADIUS accounting
+	 * requests
+	 * @ctx: Context data from conf_ctx
+	 * @msg: Received RADIUS accounting request
+	 * @status_type: Status type from the message (parsed Acct-Status-Type
+	 * attribute)
+	 * Returns: 0 on success, -1 on failure
+	 *
+	 * This can be used to log accounting information into file, database,
+	 * syslog server, etc.
+	 * Callback should not modify the message.
+	 * If 0 is returned, response is automatically created. Otherwise,
+	 * no response is created.
+	 *
+	 * acct_req_cb can be set to null to omit any custom processing of
+	 * account requests. Statistics counters will be incremented in any
+	 * case.
+	 */
+	int (*acct_req_cb)(void *ctx, struct radius_msg *msg, u32 status_type);
+
 	/**
 	 * eap_req_id_text - Optional data for EAP-Request/Identity
 	 *
-- 
2.25.1


---- On Sun, 23 Feb 2025 23:37:59 +0100 Dávid Benko  wrote ---

 > There is a long standing (over a decade) TODO on processing RADIUS server 
 > accounting requests: 
 > https://w1.fi/cgit/hostap/tree/src/radius/radius_server.c?id=012a893c469157d5734f6f33953497ea6e3b0169#n1677 
 >  
 > I created a pair of patches implementing a new callback interface for 
 > accounting requests (patch 1) and the callback which simply logs all received 
 > messages (patch 2). Configuration option to turn it on or off is also included. 
 >  
 > Even though the TODO mentions writing accounting information to a file or 
 > database, I think logging is well sufficient for many of hostapd's use cases 
 > and definitely better than nothing. 
 >  
 > Dávid Benko 
 >  
 > 


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap




[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux