/*
 * EAP server method: EAP-TNC (Trusted Network Connect)
 * Copyright (c) 2007-2010, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "eap_i.h"
#include "tncs.h"


struct eap_tnc_data {
	enum eap_tnc_state {
		START, CONTINUE, RECOMMENDATION, FRAG_ACK, WAIT_FRAG_ACK, DONE,
		FAIL
	} state;
	enum { ALLOW, ISOLATE, NO_ACCESS, NO_RECOMMENDATION } recommendation;
	struct tncs_data *tncs;
	struct wpabuf *in_buf;
	struct wpabuf *out_buf;
	size_t out_used;
	size_t fragment_size;
	unsigned int was_done:1;
	unsigned int was_fail:1;
};


/* EAP-TNC Flags */
#define EAP_TNC_FLAGS_LENGTH_INCLUDED 0x80
#define EAP_TNC_FLAGS_MORE_FRAGMENTS 0x40
#define EAP_TNC_FLAGS_START 0x20
#define EAP_TNC_VERSION_MASK 0x07

#define EAP_TNC_VERSION 1


static const char * eap_tnc_state_txt(enum eap_tnc_state state)
{
	switch (state) {
	case START:
		return "START";
	case CONTINUE:
		return "CONTINUE";
	case RECOMMENDATION:
		return "RECOMMENDATION";
	case FRAG_ACK:
		return "FRAG_ACK";
	case WAIT_FRAG_ACK:
		return "WAIT_FRAG_ACK";
	case DONE:
		return "DONE";
	case FAIL:
		return "FAIL";
	}
	return "??";
}


static void eap_tnc_set_state(struct eap_tnc_data *data,
			      enum eap_tnc_state new_state)
{
	wpa_printf(MSG_DEBUG, "EAP-TNC: %s -> %s",
		   eap_tnc_state_txt(data->state),
		   eap_tnc_state_txt(new_state));
	data->state = new_state;
}


static void * eap_tnc_init(struct eap_sm *sm)
{
	struct eap_tnc_data *data;

	data = os_zalloc(sizeof(*data));
	if (data == NULL)
		return NULL;
	eap_tnc_set_state(data, START);
	data->tncs = tncs_init();
	if (data->tncs == NULL) {
		os_free(data);
		return NULL;
	}

	data->fragment_size = sm->fragment_size > 100 ?
		sm->fragment_size - 98 : 1300;

	return data;
}


static void eap_tnc_reset(struct eap_sm *sm, void *priv)
{
	struct eap_tnc_data *data = priv;
	wpabuf_free(data->in_buf);
	wpabuf_free(data->out_buf);
	tncs_deinit(data->tncs);
	os_free(data);
}


static struct wpabuf * eap_tnc_build_start(struct eap_sm *sm,
					   struct eap_tnc_data *data, u8 id)
{
	struct wpabuf *req;

	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, 1, EAP_CODE_REQUEST,
			    id);
	if (req == NULL) {
		wpa_printf(MSG_ERROR, "EAP-TNC: Failed to allocate memory for "
			   "request");
		eap_tnc_set_state(data, FAIL);
		return NULL;
	}

	wpabuf_put_u8(req, EAP_TNC_FLAGS_START | EAP_TNC_VERSION);

	eap_tnc_set_state(data, CONTINUE);

	return req;
}


static struct wpabuf * eap_tnc_build(struct eap_sm *sm,
				     struct eap_tnc_data *data)
{
	struct wpabuf *req;
	u8 *rpos, *rpos1;
	size_t rlen;
	char *start_buf, *end_buf;
	size_t start_len, end_len;
	size_t imv_len;

	imv_len = tncs_total_send_len(data->tncs);

	start_buf = tncs_if_tnccs_start(data->tncs);
	if (start_buf == NULL)
		return NULL;
	start_len = os_strlen(start_buf);
	end_buf = tncs_if_tnccs_end();
	if (end_buf == NULL) {
		os_free(start_buf);
		return NULL;
	}
	end_len = os_strlen(end_buf);

	rlen = start_len + imv_len + end_len;
	req = wpabuf_alloc(rlen);
	if (req == NULL) {
		os_free(start_buf);
		os_free(end_buf);
		return NULL;
	}

	wpabuf_put_data(req, start_buf, start_len);
	os_free(start_buf);

