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

📄 eap_tls.c

📁 RADIUS 服务器介绍 RADIUS服务器支持标准的RADIUS协议
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * eap_tls.c * * Version:     $Id: eap_tls.c,v 1.13 2003/04/04 20:06:12 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com> *//* * *  TLS Packet Format in EAP  *  --- ------ ------ -- --- * 0                   1                   2                   3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     Code      |   Identifier  |            Length             | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     Type      |     Flags     |      TLS Message Length * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |     TLS Message Length        |       TLS Data... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * */#include "eap_tls.h"/* *      Allocate a new TLS_PACKET */EAPTLS_PACKET *eaptls_alloc(void){	EAPTLS_PACKET   *rp;	if ((rp = malloc(sizeof(EAPTLS_PACKET))) == NULL) {		radlog(L_ERR, "rlm_eap_tls: out of memory");		return NULL;	}	memset(rp, 0, sizeof(EAPTLS_PACKET));	return rp;}/* *      Free EAPTLS_PACKET */void eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr){	EAPTLS_PACKET *eaptls_packet;	if (!eaptls_packet_ptr) return;	eaptls_packet = *eaptls_packet_ptr;	if (eaptls_packet == NULL) return;	if (eaptls_packet->data) {		free(eaptls_packet->data);		eaptls_packet->data = NULL;	}	free(eaptls_packet);	*eaptls_packet_ptr = NULL;}/*   The S flag is set only within the EAP-TLS start message   sent from the EAP server to the peer.*/int eaptls_start(EAP_DS *eap_ds){	EAPTLS_PACKET 	reply;	reply.code = EAPTLS_START;	reply.length = TLS_HEADER_LEN + 1/*flags*/;	reply.flags = 0x00;	reply.flags = SET_START(reply.flags);	reply.data = NULL;	reply.dlen = 0;	eaptls_compose(eap_ds, &reply);	return 1;}int eaptls_success(EAP_DS *eap_ds){	EAPTLS_PACKET	reply;	reply.code = EAPTLS_SUCCESS;	reply.length = TLS_HEADER_LEN;	reply.flags = 0x00;	reply.data = NULL;	reply.dlen = 0;	eaptls_compose(eap_ds, &reply);	return 1;}int eaptls_fail(EAP_DS *eap_ds){	EAPTLS_PACKET	reply;	reply.code = EAPTLS_FAIL;	reply.length = TLS_HEADER_LEN;	reply.flags = 0x00;	reply.data = NULL;	reply.dlen = 0;	eaptls_compose(eap_ds, &reply);	return 1;}/*   A single TLS record may be up to 16384 octets in length, but a TLS   message may span multiple TLS records, and a TLS certificate message   may in principle be as long as 16MB. *//* * Frame the Dirty data that needs to be send to the client in an EAP-Request. * We always embed the TLS-length in all EAP-TLS packets  * that we send, for easy reference purpose. * Handles fragmentation and sending the next fragment etc., */int eaptls_request(EAP_DS *eap_ds, tls_session_t *ssn){	EAPTLS_PACKET	reply;	unsigned int	size;	unsigned int 	nlen;	unsigned int 	lbit = 0;	/* This value determines whether we set (L)ength flag for 		EVERY packet we send and add corresponding 		"TLS Message Length" field.	length_flag = TRUE;		This means we include L flag and "TLS Msg Len" in EVERY		packet we send out.       	length_flag = FALSE;		This means we include L flag and "TLS Msg Len" **ONLY**		in First packet of a fragment series. We do not use 		it anywhere else.		Having L flag in every packet is prefered.	*/	if (ssn->length_flag) {		lbit = 4;	}	if (ssn->fragment == 0) {		ssn->tls_msg_len = ssn->dirty_out.used;	}	reply.code = EAPTLS_REQUEST;	reply.flags = 0x00;	/* Send data, NOT more than the FRAGMENT size */	if (ssn->dirty_out.used > ssn->offset) {		size = ssn->offset;		reply.flags = SET_MORE_FRAGMENTS(reply.flags);		/* Length MUST be included if it is the First Fragment */		if (ssn->fragment == 0) {			lbit = 4;		}		ssn->fragment = 1;	} else {		size = ssn->dirty_out.used;		ssn->fragment = 0;	}	reply.dlen = lbit + size;	reply.length = TLS_HEADER_LEN + 1/*flags*/ + reply.dlen;	reply.data = malloc(reply.dlen);	if (lbit) {		nlen = htonl(ssn->tls_msg_len);		memcpy(reply.data, &nlen, lbit);		reply.flags = SET_LENGTH_INCLUDED(reply.flags);	}	record_minus(&ssn->dirty_out, reply.data+lbit, size);	eaptls_compose(eap_ds, &reply);	free(reply.data);	reply.data = NULL;	return 1;}/* * Acknowledge received is for one of the following messages sent earlier * 1. Handshake completed Message, so now send, EAP-Success * 2. Alert Message, now send, EAP-Failure * 3. Fragment Message, now send, next Fragment * * After Success/Failure, We are done with the Session, free all the resources */eaptls_status_t eaptls_ack_handler(EAP_HANDLER *handler){	tls_session_t *tls_session;	tls_session = (tls_session_t *)handler->opaque;	if ((tls_session == NULL) || (tls_session->info.origin == 0)) {		radlog(L_ERR, "rlm_eap_tls: Unexpected ACK received");		return EAPTLS_NOOP;	}	switch (tls_session->info.content_type) {	case alert:		eaptls_fail(handler->eap_ds);		session_free(&handler->opaque);		return EAPTLS_FAIL;	case handshake:		if (tls_session->info.handshake_type == finished) {			eaptls_success(handler->eap_ds);			eaptls_gen_mppe_keys(handler->reply_vps, 					     tls_session->ssl);			session_free(&handler->opaque);			return EAPTLS_SUCCESS;		} else if (tls_session->fragment > 0) {			/* Fragmentation handler, send next fragment */			eaptls_request(handler->eap_ds, tls_session);			return EAPTLS_REQUEST;		}		/*		 * For the rest of the conditions,		 * switch over to the default section below.		 */	default:		radlog(L_ERR, "rlm_eap_tls: Invalid ACK received");		session_free(&handler->opaque);		return EAPTLS_NOOP;	}}/*   Similarly, when the EAP server receives an EAP-Response with the M   bit set, it MUST respond with an EAP-Request with EAP-Type=EAP-TLS   and no data. This serves as a fragment ACK.    In order to prevent errors in the processing of fragments, the EAP   server MUST use increment the Identifier value for each fragment ACK   contained within an EAP-Request, and the peer MUST include this   Identifier value in the subsequent fragment contained within an EAP-   Reponse. * EAP server sends an ACK when it determines there are More fragments  * to receive to make the complete TLS-record/TLS-Message */int eaptls_send_ack(EAP_DS *eap_ds){	EAPTLS_PACKET 	reply;	reply.code = EAPTLS_ACK;	reply.length = TLS_HEADER_LEN + 1/*flags*/;	reply.flags = 0x00;	reply.data = NULL;	reply.dlen = 0;	eaptls_compose(eap_ds, &reply);	return 1;}/*   The S flag is set only within the EAP-TLS start message   sent from the EAP server to the peer.   Similarly, when the EAP server receives an EAP-Response with the M   bit set, it MUST respond with an EAP-Request with EAP-Type=EAP-TLS   and no data. This serves as a fragment ACK. The EAP peer MUST wait */eaptls_status_t eaptls_verify(EAP_DS *eap_ds, EAP_DS *prev_eap_ds){	eaptls_packet_t	*eaptls_packet, *eaptls_prev = NULL;	if ((eap_ds == NULL) 					|| 		(eap_ds->response == NULL)			|| 		(eap_ds->response->code != PW_EAP_RESPONSE)	||		(eap_ds->response->length <= EAP_HEADER_LEN + 1/*EAP-Type*/)	||		(eap_ds->response->type.type != PW_EAP_TLS)) {		radlog(L_ERR, "rlm_eap_tls: corrupted data");		return EAPTLS_INVALID;	}	eaptls_packet = (eaptls_packet_t *)eap_ds->response->type.data;	if (prev_eap_ds && prev_eap_ds->response)		eaptls_prev = (eaptls_packet_t *)prev_eap_ds->response->type.data;	/*	 * check for ACK	 * 1. Find if this is a reply to the previous request sent	 * 2. If typedata[0] == NULL && length == EAP_HEADER_LEN && ALLTLSFLAGS == 0	 */	if ((eap_ds->response->length == EAP_HEADER_LEN + 2/*EAPtype+flags*/) && 		((eaptls_packet != NULL) && (eaptls_packet->flags == 0x00))) {		if (prev_eap_ds->request->id == eap_ds->response->id) {			radlog(L_INFO, "rlm_eap_tls: Received EAP-TLS ACK message");			return EAPTLS_ACK;		} else {			radlog(L_ERR, "rlm_eap_tls: Received Invalid EAP-TLS ACK message");			return EAPTLS_INVALID;

⌨️ 快捷键说明

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