/*
 * EAP-TNC - TNCC (IF-IMC and IF-TNCCS)
 * Copyright (c) 2007, 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"
#ifndef CONFIG_NATIVE_WINDOWS
#include <dlfcn.h>
#endif /* CONFIG_NATIVE_WINDOWS */

#include "common.h"
#include "base64.h"
#include "common/tnc.h"
#include "tncc.h"
#include "eap_common/eap_tlv_common.h"
#include "eap_common/eap_defs.h"


#ifdef UNICODE
#define TSTR "%S"
#else /* UNICODE */
#define TSTR "%s"
#endif /* UNICODE */


#ifndef TNC_CONFIG_FILE
#define TNC_CONFIG_FILE "/etc/tnc_config"
#endif /* TNC_CONFIG_FILE */
#define TNC_WINREG_PATH TEXT("SOFTWARE\\Trusted Computing Group\\TNC\\IMCs")
#define IF_TNCCS_START \
"<?xml version=\"1.0\"?>\n" \
"<TNCCS-Batch BatchId=\"%d\" Recipient=\"TNCS\" " \
"xmlns=\"http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#\" " \
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
"xsi:schemaLocation=\"http://www.trustedcomputinggroup.org/IWG/TNC/1_0/" \
"IF_TNCCS# https://www.trustedcomputinggroup.org/XML/SCHEMA/TNCCS_1.0.xsd\">\n"
#define IF_TNCCS_END "\n</TNCCS-Batch>"

/* TNC IF-IMC */

/* IF-TNCCS-SOH - SSoH and SSoHR Attributes */
enum {
	SSOH_MS_MACHINE_INVENTORY = 1,
	SSOH_MS_QUARANTINE_STATE = 2,
	SSOH_MS_PACKET_INFO = 3,
	SSOH_MS_SYSTEMGENERATED_IDS = 4,
	SSOH_MS_MACHINENAME = 5,
	SSOH_MS_CORRELATIONID = 6,
	SSOH_MS_INSTALLED_SHVS = 7,
	SSOH_MS_MACHINE_INVENTORY_EX = 8
};

struct tnc_if_imc {
	struct tnc_if_imc *next;
	char *name;
	char *path;
	void *dlhandle; /* from dlopen() */
	TNC_IMCID imcID;
	TNC_ConnectionID connectionID;
	TNC_MessageTypeList supported_types;
	size_t num_supported_types;
	u8 *imc_send;
	size_t imc_send_len;

	/* Functions implemented by IMCs (with TNC_IMC_ prefix) */
	TNC_Result (*Initialize)(
		TNC_IMCID imcID,
		TNC_Version minVersion,
		TNC_Version maxVersion,
		TNC_Version *pOutActualVersion);
	TNC_Result (*NotifyConnectionChange)(
		TNC_IMCID imcID,
		TNC_ConnectionID connectionID,
		TNC_ConnectionState newState);
	TNC_Result (*BeginHandshake)(
		TNC_IMCID imcID,
		TNC_ConnectionID connectionID);
	TNC_Result (*ReceiveMessage)(
		TNC_IMCID imcID,
		TNC_ConnectionID connectionID,
		TNC_BufferReference messageBuffer,
		TNC_UInt32 messageLength,
		TNC_MessageType messageType);
	TNC_Result (*BatchEnding)(
		TNC_IMCID imcID,
		TNC_ConnectionID connectionID);
	TNC_Result (*Terminate)(TNC_IMCID imcID);
	TNC_Result (*ProvideBindFunction)(
		TNC_IMCID imcID,
		TNC_TNCC_BindFunctionPointer bindFunction);
};

struct tncc_data {
	struct tnc_if_imc *imc;
	unsigned int last_batchid;
};

#define TNC_MAX_IMC_ID 10
static struct tnc_if_imc *tnc_imc[TNC_MAX_IMC_ID] = { NULL };


/* TNCC functions that IMCs can call */

static TNC_Result TNC_TNCC_ReportMessageTypes(
	TNC_IMCID imcID,
	TNC_MessageTypeList supportedTypes,
	TNC_UInt32 typeCount)
{
	TNC_UInt32 i;
	struct tnc_if_imc *imc;

	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCC_ReportMessageTypes(imcID=%lu "
		   "typeCount=%lu)",
		   (unsigned long) imcID, (unsigned long) typeCount);

	for (i = 0; i < typeCount; i++) {
		wpa_printf(MSG_DEBUG, "TNC: supportedTypes[%lu] = %lu",
			   i, supportedTypes[i]);
	}

	if (imcID >= TNC_MAX_IMC_ID || tnc_imc[imcID] == NULL)
		return TNC_RESULT_INVALID_PARAMETER;

	imc = tnc_imc[imcID];
	os_free(imc->supported_types);
	imc->supported_types = os_memdup(supportedTypes,
					 typeCount * sizeof(TNC_MessageType));
	if (imc->supported_types == NULL)
		return TNC_RESULT_FATAL;
	imc->num_supported_types = typeCount;

	return TNC_RESULT_SUCCESS;
}


