Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Oct 1999 15:45:39 +0300 (EEST)
From:      os@altavista.net
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   misc/14284: libradius accounting patch
Message-ID:  <199910121245.PAA00711@ktpk.dp.ua>

next in thread | raw e-mail | index | archive | help

>Number:         14284
>Category:       misc
>Synopsis:       libradius accounting patch
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 12 05:50:01 PDT 1999
>Closed-Date:
>Last-Modified:
>Originator:     Oleg Semyonov
>Release:        FreeBSD 3.3-STABLE i386
>Organization:
>Environment:

FreeBSD 3.3-STABLE, 4.0-CURRENT, possibly 2.2.8-STABLE

>Description:

FreeBSD standard distribution RADIUS client library does not
support RADIUS accounting. Here is a patch for libradius for
accounting. It includes:

1. #define for RAD_CONNECT_INFO (non-rfc, but widely used).
2. #defines for Framed-Compression and NAS-Port-Type values.
2. #defines for accounting support.
3. internal insert_request_authenticator() for accounting request packets.
4. rad_auth_open() and rad_acct_open() calls for opening a handle as
   auth or acct server with appropriate defaults(for defaults only).
   rad_open() call preserved for compatibility and is equivalent to
   rad_auth_open().
5. No man changes, sorry.
6. Default accounting config file is /etc/radacct.conf (not the best
   solution, IMHO, but it works). Seems ito me the extended format for
   radius.conf is better (to add 'auth' or 'acct' word before each
   server definition).
7. #define for __printflike (for FreeBSD 2.2.8).
8. library and header renamed for compatibility with old version
   (as temporary solution).

>How-To-Repeat:

man libradius :-)

>Fix:
	
Here is the patch:


diff -urP libradius/Makefile libradius+/Makefile
--- libradius/Makefile	Sat Jan 30 00:44:47 1999
+++ libradius+/Makefile	Sat Oct  9 17:54:47 1999
@@ -24,7 +24,7 @@
 #
 #	$FreeBSD: src/lib/libradius/Makefile,v 1.2 1999/01/29 22:44:47 brian Exp $
 
-LIB=		radius
+LIB=		radius+
 SRCS=		radlib.c
 CFLAGS+=	-Wall
 DPADD+=		${LIBMD}
@@ -33,9 +33,10 @@
 SHLIB_MINOR=	0
 MAN3+=		libradius.3
 MAN5+=		radius.conf.5
+#NOMAN=		noman
 
 beforeinstall:
 	${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
-	    ${.CURDIR}/radlib.h ${DESTDIR}/usr/include
+	    ${.CURDIR}/radlib.h ${DESTDIR}${INCLUDEDIR}/radlib+.h
 
 .include <bsd.lib.mk>
diff -urP libradius/radlib.c libradius+/radlib.c
--- libradius/radlib.c	Fri Feb  5 13:23:44 1999
+++ libradius+/radlib.c	Sat Oct  9 09:38:28 1999
@@ -42,12 +42,18 @@
 #include <string.h>
 #include <unistd.h>
 
+/* For FreeBSD 2.2.8-STABLE */
+#ifndef __printflike
+#define __printflike(x,y)
+#endif
+
 #include "radlib_private.h"
 
 static void	 clear_password(struct rad_handle *);
 static void	 generr(struct rad_handle *, const char *, ...)
 		    __printflike(2, 3);
 static void	 insert_scrambled_password(struct rad_handle *, int);
+static void	 insert_request_authenticator(struct rad_handle *, int);
 static int	 is_valid_response(struct rad_handle *, int,
 		    const struct sockaddr_in *);
 static int	 put_password_attr(struct rad_handle *, int,
@@ -110,6 +116,23 @@
 	}
 }
 
