 dbd1e184e3
			
		
	
	
		dbd1e184e3
		
	
	
	
	
		
			
			This implements minimal IMC and IMV to allow TNC testing with PEAP (SoH) and TTLS/FAST with EAP-TNC. Signed-off-by: Jouni Malinen <j@w1.fi>
		
			
				
	
	
		
			203 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Example IMV for TNC testing
 | |
|  * Copyright (c) 2014, 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 "common/tnc.h"
 | |
| 
 | |
| static int initialized = 0;
 | |
| static TNC_IMVID my_id = -1;
 | |
| static TNC_TNCS_ReportMessageTypesPointer report_message_types = NULL;
 | |
| static TNC_TNCS_SendMessagePointer send_message = NULL;
 | |
| static TNC_TNCS_RequestHandshakeRetryPointer request_retry = NULL;
 | |
| TNC_TNCS_ProvideRecommendationPointer provide_recomm = NULL;
 | |
| 
 | |
| static TNC_MessageType message_types[] =
 | |
| {
 | |
| 	(TNC_VENDORID_ANY << 8) | TNC_SUBTYPE_ANY
 | |
| };
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_Initialize(
 | |
| 	/*in*/ TNC_IMVID imvID,
 | |
| 	/*in*/ TNC_Version minVersion,
 | |
| 	/*in*/ TNC_Version maxVersion,
 | |
| 	/*out*/ TNC_Version *pOutActualVersion)
 | |
