⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 authenticate.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright [C] The Regents of the University of Michigan and Merit Network, * Inc. 1992, 1993, 1994, 1995, 1996, 1997, 1998 All Rights Reserved * * Permission to use, copy, and modify this software and its documentation  * for any purpose and without fee is hereby granted, provided:  * * 1) that the above copyright notice and this permission notice appear in all *    copies of the software and derivative works or modified versions thereof,  * * 2) that both the copyright notice and this permission and disclaimer notice  *    appear in all supporting documentation, and  * * 3) that all derivative works made from this material are returned to the *    Regents of the University of Michigan and Merit Network, Inc. with *    permission to copy, to display, to distribute, and to make derivative *    works from the provided material in whole or in part for any purpose. * * Users of this code are requested to notify Merit Network, Inc. of such use * by sending email to aaa-admin@merit.edu * * Please also use aaa-admin@merit.edu to inform Merit Network, Inc of any * derivative works. * * Distribution of this software or derivative works or the associated * documentation is not allowed without an additional license. * * Licenses for other uses are available on an individually negotiated * basis.  Contact aaa-license@merit.edu for more information. * * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE REGENTS OF THE * UNIVERSITY OF MICHIGAN AND MERIT NETWORK, INC. DO NOT WARRANT THAT THE * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE.  The Regents of the * University of Michigan and Merit Network, Inc. shall not be liable for any * special, indirect, incidental or consequential damages with respect to any * claim by Licensee or any third party arising from use of the software. * * Merit AAA Server Support * Merit Network, Inc. * 4251 Plymouth Road, Suite C. * Ann Arbor, Michigan, USA 48105-2785 * * attn:  John Vollbrecht * voice: 734-764-9430 * fax:   734-647-3185 * email: aaa-admin@merit.edu * *//* * * Public entry points in this file: * * check_request * get_deny_message * */static char     rcsid[] = "$Id: authenticate.c,v 1.1.1.1 2001/08/10 20:49:27 bonze Exp $";#include	<sys/types.h>#include	<sys/param.h>#ifdef sys5#include	<sys/sysmacros.h>#endif	/* sys5 */#ifdef OSF#include	<sys/security.h>#include	<prot.h>#endif	/* OSF */#ifdef SIA#include	<sia.h>#include	<siad.h>#endif	/* SIA */#include	<sys/socket.h>#include	<sys/time.h>#include	<sys/file.h>#include	<sys/wait.h>#include	<net/if.h>#include	<netinet/in.h>#include	<stdio.h>#include	<netdb.h>#include	<errno.h>#include	<signal.h>#include	<memory.h>#include	<syslog.h>#ifndef NOSHADOW#include	<shadow.h>#endif	/* NOSHADOW */#ifdef __hpuxtrust#include	<hpsecurity.h>#endif	/* __hpuxtrust */#define _XOPEN_SOURCE#include <unistd.h>#include	"radius.h"extern char     ourhostname[MAXHOSTNAMELEN];extern char     default_radius_server[];extern int      debug_flag;extern int      token_caching_auth_type[];extern AATV    *authtype_tv[];/************************************************************************* * *	Function: check_request * *	Purpose: Process check and deny items on a request. * *	Returns: EV_ACK, EV_NAK, etc. * *************************************************************************/intcheck_request (authreq, list, sws)AUTH_REQ       *authreq;VALUE_PAIR     *list;		/* Check against this list (if present) */int             sws;		/* 0 == do accept check, 1 == do deny check */{	int             result = EV_ACK;	/* Assume success. */	VALUE_PAIR     *each;	VALUE_PAIR     *vp;	char           *why = (char *) NULL;	char            buffer[MAXPATHLEN];	/* For optional denial msg. */	static char    *func = "check_request";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	if (authreq == (AUTH_REQ *) NULL)	{		logit (LOG_DAEMON, LOG_ERR, "%s: NULL authreq!", func);		return EV_NAK;	}	/* If no list, find one. */	if (list == NULL_VP)	{		if ((sws & CHK_DENY) == CHK_DENY)		{			list = authreq->user_deny;		}		else		{			list = authreq->user_check;		}	}	/* Short circut test. */	if (list == NULL_VP)	{		return EV_ACK;	/* Nothing to check or deny, let it through */	}	/* Check each check item in the list... */	for (each = list;		(each != NULL_VP) && (result == EV_ACK);		each = each->next)	{	 	/* Ignore (config) items. */		if ((each->ap->flags & ATTR_CONFIG) == ATTR_CONFIG)		{			continue;		}		/*		 * Just look for the matching attribute in the request.		 */		if ((vp = get_vp_vend (authreq->cur_request, each->attribute,					each->ap->vendor_id)) != NULL_VP)		{			switch (each->ap->type)			{			    case PW_TYPE_OCTETS:			    case PW_TYPE_TAG_STR:			    case PW_TYPE_STRING:				if ((vp->lvalue == each->lvalue) && 					(memcmp (each->strvalue, vp->strvalue,						each->lvalue) == 0))				{					if ((sws & CHK_DENY) == CHK_DENY)					{						result = EV_NAK;						why = buffer;						sprintf (why,						    "Access not allowed, %s=%s",							vp->ap->name,							avpair_vtoa (vp, 0));					}				}				else				{					if ((sws & CHK_DENY) == 0)					{						result = EV_NAK;						why = buffer;						sprintf (why,						    "Access not allowed, %s=%s",							vp->ap->name,							avpair_vtoa (vp, 0));					}				}				break;			    case PW_TYPE_IPADDR:				if ((each->strvalue != NULL) && 					(*each->strvalue != '\0'))				{					/* Resolve all DNS names */					if (find_host_by_name (&each->lvalue,							each->strvalue) == 1)					{						why = buffer;						sprintf (why,					"Access temporarily not allowed, %s=%s",							each->ap->name,							each->strvalue);						if ((sws & CHK_DENY) == CHK_DENY)						{							result = EV_NAK;						}						else						{							logit (LOG_AUTH,								LOG_WARNING,		    "%s: request ignored - unresolved host '%s' in check item",								func,								each->strvalue);							result = EV_ABORT;						}						break; /* switch() statement */					}				}				/***FALLTHROUGH****/			    case PW_TYPE_SHORT:			    case PW_TYPE_OCTET:			    case PW_TYPE_TAG_INT:			    case PW_TYPE_INTEGER:				if (each->lvalue == vp->lvalue)				{					if ((sws & CHK_DENY) == CHK_DENY)					{						result = EV_NAK;						why = buffer;						sprintf (why,						   "Access not allowed, %s=%s",							vp->ap->name,							avpair_vtoa (vp, 0));					}				}				else				{					if ((sws & CHK_DENY) == 0)					{						result = EV_NAK;						why = buffer;						sprintf (why,						   "Access not allowed, %s=%s",							vp->ap->name,							avpair_vtoa (vp, 0));					}				}				break;			    default:				why = buffer;				sprintf (why,			      "Configuration error, access not allowed, %s=%s",					vp->ap->name,					avpair_vtoa (vp, 0));				logit (LOG_DAEMON, LOG_ERR,				     "%s: Configuration error, %s bad type %d",					func, each->ap->name, each->ap->type);				result = EV_NAK;				break;			}	        }		/* If a check item is not present, deny the request. */		else		{			if ((sws & CHK_DENY) == 0)			{				result = EV_NAK;				why = buffer;				sprintf (why, "Access not allowed, no %s",					each->ap->name);			}		}		/* If we are to check only one, do only one. */		if ((sws & CHK_ONCE) == CHK_ONCE)	        {			break;		}	} /* end of "Check each check-item" */	/*	 * Explain why denial occured, allowing explanation to be configured.	 */	if ((result != EV_ACK) && (sws & CHK_MESSAGE) == CHK_MESSAGE)	{		reply_sprintf (0, authreq,				get_deny_message (authreq, list, why));	}	return result;} /* end of check_request () */static int      chk_pass PROTO((AUTH_REQ *, int, char *));static AATV     realm_aatv = DEF_AATV_DIRECT_TYPE("REALM", AA_REALM, chk_pass);AATVPTR         rad_realm_aatv = & realm_aatv;/************************************************************************* * *	Function: chk_pass * *	Purpose: Check the users password against any server * *************************************************************************/static intchk_pass (authreq, value, af_param)AUTH_REQ       *authreq;int             value;char           *af_param;{	int             authprot;	int             type;	VALUE_PAIR     *vp;	char           *agent;	char           *realm;	char           *filter;	char            user_realm[AUTH_ID_LEN + 1];	static char    *func = "chk_pass";	dprintf(1, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	if (get_vp (authreq->cur_request, PW_CHAP_PASSWORD))	{		authprot = PW_PROTTYPE_CHAP;	}	else	{		authprot = PW_PROTTYPE_PW;	}	if ((vp = parse_realm (authreq)) == NULL_VP)	{		reply_sprintf (0, authreq,				"Improper 'userid@realm' specification");		return EV_NAK;	}	strcpy (user_realm, vp->strvalue);	if ((vp = get_vp_vend (authreq->cur_request, PW_USER_ID, VC_MERIT))	    != NULL_VP)	{		if (strchr (vp->strvalue, '.') != (char *) NULL)		{			authprot = PW_PROTTYPE_HASDOT;		}	}	if (user_realm[0] == '\0')		/* user_realm is never NULL */	{		if (find_auth_type ("", authprot,					(char *) authreq->client->file_pfx,					&type, &agent, &realm, &filter) != 0)		{			reply_sprintf (0, authreq,				"Improper 'userid@realm' specification");			return EV_NAK;		}	}	else			/* Check for protected keyword realm value */	{		if (strcasecmp (user_realm, DEFAULT_REALM) == 0 ||			strcasecmp (user_realm, NULL_REALM) == 0)		{			reply_sprintf (0, authreq,					"Invalid authentication realm: '%s'",					user_realm);			return EV_NAK;		}		/* Try to match realm name in AUTHFILE */		if (find_auth_type (user_realm, authprot,		    	     (char *) authreq->client->file_pfx, &type, &agent,				    &realm, &filter) != 0)		{			/* If no match, try for DEFAULT entry */			if (find_auth_type (DEFAULT_REALM, authprot,				     (char *) authreq->client->file_pfx, &type,					    &agent, &realm, &filter) != 0)			{		/* No DEFAULT configured so give up */				reply_sprintf (0, authreq,					"Invalid authentication realm: '%s'",					user_realm);				return EV_NAK;			}		}	}	authreq->realm_filter = filter;	if (type == AA_REALM) 	/* Watch for misconfiguration */	{		/* Can't have REALM auth type in authfile! */		logit (LOG_AUTH, LOG_ERR, "%s: Invalid Type '%d' in authfile",			 func, type);		return EV_NAK;	}#ifdef USR_CCA 	if (type == AA_LOCAL_VPN)	{		/* This is an error since all users belonging to a Local VPN 		   must be defined in the local users file, and so this function		   must not be called in the first place		*/		vp = get_vp (authreq->cur_request, PW_USER_NAME);		logit (LOG_AUTH, LOG_ERR, "%s: User %s of realm %s not defined",				func, vp->strvalue, user_realm);		return EV_NAK;	}#endif	/* USR_CCA */	return call_action (authtype_tv[type], authreq, 0, agent);} /* end of chk_pass () *//************************************************************************* * *	Function: get_deny_message * *	Purpose: Get the configured denial message, or a canned message. * *************************************************************************/char *get_deny_message (authreq, list, why)AUTH_REQ       *authreq;VALUE_PAIR     *list;	/* Suggested list to try. */char           *why;	/* Suggested message, if CI_DENY_MESSAGE is "*" */{	VALUE_PAIR     *vp;	char           *reason = "Access not allowed";	static char    *func = "get_deny_message";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	/*	 *	Find the deny message, first in the list...	 *	then in the authreq somewhere...	 */	if ((vp = get_vp_ci (list, CI_DENY_MESSAGE, 0)) == NULL_VP)	{		if (authreq != (AUTH_REQ *) NULL)		{			if ((vp = get_vp_ci (authreq->user_check,						CI_DENY_MESSAGE, 0)) == NULL_VP)			{				vp = get_vp_ci (authreq->user_deny,						CI_DENY_MESSAGE, 0);			}		}	}	if (vp != NULL_VP)	{		reason = vp->strvalue;	}	/*	 *	Special case: deny-message = "*"	 *	 *	Allows message "access not allowed, xxx = value"	 */	if (strcmp (reason, "*") == 0)	{		if (why != (char *) NULL)		{			reason = why;	        }		else		{			reason = "Access not allowed";		}	}	return reason;} /* end of get_deny_message () */static int      rad_authenticate PROTO((AUTH_REQ *, int, char *));static AATV     authen_aatv = DEF_AATV_DIRECT("AUTHENTICATE", rad_authenticate);AATVPTR		rad_authen_aatv = & authen_aatv;/************************************************************************* * *	Function: rad_authenticate * *	Purpose: Process and reply to an authentication request * *************************************************************************/static intrad_authenticate (authreq, value, realm)AUTH_REQ       *authreq;int             value;char           *realm;{#ifdef MERIT_LAS	int          cache_token;#endif	/* MERIT_LAS */	int          found_pw = 0;	int          i;	int          protocol;	int          result;	int          retval;	VALUE_PAIR  *auth_item;	VALUE_PAIR  *check_item;	VALUE_PAIR  *namepair;	VALUE_PAIR  *protpair;	VALUE_PAIR  *user_reply;	VALUE_PAIR **prev_ptr;	char        *server_name = "";	char         pwmsg[AUTH_PASS_LEN + 1];#ifdef USR_CCA        /****	char         res_assigned = FALSE;	UINT4        nas = 0;	UINT4        framed_ip = 0;	UINT4        nas_port = 0;	VALUE_PAIR  *framed_ip_vp;	VALUE_PAIR  *nas_port_vp;	VALUE_PAIR  *nas_vp;	****/	VALUE_PAIR  *term_act;#endif	/* USR_CCA */	char        *func = "rad_authenticate";	authreq->startlas = time (0); /* record time starting authentication */	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	/* Get the username from the request */	if (((namepair =		get_vp (authreq->cur_request, PW_USER_NAME)) == NULL_VP) ||		(strlen (namepair->strvalue) <= 0))	{		logit (LOG_AUTH, LOG_ERR, "%s: from %s - No User Name",			 func, ip_hostname (authreq->ipaddr));		return EV_NAK;	}	protpair = get_vp (authreq->cur_request, PW_FRAMED_PROTOCOL);	protocol = (protpair == NULL_VP) ? 0 : protpair->lvalue;	if (authreq->user_check == NULL_VP)	{		/* Look in the database only if both lists are NULL. */		if ((retval = user_find ((char *) authreq->client->file_pfx,					namepair->strvalue, protocol,					&authreq->user_check,					&authreq->user_deny,					&user_reply, 0)) < 0)		{			logit (LOG_AUTH, LOG_ERR,				"%s: from %s - Problem in user_find",			 	func, ip_hostname (authreq->ipaddr));			return EV_NAK;		}		if (retval > 0)		/* If no match, use DEFAULT entry */		{			if (user_find ((char *) authreq->client->file_pfx, 				"DEFAULT", protocol, &authreq->user_check,				&authreq->user_deny, &user_reply, 0) != 0)			{				logit (LOG_AUTH, LOG_ERR,			      "%s: from %s - Invalid/missing 'DEFAULT' entry",			   		func, ip_hostname (authreq->ipaddr));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -