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

📄 auth.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * auth.c	User authentication. * * Version:	$Id: auth.c,v 1.178 2008/04/18 09:29:49 aland Exp $ * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Copyright 2000,2006  The FreeRADIUS server project * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl> * Copyright 2000  Jeff Carneal <jeff@apex.net> */#include <freeradius-devel/ident.h>RCSID("$Id: auth.c,v 1.178 2008/04/18 09:29:49 aland Exp $")#include <freeradius-devel/radiusd.h>#include <freeradius-devel/modules.h>#include <freeradius-devel/rad_assert.h>#include <ctype.h>/* *	Return a short string showing the terminal server, port *	and calling station ID. */char *auth_name(char *buf, size_t buflen, REQUEST *request, int do_cli){	VALUE_PAIR	*cli;	VALUE_PAIR	*pair;	int		port = 0;	if ((cli = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) == NULL)		do_cli = 0;	if ((pair = pairfind(request->packet->vps, PW_NAS_PORT)) != NULL)		port = pair->vp_integer;	snprintf(buf, buflen, "from client %.128s port %u%s%.128s%s",			request->client->shortname, port,		 (do_cli ? " cli " : ""), (do_cli ? (char *)cli->vp_strvalue : ""),		 (request->packet->dst_port == 0) ? " via TLS tunnel" : "");	return buf;}/* * Make sure user/pass are clean * and then log them */static int rad_authlog(const char *msg, REQUEST *request, int goodpass) {	char clean_password[1024];	char clean_username[1024];	char buf[1024];	VALUE_PAIR *username = NULL;	if (!request->root->log_auth) {		return 0;	}	/*	 * Get the correct username based on the configured value	 */	if (log_stripped_names == 0) {		username = pairfind(request->packet->vps, PW_USER_NAME);	} else {		username = request->username;	}	/*	 *	Clean up the username	 */	if (username == NULL) {		strcpy(clean_username, "<no User-Name attribute>");	} else {		librad_safeprint((char *)username->vp_strvalue,				username->length,				clean_username, sizeof(clean_username));	}	/*	 *	Clean up the password	 */	if (request->root->log_auth_badpass || request->root->log_auth_goodpass) {		if (!request->password) {			VALUE_PAIR *auth_type;			auth_type = pairfind(request->config_items,					     PW_AUTH_TYPE);			if (auth_type && (auth_type->vp_strvalue[0] != '\0')) {				snprintf(clean_password, sizeof(clean_password),					 "<via Auth-Type = %s>",					 auth_type->vp_strvalue);			} else {				strcpy(clean_password, "<no User-Password attribute>");			}		} else if (pairfind(request->packet->vps, PW_CHAP_PASSWORD)) {			strcpy(clean_password, "<CHAP-Password>");		} else {			librad_safeprint((char *)request->password->vp_strvalue,					 request->password->length,					 clean_password, sizeof(clean_password));		}	}	if (goodpass) {		radlog(L_AUTH, "%s: [%s%s%s] (%s)",				msg,				clean_username,				request->root->log_auth_goodpass ? "/" : "",				request->root->log_auth_goodpass ? clean_password : "",				auth_name(buf, sizeof(buf), request, 1));	} else {		radlog(L_AUTH, "%s: [%s%s%s] (%s)",				msg,				clean_username,				request->root->log_auth_badpass ? "/" : "",				request->root->log_auth_badpass ? clean_password : "",				auth_name(buf, sizeof(buf), request, 1));	}	return 0;}/* *	Check password. * *	Returns:	0  OK *			-1 Password fail *			-2 Rejected (Auth-Type = Reject, send Port-Message back) *			1  End check & return, don't reply * *	NOTE: NOT the same as the RLM_ values ! */static int rad_check_password(REQUEST *request){	VALUE_PAIR *auth_type_pair;	VALUE_PAIR *cur_config_item;	VALUE_PAIR *password_pair;	VALUE_PAIR *auth_item;	uint8_t my_chap[MAX_STRING_LEN];	int auth_type = -1;	int result;	int auth_type_count = 0;	result = 0;	/*	 *	Look for matching check items. We skip the whole lot	 *	if the authentication type is PW_AUTHTYPE_ACCEPT or	 *	PW_AUTHTYPE_REJECT.	 */	cur_config_item = request->config_items;	while(((auth_type_pair = pairfind(cur_config_item, PW_AUTH_TYPE))) != NULL) {		auth_type = auth_type_pair->vp_integer;		auth_type_count++;		DEBUG2("  rad_check_password:  Found Auth-Type %s",				auth_type_pair->vp_strvalue);		cur_config_item = auth_type_pair->next;		if (auth_type == PW_AUTHTYPE_REJECT) {			DEBUG2("  rad_check_password: Auth-Type = Reject, rejecting user");			return -2;		}	}	if (( auth_type_count > 1) && (debug_flag)) {		radlog(L_ERR, "Warning:  Found %d auth-types on request for user '%s'",			auth_type_count, request->username->vp_strvalue);	}	/*	 *	This means we have a proxy reply or an accept	 *  and it wasn't rejected in the above loop.  So	 *  that means it is accepted and we do no further	 *  authentication	 */	if ((auth_type == PW_AUTHTYPE_ACCEPT) || (request->proxy)) {		DEBUG2("  rad_check_password: Auth-Type = Accept, accepting the user");		return 0;	}	password_pair =  pairfind(request->config_items, PW_USER_PASSWORD);	if (password_pair &&	    pairfind(request->config_items, PW_CLEARTEXT_PASSWORD)) {		pairdelete(&request->config_items, PW_USER_PASSWORD);		password_pair = NULL;	}	if (password_pair) {		DICT_ATTR *da;		DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");		DEBUG("!!!    Replacing User-Password in config items with Cleartext-Password.     !!!");		DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");		DEBUG("!!! Please update your configuration so that the \"known good\"               !!!");		DEBUG("!!! clear text password is in Cleartext-Password, and not in User-Password. !!!");		DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");		password_pair->attribute = PW_CLEARTEXT_PASSWORD;		da = dict_attrbyvalue(PW_CLEARTEXT_PASSWORD);		if (!da) {			radlog(L_ERR, "FATAL: You broke the dictionaries.  Please use the default dictionaries!");			_exit(1);		}		password_pair->name = da->name;	}	/*	 *	Find the "known good" password.	 *	 *	FIXME: We should get rid of these hacks, and replace	 *	them with a module.	 */	if ((password_pair = pairfind(request->config_items, PW_CRYPT_PASSWORD)) != NULL) {		/*		 *	Re-write Auth-Type, but ONLY if it isn't already		 *	set.		 */		if (auth_type == -1) auth_type = PW_AUTHTYPE_CRYPT;	} else {		password_pair = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD);	}	if (auth_type < 0) {		if (password_pair) {			auth_type = PW_AUTHTYPE_LOCAL;		} else {			/*		 	*	The admin hasn't told us how to		 	*	authenticate the user, so we reject them!		 	*		 	*	This is fail-safe.		 	*/			DEBUG2("auth: No authenticate method (Auth-Type) configuration found for the request: Rejecting the user");			return -2;		}	}	switch(auth_type) {		DICT_VALUE *dval;		case PW_AUTHTYPE_CRYPT:			/*			 *	Find the password sent by the user. It			 *	SHOULD be there, if it's not			 *	authentication fails.			 */			auth_item = request->password;			if (auth_item == NULL) {				DEBUG2("auth: No User-Password or CHAP-Password attribute in the request");				return -1;			}			DEBUG2("auth: type Crypt");			if (password_pair == NULL) {				DEBUG2("No Crypt-Password configured for the user");				rad_authlog("Login incorrect "					"(No Crypt-Password configured for the user)", request, 0);				return -1;			}			switch (fr_crypt_check((char *)auth_item->vp_strvalue,									 (char *)password_pair->vp_strvalue)) {			case -1:			  rad_authlog("Login incorrect "						  "(system failed to supply an encrypted password for comparison)", request, 0);			case 1:			  return -1;			}			break;		case PW_AUTHTYPE_LOCAL:			DEBUG2("auth: type Local");			/*			 *	Find the password sent by the user. It			 *	SHOULD be there, if it's not			 *	authentication fails.			 */			auth_item = request->password;			if (!auth_item)				auth_item = pairfind(request->packet->vps,						     PW_CHAP_PASSWORD);			if (!auth_item) {				DEBUG2("auth: No User-Password or CHAP-Password attribute in the request");				return -1;			}			/*			 *	Plain text password.			 */			if (password_pair == NULL) {				DEBUG2("auth: No password configured for the user");				rad_authlog("Login incorrect "					"(No password configured for the user)", request, 0);				return -1;			}			/*			 *	Local password is just plain text.	 		 */			if (auth_item->attribute == PW_USER_PASSWORD) {				if (strcmp((char *)password_pair->vp_strvalue,					   (char *)auth_item->vp_strvalue) != 0) {					DEBUG2("auth: user supplied User-Password does NOT match local User-Password");					return -1;				}				DEBUG2("auth: user supplied User-Password matches local User-Password");				break;			} else if (auth_item->attribute != PW_CHAP_PASSWORD) {				DEBUG2("The user did not supply a User-Password or a CHAP-Password attribute");				rad_authlog("Login incorrect "					"(no User-Password or CHAP-Password attribute)", request, 0);				return -1;			}			rad_chap_encode(request->packet, my_chap,					auth_item->vp_octets[0], password_pair);			/*			 *	Compare them			 */			if (memcmp(my_chap + 1, auth_item->vp_strvalue + 1,				   CHAP_VALUE_LENGTH) != 0) {				DEBUG2("auth: user supplied CHAP-Password does NOT match local User-Password");				return -1;			}			DEBUG2("auth: user supplied CHAP-Password matches local User-Password");			break;		default:			dval = dict_valbyattr(PW_AUTH_TYPE, auth_type);			if (dval) {				DEBUG2("auth: type \"%s\"", dval->name);			} else {				DEBUG2("auth: type UNKNOWN-%d", auth_type);			}			/*			 *	See if there is a module that handles			 *	this type, and turn the RLM_ return			 *	status into the values as defined at			 *	the top of this function.			 */			result = module_authenticate(auth_type, request);			switch (result) {				/*				 *	An authentication module FAIL				 *	return code, or any return code that				 *	is not expected from authentication,				 *	is the same as an explicit REJECT!				 */				case RLM_MODULE_FAIL:				case RLM_MODULE_INVALID:				case RLM_MODULE_NOOP:				case RLM_MODULE_NOTFOUND:				case RLM_MODULE_REJECT:				case RLM_MODULE_UPDATED:				case RLM_MODULE_USERLOCK:				default:					result = -1;					break;				case RLM_MODULE_OK:					result = 0;					break;				case RLM_MODULE_HANDLED:					result = 1;					break;			}			break;	}	return result;}/* *	Post-authentication step processes the response before it is *	sent to the NAS. It can receive both Access-Accept and Access-Reject *	replies. */int rad_postauth(REQUEST *request){	int	result;	int	postauth_type = 0;

⌨️ 快捷键说明

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