Date: Mon, 11 Oct 1999 11:18:53 +0200 From: "Oleg Semyonov" <os@altavista.net> To: <jdp@polstra.com> Cc: <freebsd-isp@freebsd.org> Subject: FreeBSD libradius accounting patch suggestion Message-ID: <000b01bf13c9$a4afc480$0400a8c0@admin.dnepr.com>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hello John!
Excuse me for my "English" but I'm sure you understand me.
I need the pppd-2.3.9(10) daemon with RADIUS authentication and
accounting.
I've patched original pppd-2.3.9 distribution for FreeBSD specifics and put
into
source the RADIUS capabilities with almost full support for auth and
accounting.
To do so I've patched your libradius sources extracted from FreeBSD 3.* for
accounting support. Patches are attached. They 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 mans changed, sorry.
6. Default accounting config file is /etc/radacct.conf (not the best
solution, IMHO, but no way to extend radius.conf(5) file format to
support accounting and maintain the compatibility with current libradius
version).
7. #define for __printflike (for FreeBSD 2.2.8).
8. library and header renamed for compatibility with old version
(as temporary solution).
I'm planning to release my pppd patches for public, so it is best if you
put my patches (or my idea in your version) into standard FreeBSD
radius library. And put it into 2.2.8-STABLE source tree because seems
to me no any incompatibilities here, and your code is fully compilable
and usable on 2.2.8.
Mail me if you find my suggestion useful, and I will update my pppd
RADIUS support for new standard FreeBSD RADIUS library before release
it to public (anybody want it?).
Thanks!
OS
---
Oleg Semyonov, the Head of IT Department of KTPK "Dnepr", Energodar, UA
Internet mail: os@altavista.net, finger/talk: os@ktpk.dp.ua, ICQ:31256452
[-- Attachment #2 --]
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?000b01bf13c9$a4afc480$0400a8c0>
