/*
 *
 *	RADIUS
 *	Remote Authentication Dial In User Service
 *
 * ASCEND: @(#)radius.h	1.3 (95/07/25 00:55:33)
 *
 *
 *	Livingston Enterprises, Inc.
 *	6920 Koll Center Parkway
 *	Pleasanton, CA   94566
 *
 *	Copyright 1992 Livingston Enterprises, 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 Livingston Enterprises, 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 Livingston Enterprises, Inc.   
 *
 *	Livingston Enterprises, Inc. makes no representations about
 *	the suitability of this software for any purpose.  It is
 *	provided "as is" without express or implied warranty.
 *
 */

/*
 *	@(#)radius.h	1.9 11/14/94 
 */

/* $Id: radius.h,v 1.7 1997/02/20 19:41:30 victor Exp $ */

#ifndef _radius_h_
#define _radius_h_

#include "conf.h"

#define AUTH_VECTOR_LEN		16
/*
//	An attribute can only be 255 characters long. one character
//	for the type, one for the length leaves 253 for the value
*/
#define AUTH_PASS_LEN		253
#ifdef ORIG
#define AUTH_STRING_LEN		128	/* maximum of 253 */
#else
#define AUTH_STRING_LEN		253	/* need 256 ???? */ 
#endif

#define IPX_NODE_ADDR_LEN               6

typedef UINT4        	IpxNet;
typedef char            IpxNode[ IPX_NODE_ADDR_LEN ];
typedef u_short         IpxSocket;


typedef struct pw_auth_hdr {
	u_char		code;
	u_char		id;
	u_short		length;
	u_char		vector[AUTH_VECTOR_LEN];
	u_char		data[2];
} AUTH_HDR;

    /* types of passwords */
typedef enum PasswordType {
	PWD_UNKNOWN	= 1,	/* not yet determined */
	PWD_TOKEN,		/* handheld security card */
	PWD_UNIX,		/* UNIX passwd file */
	PWD_RADIUS		/* radius users file */
} PasswordType;

#define AUTH_HDR_LEN			20
#define CHAP_VALUE_LENGTH		16

#define PW_AUTH_UDP_PORT		1645
#define PW_ACCT_UDP_PORT		1646

#define PW_TYPE_STRING			0
#define PW_TYPE_INTEGER			1
#define PW_TYPE_IPADDR			2
#define PW_TYPE_DATE			3
#if defined( BINARY_FILTERS )
#define PW_TYPE_FILTER_BINARY           4
#endif /* BINARY_FILTERS */


	/* Types */
#define	PW_AUTHENTICATION_REQUEST	1
#define	PW_AUTHENTICATION_ACK		2
#define	PW_AUTHENTICATION_REJECT	3
#define	PW_ACCOUNTING_REQUEST		4
#define	PW_ACCOUNTING_RESPONSE		5
#define	PW_ACCOUNTING_STATUS		6
#define PW_PASSWORD_REQUEST		7	/* Livingston-specific code */
#define PW_PASSWORD_ACK			8	/* Livingston-specific code */
#define PW_PASSWORD_REJECT		9	/* Livingston-specific code */
#define	PW_ACCOUNTING_MESSAGE		10
#define PW_ACCESS_CHALLENGE		11
#define PW_NEXT_PASSCODE		29	/* Ascend-specific code */
#define PW_NEW_PIN			30	/* Ascend-specific code */
#define PW_TERMINATE_SESSION		31	/* Ascend-specific code */
#define PW_PASSWORD_EXPIRED		32	/* Ascend-spcific code */
#define PW_ASCEND_EVENT_REQUEST  	33	/* Ascend-specific code */
#define PW_ASCEND_EVENT_RESPONSE	34	/* Ascend-specific code */

#define PW_ASCEND_DISCONNECT_REQUEST	40	/* Ascend-specific code */
#define PW_ASCEND_DISCONNECT_ACK	41	/* Ascend-specific code */
#define PW_ASCEND_DISCONNECT_NAK	42	/* Ascend-specific code */
#define PW_ASCEND_CHG_FILTERS_REQUEST	43	/* Ascend-specific code */
#define PW_ASCEND_CHG_FILTERS_ACK	44	/* Ascend-specific code */
#define PW_ASCEND_CHG_FILTERS_NAK	45	/* Ascend-specific code */

