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

📄 rlm_mschap.c

📁 RADIUS认证协议
💻 C
📖 第 1 页 / 共 3 页
字号:
	memcpy (recvkey, enckey2, 16);}/* *	mschap_authorize() - authorize user if we can authenticate *	it later. Add Auth-Type attribute if present in module *	configuration (usually Auth-Type must be "MS-CHAP") */static int mschap_authorize(void * instance, REQUEST *request){#define inst ((rlm_mschap_t *)instance)	VALUE_PAIR *challenge = NULL;	VALUE_PAIR *response = NULL;	VALUE_PAIR *vp;	const char *authtype_name = "MS-CHAP";	challenge = pairfind(request->packet->vps, PW_MSCHAP_CHALLENGE);	if (!challenge) {		return RLM_MODULE_NOOP;	}	response = pairfind(request->packet->vps, PW_MSCHAP_RESPONSE);	if (!response)		response = pairfind(request->packet->vps, PW_MSCHAP2_RESPONSE);	/*	 *	Nothing we recognize.  Don't do anything.	 */	if (!response) {		DEBUG2("  rlm_mschap: Found MS-CHAP-Challenge, but no MS-CHAP-Response.");		return RLM_MODULE_NOOP;	}	/*	 *	Choose MS-CHAP, or whatever else they told us to use.	 */	if (inst->auth_type) {		authtype_name = inst->auth_type;	}	DEBUG2("  rlm_mschap: Found MS-CHAP attributes.  Setting 'Auth-Type  = %s'", authtype_name);	/*	 *	Set Auth-Type to MS-CHAP.  The authentication code	 *	will take care of turning clear-text passwords into	 *	NT/LM passwords.	 */	pairdelete(&request->config_items, PW_AUTHTYPE);	vp = pairmake("Auth-Type", authtype_name, T_OP_EQ);	rad_assert(vp != NULL);	pairadd(&request->config_items, vp);	return RLM_MODULE_OK;#undef inst}/* *	mschap_authenticate() - authenticate user based on given *	attributes and configuration. *	We will try to find out password in configuration *	or in configured passwd file. *	If one is found we will check paraneters given by NAS. * *	If PW_SMB_ACCOUNT_CTRL is not set to ACB_PWNOTREQ we must have *	one of: *		PAP:      PW_PASSWORD or *		MS-CHAP:  PW_MSCHAP_CHALLENGE and PW_MSCHAP_RESPONSE or *		MS-CHAP2: PW_MSCHAP_CHALLENGE and PW_MSCHAP2_RESPONSE *	In case of password mismatch or locked account we MAY return *	PW_MSCHAP_ERROR for MS-CHAP or MS-CHAP v2 *	If MS-CHAP2 succeeds we MUST return *	PW_MSCHAP2_SUCCESS */static int mschap_authenticate(void * instance, REQUEST *request){#define inst ((rlm_mschap_t *)instance)	VALUE_PAIR *challenge = NULL;	VALUE_PAIR *response = NULL;	VALUE_PAIR *password = NULL;	VALUE_PAIR *lm_password, *nt_password, *smb_ctrl;	VALUE_PAIR *username;	VALUE_PAIR *reply_attr;	uint8_t nthashhash[16];	uint8_t msch2resp[42];	char *username_string;	int chap = 0;	/*	 *	Find the SMB-Account-Ctrl attribute, or the	 *	SMB-Account-Ctrl-Text attribute.	 */	smb_ctrl = pairfind(request->config_items, PW_SMB_ACCOUNT_CTRL);	if (!smb_ctrl) {		password = pairfind(request->config_items,				    PW_SMB_ACCOUNT_CTRL_TEXT);		if (password) {			smb_ctrl = pairmake("SMB-Account-CTRL", "0", T_OP_SET);			pairadd(&request->config_items, smb_ctrl);			smb_ctrl->lvalue = pdb_decode_acct_ctrl(password->strvalue);		}	}	/*	 *	We're configured to do MS-CHAP authentication.	 *	and account control information exists.  Enforce it.	 */	if (smb_ctrl) {		/*		 *	Password is not required.		 */		if ((smb_ctrl->lvalue & ACB_PWNOTREQ) != 0) {			DEBUG2("  rlm_mschap: SMB-Account-Ctrl says no password is required.");			return RLM_MODULE_OK;		}	}	/*	 *	Decide how to get the passwords.	 */	password = pairfind(request->config_items, PW_PASSWORD);	/*	 *	We need an LM-Password.	 */	lm_password = pairfind(request->config_items, PW_LM_PASSWORD);	if (lm_password) {		/*		 *	Allow raw octets.		 */		if ((lm_password->length == 16) ||		    ((lm_password->length == 32) &&		     (hex2bin(lm_password->strvalue,			      lm_password->strvalue, 16) == 16))) {			DEBUG2("  rlm_mschap: Found LM-Password");			lm_password->length = 16;		} else {			radlog(L_ERR, "rlm_mschap: Invalid LM-Password");			lm_password = NULL;		}	} else if (!password) {		DEBUG2("  rlm_mschap: No User-Password configured.  Cannot create LM-Password.");	} else {		/* there is a configured User-Password */		lm_password = pairmake("LM-Password", "", T_OP_EQ);		if (!lm_password) {			radlog(L_ERR, "No memory");		} else {			smbdes_lmpwdhash(password->strvalue,				       lm_password->strvalue);			lm_password->length = 16;			pairadd(&request->config_items, lm_password);		}	}	/*	 *	We need an NT-Password.	 */	nt_password = pairfind(request->config_items, PW_NT_PASSWORD);	if (nt_password) {		if ((nt_password->length == 16) ||		    ((nt_password->length == 32) &&		     (hex2bin(nt_password->strvalue,			      nt_password->strvalue, 16) == 16))) {			DEBUG2("  rlm_mschap: Found NT-Password");			nt_password->length = 16;                } else {			radlog(L_ERR, "rlm_mschap: Invalid NT-Password");			nt_password = NULL;		}	} else if (!password) {		DEBUG2("  rlm_mschap: No User-Password configured.  Cannot create NT-Password.");	} else {		/* there is a configured User-Password */		nt_password = pairmake("NT-Password", "", T_OP_EQ);		if (!nt_password) {			radlog(L_ERR, "No memory");			return RLM_MODULE_FAIL;		} else {			ntpwdhash(nt_password->strvalue, password->strvalue);			nt_password->length = 16;			pairadd(&request->config_items, nt_password);		}	}	challenge = pairfind(request->packet->vps, PW_MSCHAP_CHALLENGE);	if (!challenge) {		DEBUG2("  rlm_mschap: No MS-CHAP-Challenge in the request");		return RLM_MODULE_REJECT;	}	/*	 *	We also require an MS-CHAP-Response.	 */	response = pairfind(request->packet->vps, PW_MSCHAP_RESPONSE);	/*	 *	MS-CHAP-Response, means MS-CHAPv1	 */	if (response) {		int offset;		/*		 *	MS-CHAPv1 challenges are 8 octets.		 */		if (challenge->length < 8) {			radlog(L_AUTH, "rlm_mschap: MS-CHAP-Challenge has the wrong format.");			return RLM_MODULE_INVALID;		}		/*		 *	Responses are 50 octets.		 */		if (response->length < 50) {			radlog(L_AUTH, "rlm_mschap: MS-CHAP-Response has the wrong format.");			return RLM_MODULE_INVALID;		}		/*		 *	We are doing MS-CHAP.  Calculate the MS-CHAP		 *	response		 */		if (response->strvalue[1] & 0x01) {			DEBUG2("  rlm_mschap: Told to do MS-CHAPv1 with NT-Password");			password = nt_password;			offset = 26;		} else {			DEBUG2("  rlm_mschap: Told to do MS-CHAPv1 with LM-Password");			password = lm_password;			offset = 2;		}		/*		 *	Do the MS-CHAP authentication.		 */		if (do_mschap(inst, request, password, challenge->strvalue,			      response->strvalue + offset, nthashhash) < 0) {			DEBUG2("  rlm_mschap: MS-CHAP-Response is incorrect.");			add_reply(&request->reply->vps, *response->strvalue,				  "MS-CHAP-Error", "E=691 R=1", 9);			return RLM_MODULE_REJECT;		}		chap = 1;	} else if ((response = pairfind(request->packet->vps, PW_MSCHAP2_RESPONSE)) != NULL) {		uint8_t	mschapv1_challenge[16];		/*		 *	MS-CHAPv2 challenges are 16 octets.		 */		if (challenge->length < 16) {			radlog(L_AUTH, "rlm_mschap: MS-CHAP-Challenge has the wrong format.");			return RLM_MODULE_INVALID;		}		/*		 *	Responses are 50 octets.		 */		if (response->length < 50) {			radlog(L_AUTH, "rlm_mschap: MS-CHAP-Response has the wrong format.");			return RLM_MODULE_INVALID;		}		/*		 *	We also require a User-Name		 */		username = pairfind(request->packet->vps, PW_USER_NAME);		if (!username) {			radlog(L_AUTH, "rlm_mschap: We require a User-Name for MS-CHAPv2");			return RLM_MODULE_INVALID;		}		/*		 *	with_ntdomain_hack moved here		 */		if ((username_string = strchr(username->strvalue, '\\')) != NULL) {		        if (inst->with_ntdomain_hack) {			        username_string++;			} else {				DEBUG2("  rlm_mschap: NT Domain delimeter found, should we have enabled with_ntdomain_hack?");				username_string = username->strvalue;			}		} else {		        username_string = username->strvalue;		}		/*		 *	The old "mschapv2" function has been moved to		 *	here.		 *		 *	MS-CHAPv2 takes some additional data to create an		 *	MS-CHAPv1 challenge, and then does MS-CHAPv1.		 */		challenge_hash(response->strvalue + 2, /* peer challenge */			       challenge->strvalue, /* our challenge */			       username_string,	/* user name */			       mschapv1_challenge); /* resulting challenge */				DEBUG2("  rlm_mschap: Told to do MS-CHAPv2 for %s with NT-Password",		       username_string);		if (do_mschap(inst, request, nt_password, mschapv1_challenge,			      response->strvalue + 26, nthashhash) < 0) {			DEBUG2("  rlm_mschap: FAILED: MS-CHAP2-Response is incorrect");			add_reply(&request->reply->vps, *response->strvalue,				  "MS-CHAP-Error", "E=691 R=1", 9);			return RLM_MODULE_REJECT;		}		/*		 *	Get the NT-hash-hash, if necessary		 */		if (nt_password) {		}		auth_response(username_string, /* without the domain */			      nthashhash, /* nt-hash-hash */			      response->strvalue + 26, /* peer response */			      response->strvalue + 2, /* peer challenge */			      challenge->strvalue, /* our challenge */			      msch2resp); /* calculated MPPE key */		add_reply( &request->reply->vps, *response->strvalue,			   "MS-CHAP2-Success", msch2resp, 42);		chap = 2;	} else {		/* Neither CHAPv1 or CHAPv2 response: die */		radlog(L_AUTH, "rlm_mschap: No MS-CHAP response found");		return RLM_MODULE_INVALID;	}	/*	 *	We have a CHAP response, but the account may be	 *	disabled.  Reject the user with the same error code	 *	we use when their password is invalid.	 */	if (smb_ctrl) {		/*		 *	Account is disabled.		 *		 *	They're found, but they don't exist, so we		 *	return 'not found'.		 */		if (((smb_ctrl->lvalue & ACB_DISABLED) != 0) ||		    ((smb_ctrl->lvalue & ACB_NORMAL) == 0)) {			DEBUG2("  rlm_mschap: SMB-Account-Ctrl says that the account is disabled, or is not a normal account.");			add_reply( &request->reply->vps, *response->strvalue,				   "MS-CHAP-Error", "E=691 R=1", 9);			return RLM_MODULE_NOTFOUND;		}		/*		 *	User is locked out.		 */		if ((smb_ctrl->lvalue & ACB_AUTOLOCK) != 0) {			DEBUG2("  rlm_mschap: SMB-Account-Ctrl says that the account is locked out.");			add_reply( &request->reply->vps, *response->strvalue,				   "MS-CHAP-Error", "E=647 R=0", 9);			return RLM_MODULE_USERLOCK;		}	}	/* now create MPPE attributes */	if (inst->use_mppe) {		uint8_t mppe_sendkey[34];		uint8_t mppe_recvkey[34];		if (chap == 1){			DEBUG2("rlm_mschap: adding MS-CHAPv1 MPPE keys");			memset(mppe_sendkey, 0, 32);			if (lm_password) {				memcpy(mppe_sendkey, lm_password->strvalue, 8);			}			/*			 *	According to RFC 2548 we			 *	should send NT hash.  But in			 *	practice it doesn't work.			 *	Instead, we should send nthashhash			 *			 *	This is an error on RFC 2548.			 */			/*			 *	do_mschap cares to zero nthashhash if NT hash			 *	is not available.			 */			memcpy(mppe_sendkey + 8,			       nthashhash, 16);			mppe_add_reply(&request->reply->vps,				       "MS-CHAP-MPPE-Keys",				       mppe_sendkey, 32);		} else if (chap == 2) {			DEBUG2("rlm_mschap: adding MS-CHAPv2 MPPE keys");			mppe_chap2_gen_keys128(nthashhash,					       response->strvalue + 26,					       mppe_sendkey, mppe_recvkey);						mppe_add_reply(&request->reply->vps,				       "MS-MPPE-Recv-Key",				       mppe_recvkey, 16);			mppe_add_reply(&request->reply->vps,				       "MS-MPPE-Send-Key",				       mppe_sendkey, 16);		}		reply_attr = pairmake("MS-MPPE-Encryption-Policy",				      (inst->require_encryption)? "0x00000002":"0x00000001",				      T_OP_EQ);		rad_assert(reply_attr != NULL);		pairadd(&request->reply->vps, reply_attr);		reply_attr = pairmake("MS-MPPE-Encryption-Types",				      (inst->require_strong)? "0x00000004":"0x00000006",				      T_OP_EQ);		rad_assert(reply_attr != NULL);		pairadd(&request->reply->vps, reply_attr);	} /* else we weren't asked to use MPPE */	return RLM_MODULE_OK;#undef inst}module_t rlm_mschap = {  "MS-CHAP",  RLM_TYPE_THREAD_SAFE,		/* type */  NULL,				/* initialize */  mschap_instantiate,		/* instantiation */  {	  mschap_authenticate,	/* authenticate */	  mschap_authorize,	/* authorize */	  NULL,			/* pre-accounting */	  NULL,			/* accounting */	  NULL,			/* checksimul */	  NULL,			/* pre-proxy */	  NULL,			/* post-proxy */	  NULL			/* post-auth */  },  mschap_detach,		/* detach */  NULL,				/* destroy */};

⌨️ 快捷键说明

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