	rpos1 = wpabuf_put(req, 0);
	rpos = tncs_copy_send_buf(data->tncs, rpos1);
	wpabuf_put(req, rpos - rpos1);

	wpabuf_put_data(req, end_buf, end_len);
	os_free(end_buf);

	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Request",
			  wpabuf_head(req), wpabuf_len(req));

	return req;
}


static struct wpabuf * eap_tnc_build_recommendation(struct eap_sm *sm,
						    struct eap_tnc_data *data)
{
	switch (data->recommendation) {
	case ALLOW:
		eap_tnc_set_state(data, DONE);
		break;
	case ISOLATE:
		eap_tnc_set_state(data, FAIL);
		/* TODO: support assignment to a different VLAN */
		break;
	case NO_ACCESS:
		eap_tnc_set_state(data, FAIL);
		break;
	case NO_RECOMMENDATION:
		eap_tnc_set_state(data, DONE);
		break;
	default:
		wpa_printf(MSG_DEBUG, "EAP-TNC: Unknown recommendation");
		return NULL;
	}

	return eap_tnc_build(sm, data);
}


static struct wpabuf * eap_tnc_build_frag_ack(u8 id, u8 code)
{
	struct wpabuf *msg;

	msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, 1, code, id);
	if (msg == NULL) {
		wpa_printf(MSG_ERROR, "EAP-TNC: Failed to allocate memory "
			   "for fragment ack");
		return NULL;
	}
	wpabuf_put_u8(msg, EAP_TNC_VERSION); /* Flags */

	wpa_printf(MSG_DEBUG, "EAP-TNC: Send fragment ack");

	return msg;
}


static struct wpabuf * eap_tnc_build_msg(struct eap_tnc_data *data, u8 id)
{
	struct wpabuf *req;
	u8 flags;
	size_t send_len, plen;

	wpa_printf(MSG_DEBUG, "EAP-TNC: Generating Request");

	flags = EAP_TNC_VERSION;
	send_len = wpabuf_len(data->out_buf) - data->out_used;
	if (1 + send_len > data->fragment_size) {
		send_len = data->fragment_size - 1;
		flags |= EAP_TNC_FLAGS_MORE_FRAGMENTS;
		if (data->out_used == 0) {
			flags |= EAP_TNC_FLAGS_LENGTH_INCLUDED;
			send_len -= 4;
		}
	}

	plen = 1 + send_len;
	if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED)
		plen += 4;
	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, plen,
			    EAP_CODE_REQUEST, id);
	if (req == NULL)
		return NULL;

	wpabuf_put_u8(req, flags); /* Flags */
	if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED)
		wpabuf_put_be32(req, wpabuf_len(data->out_buf));

	wpabuf_put_data(req, wpabuf_head_u8(data->out_buf) + data->out_used,
			send_len);
	data->out_used += send_len;

	if (data->out_used == wpabuf_len(data->out_buf)) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: Sending out %lu bytes "
			   "(message sent completely)",
			   (unsigned long) send_len);
		wpabuf_free(data->out_buf);
		data->out_buf = NULL;
		data->out_used = 0;
		if (data->was_fail)
			eap_tnc_set_state(data, FAIL);
		else if (data->was_done)
			eap_tnc_set_state(data, DONE);
	} else {
		wpa_printf(MSG_DEBUG, "EAP-TNC: Sending out %lu bytes "
			   "(%lu more to send)", (unsigned long) send_len,
			   (unsigned long) wpabuf_len(data->out_buf) -
			   data->out_used);
		if (data->state == FAIL)
			data->was_fail = 1;
		else if (data->state == DONE)
			data->was_done = 1;
		eap_tnc_set_state(data, WAIT_FRAG_ACK);
	}

	return req;
}


static struct wpabuf * eap_tnc_buildReq(struct eap_sm *sm, void *priv, u8 id)
{
	struct eap_tnc_data *data = priv;