#define PW_ASCEND_RADIPA_ALLOCATE	50	/* Ascend-specific code */
#define PW_ASCEND_RADIPA_RELEASE	51	/* Ascend-specific code */

#define	ASCEND_SPECIAL_STRING		60 	/* nonreadble string*/

	/* Attributes */
#define	PW_USER_NAME			1
#define	PW_PASSWORD			2
#define	PW_CHAP_PASSWORD		3
#define	PW_CLIENT_ID			4
#define	PW_CLIENT_PORT_ID		5
#define	PW_USER_SERVICE_TYPE		6
#define	PW_FRAMED_PROTOCOL		7
#define	PW_FRAMED_ADDRESS		8
#define	PW_FRAMED_NETMASK		9
#define	PW_FRAMED_ROUTING		10
#define	PW_FRAMED_FILTER_ID		11
#define	PW_FRAMED_MTU			12
#define	PW_FRAMED_COMPRESSION		13
#define	PW_LOGIN_HOST			14
#define	PW_LOGIN_SERVICE		15
#define	PW_LOGIN_TCP_PORT		16
#define PW_OLD_PASSWORD			17
#define PW_PORT_MESSAGE			18
#define PW_DIALBACK_NO			19
#define PW_DIALBACK_NAME		20
#define ASCEND_PW_EXPIRATION		21	/* Officially Un-assigned */
#define PW_FRAMED_ROUTE			22
#define PW_FRAMED_IPXNET		23
#define PW_STATE			24

#define PW_ACCT_STATUS_TYPE		40
#define PW_ACCT_DELAY_TIME		41
#define PW_ACCT_INPUT_OCTETS		42
#define PW_ACCT_OUTPUT_OCTETS		43
#define PW_ACCT_SESSION_ID		44
#define PW_ACCT_AUTHENTIC		45
#define PW_ACCT_SESSION_TIME		46

#define ASCEND_ASSIGN_IP_CLIENT		144
#define ASCEND_ASSIGN_IP_SERVER		145
#define ASCEND_ASSIGN_IP_GLOBAL_POOL	146

#define	ASCEND_SESSION_SVR_KEY		151

#define ASCEND_ASSIGN_IP_POOL		218
#define ASSIGN_IP_POOL_NAME		"Ascend-Assign-IP-Pool"

#define PW_ASCEND_ARADES		181	
#define	ASCEND_TOKEN_IDLE		199
#define	ASCEND_TOKEN_IMMEDIATE		200	
	/* 201 - 203 allocated but not used in this implementation */
#define ASCEND_REQUIRE_AUTH		201
#define ASCEND_NUMBER_SESSIONS		202
#define ASCEND_AUTHEN_ALIAS		203
#define ASCEND_TOKEN_EXPIRY		204	/* internal */
	/* 205, 206 allocated but not used in this implementation */
#define ASCEND_MENU_SELECTOR		205
#define ASCEND_MENU_ITEM		206
#define	ASCEND_PW_WARNTIME		207
#define	ASCEND_PW_LIFETIME		208

/*	Stuff for ipallocd interface	*/

#define	ASCEND_THIRD_PROMPT		213
#define ASCEND_IP_POOL_DEFINITION	217


/*
 *	INTEGER TRANSLATIONS
 */

/*	USER TYPES	*/

#define	PW_LOGIN_USER			1
#define	PW_FRAMED_USER			2
#define	PW_DIALBACK_LOGIN_USER		3
#define	PW_DIALBACK_FRAMED_USER		4

/*	FRAMED PROTOCOLS	*/

#define	PW_PPP				1
#define	PW_SLIP				2

/*	FRAMED ROUTING VALUES	*/

#define	PW_NONE				0
#define	PW_BROADCAST			1
#define	PW_LISTEN			2
#define	PW_BROADCAST_LISTEN		3

/*	FRAMED COMPRESSION TYPES	*/

#define	PW_VAN_JACOBSEN_TCP_IP		1

/*	LOGIN SERVICES	*/

#define	PW_TELNET			0
#define	PW_RLOGIN			1
#define	PW_TCP_CLEAR			2
#define	PW_PORTMASTER			3

/*	AUTHENTICATION LEVEL	*/

#define PW_AUTH_NONE			0
#define PW_AUTH_RADIUS			1
#define PW_AUTH_LOCAL			2

/*	STATUS TYPES	*/

#define PW_STATUS_START			1
#define PW_STATUS_STOP			2
#define PW_STATUS_ALIVE			3

/*	Token Immediate Values	*/
#define TOK_IMM_NO			0
#define TOK_IMM_YES			1

/*	Password Aging Attribute	*/
#define PW_EXPIRATION_NAME	"Ascend-PW-Expiration"	/* attribute name */
/*	Password Aging Value Names for Attribute Ascend-Expiration	*/
#define PW_LIFETIME		"Lifetime-In-Days"	/* value name */
#define PW_WARNTIME		"Days-Of-Warning"	/* value name */

/* Default Database File Names */

#define RADIUS_DIR		"/etc/raddb"
#ifdef FreeBSD
#define RADACCT_DIR		"/var/log/radacct"
#else
#define RADACCT_DIR		"/usr/adm/radacct"
#endif

#define RADIUS_DICTIONARY	"dictionary"
#define RADIUS_CLIENTS		"clients"
#define RADIUS_USERS		"users"
#define RADIUS_HOLD		"holdusers"
#define RADIUS_LOG		"logfile"

/* Server data structures */

typedef struct dict_attr {
	char			name[32];
	int			value;
	int			type;
	struct dict_attr	*next;
} DICT_ATTR;

typedef struct dict_value {
	char			attrname[32];
	char			name[32];
	int			value;
	struct dict_value	*next;
} DICT_VALUE;

typedef struct value_pair {
	char			name[32];
	int			attribute;
	int			type;
	UINT4			lvalue;
	int			size;
	char			strvalue[AUTH_STRING_LEN];
	struct value_pair	*next;
} VALUE_PAIR;
#define NULL_PAIR ((VALUE_PAIR *) NULL)

typedef struct auth_req {
	UINT4			ipaddr;
	u_short			udp_port;
	u_char			id;
	u_char			code;
	u_char			vector[AUTH_VECTOR_LEN];
	u_char			secret[AUTH_PASS_LEN];
	VALUE_PAIR		*request;
	pid_t			child_pid;	/* Process ID of child */
	AUTH_HDR		*answer;
	size_t			answer_length;
	UINT4			timestamp;
#if defined (ACE)
	int			pipe_fd;
#endif
	struct auth_req		*next;		/* Next active request */
} AUTH_REQ;
#define NULL_REQ ((AUTH_REQ *) NULL)

    /*
     * Struct to pass information around to password authentication
     * subroutines
     */
typedef struct AuthInfo {
	int		fd;		/* file descriptor to use */
	AUTH_REQ	*authreq;	/* original auth request */
	UINT4		ipaddr;		/* from authreq, for convenience */
	u_char		*vector;	/* ditto */
	int		cacheAuth;	/* Boolean, cache hit */
	VALUE_PAIR	*cutList;	/* list of cut attributes */
	VALUE_PAIR	*authName;	/* PW_USER_NAME from req */
	VALUE_PAIR	*authPwd;	/* PW_[CHAP]_PASSWORD from req */
	VALUE_PAIR	*auth3rd;	/* PW_[CHAP]_PASSWORD from req */
	VALUE_PAIR	*authState;	/* STATE from req */
	VALUE_PAIR	*chkPwd;	/* PW_PASSWORD from 'users' */
	VALUE_PAIR	*chkSecret;	/* ASCEND_RECEIVE_SECRET from 'users' */
	VALUE_PAIR	*chkImmediate;	/* Boolean: true skips challenge */
	VALUE_PAIR	*chkIdle;	/* idle timer value */
	VALUE_PAIR	*tokExp;	/* ASCEND_TOKEN_EXPIRY from 'users' */
	time_t		tokExpSecs;	/* Seconds till token expires */
	u_char		*pw_digest;	/* as calculated */
	char		*user_msg;	/* return message */
} AuthInfo;

#define DEBUG	if(debug_flag)debugf

	/*
	 *	try to regularize the error status handling
	 *
	 *	make *SURE* you update radiusd.c "db_errmsgs"
	 *	when you update this list!
	 */
