This patch merges changes from pppd's radiusclient code to libradiusclient. Author: Vladislav Bogdanov Updates: http://bubble.nsys.by/patches/radiusclient/ diff -urNp radiusclient-0.3.2/COPYRIGHT radiusclient.ppp/COPYRIGHT --- radiusclient-0.3.2/COPYRIGHT 1998-09-24 22:10:24.000000000 +0300 +++ radiusclient.ppp/COPYRIGHT 2002-01-22 18:03:00.000000000 +0200 @@ -1,6 +1,22 @@ See the respective source files to find out which copyrights apply. ------------------------------------------------------------------------------ +Copyright (C) 2002 Roaring Penguin Software Inc. + +Permission to use, copy, modify, and distribute this software for any +purpose and without fee is hereby granted, provided that this +copyright and permission notice appear on all copies and supporting +documentation, the name of Roaring Penguin Software Inc. not be used +in advertising or publicity pertaining to distribution of the program +without specific prior permission, and notice be given in supporting +documentation that copying and distribution is by permission of +Roaring Penguin Software Inc.. + +Roaring Penguin Software Inc. makes no representations about the +suitability of this software for any purpose. It is provided "as is" +without express or implied warranty. + +------------------------------------------------------------------------------ Copyright (C) 1995,1996,1997,1998 Lars Fenneberg Permission to use, copy, modify, and distribute this software for any @@ -51,7 +67,7 @@ University of Michigan and Merit Network special, indirect, incidental or consequential damages with respect to any claim by Licensee or any third party arising from use of the software. ------------------------------------------------------------------------------ -Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it diff -urNp radiusclient-0.3.2/etc/dictionary radiusclient.ppp/etc/dictionary --- radiusclient-0.3.2/etc/dictionary 1998-01-10 19:44:26.000000000 +0200 +++ radiusclient.ppp/etc/dictionary 2002-10-01 12:51:01.000000000 +0300 @@ -23,6 +23,23 @@ # 7 = 1 (integer encoding) # +# The dictionary format now supports vendor-specific attributes. +# Vendors are introduced like this: +# +# VENDOR vendor_name vendor_number +# +# For example: +# +# VENDOR RoaringPenguin 10055 +# +# Vendor-specific attributes have a fifth field with the name of the +# vendor. For example: +# +# ATTRIBUTE RP-Upstream-Speed-Limit 1 integer RoaringPenguin +# +# introduces a Roaring Penguin vendor-specific attribbute with name +# RP-Upstream-Speed-Limit, number 1, type integer and vendor RoaringPenguin. + # # Following are the proper new names. Use these. # @@ -48,11 +65,13 @@ ATTRIBUTE Callback-Id 20 string ATTRIBUTE Framed-Route 22 string ATTRIBUTE Framed-IPX-Network 23 ipaddr ATTRIBUTE State 24 string +ATTRIBUTE Class 25 string ATTRIBUTE Session-Timeout 27 integer ATTRIBUTE Idle-Timeout 28 integer ATTRIBUTE Termination-Action 29 integer ATTRIBUTE Called-Station-Id 30 string ATTRIBUTE Calling-Station-Id 31 string +ATTRIBUTE NAS-Identifier 32 string ATTRIBUTE Acct-Status-Type 40 integer ATTRIBUTE Acct-Delay-Time 41 integer ATTRIBUTE Acct-Input-Octets 42 integer @@ -60,11 +79,17 @@ ATTRIBUTE Acct-Output-Octets 43 integer ATTRIBUTE Acct-Session-Id 44 string ATTRIBUTE Acct-Authentic 45 integer ATTRIBUTE Acct-Session-Time 46 integer +ATTRIBUTE Acct-Input-Packets 47 integer +ATTRIBUTE Acct-Output-Packets 48 integer ATTRIBUTE Acct-Terminate-Cause 49 integer +ATTRIBUTE Chap-Challenge 60 string ATTRIBUTE NAS-Port-Type 61 integer ATTRIBUTE Port-Limit 62 integer ATTRIBUTE Connect-Info 77 string +# RFC 2869 +ATTRIBUTE Acct-Interim-Interval 85 integer + # # Experimental Non Protocol Attributes used by Cistron-Radiusd # @@ -94,6 +119,14 @@ ATTRIBUTE Crypt-Password 1006 string ATTRIBUTE Connect-Rate 1007 integer # +# Experimental, implementation specific attributes +# +# Limit session traffic +ATTRIBUTE Session-Octets-Limit 227 integer +# What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out) +ATTRIBUTE Octets-Direction 228 integer + +# # Integer Translations # @@ -210,3 +243,11 @@ VALUE Add-Port-To-IP-Address Yes 1 #VALUE Server-Config Password-Expiration 30 #VALUE Server-Config Password-Warning 5 +# Octets-Direction +VALUE Octets-Direction Sum 0 +VALUE Octets-Direction Input 1 +VALUE Octets-Direction Output 2 +VALUE Octets-Direction MaxOveral 3 +VALUE Octets-Direction MaxSession 4 + +INCLUDE /etc/radiusclient/dictionary.microsoft diff -urNp radiusclient-0.3.2/etc/dictionary.ascend radiusclient.ppp/etc/dictionary.ascend --- radiusclient-0.3.2/etc/dictionary.ascend 1998-01-10 19:44:26.000000000 +0200 +++ radiusclient.ppp/etc/dictionary.ascend 2002-01-22 18:03:01.000000000 +0200 @@ -1,8 +1,6 @@ # # Ascend dictionary. # -# Enable by putting the line "$INCLUDE dictionary.ascend" into -# the main dictionary file. # # Version: 1.00 21-Jul-1997 Jens Glaser # diff -urNp radiusclient-0.3.2/etc/dictionary.compat radiusclient.ppp/etc/dictionary.compat --- radiusclient-0.3.2/etc/dictionary.compat 1998-01-10 19:44:26.000000000 +0200 +++ radiusclient.ppp/etc/dictionary.compat 2002-01-22 18:03:01.000000000 +0200 @@ -1,7 +1,5 @@ # # Obsolete names for backwards compatibility with older users files. -# Move the $INCLUDE in the main dictionary file to the end if you want -# these names to be used in the "details" logfile. # ATTRIBUTE Client-Id 4 ipaddr ATTRIBUTE Client-Port-Id 5 integer diff -urNp radiusclient-0.3.2/etc/dictionary.microsoft radiusclient.ppp/etc/dictionary.microsoft --- radiusclient-0.3.2/etc/dictionary.microsoft 1970-01-01 03:00:00.000000000 +0300 +++ radiusclient.ppp/etc/dictionary.microsoft 2002-03-06 15:23:09.000000000 +0200 @@ -0,0 +1,81 @@ +# +# Microsoft's VSA's, from RFC 2548 +# +# $Id: dictionary.microsoft,v 1.1 2002/03/06 13:23:09 dfs Exp $ +# + +VENDOR Microsoft 311 Microsoft + +ATTRIBUTE MS-CHAP-Response 1 string Microsoft +ATTRIBUTE MS-CHAP-Error 2 string Microsoft +ATTRIBUTE MS-CHAP-CPW-1 3 string Microsoft +ATTRIBUTE MS-CHAP-CPW-2 4 string Microsoft +ATTRIBUTE MS-CHAP-LM-Enc-PW 5 string Microsoft +ATTRIBUTE MS-CHAP-NT-Enc-PW 6 string Microsoft +ATTRIBUTE MS-MPPE-Encryption-Policy 7 string Microsoft +# This is referred to as both singular and plural in the RFC. +# Plural seems to make more sense. +ATTRIBUTE MS-MPPE-Encryption-Type 8 string Microsoft +ATTRIBUTE MS-MPPE-Encryption-Types 8 string Microsoft +ATTRIBUTE MS-RAS-Vendor 9 integer Microsoft +ATTRIBUTE MS-CHAP-Domain 10 string Microsoft +ATTRIBUTE MS-CHAP-Challenge 11 string Microsoft +ATTRIBUTE MS-CHAP-MPPE-Keys 12 string Microsoft +ATTRIBUTE MS-BAP-Usage 13 integer Microsoft +ATTRIBUTE MS-Link-Utilization-Threshold 14 integer Microsoft +ATTRIBUTE MS-Link-Drop-Time-Limit 15 integer Microsoft +ATTRIBUTE MS-MPPE-Send-Key 16 string Microsoft +ATTRIBUTE MS-MPPE-Recv-Key 17 string Microsoft +ATTRIBUTE MS-RAS-Version 18 string Microsoft +ATTRIBUTE MS-Old-ARAP-Password 19 string Microsoft +ATTRIBUTE MS-New-ARAP-Password 20 string Microsoft +ATTRIBUTE MS-ARAP-PW-Change-Reason 21 integer Microsoft + +ATTRIBUTE MS-Filter 22 string Microsoft +ATTRIBUTE MS-Acct-Auth-Type 23 integer Microsoft +ATTRIBUTE MS-Acct-EAP-Type 24 integer Microsoft + +ATTRIBUTE MS-CHAP2-Response 25 string Microsoft +ATTRIBUTE MS-CHAP2-Success 26 string Microsoft +ATTRIBUTE MS-CHAP2-CPW 27 string Microsoft + +ATTRIBUTE MS-Primary-DNS-Server 28 ipaddr Microsoft +ATTRIBUTE MS-Secondary-DNS-Server 29 ipaddr Microsoft +ATTRIBUTE MS-Primary-NBNS-Server 30 ipaddr Microsoft +ATTRIBUTE MS-Secondary-NBNS-Server 31 ipaddr Microsoft + +#ATTRIBUTE MS-ARAP-Challenge 33 string Microsoft + + +# +# Integer Translations +# + +# MS-BAP-Usage Values + +VALUE MS-BAP-Usage Not-Allowed 0 +VALUE MS-BAP-Usage Allowed 1 +VALUE MS-BAP-Usage Required 2 + +# MS-ARAP-Password-Change-Reason Values + +VALUE MS-ARAP-PW-Change-Reason Just-Change-Password 1 +VALUE MS-ARAP-PW-Change-Reason Expired-Password 2 +VALUE MS-ARAP-PW-Change-Reason Admin-Requires-Password-Change 3 +VALUE MS-ARAP-PW-Change-Reason Password-Too-Short 4 + +# MS-Acct-Auth-Type Values + +VALUE MS-Acct-Auth-Type PAP 1 +VALUE MS-Acct-Auth-Type CHAP 2 +VALUE MS-Acct-Auth-Type MS-CHAP-1 3 +VALUE MS-Acct-Auth-Type MS-CHAP-2 4 +VALUE MS-Acct-Auth-Type EAP 5 + +# MS-Acct-EAP-Type Values + +VALUE MS-Acct-EAP-Type MD5 4 +VALUE MS-Acct-EAP-Type OTP 5 +VALUE MS-Acct-EAP-Type Generic-Token-Card 6 +VALUE MS-Acct-EAP-Type TLS 13 + diff -urNp radiusclient-0.3.2/etc/Makefile.am radiusclient.ppp/etc/Makefile.am --- radiusclient-0.3.2/etc/Makefile.am 1998-06-28 03:08:16.000000000 +0300 +++ radiusclient.ppp/etc/Makefile.am 2002-10-05 20:49:00.000000000 +0300 @@ -15,20 +15,25 @@ CLEANFILES = *~ radiusclient.conf sbindir = @sbindir@ pkgsysconfdir = @pkgsysconfdir@ pkgsysconf_DATA = issue port-id-map radiusclient.conf \ - dictionary dictionary.ascend dictionary.compat dictionary.merit + dictionary dictionary.ascend dictionary.compat dictionary.merit \ + dictionary.microsoft EXTRA_DIST = issue port-id-map dictionary dictionary.ascend \ - dictionary.compat dictionary.merit servers radiusclient.conf.in + dictionary.compat dictionary.merit dictionary.microsoft \ + realms servers radiusclient.conf.in radiusclient.conf: radiusclient.conf.in sed -e 's|@sbin''dir@|$(sbindir)|g' \ -e 's|@pkgsysconf''dir@|$(pkgsysconfdir)|g' \ <$(srcdir)/radiusclient.conf.in >radiusclient.conf -install-data-local: servers +install-data-local: realms servers $(mkinstalldirs) $(pkgsysconfdir); \ + echo " $(INSTALL) -m600 $(srcdir)/realms $(pkgsysconfdir)/realms"; \ + $(INSTALL) -m600 $(srcdir)/realms $(pkgsysconfdir)/realms; \ echo " $(INSTALL) -m600 $(srcdir)/servers $(pkgsysconfdir)/servers"; \ $(INSTALL) -m600 $(srcdir)/servers $(pkgsysconfdir)/servers uninstall-local: + rm -f $(pkgsysconfdir)/realms rm -f $(pkgsysconfdir)/servers diff -urNp radiusclient-0.3.2/etc/radiusclient.conf.in radiusclient.ppp/etc/radiusclient.conf.in --- radiusclient-0.3.2/etc/radiusclient.conf.in 1998-03-06 23:15:27.000000000 +0200 +++ radiusclient.ppp/etc/radiusclient.conf.in 2002-10-01 12:51:01.000000000 +0300 @@ -5,23 +5,23 @@ # if you specify "radius,local" then the RADIUS server is asked # first then the local one. if only one keyword is specified only # this server is asked. -auth_order radius,local +auth_order radius -# maximum login tries a user has +# maximum login tries a user has (default 4) login_tries 4 -# timeout for all login tries -# if this time is exceeded the user is kicked out +# timeout for all login tries (default 60) +# if this time is exceeded the user is kicked out login_timeout 60 # name of the nologin file which when it exists disables logins. # it may be extended by the ttyname which will result in # a terminal specific lock (e.g. /etc/nologin.ttyS2 will disable -# logins on /dev/ttyS2) +# logins on /dev/ttyS2) (default /etc/nologin) nologin /etc/nologin # name of the issue file. it's only display when no username is passed -# on the radlogin command line +# on the radlogin command line (default /etc/radiusclient/issue) issue @pkgsysconfdir@/issue # RADIUS settings @@ -34,12 +34,12 @@ issue @pkgsysconfdir@/issue # RADIUS listens separated by a colon from the hostname. if # no port is specified /etc/services is consulted of the radius # service. if this fails also a compiled in default is used. -authserver localhost +authserver localhost:1812 # RADIUS server to use for accouting requests. All that I # said for authserver applies, too. # -acctserver localhost +acctserver localhost:1813 # file holding shared secrets used for the communication # between the RADIUS client and server @@ -49,7 +49,8 @@ servers @pkgsysconfdir@/servers # just like in the normal RADIUS distributions dictionary @pkgsysconfdir@/dictionary -# program to call for a RADIUS authenticated login +# program to call for a RADIUS authenticated login +# (default /usr/sbin/login.radius) login_radius @sbindir@/login.radius # file which holds sequence number for communication with the @@ -71,6 +72,18 @@ radius_timeout 10 # resend request this many times before trying the next server radius_retries 3 +# NAS-Identifier +# +# If supplied, this option will cause the client to send the given string +# as the contents of the NAS-Identifier attribute in RADIUS requests. No +# NAS-IP-Address attribute will be sent in this case. +# +# The default behavior is to send a NAS-IP-Address option and not send +# a NAS-Identifier. The value of the NAS-IP-Address option is chosen +# by resolving the system hostname. + +# nas_identifier MyUniqueNASName + # LOCAL settings # program to execute for local login diff -urNp radiusclient-0.3.2/etc/realms radiusclient.ppp/etc/realms --- radiusclient-0.3.2/etc/realms 1970-01-01 03:00:00.000000000 +0300 +++ radiusclient.ppp/etc/realms 2002-10-05 07:35:24.000000000 +0300 @@ -0,0 +1,22 @@ +# /etc/radiusclient/realms +# +# Handle realm @netservers.co.uk on an internal RADIUS server +# (note the server must be told to strip the realm) + +#authserver netservers.co.uk 192.168.1.1:1812 +#acctserver netservers.co.uk 192.168.1.1:1813 + +# users in realm @example.com are handled by separate servers + +#authserver example.com 10.0.0.1:1812 +#acctserver example.com 10.0.0.2:1813 + +# the DEFAULT realm matches users that do not supply a realm + +#authserver DEFAULT 192.168.1.1:1812 +#acctserver DEFAULT 192.168.1.1:1813 + +# Any realms that do not match in the realms file automatically fall +# through to the standard radius plugin which uses the servers in the +# radiusclient.conf file. Note that this is different than the +# DEFAULT realm match, above. diff -urNp radiusclient-0.3.2/include/radiusclient.h radiusclient.ppp/include/radiusclient.h --- radiusclient-0.3.2/include/radiusclient.h 1999-01-07 01:53:04.000000000 +0200 +++ radiusclient.ppp/include/radiusclient.h 2002-11-26 11:44:01.000000000 +0200 @@ -38,8 +38,15 @@ # define __P(protos) () #endif +#ifndef _UINT4_T +#ifdef _LP64 +typedef unsigned int UINT4; +typedef int INT4; +#else typedef unsigned long UINT4; -typedef long INT4; +typedef long INT4; +#endif +#endif #define AUTH_VECTOR_LEN 16 #define AUTH_PASS_LEN (3 * 16) /* multiple of 16 */ @@ -67,7 +74,7 @@ typedef long INT4; typedef struct server { int max; char *name[SERVER_MAX]; - unsigned short port[SERVER_MAX]; + unsigned short port[SERVER_MAX]; } SERVER; typedef struct pw_auth_hdr @@ -83,8 +90,8 @@ typedef struct pw_auth_hdr #define MAX_SECRET_LENGTH (3 * 16) /* MUST be multiple of 16 */ #define CHAP_VALUE_LENGTH 16 -#define PW_AUTH_UDP_PORT 1645 -#define PW_ACCT_UDP_PORT 1646 +#define PW_AUTH_UDP_PORT 1812 +#define PW_ACCT_UDP_PORT 1813 #define PW_TYPE_STRING 0 #define PW_TYPE_INTEGER 1 @@ -154,6 +161,18 @@ typedef struct pw_auth_hdr #define PW_PORT_LIMIT 62 /* integer */ #define PW_LOGIN_LAT_PORT 63 /* string */ +/* Vendor RADIUS attribute-value pairs */ +#define PW_MS_CHAP_CHALLENGE 11 /* string */ +#define PW_MS_CHAP_RESPONSE 1 /* string */ +#define PW_MS_CHAP2_RESPONSE 25 /* string */ +#define PW_MS_CHAP2_SUCCESS 26 /* string */ +#define PW_MS_MPPE_ENCRYPTION_POLICY 7 /* string */ +#define PW_MS_MPPE_ENCRYPTION_TYPE 8 /* string */ +#define PW_MS_MPPE_ENCRYPTION_TYPES PW_MS_MPPE_ENCRYPTION_TYPE +#define PW_MS_CHAP_MPPE_KEYS 12 /* string */ +#define PW_MS_MPPE_SEND_KEY 16 /* string */ +#define PW_MS_MPPE_RECV_KEY 17 /* string */ + /* Accounting */ #define PW_ACCT_STATUS_TYPE 40 /* integer */ @@ -169,11 +188,19 @@ typedef struct pw_auth_hdr #define PW_ACCT_MULTI_SESSION_ID 50 /* string */ #define PW_ACCT_LINK_COUNT 51 /* integer */ +/* From RFC 2869 */ +#define PW_ACCT_INTERIM_INTERVAL 85 /* integer */ + /* Merit Experimental Extensions */ #define PW_USER_ID 222 /* string */ #define PW_USER_REALM 223 /* string */ + +/* Session limits */ +#define PW_SESSION_OCTETS_LIMIT 227 /* integer */ +#define PW_OCTETS_DIRECTION 228 /* integer */ + /* Integer Translations */ /* SERVICE TYPES */ @@ -260,7 +287,7 @@ typedef struct pw_auth_hdr #define PW_CALLBACK 16 #define PW_USER_ERROR 17 #define PW_HOST_REQUEST 18 - + /* NAS PORT TYPES */ #define PW_ASYNC 0 @@ -275,6 +302,17 @@ typedef struct pw_auth_hdr #define PW_LOCAL 2 #define PW_REMOTE 3 +/* Session-Octets-Limit */ +#define PW_OCTETS_DIRECTION_SUM 0 +#define PW_OCTETS_DIRECTION_IN 1 +#define PW_OCTETS_DIRECTION_OUT 2 +#define PW_OCTETS_DIRECTION_MAX 3 + + +/* Vendor codes */ +#define VENDOR_NONE (-1) +#define VENDOR_MICROSOFT 311 + /* Server data structures */ typedef struct dict_attr @@ -282,6 +320,7 @@ typedef struct dict_attr char name[NAME_LENGTH + 1]; /* attribute name */ int value; /* attribute index */ int type; /* string, int, etc. */ + int vendorcode; /* vendor code */ struct dict_attr *next; } DICT_ATTR; @@ -293,20 +332,29 @@ typedef struct dict_value struct dict_value *next; } DICT_VALUE; +typedef struct vendor_dict +{ + char vendorname[NAME_LENGTH + 1]; + int vendorcode; + DICT_ATTR *attributes; + struct vendor_dict *next; +} VENDOR_DICT; + typedef struct value_pair { char name[NAME_LENGTH + 1]; int attribute; + int vendorcode; int type; UINT4 lvalue; - char strvalue[AUTH_STRING_LEN + 1]; + u_char strvalue[AUTH_STRING_LEN + 1]; struct value_pair *next; } VALUE_PAIR; /* don't change this, as it has to be the same as in the Merit radiusd code */ #define MGMT_POLL_SECRET "Hardlyasecret" -/* Define return codes from "SendServer" utility */ +/* Define return codes from "SendServer" utility */ #define BADRESP_RC -2 #define ERROR_RC -1 @@ -325,6 +373,12 @@ typedef struct send_data /* Used to pass VALUE_PAIR *receive_pairs; /* Where to place received a/v pairs */ } SEND_DATA; +typedef struct request_info +{ + char secret[MAX_SECRET_LENGTH + 1]; + u_char request_vector[AUTH_VECTOR_LEN]; +} REQUEST_INFO; + #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif @@ -350,11 +404,12 @@ __BEGIN_DECLS /* avpair.c */ -VALUE_PAIR *rc_avpair_add __P((VALUE_PAIR **, int, void *, int)); +VALUE_PAIR *rc_avpair_add __P((VALUE_PAIR **, int, void *, int, int)); int rc_avpair_assign __P((VALUE_PAIR *, void *, int)); -VALUE_PAIR *rc_avpair_new __P((int, void *, int)); +VALUE_PAIR *rc_avpair_new __P((int, void *, int, int)); VALUE_PAIR *rc_avpair_gen __P((AUTH_HDR *)); VALUE_PAIR *rc_avpair_get __P((VALUE_PAIR *, UINT4)); +VALUE_PAIR *rc_avpair_copy __P((VALUE_PAIR *)); void rc_avpair_insert __P((VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *)); void rc_avpair_free __P((VALUE_PAIR *)); int rc_avpair_parse __P((char *, VALUE_PAIR **)); @@ -365,9 +420,12 @@ VALUE_PAIR *rc_avpair_readin __P((FILE * void rc_buildreq __P((SEND_DATA *, int, char *, unsigned short, int, int)); unsigned char rc_get_seqnbr __P((void)); -int rc_auth __P((UINT4, VALUE_PAIR *, VALUE_PAIR **, char *)); +int rc_auth __P((UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *)); +int rc_auth_using_server __P((SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **, + char *, REQUEST_INFO *)); int rc_auth_proxy __P((VALUE_PAIR *, VALUE_PAIR **, char *)); int rc_acct __P((UINT4, VALUE_PAIR *)); +int rc_acct_using_server __P((SERVER *, UINT4, VALUE_PAIR *)); int rc_acct_proxy __P((VALUE_PAIR *)); int rc_check __P((char *, unsigned short, char *)); @@ -387,10 +445,12 @@ int rc_find_server __P((char *, UINT4 *, /* dict.c */ int rc_read_dictionary __P((char *)); -DICT_ATTR *rc_dict_getattr __P((int)); +DICT_ATTR *rc_dict_getattr __P((int, int)); DICT_ATTR *rc_dict_findattr __P((char *)); DICT_VALUE *rc_dict_findval __P((char *)); DICT_VALUE * rc_dict_getval __P((UINT4, char *)); +VENDOR_DICT * rc_dict_findvendor __P((char *)); +VENDOR_DICT * rc_dict_getvendor __P((int)); /* ip_util.c */ @@ -409,7 +469,7 @@ void rc_log __P((int, const char *, ...) /* sendserver.c */ -int rc_send_server __P((SEND_DATA *, char *)); +int rc_send_server __P((SEND_DATA *, char *, REQUEST_INFO *)); /* util.c */ diff -urNp radiusclient-0.3.2/lib/avpair.c radiusclient.ppp/lib/avpair.c --- radiusclient-0.3.2/lib/avpair.c 1997-12-26 01:28:08.000000000 +0200 +++ radiusclient.ppp/lib/avpair.c 2003-04-19 21:12:53.000000000 +0300 @@ -18,6 +18,9 @@ #include #include +static void rc_extract_vendor_specific_attributes(int attrlen, + unsigned char *ptr, + VALUE_PAIR **vp); /* * Function: rc_avpair_add * @@ -29,11 +32,12 @@ * */ -VALUE_PAIR *rc_avpair_add (VALUE_PAIR **list, int attrid, void *pval, int len) +VALUE_PAIR *rc_avpair_add (VALUE_PAIR **list, int attrid, void *pval, int len, + int vendorcode) { VALUE_PAIR *vp; - vp = rc_avpair_new (attrid, pval, len); + vp = rc_avpair_new (attrid, pval, len, vendorcode); if (vp != (VALUE_PAIR *) NULL) { @@ -104,12 +108,12 @@ int rc_avpair_assign (VALUE_PAIR *vp, vo * */ -VALUE_PAIR *rc_avpair_new (int attrid, void *pval, int len) +VALUE_PAIR *rc_avpair_new (int attrid, void *pval, int len, int vendorcode) { VALUE_PAIR *vp = (VALUE_PAIR *) NULL; DICT_ATTR *pda; - if ((pda = rc_dict_getattr (attrid)) == (DICT_ATTR *) NULL) + if ((pda = rc_dict_getattr (attrid, vendorcode)) == (DICT_ATTR *) NULL) { rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid); } @@ -120,6 +124,7 @@ VALUE_PAIR *rc_avpair_new (int attrid, v { strncpy (vp->name, pda->name, sizeof (vp->name)); vp->attribute = attrid; + vp->vendorcode = vendorcode; vp->next = (VALUE_PAIR *) NULL; vp->type = pda->type; if (rc_avpair_assign (vp, pval, len) == 0) @@ -159,8 +164,8 @@ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *aut DICT_ATTR *attr; VALUE_PAIR *vp; VALUE_PAIR *pair; - unsigned char hex[3]; /* For hex string conversion. */ - char buffer[256]; + unsigned char hex[3]; /* For hex string conversion. */ + char buffer[512]; /* * Extract attribute-value pairs @@ -180,7 +185,14 @@ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *aut break; } - if ((attr = rc_dict_getattr (attribute)) == (DICT_ATTR *) NULL) + /* Handle vendor-specific specially */ + if (attribute == PW_VENDOR_SPECIFIC) { + rc_extract_vendor_specific_attributes(attrlen, ptr, &vp); + ptr += attrlen; + length -= (attrlen + 2); + continue; + } + if ((attr = rc_dict_getattr (attribute, VENDOR_NONE)) == (DICT_ATTR *) NULL) { *buffer= '\0'; /* Initial length. */ for (x_ptr = ptr, x_len = attrlen ; @@ -205,6 +217,7 @@ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *aut } strcpy (pair->name, attr->name); pair->attribute = attr->value; + pair->vendorcode = VENDOR_NONE; pair->type = attr->type; pair->next = (VALUE_PAIR *) NULL; @@ -240,6 +253,96 @@ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *aut } /* + * Function: rc_extract_vendor_specific_attributes + * + * Purpose: Extracts vendor-specific attributes, assuming they are in + * the "SHOULD" format recommended by RCF 2138. + * + * Returns: found value_pair + * + */ +static void rc_extract_vendor_specific_attributes(int attrlen, + unsigned char *ptr, + VALUE_PAIR **vp) +{ + int vendor_id; + int vtype; + int vlen; + UINT4 lvalue; + DICT_ATTR *attr; + VALUE_PAIR *pair; + + /* ptr is sitting at vendor-ID */ + if (attrlen < 8) { + /* Nothing to see here... */ + return; + } + + /* High-order octet of Vendor-Id must be zero (RFC2138) */ + if (*ptr) { + return; + } + + /* Extract vendor_id */ + vendor_id = (int) ( + ((unsigned int) ptr[1]) * 256 * 256 + + ((unsigned int) ptr[2]) * 256 + + ((unsigned int) ptr[3])); + /* Bump ptr up to contents */ + ptr += 4; + + /* Set attrlen to length of data */ + attrlen -= 4; + for (; attrlen; attrlen -= vlen+2, ptr += vlen) { + vtype = *ptr++; + vlen = *ptr++; + vlen -= 2; + if (vlen < 0 || vlen > attrlen - 2) { + /* Do not log an error. We are supposed to be able to cope with + arbitrary vendor-specific gunk */ + return; + } + /* Looks plausible... */ + if ((attr = rc_dict_getattr(vtype, vendor_id)) == NULL) { + continue; + } + + /* TODO: Check that length matches data size!!!!! */ + pair = (VALUE_PAIR *) malloc(sizeof(VALUE_PAIR)); + if (!pair) { + rc_log(LOG_CRIT, "rc_avpair_gen: out of memory"); + return; + } + strcpy(pair->name, attr->name); + pair->attribute = attr->value; + pair->vendorcode = vendor_id; + pair->type = attr->type; + pair->next = NULL; + switch (attr->type) { + case PW_TYPE_STRING: + memcpy (pair->strvalue, (char *) ptr, (size_t) vlen); + pair->strvalue[vlen] = '\0'; + pair->lvalue = vlen; + rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); + break; + + case PW_TYPE_INTEGER: + case PW_TYPE_IPADDR: + memcpy ((char *) &lvalue, (char *) ptr, + sizeof (UINT4)); + pair->lvalue = ntohl (lvalue); + rc_avpair_insert (vp, (VALUE_PAIR *) NULL, pair); + break; + + default: + rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type", attr->name); + free (pair); + break; + } + } +} + +/* * Function: rc_avpair_get * * Purpose: Find the first attribute value-pair (which matches the given @@ -256,15 +359,43 @@ VALUE_PAIR *rc_avpair_get (VALUE_PAIR *v continue; } return (vp); -} +} + +/* + * Function: rc_avpair_copy + * + * Purpose: Return a copy of the existing list "p" ala strdup(). + * + */ +VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *p) +{ + VALUE_PAIR *vp, *fp = NULL, *lp = NULL; + + while (p) { + vp = malloc(sizeof(VALUE_PAIR)); + if (!vp) { + rc_log(LOG_CRIT, "rc_avpair_copy: out of memory"); + return NULL; /* leaks a little but so what */ + } + *vp = *p; + if (!fp) + fp = vp; + if (lp) + lp->next = vp; + lp = vp; + p = p->next; + } + + return fp; +} /* * Function: rc_avpair_insert * * Purpose: Given the address of an existing list "a" and a pointer - * to an entry "p" in that list, add the value pair "b" to + * to an entry "p" in that list, add the list "b" to * the "a" list after the "p" entry. If "p" is NULL, add - * the value pair "b" to the end of "a". + * the list "b" to the end of "a". * */ @@ -273,18 +404,15 @@ void rc_avpair_insert (VALUE_PAIR **a, V VALUE_PAIR *this_node = NULL; VALUE_PAIR *vp; - if (b->next != (VALUE_PAIR *) NULL) - { - rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next); - abort (); - } - if (*a == (VALUE_PAIR *) NULL) { *a = b; return; } + if (!b) + return; + vp = *a; if ( p == (VALUE_PAIR *) NULL) /* run to end of "a" list */ @@ -295,7 +423,7 @@ void rc_avpair_insert (VALUE_PAIR **a, V vp = vp->next; } } - else /* look for the "p" entry in the "a" list */ + else /* look for the "p" entry in the "a" list (or run to end) */ { this_node = *a; while (this_node != (VALUE_PAIR *) NULL) @@ -308,9 +436,15 @@ void rc_avpair_insert (VALUE_PAIR **a, V } } - b->next = this_node->next; + /* add "b" at this_node */ + vp = this_node->next; this_node->next = b; + /* run to end of "b" and connect the rest of "a" */ + while (b->next) + b = b->next; + b->next = vp; + return; } @@ -331,7 +465,7 @@ void rc_avpair_free (VALUE_PAIR *pair) free (pair); pair = next; } -} +} /* * Function: rc_fieldcpy @@ -340,7 +474,7 @@ void rc_avpair_free (VALUE_PAIR *pair) * past the data field. * */ - + static void rc_fieldcpy (char *string, char **uptr) { char *ptr; @@ -460,6 +594,7 @@ int rc_avpair_parse (char *buffer, VALUE strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->type = attr->type; + pair->vendorcode = attr->vendorcode; switch (pair->type) { @@ -495,7 +630,7 @@ int rc_avpair_parse (char *buffer, VALUE break; case PW_TYPE_IPADDR: - pair->lvalue = rc_get_ipaddr(valstr); + pair->lvalue = rc_get_ipaddr(valstr); break; case PW_TYPE_DATE: @@ -567,7 +702,7 @@ int rc_avpair_tostr (VALUE_PAIR *pair, c *name = *value = '\0'; if (!pair || pair->name[0] == '\0') { - rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty"); + rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty"); return (-1); } @@ -576,7 +711,7 @@ int rc_avpair_tostr (VALUE_PAIR *pair, c switch (pair->type) { case PW_TYPE_STRING: - lv--; + lv--; ptr = (unsigned char *) pair->strvalue; while (*ptr != '\0') { @@ -626,7 +761,7 @@ int rc_avpair_tostr (VALUE_PAIR *pair, c return (-1); break; } - + return 0; } @@ -646,18 +781,18 @@ VALUE_PAIR *rc_avpair_readin(FILE *input while (fgets(buffer, sizeof(buffer), input) != NULL) { q = buffer; - + while(*q && isspace(*q)) q++; - + if ((*q == '\n') || (*q == '#') || (*q == '\0')) continue; - + if (rc_avpair_parse(q, &vp) < 0) { rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer); rc_avpair_free(vp); return NULL; } } - + return vp; } diff -urNp radiusclient-0.3.2/lib/buildreq.c radiusclient.ppp/lib/buildreq.c --- radiusclient-0.3.2/lib/buildreq.c 1998-12-11 13:24:28.000000000 +0200 +++ radiusclient.ppp/lib/buildreq.c 2003-05-02 00:39:30.000000000 +0300 @@ -16,10 +16,48 @@ unsigned char rc_get_seqnbr(void); /* + * Function: rc_get_nas_id + * + * Purpose: fills in NAS-Identifier or NAS-IP-Address in request + * + */ + +int rc_get_nas_id(VALUE_PAIR **sendpairs) +{ + UINT4 client_id; + char *nasid; + + nasid = rc_conf_str("nas_identifier"); + if (strlen(nasid)) { + /* + * Fill in NAS-Identifier + */ + if (rc_avpair_add(sendpairs, PW_NAS_IDENTIFIER, nasid, 0, + VENDOR_NONE) == NULL) + return (ERROR_RC); + + return (OK_RC); + + } else { + /* + * Fill in NAS-IP-Address + */ + if ((client_id = rc_own_ipaddress()) == 0) + return (ERROR_RC); + + if (rc_avpair_add(sendpairs, PW_NAS_IP_ADDRESS, &client_id, + 0, VENDOR_NONE) == NULL) + return (ERROR_RC); + } + + return (OK_RC); +} + +/* * Function: rc_buildreq * * Purpose: builds a skeleton RADIUS request using information from the - * config file. + * config file. * */ @@ -58,48 +96,52 @@ unsigned char rc_get_seqnbr(void) { FILE *sf; int tries = 1; - int seq_nbr; + int seq_nbr, pos; char *seqfile = rc_conf_str("seqfile"); - + if ((sf = fopen(seqfile, "a+")) == NULL) { - rc_log(LOG_ERR,"rc_get_seqnbr: couldn't open sequence file %s: %s", seqfile, strerror(errno)); + rc_log(LOG_ERR,"rc_get_seqnbr: couldn't open sequence file %s: %s", seqfile, strerror(errno)); /* well, so guess a sequence number */ - return rc_guess_seqnbr(); - } + return rc_guess_seqnbr(); + } while (do_lock_exclusive(fileno(sf))!= 0) { if (errno != EWOULDBLOCK) { rc_log(LOG_ERR, "rc_get_seqnbr: flock failure: %s: %s", seqfile, strerror(errno)); - fclose(sf); + fclose(sf); return rc_guess_seqnbr(); } tries++; - if (tries <= 10) - rc_mdelay(500); - else + if (tries <= 10) + rc_mdelay(500); + else break; } - + if (tries > 10) { rc_log(LOG_ERR,"rc_get_seqnbr: couldn't get lock after %d tries: %s", tries-1, seqfile); - fclose(sf); + fclose(sf); return rc_guess_seqnbr(); } - + + pos = ftell(sf); rewind(sf); if (fscanf(sf, "%d", &seq_nbr) != 1) { - rc_log(LOG_ERR,"rc_get_seqnbr: fscanf failure: %s", seqfile); + if (pos != ftell(sf)) { + /* file was not empty */ + rc_log(LOG_ERR,"rc_get_seqnbr: fscanf failure: %s", seqfile); + } seq_nbr = rc_guess_seqnbr(); } - + rewind(sf); ftruncate(fileno(sf),0); fprintf(sf,"%d\n", (seq_nbr+1) & UCHAR_MAX); - + fflush(sf); /* fflush because a process may read it between the do_unlock and fclose */ - + if (do_unlock(fileno(sf)) != 0) rc_log(LOG_ERR, "rc_get_seqnbr: couldn't release lock on %s: %s", seqfile, strerror(errno)); @@ -119,35 +161,57 @@ unsigned char rc_get_seqnbr(void) * */ -int rc_auth(UINT4 client_port, VALUE_PAIR *send, VALUE_PAIR **received, - char *msg) +int rc_auth(UINT4 client_port, VALUE_PAIR *send, VALUE_PAIR **received, + char *msg, REQUEST_INFO *info) +{ + SERVER *authserver = rc_conf_srv("authserver"); + + if (!authserver) { + return (ERROR_RC); + } + return rc_auth_using_server(authserver, client_port, send, received, + msg, info); +} + +/* + * Function: rc_auth_using_server + * + * Purpose: Builds an authentication request for port id client_port + * with the value_pairs send and submits it to a server. You + * explicitly supply a server list. + * + * Returns: received value_pairs in received, messages from the server in msg + * and 0 on success, negative on failure as return value + * + */ + +int rc_auth_using_server(SERVER *authserver, + UINT4 client_port, + VALUE_PAIR *send, + VALUE_PAIR **received, + char *msg, REQUEST_INFO *info) { SEND_DATA data; - UINT4 client_id; int result; int i; - SERVER *authserver = rc_conf_srv("authserver"); int timeout = rc_conf_int("radius_timeout"); - int retries = rc_conf_int("radius_retries"); + int retries = rc_conf_int("radius_retries"); data.send_pairs = send; data.receive_pairs = NULL; /* - * Fill in NAS-IP-Address + * Fill in NAS-IP-Address or NAS-Identifier */ - - if ((client_id = rc_own_ipaddress()) == 0) - return (ERROR_RC); - - if (rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) - return (ERROR_RC); + + if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) + return (ERROR_RC); /* * Fill in NAS-Port */ - - if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0) == NULL) + + if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL) return (ERROR_RC); result = ERROR_RC; @@ -158,10 +222,10 @@ int rc_auth(UINT4 client_port, VALUE_PAI rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } - rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], + rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], authserver->port[i], timeout, retries); - - result = rc_send_server (&data, msg); + + result = rc_send_server (&data, msg, info); } *received = data.receive_pairs; @@ -202,10 +266,10 @@ int rc_auth_proxy(VALUE_PAIR *send, VALU rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } - rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], + rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i], authserver->port[i], timeout, retries); - - result = rc_send_server (&data, msg); + + result = rc_send_server (&data, msg, NULL); } *received = data.receive_pairs; @@ -215,57 +279,54 @@ int rc_auth_proxy(VALUE_PAIR *send, VALU /* - * Function: rc_acct + * Function: rc_acct_using_server * * Purpose: Builds an accounting request for port id client_port - * with the value_pairs send + * with the value_pairs send. You explicitly supply server list. * - * Remarks: NAS-IP-Address, NAS-Port and Acct-Delay-Time get filled - * in by this function, the rest has to be supplied. + * Remarks: NAS-Identifier/NAS-IP-Address, NAS-Port and Acct-Delay-Time get + * filled in by this function, the rest has to be supplied. */ -int rc_acct(UINT4 client_port, VALUE_PAIR *send) +int rc_acct_using_server(SERVER *acctserver, + UINT4 client_port, + VALUE_PAIR *send) { SEND_DATA data; VALUE_PAIR *adt_vp; - UINT4 client_id; int result; time_t start_time, dtime; char msg[4096]; int i; - SERVER *acctserver = rc_conf_srv("acctserver"); int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); - + data.send_pairs = send; data.receive_pairs = NULL; /* - * Fill in NAS-IP-Address + * Fill in NAS-IP-Address or NAS-Identifier */ - - if ((client_id = rc_own_ipaddress()) == 0) - return (ERROR_RC); - - if (rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0) == NULL) - return (ERROR_RC); + + if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) + return (ERROR_RC); /* * Fill in NAS-Port */ - - if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0) == NULL) + + if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL) return (ERROR_RC); /* * Fill in Acct-Delay-Time */ - + dtime = 0; - if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0)) == NULL) + if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, VENDOR_NONE)) == NULL) return (ERROR_RC); - start_time = time(NULL); + start_time = time(NULL); result = ERROR_RC; for(i=0; (imax) && (result != OK_RC) && (result != BADRESP_RC) ; i++) @@ -274,21 +335,39 @@ int rc_acct(UINT4 client_port, VALUE_PAI rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } - rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], + rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); dtime = time(NULL) - start_time; rc_avpair_assign(adt_vp, &dtime, 0); - - result = rc_send_server (&data, msg); + + result = rc_send_server (&data, msg, NULL); } rc_avpair_free(data.receive_pairs); - + return result; } /* + * Function: rc_acct + * + * Purpose: Builds an accounting request for port id client_port + * with the value_pairs send + * + * Remarks: NAS-Identifier/NAS-IP-Address, NAS-Port and Acct-Delay-Time get + * filled in by this function, the rest has to be supplied. + */ + +int rc_acct(UINT4 client_port, VALUE_PAIR *send) +{ + SERVER *acctserver = rc_conf_srv("acctserver"); + if (!acctserver) return (ERROR_RC); + + return rc_acct_using_server(acctserver, client_port, send); +} + +/* * Function: rc_acct_proxy * * Purpose: Builds an accounting request with the value_pairs send @@ -316,14 +395,14 @@ int rc_acct_proxy(VALUE_PAIR *send) rc_avpair_free(data.receive_pairs); data.receive_pairs = NULL; } - rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], + rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); - result = rc_send_server (&data, msg); + result = rc_send_server (&data, msg, NULL); } rc_avpair_free(data.receive_pairs); - + return result; } @@ -339,32 +418,31 @@ int rc_check(char *host, unsigned short { SEND_DATA data; int result; - UINT4 client_id, service_type; + UINT4 service_type; int timeout = rc_conf_int("radius_timeout"); int retries = rc_conf_int("radius_retries"); - + data.send_pairs = data.receive_pairs = NULL; /* - * Fill in NAS-IP-Address, although it isn't neccessary + * Fill in NAS-IP-Address or NAS-Identifier, + * although it isn't neccessary */ - - if ((client_id = rc_own_ipaddress()) == 0) - return (ERROR_RC); - - rc_avpair_add(&(data.send_pairs), PW_NAS_IP_ADDRESS, &client_id, 0); + + if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC) + return (ERROR_RC); /* * Fill in Service-Type */ - + service_type = PW_ADMINISTRATIVE; - rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0); + rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, VENDOR_NONE); rc_buildreq(&data, PW_STATUS_SERVER, host, port, timeout, retries); - result = rc_send_server (&data, msg); + result = rc_send_server (&data, msg, NULL); rc_avpair_free(data.receive_pairs); - + return result; } diff -urNp radiusclient-0.3.2/lib/config.c radiusclient.ppp/lib/config.c --- radiusclient-0.3.2/lib/config.c 1998-02-10 15:29:57.000000000 +0200 +++ radiusclient.ppp/lib/config.c 2002-10-01 12:51:01.000000000 +0300 @@ -478,9 +478,8 @@ int rc_find_server (char *server_name, U rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str("servers")); return (-1); } - - if ((myipaddr = rc_own_ipaddress()) == 0) - return (-1); + + myipaddr = rc_own_ipaddress(); result = 0; while (fgets (buffer, sizeof (buffer), clientfd) != (char *) NULL) diff -urNp radiusclient-0.3.2/lib/dict.c radiusclient.ppp/lib/dict.c --- radiusclient-0.3.2/lib/dict.c 1997-12-26 01:28:10.000000000 +0200 +++ radiusclient.ppp/lib/dict.c 2002-03-05 17:14:06.000000000 +0200 @@ -18,15 +20,17 @@ #include #include -static DICT_ATTR *dictionary_attributes; -static DICT_VALUE *dictionary_values; +static DICT_ATTR *dictionary_attributes = NULL; +static DICT_VALUE *dictionary_values = NULL; +static VENDOR_DICT *vendor_dictionaries = NULL; /* * Function: rc_read_dictionary * * Purpose: Initialize the dictionary. Read all ATTRIBUTES into * the dictionary_attributes list. Read all VALUES into - * the dictionary_values list. + * the dictionary_values list. Construct VENDOR dictionaries + * as required. * */ @@ -38,21 +42,25 @@ int rc_read_dictionary (char *filename) char valstr[AUTH_ID_LEN]; char attrstr[AUTH_ID_LEN]; char typestr[AUTH_ID_LEN]; + char vendorstr[AUTH_ID_LEN]; int line_no; DICT_ATTR *attr; DICT_VALUE *dval; + VENDOR_DICT *vdict; char buffer[256]; int value; int type; - + int n; + int retcode; if ((dictfd = fopen (filename, "r")) == (FILE *) NULL) { - rc_log(LOG_ERR, "rc_read_dictionary: couldn't open dictionary %s: %s", + rc_log(LOG_ERR, "rc_read_dictionary: couldn't open dictionary %s: %s", filename, strerror(errno)); return (-1); } line_no = 0; + retcode = 0; while (fgets (buffer, sizeof (buffer), dictfd) != (char *) NULL) { line_no++; @@ -63,16 +71,48 @@ int rc_read_dictionary (char *filename) continue; } - if (strncmp (buffer, "ATTRIBUTE", 9) == 0) + if (strncmp (buffer, "VENDOR", 6) == 0) { + /* Read the VENDOR line */ + if (sscanf(buffer, "%s%s%d", dummystr, namestr, &value) != 3) { + rc_log(LOG_ERR, "rc_read_dictionary: invalid vendor on line %d of dictionary %s", + line_no, filename); + retcode = -1; + break; + } + /* Validate entry */ + if (strlen (namestr) > NAME_LENGTH) { + rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s", + line_no, filename); + retcode = -1; + break; + } + /* Create new vendor entry */ + vdict = (VENDOR_DICT *) malloc (sizeof (VENDOR_DICT)); + if (!vdict) { + rc_log(LOG_CRIT, "rc_read_dictionary: out of memory"); + retcode = -1; + break; + } + strcpy(vdict->vendorname, namestr); + vdict->vendorcode = value; + vdict->attributes = NULL; + vdict->next = vendor_dictionaries; + vendor_dictionaries = vdict; + } + else if (strncmp (buffer, "ATTRIBUTE", 9) == 0) { - /* Read the ATTRIBUTE line */ - if (sscanf (buffer, "%s%s%s%s", dummystr, namestr, - valstr, typestr) != 4) + /* Read the ATTRIBUTE line. It is one of: + * ATTRIBUTE attr_name attr_val type OR + * ATTRIBUTE attr_name attr_val type vendor */ + vendorstr[0] = 0; + n = sscanf(buffer, "%s%s%s%s%s", dummystr, namestr, valstr, typestr, vendorstr); + if (n != 4 && n != 5) { rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } /* @@ -82,7 +122,16 @@ int rc_read_dictionary (char *filename) { rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; + } + + if (strlen (vendorstr) > NAME_LENGTH) + { + rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s", + line_no, filename); + retcode = -1; + break; } if (!isdigit (*valstr)) @@ -90,7 +139,8 @@ int rc_read_dictionary (char *filename) rc_log(LOG_ERR, "rc_read_dictionary: invalid value on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } value = atoi (valstr); @@ -115,24 +165,49 @@ int rc_read_dictionary (char *filename) rc_log(LOG_ERR, "rc_read_dictionary: invalid type on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } + /* Search for vendor if supplied */ + if (*vendorstr) { + vdict = rc_dict_findvendor(vendorstr); + if (!vdict) { + rc_log(LOG_ERR, + "rc_read_dictionary: unknown vendor on line %d of dictionary %s", + line_no, filename); + retcode = -1; + break; + } + } else { + vdict = NULL; + } /* Create a new attribute for the list */ if ((attr = (DICT_ATTR *) malloc (sizeof (DICT_ATTR))) == (DICT_ATTR *) NULL) { rc_log(LOG_CRIT, "rc_read_dictionary: out of memory"); - return (-1); + retcode = -1; + break; } strcpy (attr->name, namestr); + if (vdict) { + attr->vendorcode = vdict->vendorcode; + } else { + attr->vendorcode = VENDOR_NONE; + } attr->value = value; attr->type = type; /* Insert it into the list */ - attr->next = dictionary_attributes; - dictionary_attributes = attr; + if (vdict) { + attr->next = vdict->attributes; + vdict->attributes = attr; + } else { + attr->next = dictionary_attributes; + dictionary_attributes = attr; + } } else if (strncmp (buffer, "VALUE", 5) == 0) { @@ -143,7 +218,8 @@ int rc_read_dictionary (char *filename) rc_log(LOG_ERR, "rc_read_dictionary: invalid value entry on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } /* @@ -154,7 +230,8 @@ int rc_read_dictionary (char *filename) rc_log(LOG_ERR, "rc_read_dictionary: invalid attribute length on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } if (strlen (namestr) > NAME_LENGTH) @@ -162,7 +239,8 @@ int rc_read_dictionary (char *filename) rc_log(LOG_ERR, "rc_read_dictionary: invalid name length on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } if (!isdigit (*valstr)) @@ -170,7 +248,8 @@ int rc_read_dictionary (char *filename) rc_log(LOG_ERR, "rc_read_dictionary: invalid value on line %d of dictionary %s", line_no, filename); - return (-1); + retcode = -1; + break; } value = atoi (valstr); @@ -180,7 +259,8 @@ int rc_read_dictionary (char *filename) == (DICT_VALUE *) NULL) { rc_log(LOG_CRIT, "rc_read_dictionary: out of memory"); - return (-1); + retcode = -1; + break; } strcpy (dval->attrname, attrstr); strcpy (dval->name, namestr); @@ -190,34 +270,65 @@ int rc_read_dictionary (char *filename) dval->next = dictionary_values; dictionary_values = dval; } + else if (strncmp (buffer, "INCLUDE", 7) == 0) + { + /* Read the INCLUDE line */ + if (sscanf (buffer, "%s%s", dummystr, namestr) != 2) + { + rc_log(LOG_ERR, + "rc_read_dictionary: invalid include entry on line %d of dictionary %s", + line_no, filename); + retcode = -1; + break; + } + if (rc_read_dictionary(namestr) == -1) + { + retcode = -1; + break; + } + } } fclose (dictfd); - return (0); -} + return retcode; +} /* * Function: rc_dict_getattr * * Purpose: Return the full attribute structure based on the - * attribute id number. + * attribute id number and vendor code. If vendor code is VENDOR_NONE, + * non-vendor-specific attributes are used * */ - -DICT_ATTR *rc_dict_getattr (int attribute) + +DICT_ATTR *rc_dict_getattr (int attribute, int vendor) { DICT_ATTR *attr; + VENDOR_DICT *dict; - attr = dictionary_attributes; - while (attr != (DICT_ATTR *) NULL) - { - if (attr->value == attribute) - { - return (attr); + if (vendor == VENDOR_NONE) { + attr = dictionary_attributes; + while (attr != (DICT_ATTR *) NULL) { + if (attr->value == attribute) { + return (attr); } attr = attr->next; + } + } else { + dict = rc_dict_getvendor(vendor); + if (!dict) { + return NULL; + } + attr = dict->attributes; + while (attr) { + if (attr->value == attribute) { + return attr; + } + attr = attr->next; + } } - return ((DICT_ATTR *) NULL); -} + return NULL; +} /* * Function: rc_dict_findattr @@ -230,6 +341,7 @@ DICT_ATTR *rc_dict_getattr (int attribut DICT_ATTR *rc_dict_findattr (char *attrname) { DICT_ATTR *attr; + VENDOR_DICT *dict; attr = dictionary_attributes; while (attr != (DICT_ATTR *) NULL) @@ -240,8 +352,21 @@ DICT_ATTR *rc_dict_findattr (char *attrn } attr = attr->next; } + + /* Search vendor-specific dictionaries */ + dict = vendor_dictionaries; + while (dict) { + attr = dict->attributes; + while (attr) { + if (strcasecmp (attr->name, attrname) == 0) { + return (attr); + } + attr = attr->next; + } + dict = dict->next; + } return ((DICT_ATTR *) NULL); -} +} /* @@ -291,4 +416,44 @@ DICT_VALUE * rc_dict_getval (UINT4 value val = val->next; } return ((DICT_VALUE *) NULL); -} +} + +/* + * Function: rc_dict_findvendor + * + * Purpose: Return the vendor's dictionary given the vendor name. + * + */ +VENDOR_DICT * rc_dict_findvendor (char *vendorname) +{ + VENDOR_DICT *dict; + + dict = vendor_dictionaries; + while (dict) { + if (!strcmp(vendorname, dict->vendorname)) { + return dict; + } + dict = dict->next; + } + return NULL; +} + +/* + * Function: rc_dict_getvendor + * + * Purpose: Return the vendor's dictionary given the vendor ID + * + */ +VENDOR_DICT * rc_dict_getvendor (int id) +{ + VENDOR_DICT *dict; + + dict = vendor_dictionaries; + while (dict) { + if (id == dict->vendorcode) { + return dict; + } + dict = dict->next; + } + return NULL; +} diff -urNp radiusclient-0.3.2/lib/options.h radiusclient.ppp/lib/options.h --- radiusclient-0.3.2/lib/options.h 1998-06-28 03:08:17.000000000 +0300 +++ radiusclient.ppp/lib/options.h 2002-10-01 12:51:01.000000000 +0300 @@ -31,26 +31,30 @@ typedef struct _option { static SERVER acctserver = {0}; static SERVER authserver = {0}; +int default_tries = 4; +int default_timeout = 60; + static OPTION config_options[] = { /* internally used options */ {"config_file", OT_STR, ST_UNDEF, NULL}, /* General options */ {"auth_order", OT_AUO, ST_UNDEF, NULL}, -{"login_tries", OT_INT, ST_UNDEF, NULL}, -{"login_timeout", OT_INT, ST_UNDEF, NULL}, -{"nologin", OT_STR, ST_UNDEF, NULL}, -{"issue", OT_STR, ST_UNDEF, NULL}, +{"login_tries", OT_INT, ST_UNDEF, &default_tries}, +{"login_timeout", OT_INT, ST_UNDEF, &default_timeout}, +{"nologin", OT_STR, ST_UNDEF, "/etc/nologin"}, +{"issue", OT_STR, ST_UNDEF, "/etc/radiusclient/issue"}, /* RADIUS specific options */ {"authserver", OT_SRV, ST_UNDEF, &authserver}, {"acctserver", OT_SRV, ST_UNDEF, &acctserver}, {"servers", OT_STR, ST_UNDEF, NULL}, {"dictionary", OT_STR, ST_UNDEF, NULL}, -{"login_radius", OT_STR, ST_UNDEF, NULL}, +{"login_radius", OT_STR, ST_UNDEF, "/usr/sbin/login.radius"}, {"seqfile", OT_STR, ST_UNDEF, NULL}, {"mapfile", OT_STR, ST_UNDEF, NULL}, {"default_realm", OT_STR, ST_UNDEF, NULL}, {"radius_timeout", OT_INT, ST_UNDEF, NULL}, {"radius_retries", OT_INT, ST_UNDEF, NULL}, +{"nas_identifier", OT_STR, ST_UNDEF, ""}, /* local options */ {"login_local", OT_STR, ST_UNDEF, NULL}, }; diff -urNp radiusclient-0.3.2/lib/sendserver.c radiusclient.ppp/lib/sendserver.c --- radiusclient-0.3.2/lib/sendserver.c 2002-02-03 15:51:41.000000000 +0200 +++ radiusclient.ppp/lib/sendserver.c 2002-04-02 17:09:35.000000000 +0300 @@ -33,96 +33,128 @@ static int rc_check_reply (AUTH_HDR *, i static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth) { - int length, i, pc, secretlen, padded_length; - int total_length = 0; - UINT4 lvalue; - unsigned char passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)]; - unsigned char md5buf[256]; - unsigned char *buf, *vector; - - buf = auth->data; + int length, i, pc, secretlen, padded_length; + int total_length = 0; + UINT4 lvalue; + unsigned char passbuf[MAX(AUTH_PASS_LEN, CHAP_VALUE_LENGTH)]; + unsigned char md5buf[256]; + unsigned char *buf, *vector, *lenptr; - while (vp != (VALUE_PAIR *) NULL) + buf = auth->data; + + while (vp != (VALUE_PAIR *) NULL) { + + if (vp->vendorcode != VENDOR_NONE) { + *buf++ = PW_VENDOR_SPECIFIC; + + /* Place-holder for where to put length */ + lenptr = buf++; + + /* Insert vendor code */ + *buf++ = 0; + *buf++ = (((unsigned int) vp->vendorcode) >> 16) & 255; + *buf++ = (((unsigned int) vp->vendorcode) >> 8) & 255; + *buf++ = ((unsigned int) vp->vendorcode) & 255; + + /* Insert vendor-type */ *buf++ = vp->attribute; - switch (vp->attribute) - { - case PW_USER_PASSWORD: + /* Insert value */ + switch(vp->type) { + case PW_TYPE_STRING: + length = vp->lvalue; + *lenptr = length + 8; + *buf++ = length+2; + memcpy(buf, vp->strvalue, (size_t) length); + buf += length; + total_length += length+8; + break; + case PW_TYPE_INTEGER: + case PW_TYPE_IPADDR: + length = sizeof(UINT4); + *lenptr = length + 8; + *buf++ = length+2; + lvalue = htonl(vp->lvalue); + memcpy(buf, (char *) &lvalue, sizeof(UINT4)); + buf += length; + total_length += length+8; + break; + default: + break; + } + } else { + *buf++ = vp->attribute; + switch (vp->attribute) { + case PW_USER_PASSWORD: + + /* Encrypt the password */ + + /* Chop off password at AUTH_PASS_LEN */ + length = vp->lvalue; + if (length > AUTH_PASS_LEN) length = AUTH_PASS_LEN; + + /* Calculate the padded length */ + padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1); + + /* Record the attribute length */ + *buf++ = padded_length + 2; + + /* Pad the password with zeros */ + memset ((char *) passbuf, '\0', AUTH_PASS_LEN); + memcpy ((char *) passbuf, vp->strvalue, (size_t) length); + + secretlen = strlen (secret); + vector = (char *)auth->vector; + for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN) { + /* Calculate the MD5 digest*/ + strcpy ((char *) md5buf, secret); + memcpy ((char *) md5buf + secretlen, vector, + AUTH_VECTOR_LEN); + rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); + + /* Remeber the start of the digest */ + vector = buf; - /* Encrypt the password */ - - /* Chop off password at AUTH_PASS_LEN */ - length = vp->lvalue; - if (length > AUTH_PASS_LEN) - length = AUTH_PASS_LEN; - - /* Calculate the padded length */ - padded_length = (length+(AUTH_VECTOR_LEN-1)) & ~(AUTH_VECTOR_LEN-1); - - /* Record the attribute length */ - *buf++ = padded_length + 2; - - /* Pad the password with zeros */ - memset ((char *) passbuf, '\0', AUTH_PASS_LEN); - memcpy ((char *) passbuf, vp->strvalue, (size_t) length); - - secretlen = strlen (secret); - vector = (char *)auth->vector; - for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN) - { - /* Calculate the MD5 digest*/ - strcpy ((char *) md5buf, secret); - memcpy ((char *) md5buf + secretlen, vector, - AUTH_VECTOR_LEN); - rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); - - /* Remeber the start of the digest */ - vector = buf; - /* Xor the password into the MD5 digest */ - for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++) - { - *buf++ ^= passbuf[pc]; - } - } - - total_length += padded_length + 2; - - break; -#if 0 - case PW_CHAP_PASSWORD: - - *buf++ = CHAP_VALUE_LENGTH + 2; - - /* Encrypt the Password */ - length = vp->lvalue; - if (length > CHAP_VALUE_LENGTH) - { + for (pc = i; pc < (i + AUTH_VECTOR_LEN); pc++) { + *buf++ ^= passbuf[pc]; + } + } + + total_length += padded_length + 2; + + break; +#if 0 + case PW_CHAP_PASSWORD: + + *buf++ = CHAP_VALUE_LENGTH + 2; + + /* Encrypt the Password */ + length = vp->lvalue; + if (length > CHAP_VALUE_LENGTH) { length = CHAP_VALUE_LENGTH; - } - memset ((char *) passbuf, '\0', CHAP_VALUE_LENGTH); - memcpy ((char *) passbuf, vp->strvalue, (size_t) length); - - /* Calculate the MD5 Digest */ - secretlen = strlen (secret); - strcpy ((char *) md5buf, secret); - memcpy ((char *) md5buf + secretlen, (char *) auth->vector, - AUTH_VECTOR_LEN); - rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); - - /* Xor the password into the MD5 digest */ - for (i = 0; i < CHAP_VALUE_LENGTH; i++) - { + } + memset ((char *) passbuf, '\0', CHAP_VALUE_LENGTH); + memcpy ((char *) passbuf, vp->strvalue, (size_t) length); + + /* Calculate the MD5 Digest */ + secretlen = strlen (secret); + strcpy ((char *) md5buf, secret); + memcpy ((char *) md5buf + secretlen, (char *) auth->vector, + AUTH_VECTOR_LEN); + rc_md5_calc (buf, md5buf, secretlen + AUTH_VECTOR_LEN); + + /* Xor the password into the MD5 digest */ + for (i = 0; i < CHAP_VALUE_LENGTH; i++) { *buf++ ^= passbuf[i]; - } - total_length += CHAP_VALUE_LENGTH + 2; - - break; + } + total_length += CHAP_VALUE_LENGTH + 2; + + break; #endif - default: - switch (vp->type) - { + default: + switch (vp->type) { case PW_TYPE_STRING: length = vp->lvalue; *buf++ = length + 2; @@ -142,12 +174,13 @@ static int rc_pack_list (VALUE_PAIR *vp, default: break; - } - break; + } + break; } - vp = vp->next; + } + vp = vp->next; } - return total_length; + return total_length; } /* @@ -157,7 +190,7 @@ static int rc_pack_list (VALUE_PAIR *vp, * */ -int rc_send_server (SEND_DATA *data, char *msg) +int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info) { int sockfd; struct sockaddr salocal; @@ -246,7 +279,7 @@ int rc_send_server (SEND_DATA *data, cha else { rc_random_vector (vector); - memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN); + memcpy (auth->vector, vector, AUTH_VECTOR_LEN); total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN; @@ -307,18 +340,24 @@ int rc_send_server (SEND_DATA *data, cha memset (secret, '\0', sizeof (secret)); return (ERROR_RC); } - + recv_auth = (AUTH_HDR *)recv_buffer; - + result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr); data->receive_pairs = rc_avpair_gen(recv_auth); close (sockfd); + if (info) + { + memcpy(info->secret, secret, sizeof(info->secret)); + memcpy(info->request_vector, vector, + sizeof(info->request_vector)); + } memset (secret, '\0', sizeof (secret)); if (result != OK_RC) return (result); - + *msg = '\0'; vp = data->receive_pairs; while (vp) @@ -355,8 +394,8 @@ int rc_send_server (SEND_DATA *data, cha * */ -static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret, unsigned char *vector,\ - unsigned char seq_nbr) +static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret, + unsigned char *vector, unsigned char seq_nbr) { int secretlen; int totallen; diff -urNp radiusclient-0.3.2/src/radexample.c radiusclient.ppp/src/radexample.c --- radiusclient-0.3.2/src/radexample.c 1999-02-09 16:59:14.000000000 +0200 +++ radiusclient.ppp/src/radexample.c 2002-04-02 17:09:35.000000000 +0300 @@ -26,23 +26,32 @@ main (int argc, char **argv) int result; char username[128]; char passwd[AUTH_PASS_LEN + 1]; - VALUE_PAIR *send, *received; + VALUE_PAIR *send, *received; UINT4 service; - char msg[4096], username_realm[256]; + char msg[4096], username_realm[256]; char *default_realm = rc_conf_str("default_realm"); + char name[2048]; + char value[2048]; /* more than enough */ + char *cfile; pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0]; rc_openlog(pname); - if (rc_read_config(RC_CONFIG_FILE) != 0) + + if (argc >= 2) { + cfile = argv[1]; + } else { + cfile = RC_CONFIG_FILE; + } + if (rc_read_config(cfile) != 0) return(ERROR_RC); - + if (rc_read_dictionary(rc_conf_str("dictionary")) != 0) return(ERROR_RC); strncpy(username, rc_getstr ("login: ",1), sizeof(username)); - strncpy (passwd, rc_getstr("Password: ",0), sizeof (passwd)); + strncpy (passwd, rc_getstr("Password: ",0), sizeof (passwd)); send = NULL; @@ -58,28 +67,28 @@ main (int argc, char **argv) { strncat(username_realm, "@", sizeof(username_realm)); strncat(username_realm, default_realm, sizeof(username_realm)); - } + } - if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0) == NULL) + if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0, VENDOR_NONE) == NULL) return(ERROR_RC); - + /* * Fill in User-Password */ - - if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0) == NULL) + + if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE) == NULL) return (ERROR_RC); /* * Fill in Service-Type */ - + service = PW_AUTHENTICATE_ONLY; - if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0) == NULL) - return (ERROR_RC); - - result = rc_auth(0, send, &received, msg); - + if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0, VENDOR_NONE) == NULL) + return (ERROR_RC); + + result = rc_auth(0, send, &received, msg, NULL); + if (result == OK_RC) { fprintf(stderr, "\"%s\" RADIUS Authentication OK\n", username); @@ -88,6 +97,16 @@ main (int argc, char **argv) { fprintf(stderr, "\"%s\" RADIUS Authentication failure (RC=%i)\n", username, result); } - + + /* Print returned attributes */ + for( ; received ; received = received->next) { + if (rc_avpair_tostr(received, name, sizeof(name), value, + sizeof(value)) < 0) { + continue; + } + printf("Attr '%s' ==> Val '%s'\n", + name, value); + } + return result; } diff -urNp radiusclient-0.3.2/src/radexample-debug radiusclient.ppp/src/radexample-debug --- radiusclient-0.3.2/src/radexample-debug 1970-01-01 03:00:00.000000000 +0300 +++ radiusclient.ppp/src/radexample-debug 2002-01-22 18:03:04.000000000 +0200 @@ -0,0 +1,61 @@ +#! /bin/sh + +# radexample - temporary wrapper script for .libs/radexample +# Generated by ltmain.sh - GNU libtool 1.0 +# +# The radexample program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of `/home/dfs/Servpoet/radiusclient-0.3.1/src'. +# If it is, it will not operate correctly. + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variables: + link_against_libtool_libs=' ../lib/libradiusclient.la' + finalize_command='gcc -g -O2 -o .libs/radexampleT radexample.o -Wl,-rpath -Wl,/usr/lib -L/usr/lib -lradiusclient -lcrypt -lnsl' +else + # Find the directory that this script lives in. + thisdir=`echo $0 | sed 's%/[^/]*$%%'` + test "x$thisdir" = "x$0" && thisdir=. + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + progdir="$thisdir/.libs" + program="radexample" + + if test -f "$progdir/$program"; then + # Run the actual program with our arguments. + args= + for arg + do + # Quote arguments (to preserve shell metacharacters). + args="$args '$arg'" + done + + # Export the path to the program. + PATH="$progdir:$PATH" + export PATH + + # Add our own library path to LD_LIBRARY_PATH + LD_LIBRARY_PATH="$thisdir/../lib/.libs:$LD_LIBRARY_PATH" + + # Some systems cannot cope with colon-terminated LD_LIBRARY_PATH + LD_LIBRARY_PATH=`echo $LD_LIBRARY_PATH | sed -e 's/:*$//'` + + export LD_LIBRARY_PATH + + eval "exec ddd ./.libs/$program $args" + + echo "$0: cannot exec $program $args" + exit 1 + else + # The program doesn't exist. + echo "$0: error: $progdir/$program does not exist" 1>&2 + echo "This script is just a wrapper for $program." 1>&2 + echo "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi diff -urNp radiusclient-0.3.2/src/radius.c radiusclient.ppp/src/radius.c --- radiusclient-0.3.2/src/radius.c 1997-12-26 01:28:55.000000000 +0200 +++ radiusclient.ppp/src/radius.c 2002-04-02 17:09:35.000000000 +0300 @@ -67,30 +67,30 @@ LFUNC auth_radius(UINT4 client_port, cha break; } #else - service = PW_LOGIN; + service = PW_LOGIN; ftype = 0; ctype = 0; #endif - if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0) == NULL) + if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0, VENDOR_NONE) == NULL) return (LFUNC) NULL; /* Fill in Framed-Protocol, if neccessary */ - + if (ftype != 0) { - if (rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &ftype, 0) == NULL) - return (LFUNC) NULL; - } + if (rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &ftype, 0, VENDOR_NONE) == NULL) + return (LFUNC) NULL; + } /* Fill in Framed-Compression, if neccessary */ if (ctype != 0) { - if (rc_avpair_add(&send, PW_FRAMED_COMPRESSION, &ctype, 0) == NULL) + if (rc_avpair_add(&send, PW_FRAMED_COMPRESSION, &ctype, 0, VENDOR_NONE) == NULL) return (LFUNC) NULL; - } - + } + /* * Fill in User-Name */ @@ -105,50 +105,50 @@ LFUNC auth_radius(UINT4 client_port, cha { strncat(username_realm, "@", sizeof(username_realm)); strncat(username_realm, default_realm, sizeof(username_realm)); - } + } - if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0) == NULL) + if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0, VENDOR_NONE) == NULL) return (LFUNC) NULL; - + /* * Fill in User-Password */ - - if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0) == NULL) + + if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE) == NULL) return (LFUNC) NULL; - - result = rc_auth(client_port, send, &received, msg); + + result = rc_auth(client_port, send, &received, msg, NULL); if (result == OK_RC) { /* Set up a running count of attributes saved. */ int acount[256], attr; - + memset(acount, 0, sizeof(acount)); rc_add_env(env, "RADIUS_USER_NAME", username); - + vp = received; /* map-- keep track of the attributes so that we know when to add the delimiters. Note that we can only handle attributes < 256, which is the standard anyway. */ - + while (vp) { strcpy(name, "RADIUS_"); if (rc_avpair_tostr(vp, name+7, sizeof(name)-7, value, sizeof(value)) < 0) { rc_avpair_free(send); rc_avpair_free(received); - return (LFUNC) NULL; + return (LFUNC) NULL; } - + /* Translate "-" => "_" and uppercase*/ for(p = name; *p; p++) { *p = toupper(*p); if (*p == '-') *p = '_'; } - + /* Add to the attribute count and append the var if necessary. */ if ((attr = vp->attribute) < 256) diff -urNp radiusclient-0.3.2/src/radstatus.c radiusclient.ppp/src/radstatus.c --- radiusclient-0.3.2/src/radstatus.c 1999-01-07 01:50:54.000000000 +0200 +++ radiusclient.ppp/src/radstatus.c 2002-01-22 18:03:05.000000000 +0200 @@ -110,4 +110,5 @@ void main (int argc, char **argv) fputs(msg, stdout); } } + return 0; }