tests: TNC testing
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>
This commit is contained in:
parent
10b58b5029
commit
dbd1e184e3
11 changed files with 671 additions and 0 deletions
|
@ -32,10 +32,43 @@ typedef TNC_Result (*TNC_TNCS_BindFunctionPointer)(
|
||||||
TNC_IMVID imvID,
|
TNC_IMVID imvID,
|
||||||
char *functionName,
|
char *functionName,
|
||||||
void **pOutfunctionPointer);
|
void **pOutfunctionPointer);
|
||||||
|
typedef TNC_Result (*TNC_TNCS_ReportMessageTypesPointer)(
|
||||||
|
TNC_IMVID imvID,
|
||||||
|
TNC_MessageTypeList supportedTypes,
|
||||||
|
TNC_UInt32 typeCount);
|
||||||
|
typedef TNC_Result (*TNC_TNCS_SendMessagePointer)(
|
||||||
|
TNC_IMVID imvID,
|
||||||
|
TNC_ConnectionID connectionID,
|
||||||
|
TNC_BufferReference message,
|
||||||
|
TNC_UInt32 messageLength,
|
||||||
|
TNC_MessageType messageType);
|
||||||
|
typedef TNC_Result (*TNC_TNCS_RequestHandshakeRetryPointer)(
|
||||||
|
TNC_IMVID imvID,
|
||||||
|
TNC_ConnectionID connectionID,
|
||||||
|
TNC_RetryReason reason);
|
||||||
|
typedef TNC_Result (*TNC_TNCS_ProvideRecommendationPointer)(
|
||||||
|
TNC_IMVID imvID,
|
||||||
|
TNC_ConnectionID connectionID,
|
||||||
|
TNC_IMV_Action_Recommendation recommendation,
|
||||||
|
TNC_IMV_Evaluation_Result evaluation);
|
||||||
typedef TNC_Result (*TNC_TNCC_BindFunctionPointer)(
|
typedef TNC_Result (*TNC_TNCC_BindFunctionPointer)(
|
||||||
TNC_IMCID imcID,
|
TNC_IMCID imcID,
|
||||||
char *functionName,
|
char *functionName,
|
||||||
void **pOutfunctionPointer);
|
void **pOutfunctionPointer);
|
||||||
|
typedef TNC_Result (*TNC_TNCC_SendMessagePointer)(
|
||||||
|
TNC_IMCID imcID,
|
||||||
|
TNC_ConnectionID connectionID,
|
||||||
|
TNC_BufferReference message,
|
||||||
|
TNC_UInt32 messageLength,
|
||||||
|
TNC_MessageType messageType);
|
||||||
|
typedef TNC_Result (*TNC_TNCC_ReportMessageTypesPointer)(
|
||||||
|
TNC_IMCID imcID,
|
||||||
|
TNC_MessageTypeList supportedTypes,
|
||||||
|
TNC_UInt32 typeCount);
|
||||||
|
typedef TNC_Result (*TNC_TNCC_RequestHandshakeRetryPointer)(
|
||||||
|
TNC_IMCID imcID,
|
||||||
|
TNC_ConnectionID connectionID,
|
||||||
|
TNC_RetryReason reason);
|
||||||
|
|
||||||
#define TNC_IFIMV_VERSION_1 1
|
#define TNC_IFIMV_VERSION_1 1
|
||||||
#define TNC_IFIMC_VERSION_1 1
|
#define TNC_IFIMC_VERSION_1 1
|
||||||
|
|
|
@ -22,3 +22,7 @@ make -j8
|
||||||
cd ../mac80211_hwsim/tools
|
cd ../mac80211_hwsim/tools
|
||||||
make clean
|
make clean
|
||||||
make -j8
|
make -j8
|
||||||
|
cd ../../tests/hwsim/tnc
|
||||||
|
make clean
|
||||||
|
make -j8
|
||||||
|
cd ..
|
||||||
|
|
|
@ -29,6 +29,7 @@ CONFIG_EAP_VENDOR_TEST=y
|
||||||
CONFIG_EAP_FAST=y
|
CONFIG_EAP_FAST=y
|
||||||
CONFIG_EAP_IKEV2=y
|
CONFIG_EAP_IKEV2=y
|
||||||
CONFIG_EAP_TNC=y
|
CONFIG_EAP_TNC=y
|
||||||
|
CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\"
|
||||||
CONFIG_EAP_UNAUTH_TLS=y
|
CONFIG_EAP_UNAUTH_TLS=y
|
||||||
ifeq ($(CONFIG_TLS), openssl)
|
ifeq ($(CONFIG_TLS), openssl)
|
||||||
CONFIG_EAP_PWD=y
|
CONFIG_EAP_PWD=y
|
||||||
|
|
|
@ -27,6 +27,7 @@ CONFIG_EAP_GPSK=y
|
||||||
CONFIG_EAP_GPSK_SHA256=y
|
CONFIG_EAP_GPSK_SHA256=y
|
||||||
CONFIG_EAP_EKE=y
|
CONFIG_EAP_EKE=y
|
||||||
CONFIG_EAP_TNC=y
|
CONFIG_EAP_TNC=y
|
||||||
|
CFLAGS += -DTNC_CONFIG_FILE=\"tnc/tnc_config\"
|
||||||
CONFIG_EAP_FAST=y
|
CONFIG_EAP_FAST=y
|
||||||
CONFIG_EAP_IKEV2=y
|
CONFIG_EAP_IKEV2=y
|
||||||
|
|
||||||
|
|
93
tests/hwsim/test_tnc.py
Normal file
93
tests/hwsim/test_tnc.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# TNC tests
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import hostapd
|
||||||
|
from test_ap_eap import int_eap_server_params
|
||||||
|
|
||||||
|
def test_tnc_peap_soh(dev, apdev):
|
||||||
|
"""TNC PEAP-SoH"""
|
||||||
|
params = int_eap_server_params()
|
||||||
|
params["tnc"] = "1"
|
||||||
|
hostapd.add_ap(apdev[0]['ifname'], params)
|
||||||
|
|
||||||
|
dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
|
||||||
|
eap="PEAP", identity="user", password="password",
|
||||||
|
ca_cert="auth_serv/ca.pem",
|
||||||
|
phase1="peapver=0 tnc=soh cryptobinding=0",
|
||||||
|
phase2="auth=MSCHAPV2",
|
||||||
|
wait_connect=False)
|
||||||
|
ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Connection timed out")
|
||||||
|
|
||||||
|
dev[1].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
|
||||||
|
eap="PEAP", identity="user", password="password",
|
||||||
|
ca_cert="auth_serv/ca.pem",
|
||||||
|
phase1="peapver=0 tnc=soh1 cryptobinding=1",
|
||||||
|
phase2="auth=MSCHAPV2",
|
||||||
|
wait_connect=False)
|
||||||
|
ev = dev[1].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Connection timed out")
|
||||||
|
|
||||||
|
dev[2].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
|
||||||
|
eap="PEAP", identity="user", password="password",
|
||||||
|
ca_cert="auth_serv/ca.pem",
|
||||||
|
phase1="peapver=0 tnc=soh2 cryptobinding=2",
|
||||||
|
phase2="auth=MSCHAPV2",
|
||||||
|
wait_connect=False)
|
||||||
|
ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Connection timed out")
|
||||||
|
|
||||||
|
def test_tnc_ttls(dev, apdev):
|
||||||
|
"""TNC TTLS"""
|
||||||
|
params = int_eap_server_params()
|
||||||
|
params["tnc"] = "1"
|
||||||
|
hostapd.add_ap(apdev[0]['ifname'], params)
|
||||||
|
|
||||||
|
if not os.path.exists("tnc/libhostap_imc.so"):
|
||||||
|
logger.info("No IMC installed - skip")
|
||||||
|
return "skip"
|
||||||
|
|
||||||
|
dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
|
||||||
|
eap="TTLS", identity="DOMAIN\mschapv2 user",
|
||||||
|
anonymous_identity="ttls", password="password",
|
||||||
|
phase2="auth=MSCHAPV2",
|
||||||
|
ca_cert="auth_serv/ca.pem",
|
||||||
|
wait_connect=False)
|
||||||
|
ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Connection timed out")
|
||||||
|
|
||||||
|
def test_tnc_fast(dev, apdev):
|
||||||
|
"""TNC FAST"""
|
||||||
|
params = int_eap_server_params()
|
||||||
|
params["tnc"] = "1"
|
||||||
|
params["pac_opaque_encr_key"] ="000102030405060708090a0b0c0d0e00"
|
||||||
|
params["eap_fast_a_id"] = "101112131415161718191a1b1c1d1e00"
|
||||||
|
params["eap_fast_a_id_info"] = "test server2"
|
||||||
|
|
||||||
|
hostapd.add_ap(apdev[0]['ifname'], params)
|
||||||
|
|
||||||
|
if not os.path.exists("tnc/libhostap_imc.so"):
|
||||||
|
logger.info("No IMC installed - skip")
|
||||||
|
return "skip"
|
||||||
|
|
||||||
|
dev[0].connect("test-wpa2-eap", key_mgmt="WPA-EAP",
|
||||||
|
eap="FAST", identity="user",
|
||||||
|
anonymous_identity="FAST", password="password",
|
||||||
|
phase2="auth=GTC",
|
||||||
|
phase1="fast_provisioning=2",
|
||||||
|
pac_file="blob://fast_pac_auth_tnc",
|
||||||
|
ca_cert="auth_serv/ca.pem",
|
||||||
|
wait_connect=False)
|
||||||
|
ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
|
||||||
|
if ev is None:
|
||||||
|
raise Exception("Connection timed out")
|
11
tests/hwsim/tnc/Makefile
Normal file
11
tests/hwsim/tnc/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
CFLAGS += -I$(abspath ../../../src)
|
||||||
|
CFLAGS += -I$(abspath ../../../src/utils)
|
||||||
|
|
||||||
|
ALL=libhostap_imc.so libhostap_imv.so libhostap2_imc.so libhostap2_imv.so
|
||||||
|
all: $(ALL)
|
||||||
|
|
||||||
|
lib%.so: %.c
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(ALL)
|
183
tests/hwsim/tnc/hostap2_imc.c
Normal file
183
tests/hwsim/tnc/hostap2_imc.c
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* Example IMC 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_IMCID my_id = -1;
|
||||||
|
static TNC_TNCC_SendMessagePointer send_message = NULL;
|
||||||
|
static TNC_TNCC_ReportMessageTypesPointer report_message_types = NULL;
|
||||||
|
static TNC_TNCC_RequestHandshakeRetryPointer request_retry = NULL;
|
||||||
|
|
||||||
|
static TNC_MessageType message_types[] =
|
||||||
|
{
|
||||||
|
(TNC_VENDORID_ANY << 8) | TNC_SUBTYPE_ANY
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_Initialize(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_Version minVersion,
|
||||||
|
/*in*/ TNC_Version maxVersion,
|
||||||
|
/*out*/ TNC_Version *pOutActualVersion)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"IMC(hostap2) %s(imcID=%u, minVersion=%u, maxVersion=%u)",
|
||||||
|
__func__, (unsigned) imcID, (unsigned) minVersion,
|
||||||
|
(unsigned) maxVersion);
|
||||||
|
|
||||||
|
if (initialized)
|
||||||
|
return TNC_RESULT_ALREADY_INITIALIZED;
|
||||||
|
|
||||||
|
if (minVersion < TNC_IFIMC_VERSION_1 ||
|
||||||
|
maxVersion > TNC_IFIMC_VERSION_1)
|
||||||
|
return TNC_RESULT_NO_COMMON_VERSION;
|
||||||
|
|
||||||
|
if (!pOutActualVersion)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
*pOutActualVersion = TNC_IFIMC_VERSION_1;
|
||||||
|
my_id = imcID;
|
||||||
|
|
||||||
|
initialized = 1;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_BeginHandshake(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_ConnectionID connectionID)
|
||||||
|
{
|
||||||
|
char *msg = "hello";
|
||||||
|
TNC_Result res;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u, connectionID=%u)",
|
||||||
|
__func__, (unsigned) imcID, (unsigned) connectionID);
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
return TNC_RESULT_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if (imcID != my_id)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (!send_message)
|
||||||
|
return TNC_RESULT_FATAL;
|
||||||
|
|
||||||
|
res = send_message(imcID, connectionID, msg, os_strlen(msg), 1);
|
||||||
|
if (res != TNC_RESULT_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_ProvideBindFunction(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_TNCC_BindFunctionPointer bindFunction)
|
||||||
|
{
|
||||||
|
TNC_Result res;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u)",
|
||||||
|
__func__, (unsigned) imcID);
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
return TNC_RESULT_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if (imcID != my_id || !bindFunction)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (bindFunction(imcID, "TNC_TNCC_SendMessage",
|
||||||
|
(void **) &send_message) != TNC_RESULT_SUCCESS ||
|
||||||
|
!send_message)
|
||||||
|
return TNC_RESULT_FATAL;
|
||||||
|
|
||||||
|
if (bindFunction(imcID, "TNC_TNCC_ReportMessageTypes",
|
||||||
|
(void **) &report_message_types) !=
|
||||||
|
TNC_RESULT_SUCCESS ||
|
||||||
|
!report_message_types)
|
||||||
|
return TNC_RESULT_FATAL;
|
||||||
|
|
||||||
|
if (bindFunction(imcID, "TNC_TNCC_RequestHandshakeRetry",
|
||||||
|
(void **) &request_retry) != TNC_RESULT_SUCCESS ||
|
||||||
|
!request_retry)
|
||||||
|
return TNC_RESULT_FATAL;
|
||||||
|
|
||||||
|
res = report_message_types(imcID, message_types,
|
||||||
|
ARRAY_SIZE(message_types));
|
||||||
|
if (res != TNC_RESULT_SUCCESS)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_NotifyConnectionChange(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_ConnectionID connectionID,
|
||||||
|
/*in*/ TNC_ConnectionState newState)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"IMC(hostap2) %s(imcID=%u, connectionID=%u, newState=%u)",
|
||||||
|
__func__, (unsigned) imcID, (unsigned) connectionID,
|
||||||
|
(unsigned) newState);
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_ReceiveMessage(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_ConnectionID connectionID,
|
||||||
|
/*in*/ TNC_BufferReference message,
|
||||||
|
/*in*/ TNC_UInt32 messageLength,
|
||||||
|
/*in*/ TNC_MessageType messageType)
|
||||||
|
{
|
||||||
|
TNC_Result res;
|
||||||
|
|
||||||
|
wpa_printf(MSG_INFO,
|
||||||
|
"IMC(hostap2) %s(imcID=%u, connectionID=%u, messageType=%u)",
|
||||||
|
__func__, (unsigned) imcID, (unsigned) connectionID,
|
||||||
|
(unsigned) messageType);
|
||||||
|
wpa_hexdump_ascii(MSG_INFO, "IMC(hostap2) message",
|
||||||
|
message, messageLength);
|
||||||
|
|
||||||
|
if (messageType == 1 && messageLength == 5 &&
|
||||||
|
os_memcmp(message, "hello", 5) == 0) {
|
||||||
|
char *msg = "i'm fine";
|
||||||
|
|
||||||
|
res = send_message(imcID, connectionID, msg, os_strlen(msg), 1);
|
||||||
|
if (res != TNC_RESULT_SUCCESS)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_BatchEnding(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_ConnectionID connectionID)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u, connectionID=%u)",
|
||||||
|
__func__, (unsigned) imcID, (unsigned) connectionID);
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_Terminate(
|
||||||
|
/*in*/ TNC_IMCID imcID)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u)",
|
||||||
|
__func__, (unsigned) imcID);
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
203
tests/hwsim/tnc/hostap2_imv.c
Normal file
203
tests/hwsim/tnc/hostap2_imv.c
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
72
tests/hwsim/tnc/hostap_imc.c
Normal file
72
tests/hwsim/tnc/hostap_imc.c
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Minimal example IMC 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_IMCID my_id = -1;
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_Initialize(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_Version minVersion,
|
||||||
|
/*in*/ TNC_Version maxVersion,
|
||||||
|
/*out*/ TNC_Version *pOutActualVersion)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap) %s", __func__);
|
||||||
|
|
||||||
|
if (initialized)
|
||||||
|
return TNC_RESULT_ALREADY_INITIALIZED;
|
||||||
|
|
||||||
|
if (minVersion < TNC_IFIMC_VERSION_1 ||
|
||||||
|
maxVersion > TNC_IFIMC_VERSION_1)
|
||||||
|
return TNC_RESULT_NO_COMMON_VERSION;
|
||||||
|
|
||||||
|
if (!pOutActualVersion)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
*pOutActualVersion = TNC_IFIMC_VERSION_1;
|
||||||
|
my_id = imcID;
|
||||||
|
|
||||||
|
initialized = 1;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_BeginHandshake(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_ConnectionID connectionID)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap) %s", __func__);
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
return TNC_RESULT_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if (imcID != my_id)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMC_ProvideBindFunction(
|
||||||
|
/*in*/ TNC_IMCID imcID,
|
||||||
|
/*in*/ TNC_TNCC_BindFunctionPointer bindFunction)
|
||||||
|
{
|
||||||
|
wpa_printf(MSG_INFO, "IMC(hostap) %s", __func__);
|
||||||
|
|
||||||
|
if (!initialized)
|
||||||
|
return TNC_RESULT_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if (imcID != my_id)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
66
tests/hwsim/tnc/hostap_imv.c
Normal file
66
tests/hwsim/tnc/hostap_imv.c
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Minimal 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;
|
||||||
|
|
||||||
|
TNC_Result TNC_IMV_Initialize(
|
||||||
|
/*in*/ TNC_IMVID imvID,
|
||||||
|
/*in*/ TNC_Version minVersion,
|
||||||
|
/*in*/ TNC_Version maxVersion,
|
||||||
|
/*out*/ TNC_Version *pOutActualVersion)
|
||||||
|
{
|
||||||
|
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_SolicitRecommendation(
|
||||||
|
/*in*/ TNC_IMVID imvID,
|
||||||
|
/*in*/ TNC_ConnectionID connectionID)
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return TNC_RESULT_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if (imvID != my_id)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TNC_Result TNC_IMV_ProvideBindFunction(
|
||||||
|
/*in*/ TNC_IMVID imvID,
|
||||||
|
/*in*/ TNC_TNCS_BindFunctionPointer bindFunction)
|
||||||
|
{
|
||||||
|
if (!initialized)
|
||||||
|
return TNC_RESULT_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if (imvID != my_id)
|
||||||
|
return TNC_RESULT_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
return TNC_RESULT_SUCCESS;
|
||||||
|
}
|
4
tests/hwsim/tnc/tnc_config
Normal file
4
tests/hwsim/tnc/tnc_config
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
IMC "hostap IMC" tnc/libhostap_imc.so
|
||||||
|
IMV "hostap IMV" tnc/libhostap_imv.so
|
||||||
|
IMC "hostap2 IMC" tnc/libhostap2_imc.so
|
||||||
|
IMV "hostap2 IMV" tnc/libhostap2_imv.so
|
Loading…
Reference in a new issue