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

📄 authenticate.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 2 页
字号:
				return EV_NAK;			}		}		list_cat (&authreq->cur_request, user_reply);	}	else	{		if (authreq->user_deny == NULL_VP)		{			/* Look in the database only if both lists are NULL. */			if ((retval =				user_find ((char *) authreq->client->file_pfx,						namepair->strvalue, protocol,						(VALUE_PAIR **) NULL,						&authreq->user_deny,						(VALUE_PAIR **) NULL, 0)) < 0)			{				logit (LOG_AUTH, LOG_ERR,					"%s: from %s - Problem in user_find()",					func, ip_hostname (authreq->ipaddr));			}			else			{				if (retval > 0)				{					if (user_find ((char *)						authreq->client->file_pfx,						"DEFAULT", protocol,						(VALUE_PAIR **) NULL,						&authreq->user_deny,						(VALUE_PAIR **) NULL, 0) != 0)					{						logit (LOG_AUTH, LOG_ERR,				"%s: from %s - Invalid/missing 'DEFAULT' entry",							func,							ip_hostname (authreq->								     ipaddr));					}				}			}		}	}	result = EV_ACK; /* assume good until proven otherwise */	/* No null names allowed */	if (*namepair->strvalue == '\0')	{		result = EV_NAK;	}/* #ifdef USR_CCA */	/* RESOURCE MANAGEMENT *//*	if (authreq->code == PW_ACCESS_REQUEST && result != EV_NAK && *		(term_act = get_vp (authreq->cur_request, *				PW_TERMINATION_ACTION)) != NULL_VP) *	{ *		if (term_act->lvalue == PW_MANAGE_RESOURCES) *		{ *			result = resource_mgmt (authreq); *			if (result == EV_ACK) *			{ *				res_assigned = TRUE; *			} *		} *	}  *//* #endif	* USR_CCA */	/*	 *	See if this is strictly an authentication check.	 *	Throw out all but pw and pw expiration items if it is.	 */	if ((auth_item =		get_vp (authreq->cur_request, PW_SERVICE_TYPE)) != NULL_VP &&		(auth_item->lvalue == PW_AUTHENTICATE_ONLY))	{		for (prev_ptr = &authreq->user_check, check_item = *prev_ptr;			check_item != NULL_VP;			check_item = *prev_ptr)		{			if (check_item->ap->flags & ATTR_CONFIG)			{				switch (check_item->attribute)				{				    case CI_PROHIBIT:					if (check_item->lvalue == PW_AUTH_ONLY)					{						result = EV_NAK;					}					/* Leave in user_check list */					prev_ptr = &check_item->next;					continue;				    case CI_ENCRYPTED_PASSWORD:				    case CI_USER_PASSWORD:				    case CI_AUTHENTICATION_TYPE:					found_pw = 1;					/***FALLTHROUGH***/				    case CI_EXPIRATION:				    case CI_SERVER_NAME:					/* Leave in user_check list */					prev_ptr = &check_item->next;					continue;				    default:					break;				}			}			/* Remove all others from list */			*prev_ptr = check_item->next;			avpair_free (check_item);		}		if (found_pw == 0) /* Authenticate-Only requires a password! */		{			result = EV_NAK;		}	}	/* Check those check items */	dprintf(4, (LOG_AUTH, LOG_DEBUG,		"%s: about to check user_check items", func));	for (check_item = authreq->user_check;		((result == EV_ACK) && (check_item != NULL_VP));		check_item = check_item->next)	{		if (check_item->ap->flags & ATTR_CONFIG)		{			switch (check_item->attribute)			{			    /*			     * Check expiration date if we are doing password			     * aging.			     */			    case CI_EXPIRATION:				/* Has this user's password expired */				retval = pw_expired (check_item->lvalue,							user_reply);				if (retval < 0)				{					reply_sprintf (0, authreq,							"Password Has Expired");#ifdef ASCEND					result = EV_PW_EXPIRED;				}				else if (retval > 0)				{					reply_sprintf (0, authreq,					      "Password will expire in %d days",						retval);#else	/* ASCEND */					result = EV_NAK;#endif	/* ASCEND */				}				if (retval > 0)				{					reply_sprintf (RS_IF_ACK, authreq,					      "Password Will Expire in %d Days",					      retval);				}				break;			    case CI_SERVER_NAME:				server_name = check_item->strvalue;				break;			    case CI_AUTHENTICATION_TYPE:			    case CI_SIMULTANEOUS_USE:			    case CI_COMMENT:			    case CI_PROHIBIT:			    case CI_SERVICE_CLASS:				break;			    case CI_ENCRYPTED_PASSWORD:				retval = get_passwd (authreq, pwmsg,					    check_item->strvalue, 						check_item->strvalue);				if (retval != 0)				{					result = EV_NAK;				}				memset ((char *) pwmsg, '\0', sizeof (pwmsg));				break;			    case CI_USER_PASSWORD:			    /*			     *	Pass password to get_passwd() so it will			     *	do CHAP and PASSWORD check for us.			     */#ifdef ASCEND				/*				 *	If this is Ascend ARADES authentication,				 *	this is the wrong place to check this.				 *	This will fail since the password is				 *	not sent in the Access-Request.				 */				if ((auth_item =					get_vp_vend (authreq->cur_request,							PW_ASCEND_ARADES,							VC_ASCEND)) != NULL_VP)				{					break;				}#endif	/* ASCEND */				retval = get_passwd (authreq, pwmsg,					   check_item->strvalue, (char *) NULL);				if (retval != 0)				{					dprintf(2, (LOG_AUTH, LOG_DEBUG,					   "%s: invalid password, retval = %d",						func, retval));					result = EV_NAK;				}				/* Test Code for Challenge */				if (strcmp (pwmsg, "challenge") == 0 &&								retval == 1)				{				  memset ((char *) pwmsg, 0, sizeof (pwmsg));				  reply_sprintf (RS_IF_ACK, authreq,			       "You want me to challenge you??\r\nOkay I will");				  avpair_add (&authreq->cur_request, PW_STATE,						"1", -1);				  result = EV_ACC_CHAL;				}				memset ((char *) pwmsg, 0, sizeof (pwmsg));				break;			    default:				break;			}			continue;		}		/*		 * Process check items that didn't require special processing		 * above.  Just look for the matching attribute in the		 * request.		 */		result = check_request (authreq, check_item,					CHK_ACCEPT | CHK_ONCE);	} /* end of "Check those check items" */	/* Check those deny items */	if (result == EV_ACK)	{		result = check_request (authreq, authreq->user_deny,					CHK_DENY | CHK_MESSAGE);	} /* end of "Check those deny items" */	if ((result == EV_ACK) &&	     (check_item = get_vp_ci (authreq->user_check,					CI_AUTHENTICATION_TYPE, 0)) != NULL_VP)	{		if (authtype_tv[check_item->lvalue] == (AATV *) NULL)		{			logit (LOG_DAEMON, LOG_ERR,			 "%s: FATAL: Unsupported authentication type %d for %s",				func, check_item->lvalue, namepair->strvalue);			logit (LOG_DAEMON, LOG_ERR,				"%s: CHECK THE MAKEFILE BUILD!", func);			result = EV_FATAL;		}		else		{#ifdef MERIT_LAS			/*			 *	See if it's one of the authentication types			 *	which allow caching.  If so, call the AATV			 *	which checks the cache before calling the			 *	authentication AATV.			 */			cache_token = 0;			for (i = 0; token_caching_auth_type[i]; i++)			{				if (check_item->lvalue ==						token_caching_auth_type[i])				{					cache_token = 1;				}			}			if (cache_token > 0)			{				result = call_action (rad_cache_chk_aatv,						      authreq, 0, server_name);			}			else#endif	/* MERIT_LAS */			{				result =				   call_action (authtype_tv[check_item->lvalue],						authreq, 0, server_name);			}		}	}/* #ifdef USR_CCA	if (result != EV_ACK && result != EV_WAIT &&		res_assigned == TRUE)	{		if ((framed_ip_vp = get_vp (authreq->cur_request, 					    PW_FRAMED_IP_ADDRESS)) != NULL_VP)		{			framed_ip = framed_ip_vp->lvalue;		}		if ((nas_vp = get_vp (authreq->cur_request, PW_NAS_IP_ADDRESS))				     != NULL_VP)		{			nas = nas_vp->lvalue;		}				if ((nas_port_vp = get_vp (authreq->cur_request, 					   PW_NAS_PORT)) != NULL_VP)		{			nas_port = nas_port_vp->lvalue;		}				free_resources (namepair->strvalue, framed_ip, nas, nas_port);	}*//* #endif * USR_CCA */#ifdef USR_CCA	/* RESOURCE MANAGEMENT */	/* For Local-VPN type, CI_AUTHENTICATON_TYPE will be NULL */	if (result != EV_NAK && check_item == NULL_VP)	{		if (authreq->code == PW_ACCESS_REQUEST &&			(term_act = get_vp (authreq->cur_request,					    PW_TERMINATION_ACTION)) != NULL_VP)		{			if (term_act->lvalue == PW_MANAGE_RESOURCES)			{				result = resource_mgmt (authreq);				/* if (result == EV_ACK)				{					res_assigned = TRUE;				} */			}		}	}#endif	/* USR_CCA */	return result;} /* end of rad_authenticate () */static void     rad_2rad_init PROTO((AATV *));static int      radius_pass PROTO((AUTH_REQ *, int, char *));static AATV     rad2rad_aatv = DEF_AATV_SOCKET_TYPE("RAD2RAD", AA_RAD,							rad_2rad_init,							radius_pass,							rad_2rad_recv);AATVPTR		rad_2rad_aatv = & rad2rad_aatv;/************************************************************************* * *	Function: rad_2rad_init * *	Purpose: Perform RADIUS to RADIUS initialization. * *************************************************************************/static voidrad_2rad_init (aatv)AATV   *aatv;{	struct sockaddr_in lclsin;	static char    *func = "rad_2rad_init";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	if (aatv->sockfd == -1)	{		aatv->sockfd = setupsock (&lclsin, 0);	}	return;} /* end of rad_2rad_init () *//************************************************************************* * *	Function: radius_pass * *	Purpose: Have remote RADIUS system handle authentication for this *		 RADIUS to RADIUS request. * *	Returns: EV_ACK if valid userid and pw, *		 EV_NAK if invalid, *		 EV_WAIT if request issued. * *************************************************************************/static intradius_pass (authreq, value, realm)AUTH_REQ       *authreq;int             value;char           *realm;{	VALUE_PAIR     *vp;	char            id[AUTH_ID_LEN + 1];        int             code;	static char    *func = "radius_pass";	code = authreq->code;#ifdef USR_CCA	if (code != PW_NAS_REB_REQ &&		(vp = get_vp_vend (authreq->cur_request, PW_USER_ID, VC_MERIT))								== NULL_VP)#else	/* USR_CCA */	if ((vp = get_vp_vend (authreq->cur_request, PW_USER_ID, VC_MERIT))								== NULL_VP)#endif	/* USR_CCA */	{		logit (LOG_DAEMON, LOG_ALERT,			"%s: Improper userid specification", func);		reply_message (authreq, EC_INTERNAL, func);		return EV_NAK;	}	strcpy (id, vp->strvalue);	/*	 *	If no server system DNS name is provided, a default is used.	 *	Set #define DEFAULT_RADIUS_SERVER (or set it in authfile)	 *	to the name of the default server system to use for	 *	RADIUS authentication.	 */	if ((realm == NULL) || (realm[0] == '\0'))	{		realm = default_radius_server;	}	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: name = %s  realm = %s",		func, id, realm));	/* Check to see if we are the server for this realm */#ifdef USR_CCA        if (code != PW_NAS_REB_REQ &&	    strcasecmp (ourhostname, realm) == 0)#else	/* USR_CCA */	if (strcasecmp (ourhostname, realm) == 0)#endif	/* USR_CCA */	{		dprintf(2, (LOG_AUTH, LOG_DEBUG,			"%s: handle locally", func));		/* Treat this one just like Unix-PW authentication */		return call_action (authtype_tv[AA_UNIX], authreq, 0, realm);	}	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: handle remotely", func));        if (radius_send ((char *) authreq->fsm_aatv->id, code, 0,                        realm, authreq, rad2rad_aatv.sockfd) == -1)	{		return EV_NAK;	}	return EV_WAIT;	/* RC says to expect reply later */} /* end of radius_pass () */static int      slow_pass PROTO((AUTH_REQ *, int, char *));static AATV     slow_aatv = DEF_AATV_FREPLY_TYPE("SLOW", AA_SLOW, NULL,								slow_pass, 2);AATVPTR         rad_slow_aatv = & slow_aatv;/************************************************************************* * *	Function: slow_pass * *	Purpose: Enable flexible debugging of realm type autthentication. * *************************************************************************/static intslow_pass (authreq, value, af_param)AUTH_REQ       *authreq;int             value;char           *af_param;{	int             authprot;	int             type;	char           *agent;	char           *filter;	char           *pfx = (char *) NULL;	char           *realm;	VALUE_PAIR     *rlm_vp = NULL_VP;	VALUE_PAIR     *vp;	static char    *func = "slow_pass";	dprintf(1, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	/* If there is a prefix assocated with this authreq, get it. */	if (authreq != (AUTH_REQ *) NULL)	{		if (authreq->client != (CLIENT_ENTRY *) NULL)		{			pfx = authreq->client->file_pfx;		}	}	if (af_param == (char *) NULL)	{		reply_sprintf (RS_LOG, authreq, "%s: Missing sub-realm", func);		return EV_NAK;	}	/* Get realm for messages, etc. */	rlm_vp = get_vp_vend (authreq->cur_request, PW_USER_REALM, VC_MERIT);	/* Determine authentication protocol type */	if (get_vp (authreq->cur_request, PW_CHAP_PASSWORD))	{		authprot = PW_PROTTYPE_CHAP;	}	else	{		authprot = PW_PROTTYPE_PW;	}	/* Try to match the realm name in the authfile. */	if (find_auth_type (af_param, authprot, pfx, &type, &agent,				&realm, &filter) != 0)	{		reply_sprintf (RS_LOG, authreq,				"%s: Invalid authentication sub-realm: '%s'",				func, af_param);		return EV_NAK;	}	/* Check the various different types... */	switch (type)	{	    case AA_SLOW:		reply_sprintf (RS_LOG, authreq,				"%s: Slow won't stack realm (%s)",				func, af_param);		return EV_NAK;	    case AA_REALM:		reply_sprintf (RS_LOG, authreq,				"%s: Invalid type '%d' in authfile",				func, type);		return EV_NAK;#ifdef USR_CCA	    case AA_LOCAL_VPN:		/*		 *	This is an error since all users belonging to a		 *	Local VPN must be defined in the local users file,		 *	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, af_param);		return EV_NAK;#endif /* USR_CCA */	} /* end of switch */	if (authtype_tv[type] == (AATV *) NULL)	{		reply_sprintf (RS_LOG, authreq,			"%s: Unsupported authentication type %d", func, type);		return EV_NAK;	}	rad_sleep (10, "%s (xxx, %d, '%s'), sleeping", func, value, agent);	return call_action (authtype_tv[type], authreq, value, agent);} /* end of slow_pass () */

⌨️ 快捷键说明

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