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>
index | next in thread | raw e-mail
>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
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199910121245.PAA00711>