static TNC_Result TNC_TNCC_SendMessage(
	TNC_IMCID imcID,
	TNC_ConnectionID connectionID,
	TNC_BufferReference message,
	TNC_UInt32 messageLength,
	TNC_MessageType messageType)
{
	struct tnc_if_imc *imc;
	char *b64;
	size_t b64len;

	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCC_SendMessage(imcID=%lu "
		   "connectionID=%lu messageType=%lu)",
		   imcID, connectionID, messageType);
	wpa_hexdump_ascii(MSG_DEBUG, "TNC: TNC_TNCC_SendMessage",
			  message, messageLength);

	if (imcID >= TNC_MAX_IMC_ID || tnc_imc[imcID] == NULL)
		return TNC_RESULT_INVALID_PARAMETER;

	b64 = base64_encode(message, messageLength, &b64len);
	if (b64 == NULL)
		return TNC_RESULT_FATAL;

	imc = tnc_imc[imcID];
	os_free(imc->imc_send);
	imc->imc_send_len = 0;
	imc->imc_send = os_zalloc(b64len + 100);
	if (imc->imc_send == NULL) {
		os_free(b64);
		return TNC_RESULT_OTHER;
	}

	imc->imc_send_len =
		os_snprintf((char *) imc->imc_send, b64len + 100,
			    "<IMC-IMV-Message><Type>%08X</Type>"
			    "<Base64>%s</Base64></IMC-IMV-Message>",
			    (unsigned int) messageType, b64);

	os_free(b64);

	return TNC_RESULT_SUCCESS;
}


static TNC_Result TNC_TNCC_RequestHandshakeRetry(
	TNC_IMCID imcID,
	TNC_ConnectionID connectionID,
	TNC_RetryReason reason)
{
	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCC_RequestHandshakeRetry");

	if (imcID >= TNC_MAX_IMC_ID || tnc_imc[imcID] == NULL)
		return TNC_RESULT_INVALID_PARAMETER;

	/*
	 * TODO: trigger a call to eapol_sm_request_reauth(). This would
	 * require that the IMC continues to be loaded in memory afer
	 * authentication..
	 */

	return TNC_RESULT_SUCCESS;
}


static TNC_Result TNC_9048_LogMessage(TNC_IMCID imcID, TNC_UInt32 severity,
				      const char *message)
{
	wpa_printf(MSG_DEBUG, "TNC: TNC_9048_LogMessage(imcID=%lu "
		   "severity==%lu message='%s')",
		   imcID, severity, message);
	return TNC_RESULT_SUCCESS;
}


static TNC_Result TNC_9048_UserMessage(TNC_IMCID imcID,
				       TNC_ConnectionID connectionID,
				       const char *message)
{
	wpa_printf(MSG_DEBUG, "TNC: TNC_9048_UserMessage(imcID=%lu "
		   "connectionID==%lu message='%s')",
		   imcID, connectionID, message);
	return TNC_RESULT_SUCCESS;
}


static TNC_Result TNC_TNCC_BindFunction(
	TNC_IMCID imcID,
	char *functionName,
	void **pOutfunctionPointer)
{
	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCC_BindFunction(imcID=%lu, "
		   "functionName='%s')", (unsigned long) imcID, functionName);

	if (imcID >= TNC_MAX_IMC_ID || tnc_imc[imcID] == NULL)
		return TNC_RESULT_INVALID_PARAMETER;

	if (pOutfunctionPointer == NULL)
		return TNC_RESULT_INVALID_PARAMETER;

	if (os_strcmp(functionName, "TNC_TNCC_ReportMessageTypes") == 0)
		*pOutfunctionPointer = TNC_TNCC_ReportMessageTypes;
	else if (os_strcmp(functionName, "TNC_TNCC_SendMessage") == 0)
		*pOutfunctionPointer = TNC_TNCC_SendMessage;
	else if (os_strcmp(functionName, "TNC_TNCC_RequestHandshakeRetry") ==
		 0)
		*pOutfunctionPointer = TNC_TNCC_RequestHandshakeRetry;
	else if (os_strcmp(functionName, "TNC_9048_LogMessage") == 0)
		*pOutfunctionPointer = TNC_9048_LogMessage;
	else if (os_strcmp(functionName, "TNC_9048_UserMessage") == 0)
		*pOutfunctionPointer = TNC_9048_UserMessage;
	else
		*pOutfunctionPointer = NULL;

	return TNC_RESULT_SUCCESS;
}


static void * tncc_get_sym(void *handle, char *func)
{
	void *fptr;

#ifdef CONFIG_NATIVE_WINDOWS
#ifdef _WIN32_WCE
	fptr = GetProcAddressA(handle, func);
#else /* _WIN32_WCE */
	fptr = GetProcAddress(handle, func);
#endif /* _WIN32_WCE */
#else /* CONFIG_NATIVE_WINDOWS */
	fptr = dlsym(handle, func);
#endif /* CONFIG_NATIVE_WINDOWS */

	return fptr;
}


