1 /*
2  * Example IMC for TNC testing
3  * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "includes.h"
10 
11 #include "common.h"
12 #include "common/tnc.h"
13 
14 static int initialized = 0;
15 static TNC_IMCID my_id = -1;
16 static TNC_TNCC_SendMessagePointer send_message = NULL;
17 static TNC_TNCC_ReportMessageTypesPointer report_message_types = NULL;
18 static TNC_TNCC_RequestHandshakeRetryPointer request_retry = NULL;
19 
20 static TNC_MessageType message_types[] =
21 {
22 	(TNC_VENDORID_ANY << 8) | TNC_SUBTYPE_ANY
23 };
24 
25 
TNC_IMC_Initialize(TNC_IMCID imcID,TNC_Version minVersion,TNC_Version maxVersion,TNC_Version * pOutActualVersion)26 TNC_Result TNC_IMC_Initialize(
27 	/*in*/ TNC_IMCID imcID,
28 	/*in*/ TNC_Version minVersion,
29 	/*in*/ TNC_Version maxVersion,
30 	/*out*/ TNC_Version *pOutActualVersion)
31 {
32 	wpa_printf(MSG_INFO,
33 		   "IMC(hostap2) %s(imcID=%u, minVersion=%u, maxVersion=%u)",
34 		   __func__, (unsigned) imcID, (unsigned) minVersion,
35 		   (unsigned) maxVersion);
36 
37 	if (initialized)
38 		return TNC_RESULT_ALREADY_INITIALIZED;
39 
40 	if (minVersion < TNC_IFIMC_VERSION_1 ||
41 	    maxVersion > TNC_IFIMC_VERSION_1)
42 		return TNC_RESULT_NO_COMMON_VERSION;
43 
44 	if (!pOutActualVersion)
45 		return TNC_RESULT_INVALID_PARAMETER;
46 	*pOutActualVersion = TNC_IFIMC_VERSION_1;
47 	my_id = imcID;
48 
49 	initialized = 1;
50 
51 	return TNC_RESULT_SUCCESS;
52 }
53 
54 
TNC_IMC_BeginHandshake(TNC_IMCID imcID,TNC_ConnectionID connectionID)55 TNC_Result TNC_IMC_BeginHandshake(
56 	/*in*/ TNC_IMCID imcID,
57 	/*in*/ TNC_ConnectionID connectionID)
58 {
59 	char *msg = "hello";
60 	TNC_Result res;
61 
62 	wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u, connectionID=%u)",
63 		   __func__, (unsigned) imcID, (unsigned) connectionID);
64 
65 	if (!initialized)
66 		return TNC_RESULT_NOT_INITIALIZED;
67 
68 	if (imcID != my_id)
69 		return TNC_RESULT_INVALID_PARAMETER;
70 
71 	if (!send_message)
72 		return TNC_RESULT_FATAL;
73 
74 	res = send_message(imcID, connectionID, msg, os_strlen(msg), 1);
75 	if (res != TNC_RESULT_SUCCESS)
76 		return res;
77 
78 	return TNC_RESULT_SUCCESS;
79 }
80 
81 
TNC_IMC_ProvideBindFunction(TNC_IMCID imcID,TNC_TNCC_BindFunctionPointer bindFunction)82 TNC_Result TNC_IMC_ProvideBindFunction(
83 	/*in*/ TNC_IMCID imcID,
84 	/*in*/ TNC_TNCC_BindFunctionPointer bindFunction)
85 {
86 	TNC_Result res;
87 
88 	wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u)",
89 		   __func__, (unsigned) imcID);
90 
91 	if (!initialized)
92 		return TNC_RESULT_NOT_INITIALIZED;
93 
94 	if (imcID != my_id || !bindFunction)
95 		return TNC_RESULT_INVALID_PARAMETER;
96 
97 	if (bindFunction(imcID, "TNC_TNCC_SendMessage",
98 			 (void **) &send_message) != TNC_RESULT_SUCCESS ||
99 	    !send_message)
100 		return TNC_RESULT_FATAL;
101 
102 	if (bindFunction(imcID, "TNC_TNCC_ReportMessageTypes",
103 			 (void **) &report_message_types) !=
104 	    TNC_RESULT_SUCCESS ||
105 	    !report_message_types)
106 		return TNC_RESULT_FATAL;
107 
108 	if (bindFunction(imcID, "TNC_TNCC_RequestHandshakeRetry",
109 			 (void **) &request_retry) != TNC_RESULT_SUCCESS ||
110 	    !request_retry)
111 		return TNC_RESULT_FATAL;
112 
113 	res = report_message_types(imcID, message_types,
114 				   ARRAY_SIZE(message_types));
115 	if (res != TNC_RESULT_SUCCESS)
116 		return res;
117 
118 	return TNC_RESULT_SUCCESS;
119 }
120 
121 
TNC_IMC_NotifyConnectionChange(TNC_IMCID imcID,TNC_ConnectionID connectionID,TNC_ConnectionState newState)122 TNC_Result TNC_IMC_NotifyConnectionChange(
123 	/*in*/ TNC_IMCID imcID,
124 	/*in*/ TNC_ConnectionID connectionID,
125 	/*in*/ TNC_ConnectionState newState)
126 {
127 	wpa_printf(MSG_INFO,
128 		   "IMC(hostap2) %s(imcID=%u, connectionID=%u, newState=%u)",
129 		   __func__, (unsigned) imcID, (unsigned) connectionID,
130 		   (unsigned) newState);
131 
132 	return TNC_RESULT_SUCCESS;
133 }
134 
135 
TNC_IMC_ReceiveMessage(TNC_IMCID imcID,TNC_ConnectionID connectionID,TNC_BufferReference message,TNC_UInt32 messageLength,TNC_MessageType messageType)136 TNC_Result TNC_IMC_ReceiveMessage(
137 	/*in*/ TNC_IMCID imcID,
138 	/*in*/ TNC_ConnectionID connectionID,
139 	/*in*/ TNC_BufferReference message,
140 	/*in*/ TNC_UInt32 messageLength,
141 	/*in*/ TNC_MessageType messageType)
142 {
143 	TNC_Result res;
144 
145 	wpa_printf(MSG_INFO,
146 		   "IMC(hostap2) %s(imcID=%u, connectionID=%u, messageType=%u)",
147 		   __func__, (unsigned) imcID, (unsigned) connectionID,
148 		   (unsigned) messageType);
149 	wpa_hexdump_ascii(MSG_INFO, "IMC(hostap2) message",
150 			  message, messageLength);
151 
152 	if (messageType == 1 && messageLength == 5 &&
153 	    os_memcmp(message, "hello", 5) == 0) {
154 		char *msg = "i'm fine";
155 
156 		res = send_message(imcID, connectionID, msg, os_strlen(msg), 1);
157 		if (res != TNC_RESULT_SUCCESS)
158 			return res;
159 	}
160 
161 	return TNC_RESULT_SUCCESS;
162 }
163 
164 
TNC_IMC_BatchEnding(TNC_IMCID imcID,TNC_ConnectionID connectionID)165 TNC_Result TNC_IMC_BatchEnding(
166 	/*in*/ TNC_IMCID imcID,
167 	/*in*/ TNC_ConnectionID connectionID)
168 {
169 	wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u, connectionID=%u)",
170 		   __func__, (unsigned) imcID, (unsigned) connectionID);
171 
172 	return TNC_RESULT_SUCCESS;
173 }
174 
175 
TNC_IMC_Terminate(TNC_IMCID imcID)176 TNC_Result TNC_IMC_Terminate(
177 	/*in*/ TNC_IMCID imcID)
178 {
179 	wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u)",
180 		   __func__, (unsigned) imcID);
181 
182 	return TNC_RESULT_SUCCESS;
183 }
184