	switch (data->state) {
	case START:
		tncs_init_connection(data->tncs);
		return eap_tnc_build_start(sm, data, id);
	case CONTINUE:
		if (data->out_buf == NULL) {
			data->out_buf = eap_tnc_build(sm, data);
			if (data->out_buf == NULL) {
				wpa_printf(MSG_DEBUG, "EAP-TNC: Failed to "
					   "generate message");
				return NULL;
			}
			data->out_used = 0;
		}
		return eap_tnc_build_msg(data, id);
	case RECOMMENDATION:
		if (data->out_buf == NULL) {
			data->out_buf = eap_tnc_build_recommendation(sm, data);
			if (data->out_buf == NULL) {
				wpa_printf(MSG_DEBUG, "EAP-TNC: Failed to "
					   "generate recommendation message");
				return NULL;
			}
			data->out_used = 0;
		}
		return eap_tnc_build_msg(data, id);
	case WAIT_FRAG_ACK:
		return eap_tnc_build_msg(data, id);
	case FRAG_ACK:
		return eap_tnc_build_frag_ack(id, EAP_CODE_REQUEST);
	case DONE:
	case FAIL:
		return NULL;
	}

	return NULL;
}


static Boolean eap_tnc_check(struct eap_sm *sm, void *priv,
			     struct wpabuf *respData)
{
	struct eap_tnc_data *data = priv;
	const u8 *pos;
	size_t len;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TNC, respData,
			       &len);
	if (pos == NULL) {
		wpa_printf(MSG_INFO, "EAP-TNC: Invalid frame");
		return TRUE;
	}

	if (len == 0 && data->state != WAIT_FRAG_ACK) {
		wpa_printf(MSG_INFO, "EAP-TNC: Invalid frame (empty)");
		return TRUE;
	}

	if (len == 0)
		return FALSE; /* Fragment ACK does not include flags */

	if ((*pos & EAP_TNC_VERSION_MASK) != EAP_TNC_VERSION) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: Unsupported version %d",
			   *pos & EAP_TNC_VERSION_MASK);
		return TRUE;
	}

	if (*pos & EAP_TNC_FLAGS_START) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: Peer used Start flag");
		return TRUE;
	}

	return FALSE;
}


static void tncs_process(struct eap_tnc_data *data, struct wpabuf *inbuf)
{
	enum tncs_process_res res;

	res = tncs_process_if_tnccs(data->tncs, wpabuf_head(inbuf),
				    wpabuf_len(inbuf));
	switch (res) {
	case TNCCS_RECOMMENDATION_ALLOW:
		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS allowed access");
		eap_tnc_set_state(data, RECOMMENDATION);
		data->recommendation = ALLOW;
		break;
	case TNCCS_RECOMMENDATION_NO_RECOMMENDATION:
		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS has no recommendation");
		eap_tnc_set_state(data, RECOMMENDATION);
		data->recommendation = NO_RECOMMENDATION;
		break;
	case TNCCS_RECOMMENDATION_ISOLATE:
		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS requested isolation");
		eap_tnc_set_state(data, RECOMMENDATION);
		data->recommendation = ISOLATE;
		break;
	case TNCCS_RECOMMENDATION_NO_ACCESS:
		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS rejected access");
		eap_tnc_set_state(data, RECOMMENDATION);
		data->recommendation = NO_ACCESS;
		break;
	case TNCCS_PROCESS_ERROR:
		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS processing error");
		eap_tnc_set_state(data, FAIL);
		break;
	default:
		break;
	}
}


static int eap_tnc_process_cont(struct eap_tnc_data *data,
				const u8 *buf, size_t len)
{
	/* Process continuation of a pending message */
	if (len > wpabuf_tailroom(data->in_buf)) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: Fragment overflow");
		eap_tnc_set_state(data, FAIL);
		return -1;
	}

	wpabuf_put_data(data->in_buf, buf, len);
	wpa_printf(MSG_DEBUG, "EAP-TNC: Received %lu bytes, waiting for %lu "
		   "bytes more", (unsigned long) len,
		   (unsigned long) wpabuf_tailroom(data->in_buf));

	return 0;
}


static int eap_tnc_process_fragment(struct eap_tnc_data *data,
				    u8 flags, u32 message_length,
				    const u8 *buf, size_t len)
{
	/* Process a fragment that is not the last one of the message */
	if (data->in_buf == NULL && !(flags & EAP_TNC_FLAGS_LENGTH_INCLUDED)) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: No Message Length field in a "
			   "fragmented packet");
		return -1;
	}

	if (data->in_buf == NULL) {
		/* First fragment of the message */
		data->in_buf = wpabuf_alloc(message_length);
		if (data->in_buf == NULL) {
			wpa_printf(MSG_DEBUG, "EAP-TNC: No memory for "
				   "message");
			return -1;
		}
		wpabuf_put_data(data->in_buf, buf, len);
		wpa_printf(MSG_DEBUG, "EAP-TNC: Received %lu bytes in first "
			   "fragment, waiting for %lu bytes more",
			   (unsigned long) len,
			   (unsigned long) wpabuf_tailroom(data->in_buf));
	}

	return 0;
}