static int tncc_imc_resolve_funcs(struct tnc_if_imc *imc)
{
	void *handle = imc->dlhandle;

	/* Mandatory IMC functions */
	imc->Initialize = tncc_get_sym(handle, "TNC_IMC_Initialize");
	if (imc->Initialize == NULL) {
		wpa_printf(MSG_ERROR, "TNC: IMC does not export "
			   "TNC_IMC_Initialize");
		return -1;
	}

	imc->BeginHandshake = tncc_get_sym(handle, "TNC_IMC_BeginHandshake");
	if (imc->BeginHandshake == NULL) {
		wpa_printf(MSG_ERROR, "TNC: IMC does not export "
			   "TNC_IMC_BeginHandshake");
		return -1;
	}

	imc->ProvideBindFunction =
		tncc_get_sym(handle, "TNC_IMC_ProvideBindFunction");
	if (imc->ProvideBindFunction == NULL) {
		wpa_printf(MSG_ERROR, "TNC: IMC does not export "
			   "TNC_IMC_ProvideBindFunction");
		return -1;
	}

	/* Optional IMC functions */
	imc->NotifyConnectionChange =
		tncc_get_sym(handle, "TNC_IMC_NotifyConnectionChange");
	imc->ReceiveMessage = tncc_get_sym(handle, "TNC_IMC_ReceiveMessage");
	imc->BatchEnding = tncc_get_sym(handle, "TNC_IMC_BatchEnding");
	imc->Terminate = tncc_get_sym(handle, "TNC_IMC_Terminate");

	return 0;
}


static int tncc_imc_initialize(struct tnc_if_imc *imc)
{
	TNC_Result res;
	TNC_Version imc_ver;

	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMC_Initialize for IMC '%s'",
		   imc->name);
	res = imc->Initialize(imc->imcID, TNC_IFIMC_VERSION_1,
			      TNC_IFIMC_VERSION_1, &imc_ver);
	wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_Initialize: res=%lu imc_ver=%lu",
		   (unsigned long) res, (unsigned long) imc_ver);

	return res == TNC_RESULT_SUCCESS ? 0 : -1;
}


static int tncc_imc_terminate(struct tnc_if_imc *imc)
{
	TNC_Result res;

	if (imc->Terminate == NULL)
		return 0;

	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMC_Terminate for IMC '%s'",
		   imc->name);
	res = imc->Terminate(imc->imcID);
	wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_Terminate: %lu",
		   (unsigned long) res);

	return res == TNC_RESULT_SUCCESS ? 0 : -1;
}


static int tncc_imc_provide_bind_function(struct tnc_if_imc *imc)
{
	TNC_Result res;

	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMC_ProvideBindFunction for "
		   "IMC '%s'", imc->name);
	res = imc->ProvideBindFunction(imc->imcID, TNC_TNCC_BindFunction);
	wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_ProvideBindFunction: res=%lu",
		   (unsigned long) res);

	return res == TNC_RESULT_SUCCESS ? 0 : -1;
}


static int tncc_imc_notify_connection_change(struct tnc_if_imc *imc,
					     TNC_ConnectionState state)
{
	TNC_Result res;

	if (imc->NotifyConnectionChange == NULL)
		return 0;

	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMC_NotifyConnectionChange(%d)"
		   " for IMC '%s'", (int) state, imc->name);
	res = imc->NotifyConnectionChange(imc->imcID, imc->connectionID,
					  state);
	wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_NotifyConnectionChange: %lu",
		   (unsigned long) res);

	return res == TNC_RESULT_SUCCESS ? 0 : -1;
}


static int tncc_imc_begin_handshake(struct tnc_if_imc *imc)
{
	TNC_Result res;

	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMC_BeginHandshake for IMC "
		   "'%s'", imc->name);
	res = imc->BeginHandshake(imc->imcID, imc->connectionID);
	wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_BeginHandshake: %lu",
		   (unsigned long) res);

	return res == TNC_RESULT_SUCCESS ? 0 : -1;
}


static int tncc_load_imc(struct tnc_if_imc *imc)
{
	if (imc->path == NULL) {
		wpa_printf(MSG_DEBUG, "TNC: No IMC configured");
		return -1;
	}

	wpa_printf(MSG_DEBUG, "TNC: Opening IMC: %s (%s)",
		   imc->name, imc->path);
#ifdef CONFIG_NATIVE_WINDOWS
#ifdef UNICODE
	{
		TCHAR *lib = wpa_strdup_tchar(imc->path);
		if (lib == NULL)
			return -1;
		imc->dlhandle = LoadLibrary(lib);
		os_free(lib);
	}
#else /* UNICODE */
	imc->dlhandle = LoadLibrary(imc->path);
#endif /* UNICODE */
	if (imc->dlhandle == NULL) {
		wpa_printf(MSG_ERROR, "TNC: Failed to open IMC '%s' (%s): %d",
			   imc->name, imc->path, (int) GetLastError());
		return -1;
	}
#else /* CONFIG_NATIVE_WINDOWS */
	imc->dlhandle = dlopen(imc->path, RTLD_LAZY);
	if (imc->dlhandle == NULL) {
		wpa_printf(MSG_ERROR, "TNC: Failed to open IMC '%s' (%s): %s",
			   imc->name, imc->path, dlerror());
		return -1;
	}
#endif /* CONFIG_NATIVE_WINDOWS */

	if (tncc_imc_resolve_funcs(imc) < 0) {
		wpa_printf(MSG_ERROR, "TNC: Failed to resolve IMC functions");
		return -1;
	}

	if (tncc_imc_initialize(imc) < 0 ||
	    tncc_imc_provide_bind_function(imc) < 0) {
		wpa_printf(MSG_ERROR, "TNC: Failed to initialize IMC");
		return -1;
	}

	return 0;
}


