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

📄 ttls.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		 *	The length does NOT include the padding, so		 *	we've got to account for it here by rounding up		 *	to the nearest 4-byte boundary.		 */		length += 0x03;		length &= ~0x03;		rad_assert(data_left >= length);		data_left -= length;		data += length - offset; /* already updated */	}	/*	 *	We got this far.  It looks OK.	 */	return first;}/* *	Convert VALUE_PAIR's to diameter attributes, and write them *	to an SSL session. * *	The ONLY VALUE_PAIR's which may be passed to this function *	are ones which can go inside of a RADIUS (i.e. diameter) *	packet.  So no server-configuration attributes, or the like. */static int vp2diameter(tls_session_t *tls_session, VALUE_PAIR *first){	/*	 *	RADIUS packets are no more than 4k in size, so if	 *	we've got more than 4k of data to write, it's very	 *	bad.	 */	uint8_t		buffer[4096];	uint8_t		*p;	uint32_t	attr;	uint32_t	length;	uint32_t	vendor;	size_t		total;	VALUE_PAIR	*vp;	p = buffer;	total = 0;	for (vp = first; vp != NULL; vp = vp->next) {		/*		 *	Too much data: die.		 */		if ((total + vp->length + 12) >= sizeof(buffer)) {			DEBUG2("  TTLS output buffer is full!");			return 0;		}		/*		 *	Hmm... we don't group multiple EAP-Messages		 *	together.  Maybe we should...		 */		/*		 *	Length is no more than 253, due to RADIUS		 *	issues.		 */		length = vp->length;		vendor = (vp->attribute >> 16) & 0xffff;		if (vendor != 0) {			attr = vp->attribute & 0xffff;			length |= (1 << 31);		} else {			attr = vp->attribute;		}		/*		 *	Hmm... set the M bit for all attributes?		 */		length |= (1 << 30);		attr = ntohl(attr);		memcpy(p, &attr, sizeof(attr));		p += 4;		total += 4;		length += 8;	/* includes 8 bytes of attr & length */		if (vendor != 0) {			length += 4; /* include 4 bytes of vendor */			length = ntohl(length);			memcpy(p, &length, sizeof(length));			p += 4;			total += 4;			vendor = ntohl(vendor);			memcpy(p, &vendor, sizeof(vendor));			p += 4;			total += 4;		} else {			length = ntohl(length);			memcpy(p, &length, sizeof(length));			p += 4;			total += 4;		}		switch (vp->type) {		case PW_TYPE_INTEGER:		case PW_TYPE_DATE:			attr = ntohl(vp->vp_integer); /* stored in host order */			memcpy(p, &attr, sizeof(attr));			length = 4;			break;		case PW_TYPE_IPADDR:			memcpy(p, &vp->vp_ipaddr, 4); /* network order */			length = 4;			break;		case PW_TYPE_STRING:		case PW_TYPE_OCTETS:		default:			memcpy(p, vp->vp_strvalue, vp->length);			length = vp->length;			break;		}		/*		 *	Skip to the end of the data.		 */		p += length;		total += length;		/*		 *	Align the data to a multiple of 4 bytes.		 */		if ((total & 0x03) != 0) {			size_t i;			length = 4 - (total & 0x03);			for (i = 0; i < length; i++) {				*p = '\0';				p++;				total++;			}		}	} /* loop over the VP's to write. */	/*	 *	Write the data in the buffer to the SSL session.	 */	if (total > 0) {#ifndef NDEBUG		size_t i;		if ((debug_flag > 2) && fr_log_fp) {			for (i = 0; i < total; i++) {				if ((i & 0x0f) == 0) fprintf(fr_log_fp, "  TTLS tunnel data out %04x: ", i);				fprintf(fr_log_fp, "%02x ", buffer[i]);				if ((i & 0x0f) == 0x0f) fprintf(fr_log_fp, "\n");			}			if ((total & 0x0f) != 0) fprintf(fr_log_fp, "\n");		}#endif		(tls_session->record_plus)(&tls_session->clean_in, buffer, total);		/*		 *	FIXME: Check the return code.		 */		tls_handshake_send(tls_session);	}	/*	 *	Everything's OK.	 */	return 1;}/* *	Use a reply packet to determine what to do. */static int process_reply(EAP_HANDLER *handler, tls_session_t *tls_session,			 REQUEST *request, RADIUS_PACKET *reply){	int rcode = RLM_MODULE_REJECT;	VALUE_PAIR *vp;	ttls_tunnel_t *t = tls_session->opaque;	handler = handler;	/* -Wunused */	/*	 *	If the response packet was Access-Accept, then	 *	we're OK.  If not, die horribly.	 *	 *	FIXME: Take MS-CHAP2-Success attribute, and	 *	tunnel it back to the client, to authenticate	 *	ourselves to the client.	 *	 *	FIXME: If we have an Access-Challenge, then	 *	the Reply-Message is tunneled back to the client.	 *	 *	FIXME: If we have an EAP-Message, then that message	 *	must be tunneled back to the client.	 *	 *	FIXME: If we have an Access-Challenge with a State	 *	attribute, then do we tunnel that to the client, or	 *	keep track of it ourselves?	 *	 *	FIXME: EAP-Messages can only start with 'identity',	 *	NOT 'eap start', so we should check for that....	 */	switch (reply->code) {	case PW_AUTHENTICATION_ACK:		DEBUG2("  TTLS: Got tunneled Access-Accept");		rcode = RLM_MODULE_OK;		/*		 *	MS-CHAP2-Success means that we do NOT return		 *	an Access-Accept, but instead tunnel that		 *	attribute to the client, and keep going with		 *	the TTLS session.  Once the client accepts		 *	our identity, it will respond with an empty		 *	packet, and we will send EAP-Success.		 */		vp = NULL;		pairmove2(&vp, &reply->vps, PW_MSCHAP2_SUCCESS);		if (vp) {			DEBUG2("  TTLS: Got MS-CHAP2-Success, tunneling it to the client in a challenge.");			rcode = RLM_MODULE_HANDLED;			t->authenticated = TRUE;			/*			 *	Delete MPPE keys & encryption policy.  We don't			 *	want these here.			 */			pairdelete(&reply->vps, ((311 << 16) | 7));			pairdelete(&reply->vps, ((311 << 16) | 8));			pairdelete(&reply->vps, ((311 << 16) | 16));			pairdelete(&reply->vps, ((311 << 16) | 17));			/*			 *	Use the tunneled reply, but not now.			 */			if (t->use_tunneled_reply) {				t->reply = reply->vps;				reply->vps = NULL;			}		} else { /* no MS-CHAP2-Success */			/*			 *	Can only have EAP-Message if there's			 *	no MS-CHAP2-Success.  (FIXME: EAP-MSCHAP?)			 *			 *	We also do NOT tunnel the EAP-Success			 *	attribute back to the client, as the client			 *	can figure it out, from the non-tunneled			 *	EAP-Success packet.			 */			pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE);			pairfree(&vp);		}		/*		 *	Handle the ACK, by tunneling any necessary reply		 *	VP's back to the client.		 */		if (vp) {			vp2diameter(tls_session, vp);			pairfree(&vp);		}		/*		 *	If we've been told to use the attributes from		 *	the reply, then do so.		 *		 *	WARNING: This may leak information about the		 *	tunneled user!		 */		if (t->use_tunneled_reply) {			pairdelete(&reply->vps, PW_PROXY_STATE);			pairadd(&request->reply->vps, reply->vps);			reply->vps = NULL;		}		break;	case PW_AUTHENTICATION_REJECT:		DEBUG2("  TTLS: Got tunneled Access-Reject");		rcode = RLM_MODULE_REJECT;		break;		/*		 *	Handle Access-Challenge, but only if we		 *	send tunneled reply data.  This is because		 *	an Access-Challenge means that we MUST tunnel		 *	a Reply-Message to the client.		 */	case PW_ACCESS_CHALLENGE:		DEBUG2("  TTLS: Got tunneled Access-Challenge");		/*		 *	Keep the State attribute, if necessary.		 *		 *	Get rid of the old State, too.		 */		pairfree(&t->state);		pairmove2(&t->state, &reply->vps, PW_STATE);		/*		 *	We should really be a bit smarter about this,		 *	and move over only those attributes which		 *	are relevant to the authentication request,		 *	but that's a lot more work, and this "dumb"		 *	method works in 99.9% of the situations.		 */		vp = NULL;		pairmove2(&vp, &reply->vps, PW_EAP_MESSAGE);		/*		 *	There MUST be a Reply-Message in the challenge,		 *	which we tunnel back to the client.		 *		 *	If there isn't one in the reply VP's, then		 *	we MUST create one, with an empty string as		 *	it's value.		 */		pairmove2(&vp, &reply->vps, PW_REPLY_MESSAGE);		/*		 *	Handle the ACK, by tunneling any necessary reply		 *	VP's back to the client.		 */		if (vp) {			vp2diameter(tls_session, vp);			pairfree(&vp);		}		rcode = RLM_MODULE_HANDLED;		break;	default:		DEBUG2("  TTLS: Unknown RADIUS packet type %d: rejecting tunneled user", reply->code);		rcode = RLM_MODULE_INVALID;		break;	}	return rcode;}/* *	Do post-proxy processing, */static int eapttls_postproxy(EAP_HANDLER *handler, void *data){	int rcode;	tls_session_t *tls_session = (tls_session_t *) data;	REQUEST *fake;	DEBUG2("  TTLS: Passing reply from proxy back into the tunnel.");	/*	 *	If there was a fake request associated with the proxied	 *	request, do more processing of it.	 */	fake = (REQUEST *) request_data_get(handler->request,					    handler->request->proxy,					    REQUEST_DATA_EAP_MSCHAP_TUNNEL_CALLBACK);	/*	 *	Do the callback, if it exists, and if it was a success.	 */	if (fake && (handler->request->proxy_reply->code == PW_AUTHENTICATION_ACK)) {		VALUE_PAIR *vp;		REQUEST *request = handler->request;		/*		 *	Terrible hacks.		 */		rad_assert(fake->packet == NULL);		fake->packet = request->proxy;		fake->packet->src_ipaddr = request->packet->src_ipaddr;		request->proxy = NULL;		rad_assert(fake->reply == NULL);		fake->reply = request->proxy_reply;		request->proxy_reply = NULL;		/*		 *	Perform a post-auth stage for the tunneled		 *	session.		 */		fake->options &= ~RAD_REQUEST_OPTION_PROXY_EAP;		rcode = rad_postauth(fake);		DEBUG2("  POST-AUTH %d", rcode);#ifndef NDEBUG		if ((debug_flag > 0) && fr_log_fp) {			fprintf(fr_log_fp, "  TTLS: Final reply from tunneled session code %d\n",			       fake->reply->code);			for (vp = fake->reply->vps; vp != NULL; vp = vp->next) {				fputc('\t', fr_log_fp);				vp_print(fr_log_fp, vp);				fputc('\n', fr_log_fp);			}		}#endif		/*		 *	Terrible hacks.		 */		request->proxy = fake->packet;		fake->packet = NULL;		request->proxy_reply = fake->reply;		fake->reply = NULL;		/*		 *	And we're done with this request.		 */		switch (rcode) {                case RLM_MODULE_FAIL:			request_free(&fake);			eaptls_fail(handler->eap_ds, 0);			return 0;			break;                default:  /* Don't Do Anything */			DEBUG2(" TTLS: Got reply %d",			       request->proxy_reply->code);			break;		}	}	request_free(&fake);	/* robust if fake == NULL */	/*	 *	Process the reply from the home server.	 */	rcode = process_reply(handler, tls_session, handler->request,

⌨️ 快捷键说明

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