+static void
+insert_request_authenticator(struct rad_handle *h, int srv)
+{
+	MD5_CTX ctx;
+	const struct rad_server *srvp;
+
+	srvp = &h->servers[srv];
+
+	/* Create the request authenticator */
+	MD5Init(&ctx);
+	MD5Update(&ctx, &h->request[POS_CODE], POS_AUTH - POS_CODE);
+	MD5Update(&ctx, memset(&h->request[POS_AUTH], 0, LEN_AUTH), LEN_AUTH);
+	MD5Update(&ctx, &h->request[POS_ATTRS], h->req_len - POS_ATTRS);
+	MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
+	MD5Final(&h->request[POS_AUTH], &ctx);
+}
+
 /*
  * Return true if the current response is valid for a request to the
  * specified server.
@@ -229,9 +252,14 @@
 	else {
 		struct servent *sent;
 
-		srvp->addr.sin_port =
-		    (sent = getservbyname("radius", "udp")) != NULL ?
-			sent->s_port : htons(RADIUS_PORT);
+		if (h->type == RADIUS_AUTH)
+			srvp->addr.sin_port =
+			    (sent = getservbyname("radius", "udp")) != NULL ?
+				sent->s_port : htons(RADIUS_PORT);
+		else
+			srvp->addr.sin_port =
+			    (sent = getservbyname("radacct", "udp")) != NULL ?
+				sent->s_port : htons(RADACCT_PORT);
 	}
 	if ((srvp->secret = strdup(secret)) == NULL) {
 		generr(h, "Out of memory");
@@ -269,7 +297,8 @@
 	int retval;
 
 	if (path == NULL)
-		path = PATH_RADIUS_CONF;
+		path = (h->type == RADIUS_AUTH)
+		    ? PATH_RADIUS_CONF : PATH_RADACCT_CONF;
 	if ((fp = fopen(path, "r")) == NULL) {
 		generr(h, "Cannot open \"%s\": %s", path, strerror(errno));
 		return -1;
@@ -421,9 +450,13 @@
 		if (++h->srv >= h->num_servers)
 			h->srv = 0;
 
-	/* Insert the scrambled password into the request */
-	if (h->pass_pos != 0)
-		insert_scrambled_password(h, h->srv);
+	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST)
+		/* Insert the request authenticator into the request */
+		insert_request_authenticator(h, h->srv);
+	else
+		/* Insert the scrambled password into the request */
+		if (h->pass_pos != 0)
+			insert_scrambled_password(h, h->srv);
 
 	/* Send the request */
 	n = sendto(h->fd, h->request, h->req_len, 0,
@@ -552,14 +585,22 @@
 		}
 	}
 