static void tncc_unload_imc(struct tnc_if_imc *imc)
{
	tncc_imc_terminate(imc);
	tnc_imc[imc->imcID] = NULL;

	if (imc->dlhandle) {
#ifdef CONFIG_NATIVE_WINDOWS
		FreeLibrary(imc->dlhandle);
#else /* CONFIG_NATIVE_WINDOWS */
		dlclose(imc->dlhandle);
#endif /* CONFIG_NATIVE_WINDOWS */
	}
	os_free(imc->name);
	os_free(imc->path);
	os_free(imc->supported_types);
	os_free(imc->imc_send);
}


static int tncc_supported_type(struct tnc_if_imc *imc, unsigned int type)
{
	size_t i;
	unsigned int vendor, subtype;

	if (imc == NULL || imc->supported_types == NULL)
		return 0;

	vendor = type >> 8;
	subtype = type & 0xff;

	for (i = 0; i < imc->num_supported_types; i++) {
		unsigned int svendor, ssubtype;
		svendor = imc->supported_types[i] >> 8;
		ssubtype = imc->supported_types[i] & 0xff;
		if ((vendor == svendor || svendor == TNC_VENDORID_ANY) &&
		    (subtype == ssubtype || ssubtype == TNC_SUBTYPE_ANY))
			return 1;
	}

	return 0;
}


static void tncc_send_to_imcs(struct tncc_data *tncc, unsigned int type,
			      const u8 *msg, size_t len)
{
	struct tnc_if_imc *imc;
	TNC_Result res;

	wpa_hexdump_ascii(MSG_MSGDUMP, "TNC: Message to IMC(s)", msg, len);

	for (imc = tncc->imc; imc; imc = imc->next) {
		if (imc->ReceiveMessage == NULL ||
		    !tncc_supported_type(imc, type))
			continue;

		wpa_printf(MSG_DEBUG, "TNC: Call ReceiveMessage for IMC '%s'",
			   imc->name);
		res = imc->ReceiveMessage(imc->imcID, imc->connectionID,
					  (TNC_BufferReference) msg, len,
					  type);
		wpa_printf(MSG_DEBUG, "TNC: ReceiveMessage: %lu",
			   (unsigned long) res);
	}
}


void tncc_init_connection(struct tncc_data *tncc)
{
	struct tnc_if_imc *imc;

	for (imc = tncc->imc; imc; imc = imc->next) {
		tncc_imc_notify_connection_change(
			imc, TNC_CONNECTION_STATE_CREATE);
		tncc_imc_notify_connection_change(
			imc, TNC_CONNECTION_STATE_HANDSHAKE);

		os_free(imc->imc_send);
		imc->imc_send = NULL;
		imc->imc_send_len = 0;

		tncc_imc_begin_handshake(imc);
	}
}


size_t tncc_total_send_len(struct tncc_data *tncc)
{
	struct tnc_if_imc *imc;

	size_t len = 0;
	for (imc = tncc->imc; imc; imc = imc->next)
		len += imc->imc_send_len;
	return len;
}


u8 * tncc_copy_send_buf(struct tncc_data *tncc, u8 *pos)
{
	struct tnc_if_imc *imc;

	for (imc = tncc->imc; imc; imc = imc->next) {
		if (imc->imc_send == NULL)
			continue;

		os_memcpy(pos, imc->imc_send, imc->imc_send_len);
		pos += imc->imc_send_len;
		os_free(imc->imc_send);
		imc->imc_send = NULL;
		imc->imc_send_len = 0;
	}

	return pos;
}


char * tncc_if_tnccs_start(struct tncc_data *tncc)
{
	char *buf = os_malloc(1000);
	if (buf == NULL)
		return NULL;
	tncc->last_batchid++;
	os_snprintf(buf, 1000, IF_TNCCS_START, tncc->last_batchid);
	return buf;
}


char * tncc_if_tnccs_end(void)
{
	char *buf = os_malloc(100);
	if (buf == NULL)
		return NULL;
	os_snprintf(buf, 100, IF_TNCCS_END);
	return buf;
}


static void tncc_notify_recommendation(struct tncc_data *tncc,
				       enum tncc_process_res res)
{
	TNC_ConnectionState state;
	struct tnc_if_imc *imc;

	switch (res) {
	case TNCCS_RECOMMENDATION_ALLOW:
		state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
		break;
	case TNCCS_RECOMMENDATION_NONE:
		state = TNC_CONNECTION_STATE_ACCESS_NONE;
		break;
	case TNCCS_RECOMMENDATION_ISOLATE:
		state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
		break;
	default:
		state = TNC_CONNECTION_STATE_ACCESS_NONE;
		break;
	}

	for (imc = tncc->imc; imc; imc = imc->next)
		tncc_imc_notify_connection_change(imc, state);
}


static int tncc_get_type(char *start, unsigned int *type)
{
	char *pos = os_strstr(start, "<Type>");
	if (pos == NULL)
		return -1;
	pos += 6;
	*type = strtoul(pos, NULL, 16);
	return 0;
}


static unsigned char * tncc_get_base64(char *start, size_t *decoded_len)
{
	char *pos, *pos2;
	unsigned char *decoded;

	pos = os_strstr(start, "<Base64>");
	if (pos == NULL)
		return NULL;

	pos += 8;
	pos2 = os_strstr(pos, "</Base64>");
	if (pos2 == NULL)
		return NULL;
	*pos2 = '\0';

	decoded = base64_decode(pos, os_strlen(pos), decoded_len);
	*pos2 = '<';
	if (decoded == NULL) {
		wpa_printf(MSG_DEBUG, "TNC: Failed to decode Base64 data");
	}

	return decoded;
}