typedef enum DBASE_ERRS {
	FIRST_DBASE_ERROR	= -100,
	DEFAULT_PARSE_ERR	= -99,
	DICT_VALFIND_ERR	= -98,
	BINARY_FILTER_ERR	= -97,
	MISSING_EQUALS		= -96,
	DICT_ATTRFIND_ERR	= -95,
	REPLY_FIRST_IS_NULL	= -94,
	MISSING_NEWLINE		= -93,
	NO_USER_OR_DEFAULT_NAME	= -92,
	ZERO_LENGTH_NAME	= -91,
	NO_USER_FILE		= -90,
	NO_WHITESPACE		= -89,
	USERFILE_RENAME_FAILED	= -88,
	USERFILE_READ_ERR	= -87,
	USERFILE_WRITE_ERR	= -86,
	END_OF_USERS_LIST	= -85,
	MEMORY_ERR		= -84,
	DICTFILE_READ_ERR	= -83,
	DICTFILE_ATTRLINE_ERR	= -82,
	DICTFILE_ATTRNAME_ERR	= -81,
	DICTFILE_ATTRVALUE_ERR	= -80,
	DICTFILE_ATTRTYPE_ERR	= -79,
	DICTFILE_VALLINE_ERR	= -78,
	DICTFILE_VALATTR_ERR	= -77,
	DICTFILE_VALNAME_ERR	= -76,
	DICTFILE_VALVALUE_ERR	= -75,
	UNIX_GETPWNAME_ERR	= -74,
	UNIX_GETSHDWNAME_ERR	= -73,
	UNIX_BAD_PASSWORD	= -72,
	CLIENTFILE_READ_ERR	= -71,
	WRONG_NAS_ADDR		= -70,
	LOGFILE_APPEND_ERR	= -69,
	NULL_VALUEPAIR		= -68,
	PWD_EXPIRED		= -67,
	PIPE_CREATE_ERR		= -66,
	LAST_DBASE_ERROR
} DBASE_ERRS;
#define	NUM_DBASE_ERRORS	((LAST_DBASE_ERROR - FIRST_DBASE_ERROR) - 1)

	/* associate strings with error codes */
typedef struct DBASE_ERRMSG {
	DBASE_ERRS	ecode;
	CONST char	*emsg;
} DBASE_ERRMSG;


#define SECONDS_PER_MINUTE	(60)
#define SECONDS_PER_HOUR	(60 * SECONDS_PER_MINUTE)
#define SECONDS_PER_DAY		(24 * SECONDS_PER_HOUR)

#if defined( BINARY_FILTERS )

    /*
     * TRUE and FALSE in case they are needed
     */
#if ! defined( FALSE )
# define FALSE			0
# define TRUE			(! FALSE)
#endif

    /*
     * Two types of filters are supported, GENERIC and IP.  The identifiers
     * are:
     */
#define RAD_FILTER_GENERIC	0
#define RAD_FILTER_IP		1
#define RAD_FILTER_IPX		2

    /*
     * Generic filters mask and match up to RAD_MAX_FILTER_LEN bytes
     * starting at some offset.  The length is:
     */
#define RAD_MAX_FILTER_LEN	6


    /*
     * RadFilterComparison:
     *
     * An enumerated values for the IP filter port comparisons.
     */
typedef enum {
    RAD_NO_COMPARE,
    RAD_COMPARE_LESS,
    RAD_COMPARE_EQUAL,
    RAD_COMPARE_GREATER,
    RAD_COMPARE_NOT_EQUAL
} RadFilterComparison;

    /*
     * RadIpFilter:
     *
     * The binary format of an IP filter.  ALL fields are stored in
     * network byte order.
     *
     *	srcip:		The source IP address.
     *
     *	dstip:		The destination IP address.
     *
     *	srcmask:	The number of leading one bits in the source address
     *			mask.  Specifies the bits of interest.
     *
     *	dstmask:	The number of leading one bits in the destination
     *			address mask. Specifies the bits of interest.
     *
     *	proto:		The IP protocol number
     *
     *	establised:	A boolean value.  TRUE when we care about the
     *			established state of a TCP connection.  FALSE when
     *			we dont care.
     *
     *	srcport:	TCP or UDP source port number.
     *
     *	dstport:	TCP or UDP destination port number.
     *
     *	srcPortCmp:	One of the values of the RadFilterComparison enumeration
     *			specifying how to compare the srcport value.
     *
     *	dstPortCmp:	One of the values of the RadFilterComparison enumeration
     *			specifying how to compare the dstport value.
     *
     *	fill:		Round things out to a dword boundary.
     */
