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;
|
|
}
|