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

📄 rlm_mschap.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
				return 0;			}			/*			 *	Hack.  This is simpler than the alternatives.			 */			*p = '\0';			strlcpy(out, user_name->vp_strvalue, outlen);			*p = '\\';		}		return strlen(out);		/*		 *	Pull the User-Name out of the User-Name...		 */	} else if (strncasecmp(fmt, "User-Name", 9) == 0) {		char *p;		user_name = pairfind(request->packet->vps, PW_USER_NAME);		if (!user_name) {			DEBUG2("  rlm_mschap: No User-Name was found in the request.");			return 0;		}		/*		 *	First check to see if this is a host/ style User-Name		 *	(a la Kerberos host principal)		 */		if (strncmp(user_name->vp_strvalue, "host/", 5) == 0) {			/*			 *	If we're getting a User-Name formatted in this way,			 *	it's likely due to PEAP.  When authenticating this against			 *	a Domain, Windows will expect the User-Name to be in the			 *	format of hostname$, the SAM version of the name, so we			 *	have to convert it to that here.  We do so by stripping			 *	off the first 5 characters (host/), and copying everything			 *	from that point to the first period into a string and appending			 * 	a $ to the end.			 */			p = strchr(user_name->vp_strvalue, '.');			/*			 * use the same hack as above			 * only if a period was found			 */			if (p) *p = '\0';			snprintf(out, outlen, "%s$", user_name->vp_strvalue + 5);			if (p) *p = '.';		} else {			p = strchr(user_name->vp_strvalue, '\\');			if (p) {				p++;	/* skip the backslash */			} else {				p = user_name->vp_strvalue; /* use the whole User-Name */			}			strlcpy(out, p, outlen);		}		return strlen(out);		/*		 * Return the NT-Hash of the passed string		 */	} else if (strncasecmp(fmt, "NT-Hash ", 8) == 0) {		char *p;		p = fmt + 8;	/* 7 is the length of 'NT-Hash' */		if ((p == '\0')	 || (outlen <= 32))			return 0;		DEBUG("rlm_mschap: NT-Hash: %s",p);		ntpwdhash(buffer,p);		fr_bin2hex(buffer, out, 16);		out[32] = '\0';		DEBUG("rlm_mschap: NT-Hash: Result: %s",out);		return 32;		/*		 * Return the LM-Hash of the passed string		 */	} else if (strncasecmp(fmt, "LM-Hash ", 8) == 0) {		char *p;		p = fmt + 8;	/* 7 is the length of 'LM-Hash' */		if ((p == '\0') || (outlen <= 32))			return 0;		DEBUG("rlm_mschap: LM-Hash: %s",p);		smbdes_lmpwdhash(p, buffer);		fr_bin2hex(buffer, out, 16);		out[32] = '\0';		DEBUG("rlm_mschap: LM-Hash: Result: %s",out);		return 32;	} else {		DEBUG2("  rlm_mschap: Unknown expansion string \"%s\"",		       fmt);		return 0;	}	if (outlen == 0) return 0; /* nowhere to go, don't do anything */	/*	 *	Didn't set anything: this is bad.	 */	if (!data) {		DEBUG2("  rlm_mschap: Failed to do anything intelligent");		return 0;	}	/*	 *	Check the output length.	 */	if (outlen < ((data_len * 2) + 1)) {		data_len = (outlen - 1) / 2;	}	/*	 *	 */	for (i = 0; i < data_len; i++) {		sprintf(out + (2 * i), "%02x", data[i]);	}	out[data_len * 2] = '\0';	return data_len * 2;}static const CONF_PARSER module_config[] = {	/*	 *	Cache the password by default.	 */	{ "use_mppe",    PW_TYPE_BOOLEAN,	  offsetof(rlm_mschap_t,use_mppe), NULL, "yes" },	{ "require_encryption",    PW_TYPE_BOOLEAN,	  offsetof(rlm_mschap_t,require_encryption), NULL, "no" },	{ "require_strong",    PW_TYPE_BOOLEAN,	  offsetof(rlm_mschap_t,require_strong), NULL, "no" },	{ "with_ntdomain_hack",     PW_TYPE_BOOLEAN,	  offsetof(rlm_mschap_t,with_ntdomain_hack), NULL, "no" },	{ "passwd",   PW_TYPE_STRING_PTR,	  offsetof(rlm_mschap_t, passwd_file), NULL,  NULL },	{ "ntlm_auth",   PW_TYPE_STRING_PTR,	  offsetof(rlm_mschap_t, ntlm_auth), NULL,  NULL },#ifdef __APPLE__	{ "use_open_directory",    PW_TYPE_BOOLEAN,	  offsetof(rlm_mschap_t,open_directory), NULL, "yes" },#endif	{ NULL, -1, 0, NULL, NULL }		/* end the list */};/* *	deinstantiate module, free all memory allocated during *	mschap_instantiate() */static int mschap_detach(void *instance){#define inst ((rlm_mschap_t *)instance)	if (inst->xlat_name) {		xlat_unregister(inst->xlat_name, mschap_xlat);		free(inst->xlat_name);	}	free(instance);	return 0;#undef inst}/* *	Create instance for our module. Allocate space for *	instance structure and read configuration parameters */static int mschap_instantiate(CONF_SECTION *conf, void **instance){	rlm_mschap_t *inst;	inst = *instance = rad_malloc(sizeof(*inst));	if (!inst) {		return -1;	}	memset(inst, 0, sizeof(*inst));	if (cf_section_parse(conf, inst, module_config) < 0) {		free(inst);		return -1;	}	/*	 *	This module used to support SMB Password files, but it	 *	made it too complicated.  If the user tries to	 *	configure an SMB Password file, then die, with an	 *	error message.	 */	if (inst->passwd_file) {		radlog(L_ERR, "rlm_mschap: SMB password file is no longer supported in this module.  Use rlm_passwd module instead");		mschap_detach(inst);		return -1;	}	/*	 *	Create the dynamic translation.	 */	inst->xlat_name = cf_section_name2(conf);	if (!inst->xlat_name) inst->xlat_name = cf_section_name1(conf);	inst->xlat_name = strdup(inst->xlat_name);	xlat_register(inst->xlat_name, mschap_xlat, inst);	/*	 *	For backwards compatibility	 */	if (!dict_valbyname(PW_AUTH_TYPE, inst->xlat_name)) {		inst->auth_type = "MS-CHAP";	} else {		inst->auth_type = inst->xlat_name;	}	return 0;}/* *	add_reply() adds either MS-CHAP2-Success or MS-CHAP-Error *	attribute to reply packet */void mschap_add_reply(VALUE_PAIR** vp, unsigned char ident,		      const char* name, const char* value, int len){	VALUE_PAIR *reply_attr;	reply_attr = pairmake(name, "", T_OP_EQ);	if (!reply_attr) {		DEBUG("  rlm_mschap: Failed to create attribute %s: %s\n", name, librad_errstr);		return;	}	reply_attr->vp_octets[0] = ident;	memcpy(reply_attr->vp_octets + 1, value, len);	reply_attr->length = len + 1;	pairadd(vp, reply_attr);}/* *	Add MPPE attributes to the reply. */static void mppe_add_reply(REQUEST *request,			   const char* name, const uint8_t * value, int len){       VALUE_PAIR *vp;       vp = radius_pairmake(request, &request->reply->vps, name, "", T_OP_EQ);       if (!vp) {	       DEBUG("rlm_mschap: mppe_add_reply failed to create attribute %s: %s\n", name, librad_errstr);	       return;       }       memcpy(vp->vp_octets, value, len);       vp->length = len;}/* *	Do the MS-CHAP stuff. * *	This function is here so that all of the MS-CHAP related *	authentication is in one place, and we can perhaps later replace *	it with code to call winbindd, or something similar. */static int do_mschap(rlm_mschap_t *inst,		     REQUEST *request, VALUE_PAIR *password,		     uint8_t *challenge, uint8_t *response,		     uint8_t *nthashhash){	int		do_ntlm_auth = 0;	uint8_t		calculated[24];	VALUE_PAIR	*vp = NULL;	/*	 *	If we have ntlm_auth configured, use it unless told	 *	otherwise	 */	if (inst->ntlm_auth) do_ntlm_auth = 1;	/*	 *	If we have an ntlm_auth configuration, then we may	 *	want to use it.	 */	vp = pairfind(request->config_items,		      PW_MS_CHAP_USE_NTLM_AUTH);	if (vp) do_ntlm_auth = vp->vp_integer;	/*	 *	No ntlm_auth configured, attribute to tell us to	 *	use it exists, and we're told to use it.  We don't	 *	know what to do...	 */	if (!inst->ntlm_auth && do_ntlm_auth) {		DEBUG2("  rlm_mschap: Asked to use ntlm_auth, but it was not configured in the mschap{} section.");		return -1;	}	/*	 *	Do normal authentication.	 */	if (!do_ntlm_auth) {		/*		 *	No password: can't do authentication.		 */		if (!password) {			DEBUG2("  rlm_mschap: FAILED: No NT/LM-Password.  Cannot perform authentication.");			return -1;		}		smbdes_mschap(password->vp_strvalue, challenge, calculated);		if (memcmp(response, calculated, 24) != 0) {			return -1;		}		/*		 *	If the password exists, and is an NT-Password,		 *	then calculate the hash of the NT hash.  Doing this		 *	here minimizes work for later.		 */		if (password && (password->attribute == PW_NT_PASSWORD)) {			fr_md4_calc(nthashhash, password->vp_octets, 16);		} else {			memset(nthashhash, 0, 16);		}	} else {		/* run ntlm_auth */		int	result;		char	buffer[256];		memset(nthashhash, 0, 16);		/*		 *	Run the program, and expect that we get 16		 */		result = radius_exec_program(inst->ntlm_auth, request,					     TRUE, /* wait */					     buffer, sizeof(buffer),					     NULL, NULL, 1);		if (result != 0) {			DEBUG2("  rlm_mschap: External script failed.");			return -1;		}		/*		 *	Parse the answer as an nthashhash.		 *		 *	ntlm_auth currently returns:		 *	NT_KEY: 000102030405060708090a0b0c0d0e0f		 */		if (memcmp(buffer, "NT_KEY: ", 8) != 0) {			DEBUG2("  rlm_mschap: Invalid output from ntlm_auth: expecting NT_KEY");			return -1;		}		/*		 *	Check the length.  It should be at least 32,		 *	with an LF at the end.		 */		if (strlen(buffer + 8) < 32) {			DEBUG2("  rlm_mschap: Invalid output from ntlm_auth: NT_KEY has unexpected length");			return -1;		}		/*		 *	Update the NT hash hash, from the NT key.		 */		if (fr_hex2bin(buffer + 8, nthashhash, 16) != 16) {			DEBUG2("  rlm_mschap: Invalid output from ntlm_auth: NT_KEY has non-hex values");			return -1;		}	}	return 0;}/* *	Data for the hashes. */static const uint8_t SHSpad1[40] =               { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };static const uint8_t SHSpad2[40] =               { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,                 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,                 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,                 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };static const uint8_t magic1[27] =               { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,                 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,                 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 };static const uint8_t magic2[84] =               { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,                 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,                 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,                 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,                 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,                 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,                 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,                 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,                 0x6b, 0x65, 0x79, 0x2e };static const uint8_t magic3[84] =               { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,                 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,                 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,                 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,                 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,                 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,                 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,                 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,                 0x6b, 0x65, 0x79, 0x2e };static void mppe_GetMasterKey(uint8_t *nt_hashhash,uint8_t *nt_response,			      uint8_t *masterkey){       uint8_t digest[20];       fr_SHA1_CTX Context;       fr_SHA1Init(&Context);       fr_SHA1Update(&Context,nt_hashhash,16);       fr_SHA1Update(&Context,nt_response,24);       fr_SHA1Update(&Context,magic1,27);       fr_SHA1Final(digest,&Context);       memcpy(masterkey,digest,16);}static void mppe_GetAsymmetricStartKey(uint8_t *masterkey,uint8_t *sesskey,				       int keylen,int issend){       uint8_t digest[20];       const uint8_t *s;       fr_SHA1_CTX Context;       memset(digest,0,20);       if(issend) {               s = magic3;       } else {               s = magic2;       }       fr_SHA1Init(&Context);       fr_SHA1Update(&Context,masterkey,16);       fr_SHA1Update(&Context,SHSpad1,40);       fr_SHA1Update(&Context,s,84);       fr_SHA1Update(&Context,SHSpad2,40);       fr_SHA1Final(digest,&Context);       memcpy(sesskey,digest,keylen);}static void mppe_chap2_get_keys128(uint8_t *nt_hashhash,uint8_t *nt_response,				   uint8_t *sendkey,uint8_t *recvkey){       uint8_t masterkey[16];       mppe_GetMasterKey(nt_hashhash,nt_response,masterkey);       mppe_GetAsymmetricStartKey(masterkey,sendkey,16,1);       mppe_GetAsymmetricStartKey(masterkey,recvkey,16,0);}/*

⌨️ 快捷键说明

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