static enum tncc_process_res tncc_get_recommendation(char *start)
{
	char *pos, *pos2, saved;
	int recom;

	pos = os_strstr(start, "<TNCCS-Recommendation ");
	if (pos == NULL)
		return TNCCS_RECOMMENDATION_ERROR;

	pos += 21;
	pos = os_strstr(pos, " type=");
	if (pos == NULL)
		return TNCCS_RECOMMENDATION_ERROR;
	pos += 6;

	if (*pos == '"')
		pos++;

	pos2 = pos;
	while (*pos2 != '\0' && *pos2 != '"' && *pos2 != '>')
		pos2++;

	if (*pos2 == '\0')
		return TNCCS_RECOMMENDATION_ERROR;

	saved = *pos2;
	*pos2 = '\0';
	wpa_printf(MSG_DEBUG, "TNC: TNCCS-Recommendation: '%s'", pos);

	recom = TNCCS_RECOMMENDATION_ERROR;
	if (os_strcmp(pos, "allow") == 0)
		recom = TNCCS_RECOMMENDATION_ALLOW;
	else if (os_strcmp(pos, "none") == 0)
		recom = TNCCS_RECOMMENDATION_NONE;
	else if (os_strcmp(pos, "isolate") == 0)
		recom = TNCCS_RECOMMENDATION_ISOLATE;

	*pos2 = saved;

	return recom;
}


enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
					    const u8 *msg, size_t len)
{
	char *buf, *start, *end, *pos, *pos2, *payload;
	unsigned int batch_id;
	unsigned char *decoded;
	size_t decoded_len;
	enum tncc_process_res res = TNCCS_PROCESS_OK_NO_RECOMMENDATION;
	int recommendation_msg = 0;

	wpa_hexdump_ascii(MSG_MSGDUMP, "TNC: Received IF-TNCCS message",
			  msg, len);
	buf = dup_binstr(msg, len);
	if (buf == NULL)
		return TNCCS_PROCESS_ERROR;

	start = os_strstr(buf, "<TNCCS-Batch ");
	end = os_strstr(buf, "</TNCCS-Batch>");
	if (start == NULL || end == NULL || start > end) {
		os_free(buf);
		return TNCCS_PROCESS_ERROR;
	}

	start += 13;
	while (*start == ' ')
		start++;
	*end = '\0';

	pos = os_strstr(start, "BatchId=");
	if (pos == NULL) {
		os_free(buf);
		return TNCCS_PROCESS_ERROR;
	}

	pos += 8;
	if (*pos == '"')
		pos++;
	batch_id = atoi(pos);
	wpa_printf(MSG_DEBUG, "TNC: Received IF-TNCCS BatchId=%u",
		   batch_id);
	if (batch_id != tncc->last_batchid + 1) {
		wpa_printf(MSG_DEBUG, "TNC: Unexpected IF-TNCCS BatchId "
			   "%u (expected %u)",
			   batch_id, tncc->last_batchid + 1);
		os_free(buf);
		return TNCCS_PROCESS_ERROR;
	}
	tncc->last_batchid = batch_id;

	while (*pos != '\0' && *pos != '>')
		pos++;
	if (*pos == '\0') {
		os_free(buf);
		return TNCCS_PROCESS_ERROR;
	}
	pos++;
	payload = start;

	/*
	 * <IMC-IMV-Message>
	 * <Type>01234567</Type>
	 * <Base64>foo==</Base64>
	 * </IMC-IMV-Message>
	 */

	while (*start) {
		char *endpos;
		unsigned int type;

		pos = os_strstr(start, "<IMC-IMV-Message>");
		if (pos == NULL)
			break;
		start = pos + 17;
		end = os_strstr(start, "</IMC-IMV-Message>");
		if (end == NULL)
			break;
		*end = '\0';
		endpos = end;
		end += 18;

		if (tncc_get_type(start, &type) < 0) {
			*endpos = '<';
			start = end;
			continue;
		}
		wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type);

		decoded = tncc_get_base64(start, &decoded_len);
		if (decoded == NULL) {
			*endpos = '<';
			start = end;
			continue;
		}

		tncc_send_to_imcs(tncc, type, decoded, decoded_len);

		os_free(decoded);

		start = end;
	}

	/*
	 * <TNCC-TNCS-Message>
	 * <Type>01234567</Type>
	 * <XML><TNCCS-Foo type="foo"></TNCCS-Foo></XML>
	 * <Base64>foo==</Base64>
	 * </TNCC-TNCS-Message>
	 */

	start = payload;
	while (*start) {
		unsigned int type;
		char *xml, *xmlend, *endpos;

		pos = os_strstr(start, "<TNCC-TNCS-Message>");
		if (pos == NULL)
			break;
		start = pos + 19;
		end = os_strstr(start, "</TNCC-TNCS-Message>");
		if (end == NULL)
			break;
		*end = '\0';
		endpos = end;
		end += 20;

		if (tncc_get_type(start, &type) < 0) {
			*endpos = '<';
			start = end;
			continue;
		}
		wpa_printf(MSG_DEBUG, "TNC: TNCC-TNCS-Message Type 0x%x",
			   type);

		/* Base64 OR XML */
		decoded = NULL;
		xml = NULL;
		xmlend = NULL;
		pos = os_strstr(start, "<XML>");
		if (pos) {
			pos += 5;
			pos2 = os_strstr(pos, "</XML>");
			if (pos2 == NULL) {
				*endpos = '<';
				start = end;
				continue;
			}
			xmlend = pos2;
			xml = pos;
		} else {
			decoded = tncc_get_base64(start, &decoded_len);
			if (decoded == NULL) {
				*endpos = '<';
				start = end;
				continue;
			}
		}

		if (decoded) {
			wpa_hexdump_ascii(MSG_MSGDUMP,
					  "TNC: TNCC-TNCS-Message Base64",
					  decoded, decoded_len);
			os_free(decoded);
		}

		if (xml) {
			wpa_hexdump_ascii(MSG_MSGDUMP,
					  "TNC: TNCC-TNCS-Message XML",
					  (unsigned char *) xml,
					  xmlend - xml);
		}

		if (type == TNC_TNCCS_RECOMMENDATION && xml) {
			/*
			 * <TNCCS-Recommendation type="allow">
			 * </TNCCS-Recommendation>
			 */
			*xmlend = '\0';
			res = tncc_get_recommendation(xml);
			*xmlend = '<';
			recommendation_msg = 1;
		}

		start = end;
	}

	os_free(buf);

	if (recommendation_msg)
		tncc_notify_recommendation(tncc, res);

	return res;
}