typedef struct radip {
    UINT4  		srcip;
    UINT4  		dstip;
    unsigned char 	srcmask;
    unsigned char 	dstmask;
    unsigned char	proto;
    unsigned char	established;
    unsigned short	srcport;
    unsigned short	dstport;
    unsigned char	srcPortComp;
    unsigned char	dstPortComp;
    unsigned char       fill[4];        /* used to be fill[2] */
} RadIpFilter;

    /*
     * RadIpxFilter:
     * The binary format of a GENERIC filter.  ALL fields are stored in
     * network byte order.
     *
     *  srcIpxNet:      Source IPX Net address
     *
     *  srcIpxNode:     Source IPX Node address
     *
     *  srcIpxSoc:      Source IPX socket address
     *
     *  dstIpxNet:      Destination IPX Net address
     *
     *  dstIpxNode:     Destination IPX Node address
     *
     *  dstIpxSoc:      Destination IPX socket address
     *
     *  srcSocComp:     Source socket compare value
     *
     *  dstSocComp:     Destination socket compare value
     *
     */
typedef struct radipx {                         
    IpxNet              srcIpxNet;                      /* LongWord */
    IpxNode             srcIpxNode;                     /* Byte[6] */
    IpxSocket           srcIpxSoc;                      /* Word */
    IpxNet              dstIpxNet;                      /* LongWord */
    IpxNode             dstIpxNode;                     /* Byte[6] */
    IpxSocket           dstIpxSoc;                      /* Word */
    unsigned char       srcSocComp;
    unsigned char       dstSocComp;
} RadIpxFilter;

    /*
     * RadGenericFilter:
     *
     * The binary format of a GENERIC filter.  ALL fields are stored in
     * network byte order.
     *
     *	offset:		Number of bytes into packet to start comparison.
     *
     *	len:		Number of bytes to mask and compare.  May not
     *			exceed RAD_MAX_FILTER_LEN.
     *
     *	more:		Boolean.  If non-zero the next filter entry is
     *			also to be applied to a packet.
     *
     *	mask:		A bit mask specifying the bits to compare.
     *
     *	value:		A value to compare against the masked bits at
     *			offset in a users packet.
     *			
     *	compNeq:	Defines type of comarison (Equal or Notequal)
     *			default is Equal.
     *
     *	fill:		Round things out to a dword boundary
     */
typedef struct radgeneric {
    unsigned short	offset;
    unsigned short	len;
    unsigned short	more;
    unsigned char	mask[ RAD_MAX_FILTER_LEN ];
    unsigned char	value[ RAD_MAX_FILTER_LEN ];
    unsigned char	compNeq;
    unsigned char       fill[3];        /* used to be fill */
} RadGenericFilter;

    /*
     * RadFilter:
     *
     * A binary filter element.  Contains either a RadIpFilter or a
     * RadGenericFilter.  All fields are stored in network byte order.
     *
     *	type:		Either RAD_FILTER_GENERIC or RAD_FILTER_IP.
     *
     *	forward:	TRUE if we should forward packets that match this
     *			filter, FALSE if we should drop packets that match
     *			this filter.
     *
     *	indirection:	TRUE if this is an input filter, FALSE if this is
     *			an output filter.
     *
     *	fill:		Round things out to a dword boundary.
     *
     *	u:		A union of
     *			ip:		An ip filter entry
     *			generic:	A generic filter entry
     */
typedef struct filter {
    unsigned char 	type;
    unsigned char	forward;
    unsigned char	indirection;
    unsigned char	fill;
    union {
	RadIpFilter   	 ip;
	RadIpxFilter   	 ipx;
	RadGenericFilter generic;
    } u;
} RadFilter;

#endif /* BINARY_FILTERS */

#if defined( ASCEND_SECRET )

    /*
     * The name/number of the string attribute that will be encoded
     * in response packets.  The encoding is similar to the way PAP
     * secrets are encoded in request packets.
     */
#define ASCEND_SEND_SECRET	214
#define ASCEND_RECV_SECRET	215

#endif /* ASCEND_SECRET */

#endif /* _radius_h_ */