-	/* Make sure the user gave us a password */
-	if (h->pass_pos == 0 && !h->chap_pass) {
-		generr(h, "No User or Chap Password attributes given");
-		return -1;
-	}
-	if (h->pass_pos != 0 && h->chap_pass) {
-		generr(h, "Both User and Chap Password attributes given");
-		return -1;
+	if (h->request[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
+		/* Make sure no password given */
+		if (h->pass_pos || h->chap_pass) {
+			generr(h, "User or Chap Password in accounting request");
+			return -1;
+		}
+	} else {
+		/* Make sure the user gave us a password */
+		if (h->pass_pos == 0 && !h->chap_pass) {
+			generr(h, "No User or Chap Password attributes given");
+			return -1;
+		}
+		if (h->pass_pos != 0 && h->chap_pass) {
+			generr(h, "Both User and Chap Password attributes given");
+			return -1;
+		}
 	}
 
 	/* Fill in the length field in the message */
@@ -591,7 +632,7 @@
  * In that case, it returns NULL.
  */
 struct rad_handle *
-rad_open(void)
+rad_auth_open(void)
 {
 	struct rad_handle *h;
 
@@ -606,8 +647,26 @@
 		h->pass_len = 0;
 		h->pass_pos = 0;
 		h->chap_pass = 0;
+		h->type = RADIUS_AUTH;
 	}
 	return h;
+}
+
+struct rad_handle *
+rad_acct_open(void)
+{
+	struct rad_handle *h;
+
+	h = rad_open();
+	if (h != NULL)
+	        h->type = RADIUS_ACCT;
+	return h;
+}
+
+struct rad_handle *
+rad_open(void)
+{
+    return rad_auth_open();
 }
 
 int
diff -urP libradius/radlib.h libradius+/radlib.h
--- libradius/radlib.h	Fri Feb  5 13:23:44 1999
+++ libradius+/radlib.h	Thu Oct  7 19:46:18 1999
@@ -36,6 +36,8 @@
 #define RAD_ACCESS_REQUEST		1
 #define RAD_ACCESS_ACCEPT		2
 #define RAD_ACCESS_REJECT		3
+#define RAD_ACCOUNTING_REQUEST		4
+#define RAD_ACCOUNTING_RESPONSE		5
 #define RAD_ACCESS_CHALLENGE		11
 
 /* Attribute types and values */
@@ -66,6 +68,9 @@
 #define RAD_FILTER_ID			11	/* String */
 #define RAD_FRAMED_MTU			12	/* Integer */
 #define RAD_FRAMED_COMPRESSION		13	/* Integer */
+	#define RAD_COMP_NONE			0
+	#define RAD_COMP_VJ			1
+	#define RAD_COMP_IPXHDR			2
 #define RAD_LOGIN_IP_HOST		14	/* IP address */
 #define RAD_LOGIN_SERVICE		15	/* Integer */
 #define RAD_LOGIN_TCP_PORT		16	/* Integer */
@@ -95,8 +100,54 @@
      /* reserved for accounting		40-59 */
 #define RAD_CHAP_CHALLENGE		60	/* String */
 #define RAD_NAS_PORT_TYPE		61	/* Integer */
+	#define RAD_ASYNC			0
+	#define RAD_SYNC			1
+	#define RAD_ISDN_SYNC			2
+	#define RAD_ISDN_ASYNC_V120		3
+	#define RAD_ISDN_ASYNC_V110		4
+	#define RAD_VIRTUAL			5
 #define RAD_PORT_LIMIT			62	/* Integer */
 #define RAD_LOGIN_LAT_PORT		63	/* Integer */
+#define RAD_CONNECT_INFO		77	/* String */
+
+/* Accounting attribute types and values */
+#define RAD_ACCT_STATUS_TYPE		40	/* Integer */
+	#define RAD_START			1
+	#define RAD_STOP			2
+	#define RAD_ACCOUNTING_ON		7
+	#define RAD_ACCOUNTING_OFF		8
+#define RAD_ACCT_DELAY_TIME		41	/* Integer */
+#define RAD_ACCT_INPUT_OCTETS		42	/* Integer */
+#define RAD_ACCT_OUTPUT_OCTETS		43	/* Integer */
+#define RAD_ACCT_SESSION_ID		44	/* String */
+#define RAD_ACCT_AUTHENTIC		45	/* Integer */
+	#define RAD_AUTH_RADIUS			1
+	#define RAD_AUTH_LOCAL			2
+	#define RAD_AUTH_REMOTE			3
+#define RAD_ACCT_SESSION_TIME		46	/* Integer */
+#define RAD_ACCT_INPUT_PACKETS		47	/* Integer */
+#define RAD_ACCT_OUTPUT_PACKETS		48	/* Integer */
+#define RAD_ACCT_TERMINATE_CAUSE	49	/* Integer */
+        #define RAD_TERM_USER_REQUEST		1
+        #define RAD_TERM_LOST_CARRIER		2
+        #define RAD_TERM_LOST_SERVICE		3
+        #define RAD_TERM_IDLE_TIMEOUT		4
+        #define RAD_TERM_SESSION_TIMEOUT	5
+        #define RAD_TERM_ADMIN_RESET		6
+        #define RAD_TERM_ADMIN_REBOOT		7
+        #define RAD_TERM_PORT_ERROR		8
+        #define RAD_TERM_NAS_ERROR		9
+        #define RAD_TERM_NAS_REQUEST		10
+        #define RAD_TERM_NAS_REBOOT		11
+        #define RAD_TERM_PORT_UNNEEDED		12
+        #define RAD_TERM_PORT_PREEMPTED		13
+        #define RAD_TERM_PORT_SUSPENDED		14
+        #define RAD_TERM_SERVICE_UNAVAILABLE    15
+        #define RAD_TERM_CALLBACK		16
+        #define RAD_TERM_USER_ERROR		17
+        #define RAD_TERM_HOST_REQUEST		18
+#define	RAD_ACCT_MULTI_SESSION_ID	50	/* String */
+#define	RAD_ACCT_LINK_COUNT		51	/* Integer */
 
 struct rad_handle;
 struct timeval;
@@ -117,6 +168,8 @@
 int			 rad_init_send_request(struct rad_handle *, int *,
 			    struct timeval *);
 struct rad_handle	*rad_open(void);
+struct rad_handle	*rad_auth_open(void);
+struct rad_handle	*rad_acct_open(void);
 int			 rad_put_addr(struct rad_handle *, int, struct in_addr);
 int			 rad_put_attr(struct rad_handle *, int,
 			    const void *, size_t);
diff -urP libradius/radlib_private.h libradius+/radlib_private.h
--- libradius/radlib_private.h	Fri Feb  5 13:23:44 1999
+++ libradius+/radlib_private.h	Thu Oct  7 19:28:58 1999
@@ -34,10 +34,16 @@
 
 #include "radlib.h"
 
+/* Handle types */
+#define RADIUS_AUTH		0   /* RADIUS authentication, default */
+#define RADIUS_ACCT		1   /* RADIUS accounting */
+
 /* Defaults */
 #define MAXTRIES		3
 #define PATH_RADIUS_CONF	"/etc/radius.conf"
+#define PATH_RADACCT_CONF	"/etc/radacct.conf"
 #define RADIUS_PORT		1812
+#define RADACCT_PORT		1813
 #define TIMEOUT			3	/* In seconds */
 
 /* Limits */
@@ -81,6 +87,7 @@
 	int		 total_tries;	/* How many requests we'll send */
 	int		 try;		/* How many requests we've sent */
 	int		 srv;		/* Server number we did last */
+	int		 type;		/* Handle type */
 };
 
 #endif

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199910121245.PAA00711>