#ifdef CONFIG_NATIVE_WINDOWS
static int tncc_read_config_reg(struct tncc_data *tncc, HKEY hive)
{
	HKEY hk, hk2;
	LONG ret;
	DWORD i;
	struct tnc_if_imc *imc, *last;
	int j;

	last = tncc->imc;
	while (last && last->next)
		last = last->next;

	ret = RegOpenKeyEx(hive, TNC_WINREG_PATH, 0, KEY_ENUMERATE_SUB_KEYS,
			   &hk);
	if (ret != ERROR_SUCCESS)
		return 0;

	for (i = 0; ; i++) {
		TCHAR name[255], *val;
		DWORD namelen, buflen;

		namelen = 255;
		ret = RegEnumKeyEx(hk, i, name, &namelen, NULL, NULL, NULL,
				   NULL);

		if (ret == ERROR_NO_MORE_ITEMS)
			break;

		if (ret != ERROR_SUCCESS) {
			wpa_printf(MSG_DEBUG, "TNC: RegEnumKeyEx failed: 0x%x",
				   (unsigned int) ret);
			break;
		}

		if (namelen >= 255)
			namelen = 255 - 1;
		name[namelen] = '\0';

		wpa_printf(MSG_DEBUG, "TNC: IMC '" TSTR "'", name);

		ret = RegOpenKeyEx(hk, name, 0, KEY_QUERY_VALUE, &hk2);
		if (ret != ERROR_SUCCESS) {
			wpa_printf(MSG_DEBUG, "Could not open IMC key '" TSTR
				   "'", name);
			continue;
		}

		ret = RegQueryValueEx(hk2, TEXT("Path"), NULL, NULL, NULL,
				      &buflen);
		if (ret != ERROR_SUCCESS) {
			wpa_printf(MSG_DEBUG, "TNC: Could not read Path from "
				   "IMC key '" TSTR "'", name);
			RegCloseKey(hk2);
			continue;
		}

		val = os_malloc(buflen);
		if (val == NULL) {
			RegCloseKey(hk2);
			continue;
		}

		ret = RegQueryValueEx(hk2, TEXT("Path"), NULL, NULL,
				      (LPBYTE) val, &buflen);
		if (ret != ERROR_SUCCESS) {
			os_free(val);
			RegCloseKey(hk2);
			continue;
		}

		RegCloseKey(hk2);

		wpa_unicode2ascii_inplace(val);
		wpa_printf(MSG_DEBUG, "TNC: IMC Path '%s'", (char *) val);

		for (j = 0; j < TNC_MAX_IMC_ID; j++) {
			if (tnc_imc[j] == NULL)
				break;
		}
		if (j >= TNC_MAX_IMC_ID) {
			wpa_printf(MSG_DEBUG, "TNC: Too many IMCs");
			os_free(val);
			continue;
		}

		imc = os_zalloc(sizeof(*imc));
		if (imc == NULL) {
			os_free(val);
			break;
		}

		imc->imcID = j;

		wpa_unicode2ascii_inplace(name);
		imc->name = os_strdup((char *) name);
		imc->path = os_strdup((char *) val);

		os_free(val);

		if (last == NULL)
			tncc->imc = imc;
		else
			last->next = imc;
		last = imc;

		tnc_imc[imc->imcID] = imc;
	}

	RegCloseKey(hk);

	return 0;
}


static int tncc_read_config(struct tncc_data *tncc)
{
	if (tncc_read_config_reg(tncc, HKEY_LOCAL_MACHINE) < 0 ||
	    tncc_read_config_reg(tncc, HKEY_CURRENT_USER) < 0)
		return -1;
	return 0;
}

#else /* CONFIG_NATIVE_WINDOWS */

