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>