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

📄 rlm_wimax.c

📁 freeradius-server-2.1.3.tar.gz安装源文件
💻 C
字号:
/* * rlm_wimax.c * * Version:	$Id$ * * Copyright (C) 2008 Alan DeKok <aland@networkradius.com> * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include <freeradius-devel/ident.h>RCSID("$Id$")#include <freeradius-devel/radiusd.h>#include <freeradius-devel/modules.h>/* *	FIXME: Add check for this header to configure.in */#include <openssl/hmac.h>/* *	FIXME: Fix the build system to create definitions from names. */#define WIMAX2ATTR(x) ((24757 << 16) | (x))/* *	Find the named user in this modules database.  Create the set *	of attribute-value pairs to check and reply with for this user *	from the database. The authentication code only needs to check *	the password, the rest is done here. */static int wimax_authorize(void *instance, REQUEST *request){	VALUE_PAIR *vp;	/* quiet the compiler */	instance = instance;	request = request;	/*	 *	Fix Calling-Station-Id.  Damn you, WiMAX!	 */	vp =  pairfind(request->packet->vps, PW_CALLING_STATION_ID);	if (vp && (vp->length == 6)) {		int i;		uint8_t buffer[6];		memcpy(buffer, vp->vp_octets, 6);		/*		 *	RFC 3580 Section 3.20 says this is the preferred		 *	format.  Everyone *SANE* is using this format,		 *	so we fix it here.		 */		for (i = 0; i < 6; i++) {			fr_bin2hex(&buffer[i], &vp->vp_strvalue[i * 3], 1);			vp->vp_strvalue[(i * 3) + 2] = '-';		}		vp->vp_strvalue[(5*3)+2] = '\0';		vp->length = (5*3)+2;		DEBUG2("rlm_wimax: Fixing WiMAX binary Calling-Station-Id to %s",		       buffer);	}	return RLM_MODULE_OK;}/* *	Massage the request before recording it or proxying it */static int wimax_preacct(void *instance, REQUEST *request){	return wimax_authorize(instance, request);}/* *	Write accounting information to this modules database. */static int wimax_accounting(void *instance, REQUEST *request){	/* quiet the compiler */	instance = instance;	request = request;	return RLM_MODULE_OK;}/* *	Generate the keys after the user has been authenticated. */static int wimax_postauth(UNUSED void *instance, REQUEST *request){	VALUE_PAIR *msk, *emsk, *vp;	VALUE_PAIR *mn_nai, *ip, *fa_rk;	HMAC_CTX hmac;	unsigned int rk1_len, rk2_len, rk_len;	int rk_lifetime = 3600;	/* ? */	uint32_t mip_spi;	uint8_t usage_data[24];	uint8_t mip_rk_1[EVP_MAX_MD_SIZE], mip_rk_2[EVP_MAX_MD_SIZE];	uint8_t mip_rk[2 * EVP_MAX_MD_SIZE];	msk = pairfind(request->reply->vps, 1129);	emsk = pairfind(request->reply->vps, 1130);	if (!msk || !emsk) {		RDEBUG("No EAP-MSK or EAP-EMSK.  Cannot create WiMAX keys.");		return RLM_MODULE_NOOP;	}	/*	 *	Initialize usage data.	 */	memcpy(usage_data, "miprk@wimaxforum.org", 21);	/* with trailing \0 */	usage_data[21] = 0x02;	usage_data[22] = 0x00;	usage_data[23] = 0x01;	/*	 *	MIP-RK-1 = HMAC-SSHA256(EMSK, usage-data | 0x01)	 */	HMAC_CTX_init(&hmac);	HMAC_Init_ex(&hmac, emsk->vp_octets, emsk->length, EVP_sha256(), NULL);		HMAC_Update(&hmac, &usage_data[0], sizeof(usage_data));	HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);	/*	 *	MIP-RK-2 = HMAC-SSHA256(EMSK, MIP-RK-1 | usage-data | 0x01)	 */	HMAC_CTX_init(&hmac);	HMAC_Init_ex(&hmac, emsk->vp_octets, emsk->length, EVP_sha256(), NULL);		HMAC_Update(&hmac, (const uint8_t *) &mip_rk_1, rk1_len);	HMAC_Update(&hmac, &usage_data[0], sizeof(usage_data));	HMAC_Final(&hmac, &mip_rk_2[0], &rk2_len);	vp = pairfind(request->reply->vps, PW_SESSION_TIMEOUT);	if (vp) rk_lifetime = vp->vp_integer;	memcpy(mip_rk, mip_rk_1, rk1_len);	memcpy(mip_rk + rk1_len, mip_rk_2, rk2_len);	rk_len = rk1_len + rk2_len;	/*	 *	MIP-SPI = HMAC-SSHA256(MIP-RK, "SPI CMIP PMIP");	 */	HMAC_CTX_init(&hmac);	HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha256(), NULL);		HMAC_Update(&hmac, (const uint8_t *) "SPI CMIP PMIP", 12);	HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);	/*	 *	Take the 4 most significant octets.	 *	If less than 256, add 256.	 */	mip_spi = ((mip_rk_1[0] << 24) | (mip_rk_1[1] << 16) |		   (mip_rk_1[2] << 8) | mip_rk_1[3]);	if (mip_spi < 256) mip_spi += 256;	if (debug_flag) {		int len = rk_len;		char buffer[512];		if (len > 128) len = 128; /* buffer size */		fr_bin2hex(mip_rk, buffer, len);		radlog_request(L_DBG, 0, request, "MIP-RK = 0x%s", buffer);		radlog_request(L_DBG, 0, request, "MIP-SPI = %08x",			       ntohl(mip_spi));	}	/*	 *	FIXME: Perform SPI collision prevention	 */	/*	 *	Calculate mobility keys	 */	mn_nai = pairfind(request->packet->vps, 1912);	if (!mn_nai) mn_nai = pairfind(request->reply->vps, 1912);	if (!mn_nai) {		RDEBUG("WARNING: WiMAX-MN-NAI was not found in the request or in the reply.");		RDEBUG("WARNING: We cannot calculate MN-HA keys.");	}	/*	 *	WiMAX-IP-Technology	 */	vp = NULL;	if (mn_nai) vp = pairfind(request->reply->vps, WIMAX2ATTR(23));	if (!vp) {		RDEBUG("WARNING: WiMAX-IP-Technology not found in reply.");		RDEBUG("WARNING: Not calculating MN-HA keys");	}	if (vp) switch (vp->vp_integer) {	case 2:			/* PMIP4 */		/*		 *	Look for WiMAX-hHA-IP-MIP4		 */		ip = pairfind(request->reply->vps, WIMAX2ATTR(6));		if (!ip) {			RDEBUG("WARNING: WiMAX-hHA-IP-MIP4 not found.  Cannot calculate MN-HA-PMIP4 key");			break;		}		/*		 *	MN-HA-PMIP4 =		 *	   H(MIP-RK, "PMIP4 MN HA" | HA-IPv4 | MN-NAI);		 */		HMAC_CTX_init(&hmac);		HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);		HMAC_Update(&hmac, (const uint8_t *) "PMIP4 MN HA", 11);		HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4);		HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length);		HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);		/*		 *	Put MN-HA-PMIP4 into WiMAX-MN-hHA-MIP4-Key		 */		vp = pairfind(request->reply->vps, WIMAX2ATTR(10));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(10), PW_TYPE_OCTETS);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-Key");			break;		}		memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len);		vp->length = rk1_len;		/*		 *	Put MN-HA-PMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI		 */		vp = pairfind(request->reply->vps, WIMAX2ATTR(11));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(11), PW_TYPE_INTEGER);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-SPI");			break;		}		vp->vp_integer = mip_spi + 1;		break;	case 3:			/* CMIP4 */		/*		 *	Look for WiMAX-hHA-IP-MIP4		 */		ip = pairfind(request->reply->vps, WIMAX2ATTR(6));		if (!ip) {			RDEBUG("WARNING: WiMAX-hHA-IP-MIP4 not found.  Cannot calculate MN-HA-CMIP4 key");			break;		}		/*		 *	MN-HA-CMIP4 =		 *	   H(MIP-RK, "CMIP4 MN HA" | HA-IPv4 | MN-NAI);		 */		HMAC_CTX_init(&hmac);		HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);		HMAC_Update(&hmac, (const uint8_t *) "CMIP4 MN HA", 11);		HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4);		HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length);		HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);		/*		 *	Put MN-HA-CMIP4 into WiMAX-MN-hHA-MIP4-Key		 */		vp = pairfind(request->reply->vps, WIMAX2ATTR(10));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(10), PW_TYPE_OCTETS);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-Key");			break;		}		memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len);		vp->length = rk1_len;		/*		 *	Put MN-HA-CMIP4-SPI into WiMAX-MN-hHA-MIP4-SPI		 */		vp = pairfind(request->reply->vps, WIMAX2ATTR(11));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(11), PW_TYPE_INTEGER);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP4-SPI");			break;		}		vp->vp_integer = mip_spi;		break;	case 4:			/* CMIP6 */		/*		 *	Look for WiMAX-hHA-IP-MIP6		 */		ip = pairfind(request->reply->vps, WIMAX2ATTR(7));		if (!ip) {			RDEBUG("WARNING: WiMAX-hHA-IP-MIP6 not found.  Cannot calculate MN-HA-CMIP6 key");			break;		}		/*		 *	MN-HA-CMIP6 =		 *	   H(MIP-RK, "CMIP6 MN HA" | HA-IPv6 | MN-NAI);		 */		HMAC_CTX_init(&hmac);		HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);		HMAC_Update(&hmac, (const uint8_t *) "CMIP6 MN HA", 11);		HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipv6addr, 16);		HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length);		HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);		/*		 *	Put MN-HA-CMIP6 into WiMAX-MN-hHA-MIP6-Key		 */		vp = pairfind(request->reply->vps, WIMAX2ATTR(12));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(12), PW_TYPE_OCTETS);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP6-Key");			break;		}		memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len);		vp->length = rk1_len;		/*		 *	Put MN-HA-CMIP6-SPI into WiMAX-MN-hHA-MIP6-SPI		 */		vp = pairfind(request->reply->vps, WIMAX2ATTR(13));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(13), PW_TYPE_INTEGER);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-hHA-MIP6-SPI");			break;		}		vp->vp_integer = mip_spi + 2;		break;	default:		break;		/* do nothing */	}	/*	 *	Generate FA-RK, if requested.	 *	 *	FA-RK= H(MIP-RK, "FA-RK")	 */	fa_rk = pairfind(request->reply->vps, WIMAX2ATTR(14));	if (fa_rk && (fa_rk->length == 0)) {		HMAC_CTX_init(&hmac);		HMAC_Init_ex(&hmac, mip_rk, rk_len, EVP_sha1(), NULL);				HMAC_Update(&hmac, (const uint8_t *) "FA-RK", 5);		HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);		memcpy(fa_rk->vp_octets, &mip_rk_1[0], rk1_len);		fa_rk->length = rk1_len;	}	/*	 *	Create FA-RK-SPI, which is really SPI-CMIP4, which is	 *	really MIP-SPI.  Clear?  Of course.  This is WiMAX.	 */	if (fa_rk) {		vp = pairfind(request->reply->vps, WIMAX2ATTR(61));		if (!vp) {			vp = radius_paircreate(request, &request->reply->vps,					       WIMAX2ATTR(61), PW_TYPE_INTEGER);		}		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-FA-RK-SPI");		} else {			vp->vp_integer = mip_spi;		}	}	/*	 *	Generate MN-FA = H(FA-RK, "MN FA" | FA-IP | MN-NAI)	 */	ip = pairfind(request->reply->vps, 1913);	if (fa_rk && ip && mn_nai) {		HMAC_CTX_init(&hmac);		HMAC_Init_ex(&hmac, fa_rk->vp_octets, fa_rk->length,			     EVP_sha1(), NULL);				HMAC_Update(&hmac, (const uint8_t *) "MN FA", 5);		HMAC_Update(&hmac, (const uint8_t *) &ip->vp_ipaddr, 4);		HMAC_Update(&hmac, (const uint8_t *) &mn_nai->vp_strvalue, mn_nai->length);		HMAC_Final(&hmac, &mip_rk_1[0], &rk1_len);		vp = radius_paircreate(request, &request->reply->vps,				       1910, PW_TYPE_OCTETS);		if (!vp) {			RDEBUG("WARNING: Failed creating WiMAX-MN-FA");		} else {			memcpy(vp->vp_octets, &mip_rk_1[0], rk1_len);			vp->length = rk1_len;		}	}	/*	 *	Give additional information about requests && responses	 *	 *	WiMAX-RRQ-MN-HA-SPI	 */	vp = pairfind(request->packet->vps, WIMAX2ATTR(20));	if (vp) {		RDEBUG("Client requested MN-HA key: Should use SPI to look up key from storage.");		if (!mn_nai) {			RDEBUG("WARNING: MN-NAI was not found!");		}		/*		 *	WiMAX-RRQ-HA-IP		 */		if (!pairfind(request->packet->vps, WIMAX2ATTR(18))) {			RDEBUG("WARNING: HA-IP was not found!");		}		/*		 *	WiMAX-HA-RK-Key-Requested		 */		vp = pairfind(request->packet->vps, WIMAX2ATTR(58));		if (vp && (vp->vp_integer == 1)) {			RDEBUG("Client requested HA-RK: Should use IP to look it up from storage.");		}	}	/*	 *	Wipe the context of all sensitive information.	 */	HMAC_CTX_cleanup(&hmac);	return RLM_MODULE_UPDATED;}/* *	The module name should be the only globally exported symbol. *	That is, everything else should be 'static'. * *	If the module needs to temporarily modify it's instantiation *	data, the type should be changed to RLM_TYPE_THREAD_UNSAFE. *	The server will then take care of ensuring that the module *	is single-threaded. */module_t rlm_wimax = {	RLM_MODULE_INIT,	"wimax",	RLM_TYPE_THREAD_SAFE,		/* type */	NULL,				/* instantiation */	NULL,				/* detach */	{		NULL,			/* authentication */		wimax_authorize,	/* authorization */		wimax_preacct,		/* preaccounting */		wimax_accounting,	/* accounting */		NULL,			/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		wimax_postauth 		/* post-auth */	},};

⌨️ 快捷键说明

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