static struct tnc_if_imc * tncc_parse_imc(char *start, char *end, int *error)
{
	struct tnc_if_imc *imc;
	char *pos, *pos2;
	int i;

	for (i = 0; i < TNC_MAX_IMC_ID; i++) {
		if (tnc_imc[i] == NULL)
			break;
	}
	if (i >= TNC_MAX_IMC_ID) {
		wpa_printf(MSG_DEBUG, "TNC: Too many IMCs");
		return NULL;
	}

	imc = os_zalloc(sizeof(*imc));
	if (imc == NULL) {
		*error = 1;
		return NULL;
	}

	imc->imcID = i;

	pos = start;
	wpa_printf(MSG_DEBUG, "TNC: Configured IMC: %s", pos);
	if (pos + 1 >= end || *pos != '"') {
		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "
			   "(no starting quotation mark)", start);
		os_free(imc);
		return NULL;
	}

	pos++;
	pos2 = pos;
	while (pos2 < end && *pos2 != '"')
		pos2++;
	if (pos2 >= end) {
		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "
			   "(no ending quotation mark)", start);
		os_free(imc);
		return NULL;
	}
	*pos2 = '\0';
	wpa_printf(MSG_DEBUG, "TNC: Name: '%s'", pos);
	imc->name = os_strdup(pos);

	pos = pos2 + 1;
	if (pos >= end || *pos != ' ') {
		wpa_printf(MSG_ERROR, "TNC: Ignoring invalid IMC line '%s' "
			   "(no space after name)", start);
		os_free(imc->name);
		os_free(imc);
		return NULL;
	}

	pos++;
	wpa_printf(MSG_DEBUG, "TNC: IMC file: '%s'", pos);
	imc->path = os_strdup(pos);
	tnc_imc[imc->imcID] = imc;

	return imc;
}


static int tncc_read_config(struct tncc_data *tncc)
{
	char *config, *end, *pos, *line_end;
	size_t config_len;
	struct tnc_if_imc *imc, *last;

	last = NULL;

	config = os_readfile(TNC_CONFIG_FILE, &config_len);
	if (config == NULL) {
		wpa_printf(MSG_ERROR, "TNC: Could not open TNC configuration "
			   "file '%s'", TNC_CONFIG_FILE);
		return -1;
	}

	end = config + config_len;
	for (pos = config; pos < end; pos = line_end + 1) {
		line_end = pos;
		while (*line_end != '\n' && *line_end != '\r' &&
		       line_end < end)
			line_end++;
		*line_end = '\0';

		if (os_strncmp(pos, "IMC ", 4) == 0) {
			int error = 0;

			imc = tncc_parse_imc(pos + 4, line_end, &error);
			if (error) {
				os_free(config);
				return -1;
			}
			if (imc) {
				if (last == NULL)
					tncc->imc = imc;
				else
					last->next = imc;
				last = imc;
			}
		}
	}

	os_free(config);

	return 0;
}

#endif /* CONFIG_NATIVE_WINDOWS */


struct tncc_data * tncc_init(void)
{
	struct tncc_data *tncc;
	struct tnc_if_imc *imc;

	tncc = os_zalloc(sizeof(*tncc));
	if (tncc == NULL)
		return NULL;

	/* TODO:
	 * move loading and Initialize() to a location that is not
	 *    re-initialized for every EAP-TNC session (?)
	 */

	if (tncc_read_config(tncc) < 0) {
		wpa_printf(MSG_ERROR, "TNC: Failed to read TNC configuration");
		goto failed;
	}

	for (imc = tncc->imc; imc; imc = imc->next) {
		if (tncc_load_imc(imc)) {
			wpa_printf(MSG_ERROR, "TNC: Failed to load IMC '%s'",
				   imc->name);
			goto failed;
		}
	}

	return tncc;

failed:
	tncc_deinit(tncc);
	return NULL;
}


void tncc_deinit(struct tncc_data *tncc)
{
	struct tnc_if_imc *imc, *prev;

	imc = tncc->imc;
	while (imc) {
		tncc_unload_imc(imc);

		prev = imc;
		imc = imc->next;
		os_free(prev);
	}

	os_free(tncc);
}


static struct wpabuf * tncc_build_soh(int ver)
{
	struct wpabuf *buf;
	u8 *tlv_len, *tlv_len2, *outer_len, *inner_len, *ssoh_len, *end;
	u8 correlation_id[24];
	/* TODO: get correct name */
	char *machinename = "wpa_supplicant@w1.fi";

	if (os_get_random(correlation_id, sizeof(correlation_id)))
		return NULL;
	wpa_hexdump(MSG_DEBUG, "TNC: SoH Correlation ID",
		    correlation_id, sizeof(correlation_id));

	buf = wpabuf_alloc(200);
	if (buf == NULL)
		return NULL;

	/* Vendor-Specific TLV (Microsoft) - SoH */
	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* TLV Type */
	tlv_len = wpabuf_put(buf, 2); /* Length */
	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* Vendor_Id */
	wpabuf_put_be16(buf, 0x01); /* TLV Type - SoH TLV */
	tlv_len2 = wpabuf_put(buf, 2); /* Length */