| {
 | |
| 	wpa_printf(MSG_INFO,
 | |
| 		   "IMV(hostap2) %s(imvID=%u, minVersion=%u, maxVersion=%u)",
 | |
| 		   __func__, (unsigned) imvID, (unsigned) minVersion,
 | |
| 		   (unsigned) maxVersion);
 | |
| 
 | |
| 	if (initialized)
 | |
| 		return TNC_RESULT_ALREADY_INITIALIZED;
 | |
| 
 | |
| 	if (minVersion < TNC_IFIMV_VERSION_1 ||
 | |
| 	    maxVersion > TNC_IFIMV_VERSION_1)
 | |
| 		return TNC_RESULT_NO_COMMON_VERSION;
 | |
| 
 | |
| 	if (!pOutActualVersion)
 | |
| 		return TNC_RESULT_INVALID_PARAMETER;
 | |
| 	*pOutActualVersion = TNC_IFIMV_VERSION_1;
 | |
| 
 | |
| 	initialized = 1;
 | |
| 	my_id = imvID;
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_NotifyConnectionChange(
 | |
| 	/*in*/ TNC_IMVID imvID,
 | |
| 	/*in*/ TNC_ConnectionID connectionID,
 | |
| 	/*in*/ TNC_ConnectionState newState)
 | |
| {
 | |
| 	wpa_printf(MSG_INFO,
 | |
| 		   "IMV(hostap2) %s(imvID=%u, connectionID=%u, newState=%u)",
 | |
| 		   __func__, (unsigned) imvID, (unsigned) connectionID,
 | |
| 		   (unsigned) newState);
 | |
| 
 | |
| 	if (!initialized)
 | |
| 		return TNC_RESULT_NOT_INITIALIZED;
 | |
| 
 | |
| 	if (imvID != my_id)
 | |
| 		return TNC_RESULT_INVALID_PARAMETER;
 | |
| 
 | |
| 	/* TODO: call TNC_TNCS_ProvideRecommendation */
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_ReceiveMessage(
 | |
| 	/*in*/ TNC_IMVID imvID,
 | |
| 	/*in*/ TNC_ConnectionID connectionID,
 | |
| 	/*in*/ TNC_BufferReference message,
 | |
| 	/*in*/ TNC_UInt32 messageLength,
 | |
| 	/*in*/ TNC_MessageType messageType)
 | |
| {
 | |
| 	TNC_Result res;
 | |
| 
 | |
| 	wpa_printf(MSG_INFO,
 | |
| 		   "IMV(hostap2) %s(imvID=%u, connectionID=%u, messageType=%u)",
 | |
| 		   __func__, (unsigned) imvID, (unsigned) connectionID,
 | |
| 		   (unsigned) messageType);
 | |
| 	wpa_hexdump_ascii(MSG_INFO, "IMV(hostap2) message",
 | |
| 			  message, messageLength);
 | |
| 
 | |
| 	if (!send_message)
 | |
| 		return TNC_RESULT_FATAL;
 | |
| 
 | |
| 	if (messageType == 1 && messageLength == 5 &&
 | |
| 	    os_memcmp(message, "hello", 5) == 0) {
 | |
| 		char *msg = "hello";
 | |
| 
 | |
| 		res = send_message(imvID, connectionID, msg, os_strlen(msg), 1);
 | |
| 		if (res != TNC_RESULT_SUCCESS)
 | |
| 			return res;
 | |
| 	}
 | |
| 
 | |
| 	if (messageType == 1 && messageLength == 8 &&
 | |
| 	    os_memcmp(message, "i'm fine", 8) == 0) {
 | |
| 		if (!provide_recomm)
 | |
| 			return TNC_RESULT_FATAL;
 | |
| 		res = provide_recomm(imvID, connectionID,
 | |
| 				     TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
 | |
| 				     TNC_IMV_EVALUATION_RESULT_COMPLIANT);
 | |
| 		if (res != TNC_RESULT_SUCCESS)
 | |
| 			return res;
 | |
| 	}
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_SolicitRecommendation(
 | |
| 	/*in*/ TNC_IMVID imvID,
 | |
| 	/*in*/ TNC_ConnectionID connectionID)
 | |
| {
 | |
| 	wpa_printf(MSG_INFO, "IMV(hostap2) %s(imvID=%u, connectionID=%u)",
 | |
| 		   __func__, (unsigned) imvID, (unsigned) connectionID);
 | |
| 
 | |
| 	if (!initialized)
 | |
| 		return TNC_RESULT_NOT_INITIALIZED;
 | |
| 
 | |
| 	if (imvID != my_id)
 | |
| 		return TNC_RESULT_INVALID_PARAMETER;
 | |
| 
 | |
| 	/* TODO: call TNC_TNCS_ProvideRecommendation */
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_BatchEnding(
 | |
| 	/*in*/ TNC_IMVID imvID,
 | |
| 	/*in*/ TNC_ConnectionID connectionID)
 | |
| {
 | |
| 	wpa_printf(MSG_INFO, "IMV(hostap2) %s(imvID=%u, connectionID=%u)",
 | |
| 		   __func__, (unsigned) imvID, (unsigned) connectionID);
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_Terminate(
 | |
| 	/*in*/ TNC_IMVID imvID)
 | |
| {
 | |
| 	wpa_printf(MSG_INFO, "IMV(hostap2) %s(imvID=%u)",
 | |
| 		   __func__, (unsigned) imvID);
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 | |
| 
 | |
| 
 | |
| TNC_Result TNC_IMV_ProvideBindFunction(
 | |
| 	/*in*/ TNC_IMVID imvID,
 | |
| 	/*in*/ TNC_TNCS_BindFunctionPointer bindFunction)
 | |
| {
 | |
| 	TNC_Result res;
 | |
| 
 | |
| 	wpa_printf(MSG_INFO, "IMV(hostap2) %s(imvID=%u)",
 | |
| 		   __func__, (unsigned) imvID);
 | |
| 
 | |
| 	if (!initialized)
 | |
| 		return TNC_RESULT_NOT_INITIALIZED;
 | |
| 
 | |
| 	if (imvID != my_id || !bindFunction)
 | |
| 		return TNC_RESULT_INVALID_PARAMETER;
 | |
| 
 | |
| 	if (bindFunction(imvID, "TNC_TNCS_ReportMessageTypes",
 | |
| 			 (void **) &report_message_types) !=
 | |
| 	    TNC_RESULT_SUCCESS ||
 | |
| 	    !report_message_types)
 | |
| 		return TNC_RESULT_FATAL;
 | |
| 
 | |
| 	if (bindFunction(imvID, "TNC_TNCS_SendMessage",
 | |
| 			 (void **) &send_message) != TNC_RESULT_SUCCESS ||
 | |
| 	    !send_message)
 | |
| 		return TNC_RESULT_FATAL;
 | |
| 
 | |
| 	if (bindFunction(imvID, "TNC_TNCS_RequestHandshakeRetry",
 | |
| 			 (void **) &request_retry) != TNC_RESULT_SUCCESS ||
 | |
| 	    !request_retry)
 | |
| 		return TNC_RESULT_FATAL;
 | |
| 
 | |
| 	if (bindFunction(imvID, "TNC_TNCS_ProvideRecommendation",
 | |
| 			 (void **) &provide_recomm) != TNC_RESULT_SUCCESS ||
 | |
| 	    !provide_recomm)
 | |
| 		return TNC_RESULT_FATAL;
 | |
| 
 | |
| 	res = report_message_types(imvID, message_types,
 | |
| 				   ARRAY_SIZE(message_types));
 | |
| 	if (res != TNC_RESULT_SUCCESS)
 | |
| 		return res;
 | |
| 
 | |
| 	return TNC_RESULT_SUCCESS;
 | |
| }
 |