static void eap_tnc_process(struct eap_sm *sm, void *priv,
			    struct wpabuf *respData)
{
	struct eap_tnc_data *data = priv;
	const u8 *pos, *end;
	size_t len;
	u8 flags;
	u32 message_length = 0;
	struct wpabuf tmpbuf;

	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TNC, respData, &len);
	if (pos == NULL)
		return; /* Should not happen; message already verified */

	end = pos + len;

	if (len == 1 && (data->state == DONE || data->state == FAIL)) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: Peer acknowledged the last "
			   "message");
		return;
	}

	if (len == 0) {
		/* fragment ack */
		flags = 0;
	} else
		flags = *pos++;

	if (flags & EAP_TNC_FLAGS_LENGTH_INCLUDED) {
		if (end - pos < 4) {
			wpa_printf(MSG_DEBUG, "EAP-TNC: Message underflow");
			eap_tnc_set_state(data, FAIL);
			return;
		}
		message_length = WPA_GET_BE32(pos);
		pos += 4;

		if (message_length < (u32) (end - pos) ||
		    message_length > 75000) {
			wpa_printf(MSG_DEBUG, "EAP-TNC: Invalid Message "
				   "Length (%d; %ld remaining in this msg)",
				   message_length, (long) (end - pos));
			eap_tnc_set_state(data, FAIL);
			return;
		}
	}
	wpa_printf(MSG_DEBUG, "EAP-TNC: Received packet: Flags 0x%x "
		   "Message Length %u", flags, message_length);

	if (data->state == WAIT_FRAG_ACK) {
		if (len > 1) {
			wpa_printf(MSG_DEBUG, "EAP-TNC: Unexpected payload "
				   "in WAIT_FRAG_ACK state");
			eap_tnc_set_state(data, FAIL);
			return;
		}
		wpa_printf(MSG_DEBUG, "EAP-TNC: Fragment acknowledged");
		eap_tnc_set_state(data, CONTINUE);
		return;
	}

	if (data->in_buf && eap_tnc_process_cont(data, pos, end - pos) < 0) {
		eap_tnc_set_state(data, FAIL);
		return;
	}
		
	if (flags & EAP_TNC_FLAGS_MORE_FRAGMENTS) {
		if (eap_tnc_process_fragment(data, flags, message_length,
					     pos, end - pos) < 0)
			eap_tnc_set_state(data, FAIL);
		else
			eap_tnc_set_state(data, FRAG_ACK);
		return;
	} else if (data->state == FRAG_ACK) {
		wpa_printf(MSG_DEBUG, "EAP-TNC: All fragments received");
		eap_tnc_set_state(data, CONTINUE);
	}

	if (data->in_buf == NULL) {
		/* Wrap unfragmented messages as wpabuf without extra copy */
		wpabuf_set(&tmpbuf, pos, end - pos);
		data->in_buf = &tmpbuf;
	}

	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Received payload",
			  wpabuf_head(data->in_buf), wpabuf_len(data->in_buf));
	tncs_process(data, data->in_buf);

	if (data->in_buf != &tmpbuf)
		wpabuf_free(data->in_buf);
	data->in_buf = NULL;
}


static Boolean eap_tnc_isDone(struct eap_sm *sm, void *priv)
{
	struct eap_tnc_data *data = priv;
	return data->state == DONE || data->state == FAIL;
}


static Boolean eap_tnc_isSuccess(struct eap_sm *sm, void *priv)
{
	struct eap_tnc_data *data = priv;
	return data->state == DONE;
}


int eap_server_tnc_register(void)
{
	struct eap_method *eap;
	int ret;

	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
				      EAP_VENDOR_IETF, EAP_TYPE_TNC, "TNC");
	if (eap == NULL)
		return -1;

	eap->init = eap_tnc_init;
	eap->reset = eap_tnc_reset;
	eap->buildReq = eap_tnc_buildReq;
	eap->check = eap_tnc_check;
	eap->process = eap_tnc_process;
	eap->isDone = eap_tnc_isDone;
	eap->isSuccess = eap_tnc_isSuccess;

	ret = eap_server_method_register(eap);
	if (ret)
		eap_server_method_free(eap);
	return ret;
}
