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

📄 tncs.c

📁 最新的Host AP 新添加了许多pcmcia 的驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * EAP-TNC - TNCS (IF-IMV, IF-TNCCS, and IF-TNCCS-SOH) * Copyright (c) 2007-2008, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#include "includes.h"#include <dlfcn.h>#include "common.h"#include "base64.h"#include "tncs.h"#include "eap_common/eap_tlv_common.h"#include "eap_common/eap_defs.h"/* TODO: TNCS must be thread-safe; review the code and add locking etc. if * needed.. */#define TNC_CONFIG_FILE "/etc/tnc_config"#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-IMV */typedef unsigned long TNC_UInt32;typedef unsigned char *TNC_BufferReference;typedef TNC_UInt32 TNC_IMVID;typedef TNC_UInt32 TNC_ConnectionID;typedef TNC_UInt32 TNC_ConnectionState;typedef TNC_UInt32 TNC_RetryReason;typedef TNC_UInt32 TNC_IMV_Action_Recommendation;typedef TNC_UInt32 TNC_IMV_Evaluation_Result;typedef TNC_UInt32 TNC_MessageType;typedef TNC_MessageType *TNC_MessageTypeList;typedef TNC_UInt32 TNC_VendorID;typedef TNC_UInt32 TNC_Subtype;typedef TNC_UInt32 TNC_Version;typedef TNC_UInt32 TNC_Result;typedef TNC_UInt32 TNC_AttributeID;typedef TNC_Result (*TNC_TNCS_BindFunctionPointer)(	TNC_IMVID imvID,	char *functionName,	void **pOutfunctionPointer);#define TNC_RESULT_SUCCESS 0#define TNC_RESULT_NOT_INITIALIZED 1#define TNC_RESULT_ALREADY_INITIALIZED 2#define TNC_RESULT_NO_COMMON_VERSION 3#define TNC_RESULT_CANT_RETRY 4#define TNC_RESULT_WONT_RETRY 5#define TNC_RESULT_INVALID_PARAMETER 6#define TNC_RESULT_CANT_RESPOND 7#define TNC_RESULT_ILLEGAL_OPERATION 8#define TNC_RESULT_OTHER 9#define TNC_RESULT_FATAL 10#define TNC_CONNECTION_STATE_CREATE 0#define TNC_CONNECTION_STATE_HANDSHAKE 1#define TNC_CONNECTION_STATE_ACCESS_ALLOWED 2#define TNC_CONNECTION_STATE_ACCESS_ISOLATED 3#define TNC_CONNECTION_STATE_ACCESS_NONE 4#define TNC_CONNECTION_STATE_DELETE 5#define TNC_IFIMV_VERSION_1 1#define TNC_VENDORID_ANY ((TNC_VendorID) 0xffffff)#define TNC_SUBTYPE_ANY ((TNC_Subtype) 0xff)/* TNCC-TNCS Message Types */#define TNC_TNCCS_RECOMMENDATION		0x00000001#define TNC_TNCCS_ERROR				0x00000002#define TNC_TNCCS_PREFERREDLANGUAGE		0x00000003#define TNC_TNCCS_REASONSTRINGS			0x00000004/* Possible TNC_IMV_Action_Recommendation values: */enum IMV_Action_Recommendation {	TNC_IMV_ACTION_RECOMMENDATION_ALLOW,	TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS,	TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,	TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION};/* Possible TNC_IMV_Evaluation_Result values: */enum IMV_Evaluation_Result {	TNC_IMV_EVALUATION_RESULT_COMPLIANT,	TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR,	TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR,	TNC_IMV_EVALUATION_RESULT_ERROR,	TNC_IMV_EVALUATION_RESULT_DONT_KNOW};struct tnc_if_imv {	struct tnc_if_imv *next;	char *name;	char *path;	void *dlhandle; /* from dlopen() */	TNC_IMVID imvID;	TNC_MessageTypeList supported_types;	size_t num_supported_types;	/* Functions implemented by IMVs (with TNC_IMV_ prefix) */	TNC_Result (*Initialize)(		TNC_IMVID imvID,		TNC_Version minVersion,		TNC_Version maxVersion,		TNC_Version *pOutActualVersion);	TNC_Result (*NotifyConnectionChange)(		TNC_IMVID imvID,		TNC_ConnectionID connectionID,		TNC_ConnectionState newState);	TNC_Result (*ReceiveMessage)(		TNC_IMVID imvID,		TNC_ConnectionID connectionID,		TNC_BufferReference message,		TNC_UInt32 messageLength,		TNC_MessageType messageType);	TNC_Result (*SolicitRecommendation)(		TNC_IMVID imvID,		TNC_ConnectionID connectionID);	TNC_Result (*BatchEnding)(		TNC_IMVID imvID,		TNC_ConnectionID connectionID);	TNC_Result (*Terminate)(TNC_IMVID imvID);	TNC_Result (*ProvideBindFunction)(		TNC_IMVID imvID,		TNC_TNCS_BindFunctionPointer bindFunction);};#define TNC_MAX_IMV_ID 10struct tncs_data {	struct tncs_data *next;	struct tnc_if_imv *imv; /* local copy of tncs_global_data->imv */	TNC_ConnectionID connectionID;	unsigned int last_batchid;	enum IMV_Action_Recommendation recommendation;	int done;	struct conn_imv {		u8 *imv_send;		size_t imv_send_len;		enum IMV_Action_Recommendation recommendation;		int recommendation_set;	} imv_data[TNC_MAX_IMV_ID];	char *tncs_message;};struct tncs_global {	struct tnc_if_imv *imv;	TNC_ConnectionID next_conn_id;	struct tncs_data *connections;};static struct tncs_global *tncs_global_data = NULL;static struct tnc_if_imv * tncs_get_imv(TNC_IMVID imvID){	struct tnc_if_imv *imv;	if (imvID >= TNC_MAX_IMV_ID || tncs_global_data == NULL)		return NULL;	imv = tncs_global_data->imv;	while (imv) {		if (imv->imvID == imvID)			return imv;		imv = imv->next;	}	return NULL;}static struct tncs_data * tncs_get_conn(TNC_ConnectionID connectionID){	struct tncs_data *tncs;	if (tncs_global_data == NULL)		return NULL;	tncs = tncs_global_data->connections;	while (tncs) {		if (tncs->connectionID == connectionID)			return tncs;		tncs = tncs->next;	}	wpa_printf(MSG_DEBUG, "TNC: Connection ID %lu not found",		   (unsigned long) connectionID);	return NULL;}/* TNCS functions that IMVs can call */TNC_Result TNC_TNCS_ReportMessageTypes(	TNC_IMVID imvID,	TNC_MessageTypeList supportedTypes,	TNC_UInt32 typeCount){	TNC_UInt32 i;	struct tnc_if_imv *imv;	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_ReportMessageTypes(imvID=%lu "		   "typeCount=%lu)",		   (unsigned long) imvID, (unsigned long) typeCount);	for (i = 0; i < typeCount; i++) {		wpa_printf(MSG_DEBUG, "TNC: supportedTypes[%lu] = %lu",			   i, supportedTypes[i]);	}	imv = tncs_get_imv(imvID);	if (imv == NULL)		return TNC_RESULT_INVALID_PARAMETER;	os_free(imv->supported_types);	imv->supported_types =		os_malloc(typeCount * sizeof(TNC_MessageTypeList));	if (imv->supported_types == NULL)		return TNC_RESULT_FATAL;	os_memcpy(imv->supported_types, supportedTypes,		  typeCount * sizeof(TNC_MessageTypeList));	imv->num_supported_types = typeCount;	return TNC_RESULT_SUCCESS;}TNC_Result TNC_TNCS_SendMessage(	TNC_IMVID imvID,	TNC_ConnectionID connectionID,	TNC_BufferReference message,	TNC_UInt32 messageLength,	TNC_MessageType messageType){	struct tncs_data *tncs;	unsigned char *b64;	size_t b64len;	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_SendMessage(imvID=%lu "		   "connectionID=%lu messageType=%lu)",		   imvID, connectionID, messageType);	wpa_hexdump_ascii(MSG_DEBUG, "TNC: TNC_TNCS_SendMessage",			  message, messageLength);	if (tncs_get_imv(imvID) == NULL)		return TNC_RESULT_INVALID_PARAMETER;	tncs = tncs_get_conn(connectionID);	if (tncs == NULL)		return TNC_RESULT_INVALID_PARAMETER;	b64 = base64_encode(message, messageLength, &b64len);	if (b64 == NULL)		return TNC_RESULT_FATAL;	os_free(tncs->imv_data[imvID].imv_send);	tncs->imv_data[imvID].imv_send_len = 0;	tncs->imv_data[imvID].imv_send = os_zalloc(b64len + 100);	if (tncs->imv_data[imvID].imv_send == NULL) {		os_free(b64);		return TNC_RESULT_OTHER;	}	tncs->imv_data[imvID].imv_send_len =		os_snprintf((char *) tncs->imv_data[imvID].imv_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;}TNC_Result TNC_TNCS_RequestHandshakeRetry(	TNC_IMVID imvID,	TNC_ConnectionID connectionID,	TNC_RetryReason reason){	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_RequestHandshakeRetry");	/* TODO */	return TNC_RESULT_SUCCESS;}TNC_Result TNC_TNCS_ProvideRecommendation(	TNC_IMVID imvID,	TNC_ConnectionID connectionID,	TNC_IMV_Action_Recommendation recommendation,	TNC_IMV_Evaluation_Result evaluation){	struct tncs_data *tncs;	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_ProvideRecommendation(imvID=%lu "		   "connectionID=%lu recommendation=%lu evaluation=%lu)",		   (unsigned long) imvID, (unsigned long) connectionID,		   (unsigned long) recommendation, (unsigned long) evaluation);	if (tncs_get_imv(imvID) == NULL)		return TNC_RESULT_INVALID_PARAMETER;	tncs = tncs_get_conn(connectionID);	if (tncs == NULL)		return TNC_RESULT_INVALID_PARAMETER;	tncs->imv_data[imvID].recommendation = recommendation;	tncs->imv_data[imvID].recommendation_set = 1;	return TNC_RESULT_SUCCESS;}TNC_Result TNC_TNCS_GetAttribute(	TNC_IMVID imvID,	TNC_ConnectionID connectionID,	TNC_AttributeID attribureID,	TNC_UInt32 bufferLength,	TNC_BufferReference buffer,	TNC_UInt32 *pOutValueLength){	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_GetAttribute");	/* TODO */	return TNC_RESULT_SUCCESS;}TNC_Result TNC_TNCS_SetAttribute(	TNC_IMVID imvID,	TNC_ConnectionID connectionID,	TNC_AttributeID attribureID,	TNC_UInt32 bufferLength,	TNC_BufferReference buffer){	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_SetAttribute");	/* TODO */	return TNC_RESULT_SUCCESS;}TNC_Result TNC_TNCS_BindFunction(	TNC_IMVID imvID,	char *functionName,	void **pOutFunctionPointer){	wpa_printf(MSG_DEBUG, "TNC: TNC_TNCS_BindFunction(imcID=%lu, "		   "functionName='%s')", (unsigned long) imvID, functionName);	if (tncs_get_imv(imvID) == NULL)		return TNC_RESULT_INVALID_PARAMETER;	if (pOutFunctionPointer == NULL)		return TNC_RESULT_INVALID_PARAMETER;	if (os_strcmp(functionName, "TNC_TNCS_ReportMessageTypes") == 0)		*pOutFunctionPointer = TNC_TNCS_ReportMessageTypes;	else if (os_strcmp(functionName, "TNC_TNCS_SendMessage") == 0)		*pOutFunctionPointer = TNC_TNCS_SendMessage;	else if (os_strcmp(functionName, "TNC_TNCS_RequestHandshakeRetry") ==		 0)		*pOutFunctionPointer = TNC_TNCS_RequestHandshakeRetry;	else if (os_strcmp(functionName, "TNC_TNCS_ProvideRecommendation") ==		 0)		*pOutFunctionPointer = TNC_TNCS_ProvideRecommendation;	else if (os_strcmp(functionName, "TNC_TNCS_GetAttribute") == 0)		*pOutFunctionPointer = TNC_TNCS_GetAttribute;	else if (os_strcmp(functionName, "TNC_TNCS_SetAttribute") == 0)		*pOutFunctionPointer = TNC_TNCS_SetAttribute;	else		*pOutFunctionPointer = NULL;	return TNC_RESULT_SUCCESS;}static void * tncs_get_sym(void *handle, char *func){	void *fptr;	fptr = dlsym(handle, func);	return fptr;}static int tncs_imv_resolve_funcs(struct tnc_if_imv *imv){	void *handle = imv->dlhandle;	/* Mandatory IMV functions */	imv->Initialize = tncs_get_sym(handle, "TNC_IMV_Initialize");	if (imv->Initialize == NULL) {		wpa_printf(MSG_ERROR, "TNC: IMV does not export "			   "TNC_IMV_Initialize");		return -1;	}	imv->SolicitRecommendation = tncs_get_sym(		handle, "TNC_IMV_SolicitRecommendation");	if (imv->SolicitRecommendation == NULL) {		wpa_printf(MSG_ERROR, "TNC: IMV does not export "			   "TNC_IMV_SolicitRecommendation");		return -1;	}	imv->ProvideBindFunction =		tncs_get_sym(handle, "TNC_IMV_ProvideBindFunction");	if (imv->ProvideBindFunction == NULL) {		wpa_printf(MSG_ERROR, "TNC: IMV does not export "			   "TNC_IMV_ProvideBindFunction");		return -1;	}	/* Optional IMV functions */	imv->NotifyConnectionChange =		tncs_get_sym(handle, "TNC_IMV_NotifyConnectionChange");	imv->ReceiveMessage = tncs_get_sym(handle, "TNC_IMV_ReceiveMessage");	imv->BatchEnding = tncs_get_sym(handle, "TNC_IMV_BatchEnding");	imv->Terminate = tncs_get_sym(handle, "TNC_IMV_Terminate");	return 0;}static int tncs_imv_initialize(struct tnc_if_imv *imv){	TNC_Result res;	TNC_Version imv_ver;	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_Initialize for IMV '%s'",		   imv->name);	res = imv->Initialize(imv->imvID, TNC_IFIMV_VERSION_1,			      TNC_IFIMV_VERSION_1, &imv_ver);	wpa_printf(MSG_DEBUG, "TNC: TNC_IMV_Initialize: res=%lu imv_ver=%lu",		   (unsigned long) res, (unsigned long) imv_ver);	return res == TNC_RESULT_SUCCESS ? 0 : -1;}static int tncs_imv_terminate(struct tnc_if_imv *imv){	TNC_Result res;	if (imv->Terminate == NULL)		return 0;	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_Terminate for IMV '%s'",		   imv->name);	res = imv->Terminate(imv->imvID);	wpa_printf(MSG_DEBUG, "TNC: TNC_IMV_Terminate: %lu",		   (unsigned long) res);	return res == TNC_RESULT_SUCCESS ? 0 : -1;}static int tncs_imv_provide_bind_function(struct tnc_if_imv *imv){	TNC_Result res;	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_ProvideBindFunction for "		   "IMV '%s'", imv->name);	res = imv->ProvideBindFunction(imv->imvID, TNC_TNCS_BindFunction);	wpa_printf(MSG_DEBUG, "TNC: TNC_IMV_ProvideBindFunction: res=%lu",		   (unsigned long) res);	return res == TNC_RESULT_SUCCESS ? 0 : -1;}static int tncs_imv_notify_connection_change(struct tnc_if_imv *imv,					     TNC_ConnectionID conn,					     TNC_ConnectionState state){	TNC_Result res;	if (imv->NotifyConnectionChange == NULL)		return 0;	wpa_printf(MSG_DEBUG, "TNC: Calling TNC_IMV_NotifyConnectionChange(%d)"		   " for IMV '%s'", (int) state, imv->name);	res = imv->NotifyConnectionChange(imv->imvID, conn, state);	wpa_printf(MSG_DEBUG, "TNC: TNC_IMC_NotifyConnectionChange: %lu",		   (unsigned long) res);	return res == TNC_RESULT_SUCCESS ? 0 : -1;}static int tncs_load_imv(struct tnc_if_imv *imv){	if (imv->path == NULL) {		wpa_printf(MSG_DEBUG, "TNC: No IMV configured");		return -1;	}	wpa_printf(MSG_DEBUG, "TNC: Opening IMV: %s (%s)",		   imv->name, imv->path);	imv->dlhandle = dlopen(imv->path, RTLD_LAZY);	if (imv->dlhandle == NULL) {		wpa_printf(MSG_ERROR, "TNC: Failed to open IMV '%s' (%s): %s",			   imv->name, imv->path, dlerror());		return -1;	}	if (tncs_imv_resolve_funcs(imv) < 0) {		wpa_printf(MSG_ERROR, "TNC: Failed to resolve IMV functions");		return -1;	}	if (tncs_imv_initialize(imv) < 0 ||	    tncs_imv_provide_bind_function(imv) < 0) {		wpa_printf(MSG_ERROR, "TNC: Failed to initialize IMV");		return -1;	}	return 0;}static void tncs_free_imv(struct tnc_if_imv *imv){	os_free(imv->name);	os_free(imv->path);	os_free(imv->supported_types);}static void tncs_unload_imv(struct tnc_if_imv *imv){	tncs_imv_terminate(imv);	if (imv->dlhandle)		dlclose(imv->dlhandle);	tncs_free_imv(imv);}static int tncs_supported_type(struct tnc_if_imv *imv, unsigned int type){	size_t i;	unsigned int vendor, subtype;	if (imv == NULL || imv->supported_types == NULL)		return 0;	vendor = type >> 8;	subtype = type & 0xff;	for (i = 0; i < imv->num_supported_types; i++) {		unsigned int svendor, ssubtype;		svendor = imv->supported_types[i] >> 8;		ssubtype = imv->supported_types[i] & 0xff;		if ((vendor == svendor || svendor == TNC_VENDORID_ANY) &&		    (subtype == ssubtype || ssubtype == TNC_SUBTYPE_ANY))			return 1;	}	return 0;}static void tncs_send_to_imvs(struct tncs_data *tncs, unsigned int type,			      const u8 *msg, size_t len){	struct tnc_if_imv *imv;	TNC_Result res;	wpa_hexdump_ascii(MSG_MSGDUMP, "TNC: Message to IMV(s)", msg, len);	for (imv = tncs->imv; imv; imv = imv->next) {		if (imv->ReceiveMessage == NULL ||		    !tncs_supported_type(imv, type))			continue;		wpa_printf(MSG_DEBUG, "TNC: Call ReceiveMessage for IMV '%s'",			   imv->name);		res = imv->ReceiveMessage(imv->imvID, tncs->connectionID,					  (TNC_BufferReference) msg, len,					  type);		wpa_printf(MSG_DEBUG, "TNC: ReceiveMessage: %lu",			   (unsigned long) res);	}}static void tncs_batch_ending(struct tncs_data *tncs){	struct tnc_if_imv *imv;	TNC_Result res;	for (imv = tncs->imv; imv; imv = imv->next) {		if (imv->BatchEnding == NULL)			continue;		wpa_printf(MSG_DEBUG, "TNC: Call BatchEnding for IMV '%s'",			   imv->name);		res = imv->BatchEnding(imv->imvID, tncs->connectionID);		wpa_printf(MSG_DEBUG, "TNC: BatchEnding: %lu",			   (unsigned long) res);	}}static void tncs_solicit_recommendation(struct tncs_data *tncs){	struct tnc_if_imv *imv;	TNC_Result res;	for (imv = tncs->imv; imv; imv = imv->next) {		if (tncs->imv_data[imv->imvID].recommendation_set)			continue;		wpa_printf(MSG_DEBUG, "TNC: Call SolicitRecommendation for "			   "IMV '%s'", imv->name);

⌨️ 快捷键说明

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