	/* SoH Header */
	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV); /* Outer Type */
	outer_len = wpabuf_put(buf, 2);
	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */
	wpabuf_put_be16(buf, ver); /* Inner Type */
	inner_len = wpabuf_put(buf, 2);

	if (ver == 2) {
		/* SoH Mode Sub-Header */
		/* Outer Type */
		wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV);
		wpabuf_put_be16(buf, 4 + 24 + 1 + 1); /* Length */
		wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */
		/* Value: */
		wpabuf_put_data(buf, correlation_id, sizeof(correlation_id));
		wpabuf_put_u8(buf, 0x01); /* Intent Flag - Request */
		wpabuf_put_u8(buf, 0x00); /* Content-Type Flag */
	}

	/* SSoH TLV */
	/* System-Health-Id */
	wpabuf_put_be16(buf, 0x0002); /* Type */
	wpabuf_put_be16(buf, 4); /* Length */
	wpabuf_put_be32(buf, 79616);
	/* Vendor-Specific Attribute */
	wpabuf_put_be16(buf, EAP_TLV_VENDOR_SPECIFIC_TLV);
	ssoh_len = wpabuf_put(buf, 2);
	wpabuf_put_be32(buf, EAP_VENDOR_MICROSOFT); /* IANA SMI Code */

	/* MS-Packet-Info */
	wpabuf_put_u8(buf, SSOH_MS_PACKET_INFO);
	/* Note: IF-TNCCS-SOH v1.0 r8 claims this field to be:
	 * Reserved(4 bits) r(1 bit) Vers(3 bits), but Windows XP
	 * SP3 seems to be sending 0x11 for SSoH, i.e., r(request/response) bit
	 * would not be in the specified location.
	 * [MS-SOH] 4.0.2: Reserved(3 bits) r(1 bit) Vers(4 bits)
	 */
	wpabuf_put_u8(buf, 0x11); /* r=request, vers=1 */

	/* MS-Machine-Inventory */
	/* TODO: get correct values; 0 = not applicable for OS */
	wpabuf_put_u8(buf, SSOH_MS_MACHINE_INVENTORY);
	wpabuf_put_be32(buf, 0); /* osVersionMajor */
	wpabuf_put_be32(buf, 0); /* osVersionMinor */
	wpabuf_put_be32(buf, 0); /* osVersionBuild */
	wpabuf_put_be16(buf, 0); /* spVersionMajor */
	wpabuf_put_be16(buf, 0); /* spVersionMinor */
	wpabuf_put_be16(buf, 0); /* procArch */

	/* MS-MachineName */
	wpabuf_put_u8(buf, SSOH_MS_MACHINENAME);
	wpabuf_put_be16(buf, os_strlen(machinename) + 1);
	wpabuf_put_data(buf, machinename, os_strlen(machinename) + 1);

	/* MS-CorrelationId */
	wpabuf_put_u8(buf, SSOH_MS_CORRELATIONID);
	wpabuf_put_data(buf, correlation_id, sizeof(correlation_id));

	/* MS-Quarantine-State */
	wpabuf_put_u8(buf, SSOH_MS_QUARANTINE_STATE);
	wpabuf_put_be16(buf, 1); /* Flags: ExtState=0, f=0, qState=1 */
	wpabuf_put_be32(buf, 0xffffffff); /* ProbTime (hi) */
	wpabuf_put_be32(buf, 0xffffffff); /* ProbTime (lo) */
	wpabuf_put_be16(buf, 1); /* urlLenInBytes */
	wpabuf_put_u8(buf, 0); /* null termination for the url */

	/* MS-Machine-Inventory-Ex */
	wpabuf_put_u8(buf, SSOH_MS_MACHINE_INVENTORY_EX);
	wpabuf_put_be32(buf, 0); /* Reserved
				  * (note: Windows XP SP3 uses 0xdecafbad) */
	wpabuf_put_u8(buf, 1); /* ProductType: Client */

	/* Update SSoH Length */
	end = wpabuf_put(buf, 0);
	WPA_PUT_BE16(ssoh_len, end - ssoh_len - 2);

	/* TODO: SoHReportEntry TLV (zero or more) */

	/* Update length fields */
	end = wpabuf_put(buf, 0);
	WPA_PUT_BE16(tlv_len, end - tlv_len - 2);
	WPA_PUT_BE16(tlv_len2, end - tlv_len2 - 2);
	WPA_PUT_BE16(outer_len, end - outer_len - 2);
	WPA_PUT_BE16(inner_len, end - inner_len - 2);

	return buf;
}


struct wpabuf * tncc_process_soh_request(int ver, const u8 *data, size_t len)
{
	const u8 *pos;

	wpa_hexdump(MSG_DEBUG, "TNC: SoH Request", data, len);

	if (len < 12)
		return NULL;

	/* SoH Request */
	pos = data;

	/* TLV Type */
	if (WPA_GET_BE16(pos) != EAP_TLV_VENDOR_SPECIFIC_TLV)
		return NULL;
	pos += 2;

	/* Length */
	if (WPA_GET_BE16(pos) < 8)
		return NULL;
	pos += 2;

	/* Vendor_Id */
	if (WPA_GET_BE32(pos) != EAP_VENDOR_MICROSOFT)
		return NULL;
	pos += 4;

	/* TLV Type */
	if (WPA_GET_BE16(pos) != 0x02 /* SoH request TLV */)
		return NULL;

	wpa_printf(MSG_DEBUG, "TNC: SoH Request TLV received");

	return tncc_build_soh(2);
}
