|
1 /* |
|
2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: EAP and WLAN authentication protocols. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // This is enumeration of EAPOL source code. |
|
20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
21 #undef EAP_FILE_NUMBER_ENUM |
|
22 #define EAP_FILE_NUMBER_ENUM 48 |
|
23 #undef EAP_FILE_NUMBER_DATE |
|
24 #define EAP_FILE_NUMBER_DATE 1127594498 |
|
25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
26 |
|
27 |
|
28 |
|
29 #include "eap_am_memory.h" |
|
30 #include "eap_tools.h" |
|
31 #include "eapol_core.h" |
|
32 #include "eap_crypto_api.h" |
|
33 #include "eapol_key_header.h" |
|
34 #include "eapol_rc4_key_header.h" |
|
35 #include "eap_state_notification.h" |
|
36 #include "eap_automatic_variable.h" |
|
37 #include "eap_network_id_selector.h" |
|
38 #include "eap_config.h" |
|
39 #include "eap_buffer.h" |
|
40 #include "eapol_session_key.h" |
|
41 #include "eap_master_session_key.h" |
|
42 |
|
43 #define MPPE_KEY_LENGTH 32 |
|
44 |
|
45 //-------------------------------------------------- |
|
46 |
|
47 // |
|
48 EAP_FUNC_EXPORT eapol_core_c::~eapol_core_c() |
|
49 { |
|
50 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
51 |
|
52 EAP_TRACE_DEBUG( |
|
53 m_am_tools, |
|
54 TRACE_FLAGS_DEFAULT, |
|
55 (EAPL("eapol_core_c::~eapol_core_c(): this = 0x%08x\n"), |
|
56 this)); |
|
57 |
|
58 EAP_ASSERT(m_shutdown_was_called == true); |
|
59 |
|
60 delete m_eap_core; |
|
61 |
|
62 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
63 } |
|
64 |
|
65 //-------------------------------------------------- |
|
66 |
|
67 #if defined(_WIN32) && !defined(__GNUC__) |
|
68 #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list |
|
69 #endif |
|
70 |
|
71 // |
|
72 EAP_FUNC_EXPORT eapol_core_c::eapol_core_c( |
|
73 abs_eap_am_tools_c * const tools, |
|
74 abs_eapol_core_c * const partner, |
|
75 const bool is_client_when_true) |
|
76 : m_partner(partner) |
|
77 #if !defined(NO_EAP_SESSION_CORE) |
|
78 , m_eap_core(new eap_session_core_c(tools, this, is_client_when_true)) |
|
79 #else |
|
80 , m_eap_core(new eap_core_c(tools, this, is_client_when_true, 0, false)) |
|
81 #endif |
|
82 #if defined(USE_EAPOL_KEY_STATE) |
|
83 , m_eapol_key_state_map(tools, this) |
|
84 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
85 , m_am_tools(tools) |
|
86 , m_master_session_key(m_am_tools) |
|
87 , m_authentication_type(eapol_key_authentication_type_none) |
|
88 , m_eapol_header_offset(0u) |
|
89 , m_MTU(0u) |
|
90 , m_trailer_length(0u) |
|
91 , m_max_eapol_starts(0u) |
|
92 , m_eapol_start_interval(0u) |
|
93 , m_eapol_starts_sent(0u) |
|
94 , m_is_client(is_client_when_true) |
|
95 , m_is_valid(false) |
|
96 , m_shutdown_was_called(false) |
|
97 , m_block_state_notifications(false) |
|
98 #if defined(USE_EAPOL_KEY_STATE) |
|
99 , m_skip_start_4_way_handshake(false) |
|
100 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
101 { |
|
102 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
103 |
|
104 EAP_TRACE_DEBUG( |
|
105 m_am_tools, |
|
106 TRACE_FLAGS_DEFAULT, |
|
107 (EAPL("eapol_core_c::eapol_core_c(): %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"), |
|
108 (m_is_client == true) ? "client": "server", |
|
109 this, |
|
110 dynamic_cast<abs_eap_base_timer_c *>(this), |
|
111 __DATE__, |
|
112 __TIME__)); |
|
113 |
|
114 if (m_eap_core != 0 |
|
115 && m_eap_core->get_is_valid() == true) |
|
116 { |
|
117 set_is_valid(); |
|
118 } |
|
119 |
|
120 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
121 } |
|
122 |
|
123 //-------------------------------------------------- |
|
124 |
|
125 // |
|
126 EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_process( |
|
127 const eap_am_network_id_c * const receive_network_id, |
|
128 eap_general_header_base_c * const packet_data, |
|
129 const u32_t packet_length) |
|
130 { |
|
131 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
132 |
|
133 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
134 |
|
135 eap_status_e status = eap_status_process_general_error; |
|
136 |
|
137 if (receive_network_id == 0 |
|
138 || receive_network_id->get_is_valid_data() == false) |
|
139 { |
|
140 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
141 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
142 } |
|
143 |
|
144 if (packet_data == 0 |
|
145 || packet_length < eap_header_base_c::get_header_length()) |
|
146 { |
|
147 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
148 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
149 } |
|
150 |
|
151 eapol_header_wr_c eapol( |
|
152 m_am_tools, |
|
153 packet_data->get_header_buffer(packet_data->get_header_buffer_length()), |
|
154 packet_data->get_header_buffer_length()); |
|
155 |
|
156 if (eapol.get_is_valid() == false) |
|
157 { |
|
158 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
159 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
160 } |
|
161 |
|
162 if (packet_length < eapol.get_data_length()) |
|
163 { |
|
164 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
165 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
166 } |
|
167 |
|
168 if (m_eap_core == 0) |
|
169 { |
|
170 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
171 } |
|
172 |
|
173 if (packet_length < eapol_header_rd_c::get_header_length() // First we need atleast header to check the data length. |
|
174 || packet_length < eapol_header_rd_c::get_header_length()+eapol.get_data_length()) |
|
175 { |
|
176 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
177 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
178 } |
|
179 |
|
180 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("-> EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet_length 0x%04x\n"), |
|
181 (m_is_client == true) ? "client": "server", |
|
182 eapol.get_version(), |
|
183 eapol.get_packet_type(), |
|
184 eapol.get_type_string(), |
|
185 eapol.get_data_length(), |
|
186 packet_length)); |
|
187 |
|
188 status = eapol.check_header(); |
|
189 if (status != eap_status_ok) |
|
190 { |
|
191 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
192 return EAP_STATUS_RETURN(m_am_tools, status); |
|
193 } |
|
194 |
|
195 if (receive_network_id->get_type() == eapol_ethernet_type_preauthentication |
|
196 && eapol.get_packet_type() != eapol_packet_type_eap |
|
197 && eapol.get_packet_type() != eapol_packet_type_start) |
|
198 { |
|
199 // Only EAP-Packet and EAPOL-Start are valid for preauthentication. |
|
200 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
201 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); |
|
202 } |
|
203 |
|
204 |
|
205 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
206 |
|
207 eapol_key_state_c *eapol_key_state = 0; |
|
208 |
|
209 { |
|
210 // Here we swap the addresses. |
|
211 eap_am_network_id_c send_network_id( |
|
212 m_am_tools, |
|
213 receive_network_id->get_destination_id(), |
|
214 receive_network_id->get_source_id(), |
|
215 receive_network_id->get_type()); |
|
216 if (send_network_id.get_is_valid_data() == false) |
|
217 { |
|
218 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
219 } |
|
220 |
|
221 eap_network_id_selector_c state_selector( |
|
222 m_am_tools, |
|
223 &send_network_id); |
|
224 |
|
225 if (state_selector.get_is_valid() == false) |
|
226 { |
|
227 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
228 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
229 } |
|
230 |
|
231 EAP_TRACE_DATA_DEBUG( |
|
232 m_am_tools, |
|
233 TRACE_FLAGS_DEFAULT, |
|
234 (EAPL("packet_process(): EAPOL-Key session"), |
|
235 state_selector.get_data(state_selector.get_data_length()), |
|
236 state_selector.get_data_length())); |
|
237 |
|
238 |
|
239 // Check do we have handler for this packet. This applies to EAP-packets too. |
|
240 eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
241 |
|
242 if (eapol_key_state == 0) |
|
243 { |
|
244 EAP_TRACE_DEBUG( |
|
245 m_am_tools, |
|
246 TRACE_FLAGS_DEFAULT, |
|
247 (EAPL("ERROR: eapol_core_c::packet_process() failed, no eapol_key_state_c object for this packet. Drop packet.\n"))); |
|
248 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
249 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
250 } |
|
251 } |
|
252 |
|
253 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
254 |
|
255 |
|
256 if (eapol.get_packet_type() == eapol_packet_type_eap |
|
257 && eapol.get_data_length() >= eap_header_base_c::get_header_length()) |
|
258 { |
|
259 if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP |
|
260 && m_authentication_type != eapol_key_authentication_type_WPA_EAP |
|
261 && m_authentication_type != eapol_key_authentication_type_802_1X |
|
262 #if defined(EAP_USE_WPXM) |
|
263 && m_authentication_type != eapol_key_authentication_type_WPXM |
|
264 #endif //#if defined(EAP_USE_WPXM) |
|
265 && m_authentication_type != eapol_key_authentication_type_WFA_SC |
|
266 ) |
|
267 { |
|
268 EAP_TRACE_DEBUG( |
|
269 m_am_tools, |
|
270 TRACE_FLAGS_DEFAULT, |
|
271 (EAPL("WARNING: eapol_core_c::packet_process(): Illegal authentication type 0x%08x\n"), |
|
272 m_authentication_type)); |
|
273 |
|
274 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
275 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); |
|
276 } |
|
277 |
|
278 |
|
279 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
280 |
|
281 // Test first we are connected. |
|
282 if (eapol_key_state->get_is_associated() == true) |
|
283 { |
|
284 status = m_eap_core->synchronous_create_eap_session(receive_network_id); |
|
285 if (status != eap_status_ok) |
|
286 { |
|
287 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
288 return EAP_STATUS_RETURN(m_am_tools, status); |
|
289 } |
|
290 } |
|
291 |
|
292 #endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
293 |
|
294 |
|
295 eap_header_wr_c eap( |
|
296 m_am_tools, |
|
297 eapol.get_eap_header(), |
|
298 eapol.get_data_length()); |
|
299 |
|
300 status = m_eap_core->packet_process( |
|
301 receive_network_id, |
|
302 &eap, |
|
303 eapol.get_data_length()); |
|
304 |
|
305 EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); |
|
306 } |
|
307 else if (m_is_client == false |
|
308 && eapol.get_packet_type() == eapol_packet_type_logoff) |
|
309 { |
|
310 status = eap_status_ok; |
|
311 } |
|
312 else if (m_is_client == false |
|
313 && eapol.get_packet_type() == eapol_packet_type_start) |
|
314 { |
|
315 if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP |
|
316 && m_authentication_type != eapol_key_authentication_type_WPA_EAP |
|
317 && m_authentication_type != eapol_key_authentication_type_802_1X |
|
318 && m_authentication_type != eapol_key_authentication_type_WFA_SC |
|
319 #if defined(EAP_USE_WPXM) |
|
320 && m_authentication_type != eapol_key_authentication_type_WPXM |
|
321 #endif //#if defined(EAP_USE_WPXM) |
|
322 ) |
|
323 { |
|
324 EAP_TRACE_DEBUG( |
|
325 m_am_tools, |
|
326 TRACE_FLAGS_DEFAULT, |
|
327 (EAPL("WARNING: eapol_core_c::packet_process(): Illegal authentication type 0x%08x\n"), |
|
328 m_authentication_type)); |
|
329 |
|
330 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
331 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); |
|
332 } |
|
333 |
|
334 // This call does not cause clean restart. On-going authentication is not terminated. |
|
335 status = restart_authentication( |
|
336 receive_network_id, |
|
337 m_is_client, |
|
338 false); |
|
339 } |
|
340 #if defined(USE_EAPOL_KEY_STATE) |
|
341 else if (eapol.get_packet_type() == eapol_packet_type_key) |
|
342 { |
|
343 if (m_authentication_type != eapol_key_authentication_type_RSNA_EAP |
|
344 && m_authentication_type != eapol_key_authentication_type_RSNA_PSK |
|
345 && m_authentication_type != eapol_key_authentication_type_WPA_EAP |
|
346 && m_authentication_type != eapol_key_authentication_type_WPA_PSK |
|
347 && m_authentication_type != eapol_key_authentication_type_802_1X |
|
348 #if defined(EAP_USE_WPXM) |
|
349 && m_authentication_type != eapol_key_authentication_type_WPXM |
|
350 #endif //#if defined(EAP_USE_WPXM) |
|
351 ) |
|
352 { |
|
353 EAP_TRACE_DEBUG( |
|
354 m_am_tools, |
|
355 TRACE_FLAGS_DEFAULT, |
|
356 (EAPL("WARNING: eapol_core_c::packet_process(): Illegal authentication type 0x%08x\n"), |
|
357 m_authentication_type)); |
|
358 |
|
359 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
360 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_eapol_type); |
|
361 } |
|
362 |
|
363 // Indicates EAP-Core of received EAPOL-Key message. |
|
364 // This is indication of finished EAP-authentication. |
|
365 // NOTE, we do not care of the status. |
|
366 // Some EAP-types does not implement this function. |
|
367 (void) eap_acknowledge(receive_network_id); |
|
368 |
|
369 if (eapol_key_state != 0) |
|
370 { |
|
371 status = eapol_key_state->process_eapol_key_frame( |
|
372 receive_network_id, |
|
373 packet_data, |
|
374 packet_length); |
|
375 } |
|
376 else |
|
377 { |
|
378 EAP_TRACE_DEBUG( |
|
379 m_am_tools, |
|
380 TRACE_FLAGS_DEFAULT, |
|
381 (EAPL("ERROR: process_eapol_key_frame() failed, no eapol_key_state_c object\n"))); |
|
382 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
383 return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); |
|
384 } |
|
385 } |
|
386 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
387 #if ! defined(USE_EAPOL_KEY_STATE) |
|
388 else if ( |
|
389 m_is_client == true |
|
390 && eapol.get_packet_type() == eapol_packet_type_key) |
|
391 { |
|
392 // Handle EAPOL-Key frame. |
|
393 // Here is assumed the EAPOL-Key frame includes RC4 Key Descriptor. |
|
394 /** |
|
395 * @{ Here we need to check the Descriptor Type field. |
|
396 * It may be RC4 Key Descriptor, RSNA Key Descriptor or other descriptor. } |
|
397 */ |
|
398 |
|
399 eapol_RC4_key_header_c eapol_key_msg( |
|
400 m_am_tools, |
|
401 eapol.get_header_buffer(eapol.get_header_buffer_length()), |
|
402 eapol.get_header_buffer_length()); |
|
403 if (eapol_key_msg.get_is_valid() == false) |
|
404 { |
|
405 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
406 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
407 } |
|
408 else if (eapol_key_msg.check_header() != eap_status_ok) |
|
409 { |
|
410 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
411 return EAP_STATUS_RETURN(m_am_tools, status); |
|
412 } |
|
413 |
|
414 status = handle_RC4_key_descriptor( |
|
415 receive_network_id, |
|
416 &eapol_key_msg, |
|
417 packet_length); |
|
418 } |
|
419 #endif //#if ! defined(USE_EAPOL_KEY_STATE) |
|
420 else |
|
421 { |
|
422 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: %s, packet_type=0x%02x=%s not handled, data length 0x%04x.\n"), |
|
423 (m_is_client == true) ? "client": "server", |
|
424 eapol.get_packet_type(), |
|
425 eapol.get_type_string(), |
|
426 eapol.get_data_length())); |
|
427 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" source"), receive_network_id->get_source(), receive_network_id->get_source_length())); |
|
428 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("destination"), receive_network_id->get_destination(), receive_network_id->get_destination_length())); |
|
429 |
|
430 status = eap_status_wrong_eapol_type; |
|
431 } |
|
432 |
|
433 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
434 return EAP_STATUS_RETURN(m_am_tools, status); |
|
435 } |
|
436 |
|
437 //-------------------------------------------------- |
|
438 |
|
439 // |
|
440 EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_send( |
|
441 const eap_am_network_id_c * const send_network_id, |
|
442 eap_buf_chain_wr_c * const sent_packet, |
|
443 const u32_t header_offset, |
|
444 const u32_t data_length, |
|
445 const u32_t buffer_length) |
|
446 { |
|
447 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
448 |
|
449 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
450 EAP_ASSERT(header_offset < sent_packet->get_data_length()); |
|
451 EAP_ASSERT(data_length <= sent_packet->get_data_length()); |
|
452 EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); |
|
453 |
|
454 if (header_offset < eap_header_wr_c::get_header_length()) |
|
455 { |
|
456 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
457 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
458 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
459 } |
|
460 |
|
461 eapol_header_wr_c eapol( |
|
462 m_am_tools, |
|
463 sent_packet->get_data_offset( |
|
464 header_offset-eap_header_wr_c::get_header_length(), data_length), |
|
465 data_length); |
|
466 |
|
467 if (eapol.get_is_valid() == false) |
|
468 { |
|
469 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
470 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
471 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
472 } |
|
473 |
|
474 eapol.set_version(eapol_protocol_version_1); |
|
475 eapol.set_packet_type(eapol_packet_type_eap); |
|
476 eapol.set_data_length(static_cast<u16_t>(data_length)); |
|
477 |
|
478 { |
|
479 eap_network_id_selector_c state_selector( |
|
480 m_am_tools, |
|
481 send_network_id); |
|
482 if (state_selector.get_is_valid() == false) |
|
483 { |
|
484 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
485 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
486 } |
|
487 |
|
488 EAP_TRACE_DATA_DEBUG( |
|
489 m_am_tools, |
|
490 TRACE_FLAGS_DEFAULT, |
|
491 (EAPL("packet_send(): EAPOL-Key session"), |
|
492 state_selector.get_data(state_selector.get_data_length()), |
|
493 state_selector.get_data_length())); |
|
494 |
|
495 eapol_key_state_c *session = m_eapol_key_state_map.get_handler(&state_selector); |
|
496 |
|
497 bool encryption_on(false); |
|
498 |
|
499 if (session != 0 |
|
500 && session->get_is_valid() == true) |
|
501 { |
|
502 encryption_on = session->get_is_encryption_on(); |
|
503 } |
|
504 |
|
505 EAP_TRACE_DEBUG( |
|
506 m_am_tools, |
|
507 TRACE_FLAGS_DEFAULT, |
|
508 (EAPL("Read EAPOL-Key session: encryption is %s\n"), |
|
509 ((encryption_on == true) ? "on" : "off"))); |
|
510 |
|
511 sent_packet->set_encrypt(encryption_on); |
|
512 } |
|
513 |
|
514 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("<- EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet_length 0x%04x\n"), |
|
515 (m_is_client == true) ? "client": "server", |
|
516 eapol.get_version(), |
|
517 eapol.get_packet_type(), |
|
518 eapol.get_type_string(), |
|
519 eapol.get_data_length(), |
|
520 data_length)); |
|
521 |
|
522 if (m_shutdown_was_called == true |
|
523 && m_is_client == true) |
|
524 { |
|
525 EAP_TRACE_DEBUG( |
|
526 m_am_tools, |
|
527 TRACE_FLAGS_DEFAULT, |
|
528 (EAPL("WARNING: EAP_Core: %s, eapol_core_c::packet_send(): %s packet dropped quietly because shutdown was already called.\n"), |
|
529 (m_is_client == true) ? "client": "server", |
|
530 eapol.get_type_string())); |
|
531 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
532 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
533 } |
|
534 |
|
535 eap_status_e status = m_partner->packet_send( |
|
536 send_network_id, sent_packet, header_offset-eapol_header_wr_c::get_header_length(), |
|
537 data_length+eapol_header_wr_c::get_header_length(), buffer_length); |
|
538 |
|
539 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
540 return EAP_STATUS_RETURN(m_am_tools, status); |
|
541 } |
|
542 |
|
543 //-------------------------------------------------- |
|
544 |
|
545 // |
|
546 EAP_FUNC_EXPORT u32_t eapol_core_c::get_header_offset( |
|
547 u32_t * const MTU, |
|
548 u32_t * const trailer_length) |
|
549 { |
|
550 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
551 |
|
552 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
553 |
|
554 const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); |
|
555 (*MTU) -= eapol_header_wr_c::get_header_length(); |
|
556 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
557 return offset+eapol_header_wr_c::get_header_length(); |
|
558 } |
|
559 |
|
560 //-------------------------------------------------- |
|
561 |
|
562 // |
|
563 EAP_FUNC_EXPORT eap_status_e eapol_core_c::eap_acknowledge( |
|
564 const eap_am_network_id_c * const receive_network_id) |
|
565 { |
|
566 // Any Network Protocol packet is accepted as a success indication. |
|
567 // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". |
|
568 |
|
569 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
570 |
|
571 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
572 |
|
573 if (m_eap_core == 0) |
|
574 { |
|
575 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
576 } |
|
577 |
|
578 eap_status_e status = m_eap_core->eap_acknowledge(receive_network_id); |
|
579 |
|
580 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
581 |
|
582 return EAP_STATUS_RETURN(m_am_tools, status); |
|
583 } |
|
584 |
|
585 //-------------------------------------------------- |
|
586 |
|
587 // |
|
588 EAP_FUNC_EXPORT eap_status_e eapol_core_c::load_module( |
|
589 const eap_type_value_e type, |
|
590 const eap_type_value_e tunneling_type, |
|
591 abs_eap_base_type_c * const partner, |
|
592 eap_base_type_c ** const eap_type, |
|
593 const bool is_client_when_true, |
|
594 const eap_am_network_id_c * const receive_network_id) |
|
595 { |
|
596 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
597 |
|
598 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
599 |
|
600 eap_status_e status = m_partner->load_module( |
|
601 type, |
|
602 tunneling_type, |
|
603 partner, |
|
604 eap_type, |
|
605 is_client_when_true, |
|
606 receive_network_id); |
|
607 |
|
608 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
609 return EAP_STATUS_RETURN(m_am_tools, status); |
|
610 } |
|
611 |
|
612 //-------------------------------------------------- |
|
613 |
|
614 // |
|
615 EAP_FUNC_EXPORT eap_status_e eapol_core_c::unload_module(const eap_type_value_e type) |
|
616 { |
|
617 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
618 |
|
619 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
620 |
|
621 const eap_status_e status = m_partner->unload_module(type); |
|
622 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
623 return EAP_STATUS_RETURN(m_am_tools, status); |
|
624 } |
|
625 |
|
626 //-------------------------------------------------- |
|
627 |
|
628 // |
|
629 EAP_FUNC_EXPORT eap_status_e eapol_core_c::restart_authentication( |
|
630 const eap_am_network_id_c * const receive_network_id, |
|
631 const bool is_client_when_true, |
|
632 const bool force_clean_restart, |
|
633 const bool from_timer) |
|
634 { |
|
635 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
636 |
|
637 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
638 |
|
639 EAP_TRACE_DEBUG( |
|
640 m_am_tools, |
|
641 TRACE_FLAGS_DEFAULT, |
|
642 (EAPL("eapol_core_c::restart_authentication(): %s\n"), |
|
643 (m_is_client == true) ? "client": "server")); |
|
644 |
|
645 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::restart_authentication()"); |
|
646 |
|
647 eap_status_e status = eap_status_process_general_error; |
|
648 |
|
649 if (receive_network_id->get_type() != eapol_ethernet_type_pae |
|
650 && receive_network_id->get_type() != eapol_ethernet_type_preauthentication) |
|
651 { |
|
652 EAP_TRACE_DEBUG( |
|
653 m_am_tools, |
|
654 TRACE_FLAGS_DEFAULT, |
|
655 (EAPL("WARNING: eapol_core_c::restart_authentication(): Illegal Ethernet type %d\n"), |
|
656 receive_network_id->get_type())); |
|
657 |
|
658 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
659 return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); |
|
660 } |
|
661 |
|
662 if (is_client_when_true == true) |
|
663 { |
|
664 // Client sends a EAPOL-Start message. |
|
665 (void) m_partner->cancel_timer( |
|
666 this, |
|
667 EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); |
|
668 |
|
669 #if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
670 #if !defined(NO_EAP_SESSION_CORE) |
|
671 // First we remove possible EAP session. |
|
672 (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); |
|
673 #endif |
|
674 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
675 |
|
676 // Here we swap the addresses. |
|
677 eap_am_network_id_c send_network_id(m_am_tools, |
|
678 receive_network_id->get_destination_id(), |
|
679 receive_network_id->get_source_id(), |
|
680 receive_network_id->get_type()); |
|
681 if (send_network_id.get_is_valid_data() == false) |
|
682 { |
|
683 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
684 } |
|
685 |
|
686 eap_buf_chain_wr_c start_packet( |
|
687 eap_write_buffer, |
|
688 m_am_tools, |
|
689 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
690 |
|
691 if (start_packet.get_is_valid() == false) |
|
692 { |
|
693 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); |
|
694 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
695 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
696 } |
|
697 |
|
698 u32_t buffer_size = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; |
|
699 EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length); |
|
700 if (m_MTU-m_trailer_length < buffer_size) |
|
701 { |
|
702 buffer_size = m_MTU-m_trailer_length; |
|
703 } |
|
704 |
|
705 EAP_ASSERT_ALWAYS(buffer_size >= m_eapol_header_offset); |
|
706 eapol_header_wr_c eapol( |
|
707 m_am_tools, |
|
708 start_packet.get_data_offset( |
|
709 m_eapol_header_offset, |
|
710 (buffer_size-m_eapol_header_offset)), |
|
711 (buffer_size-m_eapol_header_offset)); |
|
712 |
|
713 if (eapol.get_is_valid() == false) |
|
714 { |
|
715 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
716 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
717 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
718 } |
|
719 |
|
720 eapol.set_version(eapol_protocol_version_1); |
|
721 eapol.set_packet_type(eapol_packet_type_start); |
|
722 eapol.set_data_length(0); |
|
723 |
|
724 start_packet.set_data_length( |
|
725 m_eapol_header_offset |
|
726 +eapol_header_wr_c::get_header_length() |
|
727 +eapol.get_data_length()); |
|
728 |
|
729 EAP_TRACE_DEBUG( |
|
730 m_am_tools, |
|
731 TRACE_FLAGS_DEFAULT, |
|
732 (EAPL("<- EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet length 0x%04x\n"), |
|
733 (m_is_client == true) ? "client": "server", |
|
734 eapol.get_version(), |
|
735 eapol.get_packet_type(), |
|
736 eapol.get_type_string(), |
|
737 eapol.get_data_length(), |
|
738 eapol_header_wr_c::get_header_length()+eapol.get_data_length())); |
|
739 |
|
740 status = m_partner->packet_send( |
|
741 &send_network_id, |
|
742 &start_packet, |
|
743 m_eapol_header_offset, |
|
744 eapol_header_wr_c::get_header_length()+eapol.get_data_length(), |
|
745 buffer_size); |
|
746 |
|
747 if (from_timer == false) |
|
748 { |
|
749 // Reset EAPOL-Start counter because this is not a resending. |
|
750 m_eapol_starts_sent = 1; |
|
751 // Send notification |
|
752 eap_state_notification_c notification( |
|
753 m_am_tools, |
|
754 &send_network_id, |
|
755 true, // m_is_client |
|
756 eap_state_notification_generic, |
|
757 eap_protocol_layer_eapol, |
|
758 eap_type_none, |
|
759 eapol_state_none, |
|
760 eapol_state_start_sent, |
|
761 0 /* EAP identifier not valid here */, |
|
762 false); |
|
763 state_notification(¬ification); |
|
764 } |
|
765 |
|
766 // This copy is important because timer needs data that is allocated from heap. |
|
767 eap_am_network_id_c * const copy_receive_network_id = receive_network_id->copy(); |
|
768 eap_automatic_variable_c<eap_am_network_id_c> automatic_copy_receive_network_id( |
|
769 m_am_tools, |
|
770 copy_receive_network_id); |
|
771 |
|
772 if (copy_receive_network_id == 0 |
|
773 || copy_receive_network_id->get_is_valid_data() == false) |
|
774 { |
|
775 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
776 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
777 } |
|
778 |
|
779 // Timer will hold copy_send_network_id data. |
|
780 automatic_copy_receive_network_id.do_not_free_variable(); |
|
781 |
|
782 status = m_partner->set_timer( |
|
783 this, |
|
784 EAPOL_CORE_TIMER_SEND_START_AGAIN_ID, |
|
785 copy_receive_network_id, |
|
786 m_eapol_start_interval); |
|
787 if (status != eap_status_ok) |
|
788 { |
|
789 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
790 return EAP_STATUS_RETURN(m_am_tools, status); |
|
791 } |
|
792 |
|
793 EAP_TRACE_DEBUG( |
|
794 m_am_tools, |
|
795 TRACE_FLAGS_DEFAULT, |
|
796 (EAPL("TIMER: %s: EAPOL_CORE_TIMER_SEND_START_AGAIN_ID set %d ms.\n"), |
|
797 (m_is_client == true ? "client": "server"), |
|
798 m_eapol_start_interval)); |
|
799 |
|
800 } |
|
801 #if defined(USE_EAP_CORE_SERVER) |
|
802 else |
|
803 { |
|
804 // Server. |
|
805 |
|
806 if (m_eap_core == 0) |
|
807 { |
|
808 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
809 } |
|
810 |
|
811 if (force_clean_restart == true) |
|
812 { |
|
813 // It is bad idea to terminate on-going authentication |
|
814 // when EAPOL-Start is received. |
|
815 // Because of that synchronous_remove_eap_session() is called |
|
816 // only when force_clean_restart is true. |
|
817 #if !defined(NO_EAP_SESSION_CORE) |
|
818 bool previous_block = m_block_state_notifications; |
|
819 m_block_state_notifications = true; |
|
820 (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); |
|
821 m_block_state_notifications = previous_block; |
|
822 #endif |
|
823 } |
|
824 |
|
825 if (m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
826 || m_authentication_type == eapol_key_authentication_type_WPA_EAP |
|
827 || m_authentication_type == eapol_key_authentication_type_802_1X |
|
828 #if defined(EAP_USE_WPXM) |
|
829 || m_authentication_type == eapol_key_authentication_type_WPXM |
|
830 #endif //#if defined(EAP_USE_WPXM) |
|
831 || m_authentication_type == eapol_key_authentication_type_WFA_SC |
|
832 ) |
|
833 { |
|
834 status = m_eap_core->send_eap_identity_request(receive_network_id); |
|
835 } |
|
836 else |
|
837 { |
|
838 status = eap_status_ok; |
|
839 } |
|
840 } |
|
841 |
|
842 #else |
|
843 |
|
844 EAP_UNREFERENCED_PARAMETER(force_clean_restart); // Only server version uses this. |
|
845 |
|
846 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
847 |
|
848 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
849 return EAP_STATUS_RETURN(m_am_tools, status); |
|
850 } |
|
851 |
|
852 //-------------------------------------------------- |
|
853 |
|
854 // |
|
855 EAP_FUNC_EXPORT eap_status_e eapol_core_c::check_pmksa_cache( |
|
856 eap_array_c<eap_am_network_id_c> * const bssid_sta_receive_network_ids, |
|
857 const eapol_key_authentication_type_e selected_eapol_key_authentication_type, |
|
858 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, |
|
859 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite) |
|
860 { |
|
861 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
862 |
|
863 EAP_TRACE_DEBUG( |
|
864 m_am_tools, |
|
865 TRACE_FLAGS_DEFAULT, |
|
866 (EAPL("eapol_core_c::check_pmksa_cache(): %s\n"), |
|
867 (m_is_client == true) ? "client": "server")); |
|
868 |
|
869 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::check_pmksa_cache()"); |
|
870 |
|
871 eap_status_e status = eap_status_ok; |
|
872 |
|
873 for (u32_t ind = 0ul; ind < bssid_sta_receive_network_ids->get_object_count();) |
|
874 { |
|
875 eap_am_network_id_c * const receive_network_id = bssid_sta_receive_network_ids->get_object(ind); |
|
876 if (receive_network_id == 0) |
|
877 { |
|
878 bssid_sta_receive_network_ids->reset(); |
|
879 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
880 } |
|
881 |
|
882 // Here we swap the addresses. |
|
883 eap_am_network_id_c send_network_id( |
|
884 m_am_tools, |
|
885 receive_network_id->get_destination_id(), |
|
886 receive_network_id->get_source_id(), |
|
887 receive_network_id->get_type()); |
|
888 if (send_network_id.get_is_valid_data() == false) |
|
889 { |
|
890 bssid_sta_receive_network_ids->reset(); |
|
891 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
892 } |
|
893 |
|
894 eap_network_id_selector_c state_selector( |
|
895 m_am_tools, |
|
896 &send_network_id); |
|
897 if (state_selector.get_is_valid() == false) |
|
898 { |
|
899 bssid_sta_receive_network_ids->reset(); |
|
900 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
901 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
902 } |
|
903 |
|
904 EAP_TRACE_DATA_DEBUG( |
|
905 m_am_tools, |
|
906 TRACE_FLAGS_DEFAULT, |
|
907 (EAPL("check_pmksa_cache(): checks PMKSA EAPOL-Key session"), |
|
908 state_selector.get_data(state_selector.get_data_length()), |
|
909 state_selector.get_data_length())); |
|
910 |
|
911 eapol_key_state_c *session = m_eapol_key_state_map.get_handler(&state_selector); |
|
912 |
|
913 if (session == 0 |
|
914 || selected_eapol_key_authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
915 || selected_eapol_key_authentication_type == eapol_key_authentication_type_WPA_PSK |
|
916 || session->check_pmksa_cache( |
|
917 selected_eapol_key_authentication_type, |
|
918 pairwise_key_cipher_suite, |
|
919 group_key_cipher_suite) != eap_status_ok) |
|
920 { |
|
921 // No cached PMKID for this address and security suite. |
|
922 EAP_TRACE_DATA_DEBUG( |
|
923 m_am_tools, |
|
924 TRACE_FLAGS_DEFAULT, |
|
925 (EAPL("No cached PMKID for this address"), |
|
926 state_selector.get_data(state_selector.get_data_length()), |
|
927 state_selector.get_data_length())); |
|
928 |
|
929 status = bssid_sta_receive_network_ids->remove_object(ind); |
|
930 if (status != eap_status_ok) |
|
931 { |
|
932 bssid_sta_receive_network_ids->reset(); |
|
933 return EAP_STATUS_RETURN(m_am_tools, status); |
|
934 } |
|
935 |
|
936 // Note here we do not increase index because we removed the current object. |
|
937 } |
|
938 else |
|
939 { |
|
940 // Check the next index. |
|
941 ++ind; |
|
942 } |
|
943 } // for() |
|
944 |
|
945 if (bssid_sta_receive_network_ids->get_object_count() > 0ul) |
|
946 { |
|
947 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
948 return EAP_STATUS_RETURN(m_am_tools, status); |
|
949 } |
|
950 else |
|
951 { |
|
952 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
953 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_found); |
|
954 } |
|
955 } |
|
956 |
|
957 //-------------------------------------------------- |
|
958 |
|
959 /** |
|
960 * This function removes PMKSA from cache. |
|
961 * @param receive_network_id carries the MAC addresses. |
|
962 * MAC address of Authenticator should be in source address. |
|
963 * MAC address of Supplicant should be in destination address. |
|
964 */ |
|
965 EAP_FUNC_EXPORT eap_status_e eapol_core_c::remove_pmksa_from_cache( |
|
966 const eap_am_network_id_c * const receive_network_id |
|
967 ) |
|
968 { |
|
969 eap_status_e status = eap_status_process_general_error; |
|
970 |
|
971 EAP_TRACE_DEBUG( |
|
972 m_am_tools, |
|
973 TRACE_FLAGS_DEFAULT, |
|
974 (EAPL("%s: eapol_core_c::remove_pmksa_from_cache().\n"), |
|
975 (m_is_client == true) ? "client": "server")); |
|
976 |
|
977 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::remove_pmksa_from_cache()"); |
|
978 |
|
979 if (receive_network_id == 0) |
|
980 { |
|
981 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
982 } |
|
983 |
|
984 // Here we swap the addresses. |
|
985 eap_am_network_id_c send_network_id( |
|
986 m_am_tools, |
|
987 receive_network_id->get_destination_id(), |
|
988 receive_network_id->get_source_id(), |
|
989 receive_network_id->get_type()); |
|
990 if (send_network_id.get_is_valid_data() == false) |
|
991 { |
|
992 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
993 } |
|
994 |
|
995 status = remove_eapol_key_state( |
|
996 &send_network_id); |
|
997 if (status != eap_status_ok) |
|
998 { |
|
999 EAP_TRACE_DEBUG( |
|
1000 m_am_tools, |
|
1001 TRACE_FLAGS_DEFAULT, |
|
1002 (EAPL("WARNING: eapol_core_c::disassociation(): ") |
|
1003 EAPL("remove_eapol_key_state(), eap_status_e %d\n"), |
|
1004 status)); |
|
1005 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1006 } |
|
1007 |
|
1008 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1009 } |
|
1010 |
|
1011 //-------------------------------------------------- |
|
1012 |
|
1013 // |
|
1014 EAP_FUNC_EXPORT eap_status_e eapol_core_c::start_preauthentication( |
|
1015 const eap_am_network_id_c * const receive_network_id, |
|
1016 const eapol_key_authentication_type_e authentication_type) |
|
1017 { |
|
1018 eap_status_e status = eap_status_process_general_error; |
|
1019 |
|
1020 EAP_TRACE_DEBUG( |
|
1021 m_am_tools, |
|
1022 TRACE_FLAGS_DEFAULT, |
|
1023 (EAPL("%s: eapol_core_c::start_preauthentication().\n"), |
|
1024 (m_is_client == true) ? "client": "server")); |
|
1025 |
|
1026 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::start_preauthentication()"); |
|
1027 |
|
1028 #if defined(USE_EAPOL_KEY_STATE) |
|
1029 |
|
1030 if (receive_network_id->get_type() != eapol_ethernet_type_preauthentication) |
|
1031 { |
|
1032 EAP_TRACE_DEBUG( |
|
1033 m_am_tools, |
|
1034 TRACE_FLAGS_DEFAULT, |
|
1035 (EAPL("WARNING: eapol_core_c::start_preauthentication(): Illegal Ethernet type 0x%04x\n"), |
|
1036 receive_network_id->get_type())); |
|
1037 |
|
1038 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1039 return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); |
|
1040 } |
|
1041 |
|
1042 |
|
1043 if (m_authentication_type != authentication_type) |
|
1044 { |
|
1045 EAP_TRACE_DEBUG( |
|
1046 m_am_tools, |
|
1047 TRACE_FLAGS_DEFAULT, |
|
1048 (EAPL("WARNING: eapol_core_c::start_preauthentication(): Illegal authentication type 0x%08x, ") |
|
1049 EAPL("it should be 0x%08x\n"), |
|
1050 authentication_type, |
|
1051 m_authentication_type)); |
|
1052 |
|
1053 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1054 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_authentication_type); |
|
1055 } |
|
1056 |
|
1057 |
|
1058 // Here we swap the addresses. |
|
1059 eap_am_network_id_c send_network_id( |
|
1060 m_am_tools, |
|
1061 receive_network_id->get_destination_id(), |
|
1062 receive_network_id->get_source_id(), |
|
1063 receive_network_id->get_type()); |
|
1064 if (send_network_id.get_is_valid_data() == false) |
|
1065 { |
|
1066 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1067 } |
|
1068 |
|
1069 eap_network_id_selector_c state_selector( |
|
1070 m_am_tools, |
|
1071 &send_network_id); |
|
1072 |
|
1073 if (state_selector.get_is_valid() == false) |
|
1074 { |
|
1075 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1076 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1077 } |
|
1078 |
|
1079 EAP_TRACE_DATA_DEBUG( |
|
1080 m_am_tools, |
|
1081 TRACE_FLAGS_DEFAULT, |
|
1082 (EAPL("start_preauthentication(): EAPOL-Key session"), |
|
1083 state_selector.get_data(state_selector.get_data_length()), |
|
1084 state_selector.get_data_length())); |
|
1085 |
|
1086 |
|
1087 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
1088 |
|
1089 if (eapol_key_state != 0) |
|
1090 { |
|
1091 // Reuse the session. |
|
1092 eapol_key_state->unset_marked_removed(); |
|
1093 |
|
1094 status = eapol_key_state->reset(); |
|
1095 if (status != eap_status_ok) |
|
1096 { |
|
1097 // We cannot reuse the session. |
|
1098 EAP_TRACE_ERROR( |
|
1099 m_am_tools, |
|
1100 TRACE_FLAGS_ERROR, |
|
1101 (EAPL("start_preauthentication(): eapol_key_state NOT reused.\n"))); |
|
1102 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1103 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1104 } |
|
1105 } |
|
1106 |
|
1107 |
|
1108 if (eapol_key_state == 0) |
|
1109 { |
|
1110 eapol_key_state = new eapol_key_state_c( |
|
1111 m_am_tools, |
|
1112 this, |
|
1113 m_partner, |
|
1114 m_is_client, |
|
1115 receive_network_id, |
|
1116 authentication_type); |
|
1117 if (eapol_key_state == 0 |
|
1118 || eapol_key_state->get_is_valid() == false) |
|
1119 { |
|
1120 if (eapol_key_state != 0) |
|
1121 { |
|
1122 eapol_key_state->shutdown(); |
|
1123 } |
|
1124 else |
|
1125 { |
|
1126 EAP_TRACE_DEBUG( |
|
1127 m_am_tools, |
|
1128 TRACE_FLAGS_DEFAULT, |
|
1129 (EAPL("WARNING: eapol_core_c::start_preauthentication(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), |
|
1130 eapol_key_state)); |
|
1131 } |
|
1132 delete eapol_key_state; |
|
1133 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1134 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1135 } |
|
1136 |
|
1137 status = eapol_key_state->initialize_preauthentication( |
|
1138 receive_network_id, |
|
1139 authentication_type); |
|
1140 if (status != eap_status_ok) |
|
1141 { |
|
1142 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1143 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1144 } |
|
1145 |
|
1146 status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); |
|
1147 if (status != eap_status_ok) |
|
1148 { |
|
1149 eapol_key_state->shutdown(); |
|
1150 delete eapol_key_state; |
|
1151 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1152 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1153 } |
|
1154 } |
|
1155 else |
|
1156 { |
|
1157 status = eapol_key_state->initialize_preauthentication( |
|
1158 receive_network_id, |
|
1159 authentication_type); |
|
1160 if (status != eap_status_ok) |
|
1161 { |
|
1162 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1163 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1164 } |
|
1165 } |
|
1166 |
|
1167 |
|
1168 status = eapol_key_state->configure(); |
|
1169 if (status != eap_status_ok) |
|
1170 { |
|
1171 status = remove_eapol_key_state( |
|
1172 &send_network_id); |
|
1173 if (status != eap_status_ok) |
|
1174 { |
|
1175 EAP_TRACE_DEBUG( |
|
1176 m_am_tools, |
|
1177 TRACE_FLAGS_DEFAULT, |
|
1178 (EAPL("WARNING: eapol_core_c::start_preauthentication(): remove_eapol_key_state(), eap_status_e %d\n"), |
|
1179 status)); |
|
1180 } |
|
1181 |
|
1182 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1183 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1184 } |
|
1185 |
|
1186 |
|
1187 // This call does cause clean restart. On-going authentication is terminated. |
|
1188 status = restart_authentication( |
|
1189 receive_network_id, |
|
1190 m_is_client, |
|
1191 true, |
|
1192 false); |
|
1193 |
|
1194 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1195 |
|
1196 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1197 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1198 } |
|
1199 |
|
1200 //-------------------------------------------------- |
|
1201 |
|
1202 // |
|
1203 eap_status_e eapol_core_c::copy_eapol_key_state( |
|
1204 const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. |
|
1205 const eap_am_network_id_c * const new_receive_network_id ///< source includes remote address, destination includes local address. |
|
1206 ) |
|
1207 { |
|
1208 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1209 |
|
1210 EAP_TRACE_DEBUG( |
|
1211 m_am_tools, |
|
1212 TRACE_FLAGS_DEFAULT, |
|
1213 (EAPL("%s: eapol_core_c::copy_eapol_key_state()\n"), |
|
1214 (m_is_client == true) ? "client": "server")); |
|
1215 |
|
1216 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::copy_eapol_key_state()"); |
|
1217 |
|
1218 eap_status_e status(eap_status_process_general_error); |
|
1219 |
|
1220 if (old_receive_network_id == 0 |
|
1221 || old_receive_network_id->get_is_valid_data() == false) |
|
1222 { |
|
1223 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1224 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1225 } |
|
1226 |
|
1227 if (new_receive_network_id == 0 |
|
1228 || new_receive_network_id->get_is_valid_data() == false) |
|
1229 { |
|
1230 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1231 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1232 } |
|
1233 |
|
1234 #if defined(USE_EAPOL_KEY_STATE) |
|
1235 |
|
1236 // Here we swap the addresses. |
|
1237 eap_am_network_id_c old_send_network_id( |
|
1238 m_am_tools, |
|
1239 old_receive_network_id->get_destination_id(), |
|
1240 old_receive_network_id->get_source_id(), |
|
1241 old_receive_network_id->get_type()); |
|
1242 if (old_send_network_id.get_is_valid_data() == false) |
|
1243 { |
|
1244 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1245 } |
|
1246 |
|
1247 eap_network_id_selector_c old_state_selector( |
|
1248 m_am_tools, |
|
1249 &old_send_network_id); |
|
1250 |
|
1251 if (old_state_selector.get_is_valid() == false) |
|
1252 { |
|
1253 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1254 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1255 } |
|
1256 |
|
1257 EAP_TRACE_DATA_DEBUG( |
|
1258 m_am_tools, |
|
1259 TRACE_FLAGS_DEFAULT, |
|
1260 (EAPL("copy_eapol_key_state(): old EAPOL-Key session"), |
|
1261 old_state_selector.get_data(), |
|
1262 old_state_selector.get_data_length())); |
|
1263 |
|
1264 eapol_key_state_c *old_eapol_key_state = m_eapol_key_state_map.get_handler(&old_state_selector); |
|
1265 |
|
1266 if (old_eapol_key_state != 0) |
|
1267 { |
|
1268 { |
|
1269 // Here we remove the old state from map. Note the old state is not deleted. |
|
1270 // Later we add the modified old map to new location in the map. |
|
1271 status = m_eapol_key_state_map.remove_handler(&old_state_selector, false); |
|
1272 if (status != eap_status_ok) |
|
1273 { |
|
1274 old_eapol_key_state->shutdown(); |
|
1275 delete old_eapol_key_state; |
|
1276 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1277 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1278 } |
|
1279 |
|
1280 // Set up the old state and add it to m_eapol_key_state_map. |
|
1281 |
|
1282 // Here we swap the addresses. |
|
1283 eap_am_network_id_c new_send_network_id( |
|
1284 m_am_tools, |
|
1285 new_receive_network_id->get_destination_id(), |
|
1286 new_receive_network_id->get_source_id(), |
|
1287 new_receive_network_id->get_type()); |
|
1288 if (new_send_network_id.get_is_valid_data() == false) |
|
1289 { |
|
1290 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1291 } |
|
1292 |
|
1293 #if defined(EAP_USE_WPXM) |
|
1294 status = old_eapol_key_state->set_WPXM_parameters(new_receive_network_id); |
|
1295 if (status != eap_status_ok) |
|
1296 { |
|
1297 old_eapol_key_state->shutdown(); |
|
1298 delete old_eapol_key_state; |
|
1299 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1300 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1301 } |
|
1302 #endif //#if defined(EAP_USE_WPXM) |
|
1303 |
|
1304 eap_network_id_selector_c new_state_selector( |
|
1305 m_am_tools, |
|
1306 &new_send_network_id); |
|
1307 |
|
1308 if (new_state_selector.get_is_valid() == false) |
|
1309 { |
|
1310 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1311 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1312 } |
|
1313 |
|
1314 EAP_TRACE_DATA_DEBUG( |
|
1315 m_am_tools, |
|
1316 TRACE_FLAGS_DEFAULT, |
|
1317 (EAPL("copy_eapol_key_state(): new EAPOL-Key session"), |
|
1318 new_state_selector.get_data(), |
|
1319 new_state_selector.get_data_length())); |
|
1320 |
|
1321 status = m_eapol_key_state_map.add_handler(&new_state_selector, old_eapol_key_state); |
|
1322 if (status != eap_status_ok) |
|
1323 { |
|
1324 old_eapol_key_state->shutdown(); |
|
1325 delete old_eapol_key_state; |
|
1326 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1327 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1328 } |
|
1329 } |
|
1330 } |
|
1331 |
|
1332 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1333 |
|
1334 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1335 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1336 } |
|
1337 |
|
1338 //-------------------------------------------------- |
|
1339 |
|
1340 // |
|
1341 eap_status_e eapol_core_c::generate_new_pmksa( |
|
1342 eapol_key_state_c * * const new_eapol_key_state, |
|
1343 const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. |
|
1344 const eap_am_network_id_c * const new_receive_network_id ///< source includes remote address, destination includes local address. |
|
1345 ) |
|
1346 { |
|
1347 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1348 |
|
1349 EAP_TRACE_DEBUG( |
|
1350 m_am_tools, |
|
1351 TRACE_FLAGS_DEFAULT, |
|
1352 (EAPL("%s: eapol_core_c::generate_new_pmksa()\n"), |
|
1353 (m_is_client == true) ? "client": "server")); |
|
1354 |
|
1355 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::generate_new_pmksa()"); |
|
1356 |
|
1357 eap_status_e status(eap_status_process_general_error); |
|
1358 |
|
1359 if (new_eapol_key_state == 0) |
|
1360 { |
|
1361 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1362 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1363 } |
|
1364 |
|
1365 if (old_receive_network_id == 0 |
|
1366 || old_receive_network_id->get_is_valid_data() == false) |
|
1367 { |
|
1368 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1369 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1370 } |
|
1371 |
|
1372 if (new_receive_network_id == 0 |
|
1373 || new_receive_network_id->get_is_valid_data() == false) |
|
1374 { |
|
1375 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1376 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1377 } |
|
1378 |
|
1379 #if defined(USE_EAPOL_KEY_STATE) |
|
1380 |
|
1381 // Here we swap the addresses. |
|
1382 eap_am_network_id_c old_send_network_id( |
|
1383 m_am_tools, |
|
1384 old_receive_network_id->get_destination_id(), |
|
1385 old_receive_network_id->get_source_id(), |
|
1386 old_receive_network_id->get_type()); |
|
1387 if (old_send_network_id.get_is_valid_data() == false) |
|
1388 { |
|
1389 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1390 } |
|
1391 |
|
1392 eap_network_id_selector_c old_state_selector( |
|
1393 m_am_tools, |
|
1394 &old_send_network_id); |
|
1395 |
|
1396 if (old_state_selector.get_is_valid() == false) |
|
1397 { |
|
1398 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1399 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1400 } |
|
1401 |
|
1402 EAP_TRACE_DATA_DEBUG( |
|
1403 m_am_tools, |
|
1404 TRACE_FLAGS_DEFAULT, |
|
1405 (EAPL("generate_new_pmksa(): old EAPOL-Key session"), |
|
1406 old_state_selector.get_data(), |
|
1407 old_state_selector.get_data_length())); |
|
1408 |
|
1409 eapol_key_state_c *old_eapol_key_state = m_eapol_key_state_map.get_handler(&old_state_selector); |
|
1410 |
|
1411 if (old_eapol_key_state != 0) |
|
1412 { |
|
1413 *new_eapol_key_state = old_eapol_key_state->copy(new_receive_network_id); |
|
1414 |
|
1415 if (*new_eapol_key_state == 0 |
|
1416 || (*new_eapol_key_state)->get_is_valid() == false) |
|
1417 { |
|
1418 if (*new_eapol_key_state != 0) |
|
1419 { |
|
1420 (*new_eapol_key_state)->shutdown(); |
|
1421 delete *new_eapol_key_state; |
|
1422 *new_eapol_key_state = 0; |
|
1423 } |
|
1424 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1425 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1426 } |
|
1427 |
|
1428 if (*new_eapol_key_state != 0) |
|
1429 { |
|
1430 // Here we swap the addresses. |
|
1431 eap_am_network_id_c new_send_network_id( |
|
1432 m_am_tools, |
|
1433 new_receive_network_id->get_destination_id(), |
|
1434 new_receive_network_id->get_source_id(), |
|
1435 new_receive_network_id->get_type()); |
|
1436 if (new_send_network_id.get_is_valid_data() == false) |
|
1437 { |
|
1438 (*new_eapol_key_state)->shutdown(); |
|
1439 delete *new_eapol_key_state; |
|
1440 *new_eapol_key_state = 0; |
|
1441 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1442 } |
|
1443 |
|
1444 eap_network_id_selector_c new_state_selector( |
|
1445 m_am_tools, |
|
1446 &new_send_network_id); |
|
1447 |
|
1448 if (new_state_selector.get_is_valid() == false) |
|
1449 { |
|
1450 (*new_eapol_key_state)->shutdown(); |
|
1451 delete *new_eapol_key_state; |
|
1452 *new_eapol_key_state = 0; |
|
1453 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1454 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1455 } |
|
1456 |
|
1457 EAP_TRACE_DATA_DEBUG( |
|
1458 m_am_tools, |
|
1459 TRACE_FLAGS_DEFAULT, |
|
1460 (EAPL("generate_new_pmksa(): new EAPOL-Key session"), |
|
1461 new_state_selector.get_data(), |
|
1462 new_state_selector.get_data_length())); |
|
1463 |
|
1464 status = m_eapol_key_state_map.add_handler(&new_state_selector, *new_eapol_key_state); |
|
1465 if (status != eap_status_ok) |
|
1466 { |
|
1467 (*new_eapol_key_state)->shutdown(); |
|
1468 delete *new_eapol_key_state; |
|
1469 *new_eapol_key_state = 0; |
|
1470 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1471 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1472 } |
|
1473 } |
|
1474 } |
|
1475 else |
|
1476 { |
|
1477 status = eap_status_not_found; |
|
1478 } |
|
1479 |
|
1480 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1481 |
|
1482 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1483 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1484 } |
|
1485 |
|
1486 //-------------------------------------------------- |
|
1487 |
|
1488 // |
|
1489 eap_status_e eapol_core_c::read_reassociation_parameters( |
|
1490 const eap_am_network_id_c * const old_receive_network_id, ///< source includes remote address, destination includes local address. |
|
1491 const eap_am_network_id_c * const new_receive_network_id, ///< source includes remote address, destination includes local address. |
|
1492 const eapol_key_authentication_type_e authentication_type, |
|
1493 eap_variable_data_c * const PMKID, |
|
1494 const eap_variable_data_c * const received_WPA_ie, |
|
1495 const eap_variable_data_c * const sent_WPA_ie) |
|
1496 { |
|
1497 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1498 |
|
1499 EAP_TRACE_DEBUG( |
|
1500 m_am_tools, |
|
1501 TRACE_FLAGS_DEFAULT, |
|
1502 (EAPL("%s: eapol_core_c::read_reassociation_parameters()\n"), |
|
1503 (m_is_client == true) ? "client": "server")); |
|
1504 |
|
1505 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::read_reassociation_parameters()"); |
|
1506 |
|
1507 eap_status_e status(eap_status_process_general_error); |
|
1508 |
|
1509 #if defined(USE_EAPOL_KEY_STATE) |
|
1510 |
|
1511 // No need to check authentication type anymore. It can be changed in reassociation. |
|
1512 |
|
1513 #if defined(EAP_USE_WPXM) |
|
1514 if (authentication_type == eapol_key_authentication_type_WPXM) |
|
1515 { |
|
1516 status = copy_eapol_key_state(old_receive_network_id, new_receive_network_id); |
|
1517 if (status != eap_status_ok) |
|
1518 { |
|
1519 // We cannot copy the session. |
|
1520 EAP_TRACE_ERROR( |
|
1521 m_am_tools, |
|
1522 TRACE_FLAGS_ERROR, |
|
1523 (EAPL("eapol_core_c::read_reassociation_parameters(): cannot copy eapol_key_state.\n"))); |
|
1524 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1525 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1526 } |
|
1527 } |
|
1528 #else |
|
1529 EAP_UNREFERENCED_PARAMETER(old_receive_network_id); |
|
1530 #endif //#if defined(EAP_USE_WPXM) |
|
1531 |
|
1532 // Here we swap the addresses. |
|
1533 eap_am_network_id_c new_send_network_id( |
|
1534 m_am_tools, |
|
1535 new_receive_network_id->get_destination_id(), |
|
1536 new_receive_network_id->get_source_id(), |
|
1537 new_receive_network_id->get_type()); |
|
1538 if (new_send_network_id.get_is_valid_data() == false) |
|
1539 { |
|
1540 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1541 } |
|
1542 |
|
1543 eap_network_id_selector_c state_selector( |
|
1544 m_am_tools, |
|
1545 &new_send_network_id); |
|
1546 |
|
1547 if (state_selector.get_is_valid() == false) |
|
1548 { |
|
1549 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1550 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1551 } |
|
1552 |
|
1553 EAP_TRACE_DATA_DEBUG( |
|
1554 m_am_tools, |
|
1555 TRACE_FLAGS_DEFAULT, |
|
1556 (EAPL("read_reassociation_parameters(): EAPOL-Key session"), |
|
1557 state_selector.get_data(state_selector.get_data_length()), |
|
1558 state_selector.get_data_length())); |
|
1559 |
|
1560 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
1561 |
|
1562 if (eapol_key_state == 0 |
|
1563 && authentication_type == eapol_key_authentication_type_RSNA_EAP) |
|
1564 { |
|
1565 // Creates a new PMKSA based on old PMKSA and the new MAC address of new access point. |
|
1566 status = generate_new_pmksa(&eapol_key_state, old_receive_network_id, new_receive_network_id); |
|
1567 if (status != eap_status_ok) |
|
1568 { |
|
1569 // We cannot generate a new PMKSA. |
|
1570 EAP_TRACE_DEBUG( |
|
1571 m_am_tools, |
|
1572 TRACE_FLAGS_DEFAULT, |
|
1573 (EAPL("eapol_core_c::read_reassociation_parameters(): new eapol_key_state NOT generated.\n"))); |
|
1574 status = eap_status_not_found; |
|
1575 } |
|
1576 } |
|
1577 |
|
1578 if (eapol_key_state != 0) |
|
1579 { |
|
1580 status = eapol_key_state->reset_cached_pmksa(); |
|
1581 if (status != eap_status_ok) |
|
1582 { |
|
1583 // We cannot reuse the session. |
|
1584 EAP_TRACE_ERROR( |
|
1585 m_am_tools, |
|
1586 TRACE_FLAGS_ERROR, |
|
1587 (EAPL("eapol_core_c::read_reassociation_parameters(): eapol_key_state NOT reused.\n"))); |
|
1588 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1589 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1590 } |
|
1591 |
|
1592 // We have state for this connection. |
|
1593 status = eapol_key_state->read_reassociation_parameters( |
|
1594 new_receive_network_id, ///< source includes remote address, destination includes local address. |
|
1595 authentication_type, |
|
1596 PMKID, |
|
1597 received_WPA_ie, |
|
1598 sent_WPA_ie); |
|
1599 if (status != eap_status_ok) |
|
1600 { |
|
1601 // ERROR, Cannot reassociate. |
|
1602 |
|
1603 EAP_TRACE_DEBUG( |
|
1604 m_am_tools, |
|
1605 TRACE_FLAGS_DEFAULT, |
|
1606 (EAPL("ERROR: eapol_core_c::read_reassociation_parameters(): Cannot reassociate.\n"))); |
|
1607 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1608 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1609 } |
|
1610 } |
|
1611 else |
|
1612 { |
|
1613 status = eap_status_not_found; |
|
1614 } |
|
1615 |
|
1616 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1617 |
|
1618 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1619 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1620 } |
|
1621 |
|
1622 //-------------------------------------------------- |
|
1623 |
|
1624 // |
|
1625 EAP_FUNC_EXPORT eap_status_e eapol_core_c::start_reassociation( |
|
1626 const eap_am_network_id_c * const receive_network_id, |
|
1627 const eapol_key_authentication_type_e authentication_type, |
|
1628 const eap_variable_data_c * const /*PMKID*/) |
|
1629 { |
|
1630 EAP_TRACE_DEBUG( |
|
1631 m_am_tools, |
|
1632 TRACE_FLAGS_DEFAULT, |
|
1633 (EAPL("%s: eapol_core_c::start_reassociation()\n"), |
|
1634 (m_is_client == true) ? "client": "server")); |
|
1635 |
|
1636 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::start_reassociation()"); |
|
1637 |
|
1638 // Here we swap the addresses. |
|
1639 eap_am_network_id_c send_network_id( |
|
1640 m_am_tools, |
|
1641 receive_network_id->get_destination_id(), |
|
1642 receive_network_id->get_source_id(), |
|
1643 receive_network_id->get_type()); |
|
1644 if (send_network_id.get_is_valid_data() == false) |
|
1645 { |
|
1646 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1647 } |
|
1648 |
|
1649 eap_network_id_selector_c state_selector( |
|
1650 m_am_tools, |
|
1651 &send_network_id); |
|
1652 |
|
1653 if (state_selector.get_is_valid() == false) |
|
1654 { |
|
1655 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1656 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1657 } |
|
1658 |
|
1659 EAP_TRACE_DATA_DEBUG( |
|
1660 m_am_tools, |
|
1661 TRACE_FLAGS_DEFAULT, |
|
1662 (EAPL("start_reassociation(): EAPOL-Key session"), |
|
1663 state_selector.get_data(state_selector.get_data_length()), |
|
1664 state_selector.get_data_length())); |
|
1665 |
|
1666 eap_status_e status(eap_status_process_general_error); |
|
1667 |
|
1668 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
1669 |
|
1670 if (eapol_key_state != 0) |
|
1671 { |
|
1672 status = eapol_key_state->reset_cached_pmksa(); |
|
1673 if (status != eap_status_ok) |
|
1674 { |
|
1675 // We cannot reuse the session. |
|
1676 EAP_TRACE_ERROR( |
|
1677 m_am_tools, |
|
1678 TRACE_FLAGS_ERROR, |
|
1679 (EAPL("eapol_core_c::start_reassociation(): eapol_key_state NOT reused.\n"))); |
|
1680 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1681 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1682 } |
|
1683 |
|
1684 #if defined(USE_EAPOL_KEY_STATE) |
|
1685 if (m_skip_start_4_way_handshake == true |
|
1686 && (authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
1687 || authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
1688 || authentication_type == eapol_key_authentication_type_WPA_EAP |
|
1689 || authentication_type == eapol_key_authentication_type_WPA_PSK)) |
|
1690 { |
|
1691 // This is test to skip 4-Way Handshake start. |
|
1692 EAP_TRACE_DEBUG( |
|
1693 m_am_tools, |
|
1694 TRACE_FLAGS_DEFAULT, |
|
1695 (EAPL("WARNING: eapol_core_c::start_reassociation(): ") |
|
1696 EAPL("skips start_4_way_handshake()\n"))); |
|
1697 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1698 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1699 } |
|
1700 else |
|
1701 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1702 { |
|
1703 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
1704 status = eapol_key_state->start_4_way_handshake( |
|
1705 receive_network_id); |
|
1706 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
1707 } |
|
1708 |
|
1709 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
1710 if (status != eap_status_ok) |
|
1711 { |
|
1712 EAP_TRACE_DEBUG( |
|
1713 m_am_tools, |
|
1714 TRACE_FLAGS_DEFAULT, |
|
1715 (EAPL("ERROR: eapol_core_c::start_reassociation(): ") |
|
1716 EAPL("start_4_way_handshake() failed, eap_status_e %d\n"), |
|
1717 status)); |
|
1718 } |
|
1719 else |
|
1720 { |
|
1721 EAP_TRACE_DEBUG( |
|
1722 m_am_tools, |
|
1723 TRACE_FLAGS_DEFAULT, |
|
1724 (EAPL("eapol_core_c::start_reassociation(): ") |
|
1725 EAPL("start_4_way_handshake(), eap_status_e %d\n"), |
|
1726 status)); |
|
1727 } |
|
1728 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
1729 |
|
1730 } |
|
1731 |
|
1732 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1733 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1734 } |
|
1735 |
|
1736 //-------------------------------------------------- |
|
1737 |
|
1738 // |
|
1739 eap_status_e eapol_core_c::complete_reassociation( |
|
1740 const eapol_wlan_authentication_state_e reassociation_result, |
|
1741 const eap_am_network_id_c * const receive_network_id, |
|
1742 const eapol_key_authentication_type_e authentication_type, |
|
1743 const eap_variable_data_c * const received_WPA_IE, |
|
1744 const eap_variable_data_c * const sent_WPA_IE, |
|
1745 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e pairwise_key_cipher_suite, |
|
1746 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e group_key_cipher_suite |
|
1747 ) |
|
1748 { |
|
1749 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1750 |
|
1751 EAP_TRACE_DEBUG( |
|
1752 m_am_tools, |
|
1753 TRACE_FLAGS_DEFAULT, |
|
1754 (EAPL("%s: eapol_core_c::complete_reassociation()\n"), |
|
1755 (m_is_client == true) ? "client": "server")); |
|
1756 |
|
1757 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::complete_reassociation()"); |
|
1758 |
|
1759 #if defined(USE_EAPOL_KEY_STATE) |
|
1760 |
|
1761 // Here we swap the addresses. |
|
1762 eap_am_network_id_c send_network_id( |
|
1763 m_am_tools, |
|
1764 receive_network_id->get_destination_id(), |
|
1765 receive_network_id->get_source_id(), |
|
1766 receive_network_id->get_type()); |
|
1767 if (send_network_id.get_is_valid_data() == false) |
|
1768 { |
|
1769 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1770 } |
|
1771 |
|
1772 |
|
1773 // No need to check previous authentication type. It can be changed in reassociation. |
|
1774 m_authentication_type = authentication_type; |
|
1775 |
|
1776 |
|
1777 eap_network_id_selector_c state_selector( |
|
1778 m_am_tools, |
|
1779 &send_network_id); |
|
1780 |
|
1781 if (state_selector.get_is_valid() == false) |
|
1782 { |
|
1783 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1784 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1785 } |
|
1786 |
|
1787 EAP_TRACE_DATA_DEBUG( |
|
1788 m_am_tools, |
|
1789 TRACE_FLAGS_DEFAULT, |
|
1790 (EAPL("complete_reassociation(): EAPOL-Key session"), |
|
1791 state_selector.get_data(state_selector.get_data_length()), |
|
1792 state_selector.get_data_length())); |
|
1793 |
|
1794 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
1795 |
|
1796 if (eapol_key_state != 0) |
|
1797 { |
|
1798 // We have state for this connection. |
|
1799 eap_status_e status = eapol_key_state->complete_reassociation( |
|
1800 reassociation_result, |
|
1801 receive_network_id, |
|
1802 authentication_type, |
|
1803 received_WPA_IE, |
|
1804 sent_WPA_IE, |
|
1805 pairwise_key_cipher_suite, |
|
1806 group_key_cipher_suite |
|
1807 ); |
|
1808 |
|
1809 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1810 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1811 } |
|
1812 else |
|
1813 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1814 { |
|
1815 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1816 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1817 } |
|
1818 } |
|
1819 |
|
1820 //-------------------------------------------------- |
|
1821 |
|
1822 // |
|
1823 EAP_FUNC_EXPORT eap_status_e eapol_core_c::send_logoff( |
|
1824 const eap_am_network_id_c * const receive_network_id) |
|
1825 { |
|
1826 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1827 |
|
1828 EAP_TRACE_DEBUG( |
|
1829 m_am_tools, |
|
1830 TRACE_FLAGS_DEFAULT, |
|
1831 (EAPL("%s: eapol_core_c::send_logoff()\n"), |
|
1832 (m_is_client == true) ? "client": "server")); |
|
1833 |
|
1834 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::send_logoff()"); |
|
1835 |
|
1836 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
1837 |
|
1838 eap_status_e status(eap_status_not_supported); |
|
1839 |
|
1840 if (m_eap_core == 0) |
|
1841 { |
|
1842 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1843 } |
|
1844 |
|
1845 if (receive_network_id == 0) |
|
1846 { |
|
1847 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1848 } |
|
1849 |
|
1850 // Here we swap the addresses. |
|
1851 eap_am_network_id_c send_network_id(m_am_tools, |
|
1852 receive_network_id->get_destination_id(), |
|
1853 receive_network_id->get_source_id(), |
|
1854 receive_network_id->get_type()); |
|
1855 if (send_network_id.get_is_valid_data() == false) |
|
1856 { |
|
1857 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1858 } |
|
1859 |
|
1860 eap_buf_chain_wr_c logoff_packet( |
|
1861 eap_write_buffer, |
|
1862 m_am_tools, |
|
1863 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
1864 |
|
1865 if (logoff_packet.get_is_valid() == false) |
|
1866 { |
|
1867 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); |
|
1868 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1869 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1870 } |
|
1871 |
|
1872 u32_t data_length = EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH; |
|
1873 |
|
1874 if (data_length > 0) |
|
1875 { |
|
1876 data_length = 0; |
|
1877 } |
|
1878 |
|
1879 eapol_header_wr_c eapol( |
|
1880 m_am_tools, |
|
1881 logoff_packet.get_data_offset( |
|
1882 m_eapol_header_offset, m_eapol_header_offset+data_length), |
|
1883 m_eapol_header_offset+data_length); |
|
1884 |
|
1885 if (eapol.get_is_valid() == false) |
|
1886 { |
|
1887 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
1888 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1889 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
1890 } |
|
1891 |
|
1892 eapol.set_version(eapol_protocol_version_1); |
|
1893 eapol.set_packet_type(eapol_packet_type_logoff); |
|
1894 eapol.set_data_length(static_cast<u16_t>(data_length)); |
|
1895 |
|
1896 logoff_packet.set_data_length(m_eapol_header_offset+eapol_header_wr_c::get_header_length()+data_length); |
|
1897 |
|
1898 EAP_TRACE_DEBUG( |
|
1899 m_am_tools, |
|
1900 TRACE_FLAGS_DEFAULT, |
|
1901 (EAPL("<- EAPOL: %s, version=0x%02x, packet_type=0x%02x=%s, data_length=0x%04x, packet length 0x%04x\n"), |
|
1902 (m_is_client == true) ? "client": "server", |
|
1903 eapol.get_version(), |
|
1904 eapol.get_packet_type(), |
|
1905 eapol.get_type_string(), |
|
1906 eapol.get_data_length(), |
|
1907 eapol.get_header_length()+eapol.get_data_length())); |
|
1908 |
|
1909 status = m_partner->packet_send( |
|
1910 &send_network_id, &logoff_packet, m_eapol_header_offset, |
|
1911 eapol.get_header_length()+eapol.get_data_length(), EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
1912 |
|
1913 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1914 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1915 } |
|
1916 |
|
1917 //-------------------------------------------------- |
|
1918 |
|
1919 // |
|
1920 EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_data_crypto_keys( |
|
1921 const eap_am_network_id_c * const send_network_id, |
|
1922 const eap_master_session_key_c * const master_session_key |
|
1923 ) |
|
1924 { |
|
1925 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1926 |
|
1927 EAP_TRACE_DEBUG( |
|
1928 m_am_tools, |
|
1929 TRACE_FLAGS_DEFAULT, |
|
1930 (EAPL("%s: eapol_core_c::packet_data_crypto_keys()\n"), |
|
1931 (m_is_client == true) ? "client": "server")); |
|
1932 |
|
1933 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::packet_data_crypto_keys()"); |
|
1934 |
|
1935 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
1936 |
|
1937 eap_status_e status = eap_status_process_general_error; |
|
1938 |
|
1939 if (master_session_key->get_is_valid() == true) |
|
1940 { |
|
1941 EAP_TRACE_DATA_DEBUG( |
|
1942 m_am_tools, |
|
1943 TRACE_FLAGS_DEFAULT, |
|
1944 (EAPL("master session key"), |
|
1945 master_session_key->get_data(master_session_key->get_data_length()), |
|
1946 master_session_key->get_data_length())); |
|
1947 } |
|
1948 |
|
1949 #if defined(USE_EAPOL_KEY_STATE) |
|
1950 |
|
1951 eap_network_id_selector_c state_selector( |
|
1952 m_am_tools, |
|
1953 send_network_id); |
|
1954 |
|
1955 if (state_selector.get_is_valid() == false) |
|
1956 { |
|
1957 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1958 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1959 } |
|
1960 |
|
1961 EAP_TRACE_DATA_DEBUG( |
|
1962 m_am_tools, |
|
1963 TRACE_FLAGS_DEFAULT, |
|
1964 (EAPL("packet_data_crypto_keys(): EAPOL-Key session"), |
|
1965 state_selector.get_data(state_selector.get_data_length()), |
|
1966 state_selector.get_data_length())); |
|
1967 |
|
1968 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
1969 |
|
1970 if (eapol_key_state != 0) |
|
1971 { |
|
1972 status = eapol_key_state->set_pairwise_PMK( |
|
1973 master_session_key, |
|
1974 send_network_id); |
|
1975 } |
|
1976 else |
|
1977 { |
|
1978 EAP_TRACE_DEBUG( |
|
1979 m_am_tools, |
|
1980 TRACE_FLAGS_DEFAULT, |
|
1981 (EAPL("ERROR: packet_data_crypto_keys() failed, no eapol_key_state_c object\n"))); |
|
1982 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1983 return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); |
|
1984 } |
|
1985 |
|
1986 #else |
|
1987 |
|
1988 // Store the session key so it can be used when EAPOL-Key is received. |
|
1989 m_master_session_key.reset(); |
|
1990 |
|
1991 status = m_master_session_key.set_copy_of_buffer(master_session_key); |
|
1992 if (status != eap_status_ok) |
|
1993 { |
|
1994 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1995 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1996 } |
|
1997 |
|
1998 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
1999 |
|
2000 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2001 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2002 } |
|
2003 |
|
2004 //-------------------------------------------------- |
|
2005 |
|
2006 // |
|
2007 EAP_FUNC_EXPORT eap_status_e eapol_core_c::packet_data_session_key( |
|
2008 const eap_am_network_id_c * const send_network_id, |
|
2009 const eapol_session_key_c * const key) |
|
2010 { |
|
2011 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2012 |
|
2013 EAP_TRACE_DEBUG( |
|
2014 m_am_tools, |
|
2015 TRACE_FLAGS_DEFAULT, |
|
2016 (EAPL("%s: eapol_core_c::packet_data_session_key()\n"), |
|
2017 (m_is_client == true) ? "client": "server")); |
|
2018 |
|
2019 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::packet_data_session_key()"); |
|
2020 |
|
2021 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2022 |
|
2023 eap_status_e status = eap_status_process_general_error; |
|
2024 |
|
2025 if (key->get_is_valid() == true) |
|
2026 { |
|
2027 EAP_TRACE_DEBUG( |
|
2028 m_am_tools, |
|
2029 TRACE_FLAGS_DEFAULT, |
|
2030 (EAPL("eapol session key: type 0x%02x, index 0x%02x, tx %d\n"), |
|
2031 key->get_key_type(), |
|
2032 key->get_key_index(), |
|
2033 key->get_key_tx_bit())); |
|
2034 |
|
2035 EAP_TRACE_DATA_DEBUG( |
|
2036 m_am_tools, |
|
2037 TRACE_FLAGS_DEFAULT, |
|
2038 (EAPL("eapol session key"), |
|
2039 key->get_key()->get_data(key->get_key()->get_data_length()), |
|
2040 key->get_key()->get_data_length())); |
|
2041 } |
|
2042 |
|
2043 // Forward the keys to lower layers |
|
2044 status = m_partner->packet_data_session_key( |
|
2045 send_network_id, |
|
2046 key); |
|
2047 |
|
2048 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2049 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2050 } |
|
2051 |
|
2052 //-------------------------------------------------- |
|
2053 |
|
2054 #if !defined(USE_EAPOL_KEY_STATE) |
|
2055 |
|
2056 // |
|
2057 eap_status_e eapol_core_c::handle_RC4_key_descriptor( |
|
2058 const eap_am_network_id_c * const receive_network_id, |
|
2059 eapol_RC4_key_header_c* const packet, |
|
2060 const u32_t packet_length) |
|
2061 { |
|
2062 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2063 |
|
2064 EAP_TRACE_DEBUG( |
|
2065 m_am_tools, |
|
2066 TRACE_FLAGS_DEFAULT, |
|
2067 (EAPL("%s: eapol_core_c::handle_RC4_key_descriptor()\n"), |
|
2068 (m_is_client == true) ? "client": "server")); |
|
2069 |
|
2070 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::handle_RC4_key_descriptor()"); |
|
2071 |
|
2072 eap_status_e status = eap_status_process_general_error; |
|
2073 |
|
2074 // Check the packet length |
|
2075 if (static_cast<u32_t>(packet->get_header_length()) != packet_length |
|
2076 && static_cast<u32_t>(packet->get_header_length() + packet->get_key_length()) != packet_length) |
|
2077 { |
|
2078 EAP_TRACE_DEBUG( |
|
2079 m_am_tools, |
|
2080 TRACE_FLAGS_DEFAULT, |
|
2081 (EAPL("ERROR: Illegal EAPOL-Key frame length, packet->get_header_length() %d, packet_length %d\n"), |
|
2082 packet->get_header_length(), |
|
2083 packet_length)); |
|
2084 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2085 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
2086 } |
|
2087 |
|
2088 // Get MS-MPPE-Recv-Key and MS-MPPE-Send-Key |
|
2089 // Recv-Key is the first 32 bytes of master session key and Send-Key is the next 32 bytes. |
|
2090 eap_variable_data_c mppe_recv_key(m_am_tools); |
|
2091 eap_variable_data_c mppe_send_key(m_am_tools); |
|
2092 if (m_master_session_key.get_data_length() == 16ul) |
|
2093 { |
|
2094 status = mppe_recv_key.set_buffer( |
|
2095 m_master_session_key.get_data(m_master_session_key.get_data_length()), |
|
2096 m_master_session_key.get_data_length(), |
|
2097 false, |
|
2098 false); |
|
2099 if (status != eap_status_ok) |
|
2100 { |
|
2101 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2102 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2103 } |
|
2104 |
|
2105 status = mppe_send_key.set_buffer( |
|
2106 m_master_session_key.get_data(m_master_session_key.get_data_length()), |
|
2107 m_master_session_key.get_data_length(), |
|
2108 false, |
|
2109 false); |
|
2110 if (status != eap_status_ok) |
|
2111 { |
|
2112 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2113 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2114 } |
|
2115 } |
|
2116 else |
|
2117 { |
|
2118 status = mppe_recv_key.set_buffer( |
|
2119 m_master_session_key.get_data(MPPE_KEY_LENGTH), |
|
2120 MPPE_KEY_LENGTH, |
|
2121 false, |
|
2122 false); |
|
2123 if (status != eap_status_ok) |
|
2124 { |
|
2125 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2126 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2127 } |
|
2128 |
|
2129 status = mppe_send_key.set_buffer( |
|
2130 m_master_session_key.get_data_offset(MPPE_KEY_LENGTH, MPPE_KEY_LENGTH), |
|
2131 MPPE_KEY_LENGTH, |
|
2132 false, |
|
2133 false); |
|
2134 if (status != eap_status_ok) |
|
2135 { |
|
2136 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2137 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2138 } |
|
2139 } |
|
2140 |
|
2141 if (mppe_recv_key.get_is_valid() == false |
|
2142 || mppe_send_key.get_is_valid() == false) |
|
2143 { |
|
2144 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2145 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2146 } |
|
2147 |
|
2148 // Verify the the MD5 signature in Eapol-Key |
|
2149 crypto_md5_c md5(m_am_tools); |
|
2150 crypto_hmac_c hmac_md5(m_am_tools, &md5, false); |
|
2151 if (hmac_md5.get_is_valid() == false) |
|
2152 { |
|
2153 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2154 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2155 } |
|
2156 |
|
2157 // MPPE-Send-Key is used as the signature key. |
|
2158 if (hmac_md5.hmac_set_key(&mppe_send_key) != eap_status_ok) |
|
2159 { |
|
2160 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_init failed\n"))); |
|
2161 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2162 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2163 } |
|
2164 |
|
2165 // Save the signature from the packet |
|
2166 eap_variable_data_c signature(m_am_tools); |
|
2167 status = signature.set_copy_of_buffer(packet->get_key_signature(), EAPOL_RC4_KEY_SIGNATURE_LENGTH); |
|
2168 if (status != eap_status_ok) |
|
2169 { |
|
2170 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2171 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2172 } |
|
2173 |
|
2174 // Replace the signature with zeros. |
|
2175 packet->zero_key_signature(m_am_tools); |
|
2176 |
|
2177 // Send the data to HMAC-MD5 module |
|
2178 if (hmac_md5.hmac_update(packet->get_header_buffer(packet_length), packet_length) != eap_status_ok) |
|
2179 { |
|
2180 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_update failed\n"))); |
|
2181 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2182 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2183 } |
|
2184 |
|
2185 // Get the calculated signature |
|
2186 u8_t tmp_signature[EAPOL_RC4_KEY_SIGNATURE_LENGTH]; |
|
2187 u32_t length = EAPOL_RC4_KEY_SIGNATURE_LENGTH; |
|
2188 if (hmac_md5.hmac_final(tmp_signature, &length) != eap_status_ok) |
|
2189 { |
|
2190 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: hmac_md5_final failed\n"))); |
|
2191 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2192 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2193 } |
|
2194 |
|
2195 // Compare the calculated and original signature |
|
2196 if (m_am_tools->memcmp( |
|
2197 tmp_signature, |
|
2198 signature.get_data( |
|
2199 EAPOL_RC4_KEY_SIGNATURE_LENGTH), |
|
2200 EAPOL_RC4_KEY_SIGNATURE_LENGTH) != 0) |
|
2201 { |
|
2202 // Signatures did not match. Something's wrong. |
|
2203 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: EAPOL-Key HMAC-MD5 check failed.\n"))); |
|
2204 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2205 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2206 } |
|
2207 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("EAPOL-Key HMAC-MD5 check passed.\n"))); |
|
2208 |
|
2209 eap_variable_data_c key_out(m_am_tools); |
|
2210 // Decrypt the RC4 encrypted key |
|
2211 if (packet->get_key() == 0) |
|
2212 { |
|
2213 // EAPOL-Key does not contain the key. This means that we should use |
|
2214 // the first bytes from MS-MPPE-Recv-Key as the key. There is a slight |
|
2215 // confusion in draft-congdon-radius-8021x-23.txt regarding this but this is how |
|
2216 // it works. |
|
2217 if (packet->get_key_length() > 0) |
|
2218 { |
|
2219 status = key_out.set_copy_of_buffer(mppe_recv_key.get_data(packet->get_key_length()), packet->get_key_length()); |
|
2220 if (status != eap_status_ok) |
|
2221 { |
|
2222 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2223 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2224 } |
|
2225 } |
|
2226 else |
|
2227 { |
|
2228 // Key message with no key length? |
|
2229 // Just ignore the message. |
|
2230 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got empty WEP unicast key message.\n"))); |
|
2231 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2232 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2233 } |
|
2234 } |
|
2235 else |
|
2236 { |
|
2237 // Set-up RC4 key. Key is the IV and the MS-MPPE-Recv-Key truncated together. |
|
2238 eap_variable_data_c rc4_key(m_am_tools); |
|
2239 status = rc4_key.set_copy_of_buffer(packet->get_key_IV(), EAPOL_RC4_KEY_IV_LENGTH); |
|
2240 if (status != eap_status_ok) |
|
2241 { |
|
2242 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2243 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2244 } |
|
2245 |
|
2246 rc4_key.add_data(&mppe_recv_key); |
|
2247 |
|
2248 // Set-up RC4 module |
|
2249 crypto_rc4_c rc4(m_am_tools); |
|
2250 // Set the key for RC4 |
|
2251 if (rc4.set_key(&rc4_key) != eap_status_ok) |
|
2252 { |
|
2253 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: rc4_set_key failed\n"))); |
|
2254 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2255 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2256 } |
|
2257 |
|
2258 // Decrypt the key to key_out |
|
2259 key_out.set_buffer_length(packet->get_key_length()); |
|
2260 if (rc4.decrypt_data(packet->get_key(), key_out.get_data(packet->get_key_length()), packet->get_key_length()) != eap_status_ok) |
|
2261 { |
|
2262 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("ERROR: rc4 failed\n"))); |
|
2263 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2264 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2265 } |
|
2266 key_out.set_data_length(packet->get_key_length()); |
|
2267 } |
|
2268 |
|
2269 // Find out the key type. At the moment only WEP keys are supported. |
|
2270 eapol_key_type_e key_type; |
|
2271 switch (packet->get_key_flag()) |
|
2272 { |
|
2273 case eapol_RC4_key_flag_broadcast: |
|
2274 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WEP broadcast key\n"))); |
|
2275 key_type = eapol_key_type_broadcast; |
|
2276 break; |
|
2277 case eapol_RC4_key_flag_unicast: |
|
2278 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("Got WEP unicast key\n"))); |
|
2279 key_type = eapol_key_type_unicast; |
|
2280 break; |
|
2281 default: |
|
2282 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2283 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2284 } |
|
2285 |
|
2286 EAP_TRACE_DATA_DEBUG( |
|
2287 m_am_tools, |
|
2288 TRACE_FLAGS_DEFAULT, |
|
2289 (EAPL("Key"), |
|
2290 key_out.get_data(key_out.get_data_length()), |
|
2291 key_out.get_data_length())); |
|
2292 |
|
2293 // Here we swap the addresses. |
|
2294 eap_am_network_id_c send_network_id(m_am_tools, |
|
2295 receive_network_id->get_destination_id(), |
|
2296 receive_network_id->get_source_id(), |
|
2297 receive_network_id->get_type()); |
|
2298 if (send_network_id.get_is_valid_data() == false) |
|
2299 { |
|
2300 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2301 } |
|
2302 |
|
2303 eapol_session_key_c wep_key( |
|
2304 m_am_tools, |
|
2305 &key_out, |
|
2306 key_type, |
|
2307 packet->get_key_index(), |
|
2308 true); |
|
2309 |
|
2310 // Forward the keys to lower layers |
|
2311 status = m_partner->packet_data_session_key( |
|
2312 &send_network_id, |
|
2313 &wep_key); |
|
2314 |
|
2315 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2316 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2317 } |
|
2318 |
|
2319 #endif //#if !defined(USE_EAPOL_KEY_STATE) |
|
2320 |
|
2321 //-------------------------------------------------- |
|
2322 |
|
2323 // |
|
2324 EAP_FUNC_EXPORT eap_status_e eapol_core_c::configure() |
|
2325 { |
|
2326 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2327 |
|
2328 EAP_TRACE_DEBUG( |
|
2329 m_am_tools, |
|
2330 TRACE_FLAGS_DEFAULT, |
|
2331 (EAPL("%s: eapol_core_c::configure()\n"), |
|
2332 (m_is_client == true) ? "client": "server")); |
|
2333 |
|
2334 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::configure()"); |
|
2335 |
|
2336 m_eapol_header_offset = m_partner->get_header_offset( |
|
2337 &m_MTU, &m_trailer_length); |
|
2338 |
|
2339 eap_status_e status = eap_status_process_general_error; |
|
2340 |
|
2341 { |
|
2342 eap_variable_data_c max_eapol_starts(m_am_tools); |
|
2343 |
|
2344 status = read_configure( |
|
2345 cf_str_EAPOL_CORE_starts_max_count.get_field(), |
|
2346 &max_eapol_starts); |
|
2347 if (status != eap_status_ok |
|
2348 || max_eapol_starts.get_is_valid_data() == false |
|
2349 || max_eapol_starts.get_data_length() < sizeof(u32_t)) |
|
2350 { |
|
2351 // Probably not found from db. Use the default value. |
|
2352 m_max_eapol_starts = EAPOL_CORE_MAX_EAPOL_START_SENDINGS; |
|
2353 } |
|
2354 else |
|
2355 { |
|
2356 m_max_eapol_starts = *reinterpret_cast<u32_t *>( |
|
2357 max_eapol_starts.get_data(sizeof(u32_t))); |
|
2358 } |
|
2359 } |
|
2360 |
|
2361 { |
|
2362 eap_variable_data_c eapol_start_interval(m_am_tools); |
|
2363 |
|
2364 status = read_configure( |
|
2365 cf_str_EAPOL_CORE_send_start_interval.get_field(), |
|
2366 &eapol_start_interval); |
|
2367 if (status != eap_status_ok |
|
2368 || eapol_start_interval.get_is_valid_data() == false |
|
2369 || eapol_start_interval.get_data_length() < sizeof(u32_t)) |
|
2370 { |
|
2371 // Probably not found from db. Use the default value. |
|
2372 m_eapol_start_interval = EAPOL_CORE_TIMER_SEND_START_AGAIN_TIMEOUT; |
|
2373 } |
|
2374 else |
|
2375 { |
|
2376 m_eapol_start_interval = *reinterpret_cast<u32_t *>( |
|
2377 eapol_start_interval.get_data(sizeof(u32_t))); |
|
2378 } |
|
2379 } |
|
2380 |
|
2381 #if defined(USE_EAP_CORE_SERVER) |
|
2382 if (m_is_client == false) |
|
2383 { |
|
2384 eap_variable_data_c data(m_am_tools); |
|
2385 |
|
2386 eap_status_e status = read_configure( |
|
2387 cf_str_EAPOL_CORE_skip_start_4_way_handshake.get_field(), |
|
2388 &data); |
|
2389 if (status == eap_status_ok |
|
2390 && data.get_data_length() == sizeof(u32_t) |
|
2391 && data.get_data(data.get_data_length()) != 0) |
|
2392 { |
|
2393 u32_t *flag = reinterpret_cast<u32_t *>(data.get_data(data.get_data_length())); |
|
2394 |
|
2395 if (flag != 0) |
|
2396 { |
|
2397 if ((*flag) != 0ul) |
|
2398 { |
|
2399 m_skip_start_4_way_handshake = true; |
|
2400 } |
|
2401 else |
|
2402 { |
|
2403 m_skip_start_4_way_handshake = false; |
|
2404 } |
|
2405 } |
|
2406 } |
|
2407 } |
|
2408 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
2409 |
|
2410 return EAP_STATUS_RETURN(m_am_tools, m_eap_core->configure()); |
|
2411 } |
|
2412 |
|
2413 //-------------------------------------------------- |
|
2414 |
|
2415 #if defined(USE_EAPOL_KEY_STATE) |
|
2416 |
|
2417 // |
|
2418 EAP_FUNC_EXPORT eap_status_e eapol_core_c::shutdown_operation( |
|
2419 eapol_key_state_c * const handler, |
|
2420 abs_eap_am_tools_c * const m_am_tools) |
|
2421 { |
|
2422 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2423 |
|
2424 EAP_UNREFERENCED_PARAMETER(m_am_tools); |
|
2425 |
|
2426 eap_status_e status = handler->shutdown(); |
|
2427 |
|
2428 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2429 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2430 } |
|
2431 |
|
2432 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2433 |
|
2434 //-------------------------------------------------- |
|
2435 |
|
2436 // |
|
2437 EAP_FUNC_EXPORT eap_status_e eapol_core_c::shutdown() |
|
2438 { |
|
2439 EAP_TRACE_DEBUG( |
|
2440 m_am_tools, |
|
2441 TRACE_FLAGS_DEFAULT, |
|
2442 (EAPL("%s: eapol_core_c::shutdown(), m_shutdown_was_called=%d\n"), |
|
2443 (m_is_client == true) ? "client": "server", |
|
2444 m_shutdown_was_called)); |
|
2445 |
|
2446 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::shutdown()"); |
|
2447 |
|
2448 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2449 |
|
2450 if (m_shutdown_was_called == true) |
|
2451 { |
|
2452 // Shutdown function was called already. |
|
2453 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2454 } |
|
2455 m_shutdown_was_called = true; |
|
2456 |
|
2457 eap_status_e status; |
|
2458 #if defined(USE_EAPOL_KEY_STATE) |
|
2459 status = m_eapol_key_state_map.for_each(shutdown_operation, true); |
|
2460 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2461 |
|
2462 if (m_eap_core != 0) |
|
2463 { |
|
2464 status = m_eap_core->shutdown(); |
|
2465 } |
|
2466 |
|
2467 // This will cancel all timers of this object. |
|
2468 m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); |
|
2469 #if defined(USE_EAPOL_KEY_STATE) |
|
2470 m_partner->cancel_timer(this, EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID); |
|
2471 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2472 |
|
2473 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2474 } |
|
2475 |
|
2476 //-------------------------------------------------- |
|
2477 |
|
2478 // |
|
2479 EAP_FUNC_EXPORT eap_status_e eapol_core_c::read_configure( |
|
2480 const eap_configuration_field_c * const field, |
|
2481 eap_variable_data_c * const data) |
|
2482 { |
|
2483 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2484 |
|
2485 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2486 |
|
2487 const eap_status_e status = m_partner->read_configure(field, data); |
|
2488 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2489 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2490 } |
|
2491 |
|
2492 //-------------------------------------------------- |
|
2493 |
|
2494 EAP_FUNC_EXPORT eap_status_e eapol_core_c::write_configure( |
|
2495 const eap_configuration_field_c * const field, |
|
2496 eap_variable_data_c * const data) |
|
2497 { |
|
2498 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2499 |
|
2500 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2501 |
|
2502 const eap_status_e status = m_partner->write_configure(field, data); |
|
2503 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2504 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2505 } |
|
2506 |
|
2507 //-------------------------------------------------- |
|
2508 |
|
2509 // |
|
2510 EAP_FUNC_EXPORT void eapol_core_c::set_is_valid() |
|
2511 { |
|
2512 m_is_valid = true; |
|
2513 } |
|
2514 |
|
2515 //-------------------------------------------------- |
|
2516 |
|
2517 // |
|
2518 EAP_FUNC_EXPORT bool eapol_core_c::get_is_valid() |
|
2519 { |
|
2520 return m_is_valid; |
|
2521 } |
|
2522 |
|
2523 //-------------------------------------------------- |
|
2524 |
|
2525 // |
|
2526 EAP_FUNC_EXPORT eap_status_e eapol_core_c::timer_expired( |
|
2527 const u32_t id, void *data) |
|
2528 { |
|
2529 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2530 |
|
2531 EAP_TRACE_DEBUG( |
|
2532 m_am_tools, |
|
2533 TRACE_FLAGS_DEFAULT, |
|
2534 (EAPL("TIMER: %s: [0x%08x]->eapol_core_c::timer_expired(id 0x%02x, data 0x%08x).\n"), |
|
2535 (m_is_client == true) ? "client": "server", |
|
2536 this, |
|
2537 id, |
|
2538 data)); |
|
2539 |
|
2540 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::timer_expired()"); |
|
2541 |
|
2542 if (id == EAPOL_CORE_TIMER_SEND_START_AGAIN_ID) |
|
2543 { |
|
2544 const eap_am_network_id_c * const receive_network_id |
|
2545 = reinterpret_cast<const eap_am_network_id_c *>(data); |
|
2546 if (m_eapol_starts_sent < m_max_eapol_starts) |
|
2547 { |
|
2548 EAP_TRACE_DEBUG( |
|
2549 m_am_tools, |
|
2550 TRACE_FLAGS_DEFAULT, |
|
2551 (EAPL("TIMER: %s: EAPOL_CORE_TIMER_SEND_START_AGAIN_ID expired, re-start authentication.\n"), |
|
2552 (m_is_client == true ? "client": "server"), |
|
2553 m_eapol_start_interval)); |
|
2554 |
|
2555 m_eapol_starts_sent++; |
|
2556 restart_authentication(receive_network_id , m_is_client, true, true); |
|
2557 } |
|
2558 else |
|
2559 { |
|
2560 EAP_TRACE_DEBUG( |
|
2561 m_am_tools, |
|
2562 TRACE_FLAGS_DEFAULT, |
|
2563 (EAPL("ERROR: TIMER: %s: EAPOL_CORE_TIMER_SEND_START_AGAIN_ID expired, too many re-starts, notifies lower layers.\n"), |
|
2564 (m_is_client == true ? "client": "server"), |
|
2565 m_eapol_start_interval)); |
|
2566 |
|
2567 // Here we swap the addresses. |
|
2568 eap_am_network_id_c send_network_id(m_am_tools, |
|
2569 receive_network_id->get_destination_id(), |
|
2570 receive_network_id->get_source_id(), |
|
2571 receive_network_id->get_type()); |
|
2572 if (send_network_id.get_is_valid_data() == false) |
|
2573 { |
|
2574 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2575 } |
|
2576 |
|
2577 // EAPOL-Start has been sent enough times. Send notification to lower layers. |
|
2578 // After this EAPOL stays quiet and waits for incoming |
|
2579 // packets or authentication restarting. |
|
2580 eap_state_notification_c notification( |
|
2581 m_am_tools, |
|
2582 &send_network_id, |
|
2583 true, // m_is_client |
|
2584 eap_state_notification_generic, |
|
2585 eap_protocol_layer_eapol, |
|
2586 eap_type_none, |
|
2587 eapol_state_start_sent, |
|
2588 eapol_state_no_start_response, |
|
2589 0 /* EAP identifier not valid here */, |
|
2590 false); |
|
2591 |
|
2592 notification.set_authentication_error(eap_status_authentication_failure); |
|
2593 |
|
2594 state_notification(¬ification); |
|
2595 } |
|
2596 } |
|
2597 #if defined(USE_EAPOL_KEY_STATE) |
|
2598 else if (id == EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID) |
|
2599 { |
|
2600 EAP_TRACE_DEBUG( |
|
2601 m_am_tools, |
|
2602 TRACE_FLAGS_DEFAULT, |
|
2603 (EAPL("TIMER: EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID elapsed, %s.\n"), |
|
2604 (m_is_client == true) ? "client": "server")); |
|
2605 |
|
2606 const eap_am_network_id_c * const send_network_id |
|
2607 = reinterpret_cast<const eap_am_network_id_c *>(data); |
|
2608 if (send_network_id->get_is_valid_data() == false) |
|
2609 { |
|
2610 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2611 } |
|
2612 |
|
2613 (void) remove_eapol_key_state(send_network_id); |
|
2614 } |
|
2615 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2616 |
|
2617 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2618 } |
|
2619 |
|
2620 //-------------------------------------------------- |
|
2621 |
|
2622 // |
|
2623 EAP_FUNC_EXPORT eap_status_e eapol_core_c::timer_delete_data( |
|
2624 const u32_t id, void *data) |
|
2625 { |
|
2626 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2627 |
|
2628 EAP_TRACE_DEBUG( |
|
2629 m_am_tools, |
|
2630 TRACE_FLAGS_DEFAULT, |
|
2631 (EAPL("TIMER: %s: [0x%08x]->eapol_core_c::timer_delete_data(id 0x%02x, data 0x%08x).\n"), |
|
2632 (m_is_client == true) ? "client": "server", |
|
2633 this, id, data)); |
|
2634 |
|
2635 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::timer_delete_data()"); |
|
2636 |
|
2637 if (id == EAPOL_CORE_TIMER_SEND_START_AGAIN_ID) |
|
2638 { |
|
2639 const eap_am_network_id_c * const send_network_id |
|
2640 = reinterpret_cast<const eap_am_network_id_c *>(data); |
|
2641 delete send_network_id; |
|
2642 } |
|
2643 #if defined(USE_EAPOL_KEY_STATE) |
|
2644 else if (id == EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID) |
|
2645 |
|
2646 { |
|
2647 const eap_am_network_id_c * const send_network_id |
|
2648 = reinterpret_cast<const eap_am_network_id_c *>(data); |
|
2649 delete send_network_id; |
|
2650 } |
|
2651 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2652 |
|
2653 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2654 } |
|
2655 |
|
2656 //-------------------------------------------------- |
|
2657 |
|
2658 #if defined(USE_EAPOL_KEY_STATE) |
|
2659 |
|
2660 // |
|
2661 EAP_FUNC_EXPORT eap_status_e eapol_core_c::init_eapol_key_pmksa_caching_timeout( |
|
2662 const eap_am_network_id_c * const send_network_id) |
|
2663 { |
|
2664 EAP_TRACE_DEBUG( |
|
2665 m_am_tools, |
|
2666 TRACE_FLAGS_DEFAULT, |
|
2667 (EAPL("%s: eapol_core_c::init_eapol_key_pmksa_caching_timeout().\n"), |
|
2668 (m_is_client == true) ? "client": "server")); |
|
2669 |
|
2670 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::init_eapol_key_pmksa_caching_timeout()"); |
|
2671 |
|
2672 // Initialize PMK caching timeout of EAPOL Key state. |
|
2673 eap_network_id_selector_c state_selector( |
|
2674 m_am_tools, |
|
2675 send_network_id); |
|
2676 |
|
2677 if (state_selector.get_is_valid() == false) |
|
2678 { |
|
2679 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2680 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2681 } |
|
2682 |
|
2683 EAP_TRACE_DATA_DEBUG( |
|
2684 m_am_tools, |
|
2685 TRACE_FLAGS_DEFAULT, |
|
2686 (EAPL("init_eapol_key_pmksa_caching_timeout(): EAPOL-Key session"), |
|
2687 state_selector.get_data(state_selector.get_data_length()), |
|
2688 state_selector.get_data_length())); |
|
2689 |
|
2690 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
2691 |
|
2692 if (eapol_key_state == 0) |
|
2693 { |
|
2694 EAP_TRACE_DEBUG( |
|
2695 m_am_tools, |
|
2696 TRACE_FLAGS_DEFAULT, |
|
2697 (EAPL("session not found.\n"), |
|
2698 (m_is_client == true) ? "client": "server")); |
|
2699 |
|
2700 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2701 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2702 } |
|
2703 |
|
2704 eap_status_e status = eapol_key_state->init_pmksa_caching_timeout(); |
|
2705 if (status != eap_status_ok) |
|
2706 { |
|
2707 EAP_TRACE_DEBUG( |
|
2708 m_am_tools, |
|
2709 TRACE_FLAGS_DEFAULT, |
|
2710 (EAPL("WARNING: eapol_core_c::init_eapol_key_pmksa_caching_timeout(): ") |
|
2711 EAPL("eapol_key_state->init_pmksa_caching_timeout(), eap_status_e %d\n"), |
|
2712 status)); |
|
2713 } |
|
2714 |
|
2715 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2716 } |
|
2717 |
|
2718 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2719 |
|
2720 //-------------------------------------------------- |
|
2721 |
|
2722 #if defined(USE_EAPOL_KEY_STATE) |
|
2723 |
|
2724 // |
|
2725 EAP_FUNC_EXPORT eap_status_e eapol_core_c::indicate_eapol_key_state_started_eap_authentication( |
|
2726 const eap_am_network_id_c * const send_network_id) |
|
2727 { |
|
2728 EAP_TRACE_DEBUG( |
|
2729 m_am_tools, |
|
2730 TRACE_FLAGS_DEFAULT, |
|
2731 (EAPL("%s: eapol_core_c::indicate_eapol_key_state_started_eap_authentication().\n"), |
|
2732 (m_is_client == true) ? "client": "server")); |
|
2733 |
|
2734 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::indicate_eapol_key_state_started_eap_authentication()"); |
|
2735 |
|
2736 // Remove possible EAPOL Key state. |
|
2737 eap_network_id_selector_c state_selector( |
|
2738 m_am_tools, |
|
2739 send_network_id); |
|
2740 |
|
2741 if (state_selector.get_is_valid() == false) |
|
2742 { |
|
2743 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2744 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2745 } |
|
2746 |
|
2747 EAP_TRACE_DATA_DEBUG( |
|
2748 m_am_tools, |
|
2749 TRACE_FLAGS_DEFAULT, |
|
2750 (EAPL("indicate_eapol_key_state_started_eap_authentication(): EAPOL-Key session"), |
|
2751 state_selector.get_data(state_selector.get_data_length()), |
|
2752 state_selector.get_data_length())); |
|
2753 |
|
2754 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
2755 |
|
2756 eap_status_e status(eap_status_handler_does_not_exists_error); |
|
2757 |
|
2758 if (eapol_key_state != 0) |
|
2759 { |
|
2760 status = eapol_key_state->started_eap_authentication(); |
|
2761 } |
|
2762 else |
|
2763 { |
|
2764 EAP_TRACE_DEBUG( |
|
2765 m_am_tools, |
|
2766 TRACE_FLAGS_DEFAULT, |
|
2767 (EAPL("WARNING: eapol_core_c::indicate_eapol_key_state_started_eap_authentication(): Cannot run eapol_key_state->started_eap_authentication() 0x%08x\n"), |
|
2768 eapol_key_state)); |
|
2769 } |
|
2770 |
|
2771 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2772 } |
|
2773 |
|
2774 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2775 |
|
2776 //-------------------------------------------------- |
|
2777 |
|
2778 #if defined(USE_EAPOL_KEY_STATE) |
|
2779 |
|
2780 // |
|
2781 EAP_FUNC_EXPORT eap_status_e eapol_core_c::remove_eapol_key_state( |
|
2782 const eap_am_network_id_c * const send_network_id) |
|
2783 { |
|
2784 EAP_TRACE_DEBUG( |
|
2785 m_am_tools, |
|
2786 TRACE_FLAGS_DEFAULT, |
|
2787 (EAPL("%s: eapol_core_c::remove_eapol_key_state().\n"), |
|
2788 (m_is_client == true) ? "client": "server")); |
|
2789 |
|
2790 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::remove_eapol_key_state()"); |
|
2791 |
|
2792 // Remove possible EAPOL Key state. |
|
2793 eap_network_id_selector_c state_selector( |
|
2794 m_am_tools, |
|
2795 send_network_id); |
|
2796 |
|
2797 if (state_selector.get_is_valid() == false) |
|
2798 { |
|
2799 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2800 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2801 } |
|
2802 |
|
2803 EAP_TRACE_DATA_DEBUG( |
|
2804 m_am_tools, |
|
2805 TRACE_FLAGS_DEFAULT, |
|
2806 (EAPL("remove_eapol_key_state(): EAPOL-Key session"), |
|
2807 state_selector.get_data(state_selector.get_data_length()), |
|
2808 state_selector.get_data_length())); |
|
2809 |
|
2810 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
2811 |
|
2812 if (eapol_key_state != 0) |
|
2813 { |
|
2814 if (eapol_key_state->get_marked_removed() == false) |
|
2815 { |
|
2816 // Do not remove object in use. |
|
2817 EAP_TRACE_DEBUG( |
|
2818 m_am_tools, |
|
2819 TRACE_FLAGS_DEFAULT, |
|
2820 (EAPL("WARNING: eapol_core_c::remove_eapol_key_state(): Cannot removed used object 0x%08x\n"), |
|
2821 eapol_key_state)); |
|
2822 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2823 } |
|
2824 |
|
2825 eapol_key_state->shutdown(); |
|
2826 } |
|
2827 else |
|
2828 { |
|
2829 EAP_TRACE_DEBUG( |
|
2830 m_am_tools, |
|
2831 TRACE_FLAGS_DEFAULT, |
|
2832 (EAPL("WARNING: eapol_core_c::remove_eapol_key_state(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), |
|
2833 eapol_key_state)); |
|
2834 } |
|
2835 |
|
2836 eap_status_e status = m_eapol_key_state_map.remove_handler(&state_selector, true); |
|
2837 if (status != eap_status_ok) |
|
2838 { |
|
2839 EAP_TRACE_DEBUG( |
|
2840 m_am_tools, |
|
2841 TRACE_FLAGS_DEFAULT, |
|
2842 (EAPL("WARNING: eapol_core_c::remove_eapol_key_state(): ") |
|
2843 EAPL("eapol_key_state->remove_handler(), eap_status_e %d\n"), |
|
2844 status)); |
|
2845 } |
|
2846 |
|
2847 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2848 } |
|
2849 |
|
2850 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2851 |
|
2852 //-------------------------------------------------- |
|
2853 |
|
2854 #if defined(USE_EAPOL_KEY_STATE) |
|
2855 |
|
2856 // |
|
2857 eap_status_e eapol_core_c::asynchronous_init_remove_eapol_key_state( |
|
2858 const eap_am_network_id_c * const send_network_id) |
|
2859 { |
|
2860 EAP_TRACE_DEBUG( |
|
2861 m_am_tools, |
|
2862 TRACE_FLAGS_DEFAULT, |
|
2863 (EAPL("%s: eapol_core_c::asynchronous_init_remove_eapol_key_state().\n"), |
|
2864 (m_is_client == true) ? "client": "server")); |
|
2865 |
|
2866 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::asynchronous_init_remove_eapol_key_state()"); |
|
2867 |
|
2868 // NOTE: we cannot delete the eapol_key_state_c object directly, because we will |
|
2869 // return from here to removed object. |
|
2870 |
|
2871 eap_status_e status = eap_status_process_general_error; |
|
2872 |
|
2873 eap_network_id_selector_c state_selector( |
|
2874 m_am_tools, |
|
2875 send_network_id); |
|
2876 |
|
2877 if (state_selector.get_is_valid() == false) |
|
2878 { |
|
2879 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2880 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2881 } |
|
2882 |
|
2883 EAP_TRACE_DATA_DEBUG( |
|
2884 m_am_tools, |
|
2885 TRACE_FLAGS_DEFAULT, |
|
2886 (EAPL("asynchronous_init_remove_eapol_key_state(): EAPOL-Key session"), |
|
2887 state_selector.get_data(state_selector.get_data_length()), |
|
2888 state_selector.get_data_length())); |
|
2889 |
|
2890 eapol_key_state_c *session = m_eapol_key_state_map.get_handler(&state_selector); |
|
2891 |
|
2892 if (session != 0) |
|
2893 { |
|
2894 session->set_marked_removed(); |
|
2895 |
|
2896 // So we initiate a timer to remove session identified by state_selector. |
|
2897 eap_am_network_id_c * const copy_send_network_id = send_network_id->copy(); |
|
2898 if (copy_send_network_id == 0 |
|
2899 || copy_send_network_id->get_is_valid_data() == false) |
|
2900 { |
|
2901 delete copy_send_network_id; |
|
2902 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2903 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2904 } |
|
2905 |
|
2906 status = m_partner->set_timer( |
|
2907 this, |
|
2908 EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID, |
|
2909 copy_send_network_id, |
|
2910 EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_TIMEOUT); |
|
2911 if (status != eap_status_ok) |
|
2912 { |
|
2913 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2914 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2915 } |
|
2916 |
|
2917 EAP_TRACE_DEBUG( |
|
2918 m_am_tools, |
|
2919 TRACE_FLAGS_DEFAULT, |
|
2920 (EAPL("eapol_core_c::asynchronous_init_remove_eapol_key_state()") |
|
2921 EAPL(": %s: EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID timer set %d ms.\n"), |
|
2922 (m_is_client == true) ? "client": "server", |
|
2923 EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_TIMEOUT)); |
|
2924 } |
|
2925 else |
|
2926 { |
|
2927 // Not found, cannot remove. |
|
2928 EAP_TRACE_DEBUG( |
|
2929 m_am_tools, |
|
2930 TRACE_FLAGS_DEFAULT, |
|
2931 (EAPL("ERROR: eapol_core_c::asynchronous_init_remove_eapol_key_state()") |
|
2932 EAPL(": %s: failed session not found.\n"), |
|
2933 (m_is_client == true) ? "client": "server")); |
|
2934 |
|
2935 status = eap_status_ok; |
|
2936 } |
|
2937 |
|
2938 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2939 } |
|
2940 |
|
2941 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
2942 |
|
2943 //-------------------------------------------------- |
|
2944 |
|
2945 EAP_FUNC_EXPORT void eapol_core_c::state_notification( |
|
2946 const abs_eap_state_notification_c * const state) |
|
2947 { |
|
2948 eap_status_e status = eap_status_process_general_error; |
|
2949 |
|
2950 EAP_TRACE_DEBUG( |
|
2951 m_am_tools, |
|
2952 TRACE_FLAGS_DEFAULT, |
|
2953 (EAPL("%s: eapol_core_c::state_notification(): m_block_state_notifications=%d.\n"), |
|
2954 (m_is_client == true) ? "client": "server", |
|
2955 m_block_state_notifications)); |
|
2956 |
|
2957 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::state_notification()"); |
|
2958 |
|
2959 if (m_block_state_notifications == true) |
|
2960 { |
|
2961 EAP_TRACE_DEBUG( |
|
2962 m_am_tools, |
|
2963 TRACE_FLAGS_DEFAULT, |
|
2964 (EAPL("WARNING: eapol_core_c::state_notification(): Blocks state notification") |
|
2965 EAPL("Protocol layer %d, Protocol %d, State transition ") |
|
2966 EAPL("from %d=%s to %d=%s, client %d\n"), |
|
2967 state->get_protocol_layer(), |
|
2968 state->get_protocol(), |
|
2969 state->get_previous_state(), |
|
2970 state->get_previous_state_string(), |
|
2971 state->get_current_state(), |
|
2972 state->get_current_state_string(), |
|
2973 state->get_is_client())); |
|
2974 |
|
2975 return; |
|
2976 } |
|
2977 |
|
2978 if (state->get_protocol_layer() == eap_protocol_layer_eap) |
|
2979 { |
|
2980 if (state->get_current_state() == eap_state_identity_request_received |
|
2981 || state->get_current_state() == eap_state_eap_response_sent) |
|
2982 { |
|
2983 if (state->get_current_state() == eap_state_identity_request_received) |
|
2984 { |
|
2985 (void) m_partner->cancel_timer( |
|
2986 this, |
|
2987 EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); |
|
2988 } |
|
2989 |
|
2990 if (state->get_current_state() == eap_state_identity_request_received |
|
2991 || state->get_current_state() == eap_state_eap_response_sent) |
|
2992 { |
|
2993 #if defined(USE_EAPOL_KEY_STATE) |
|
2994 // Indicate EAPOL Key state the started EAP-authentication. |
|
2995 status = indicate_eapol_key_state_started_eap_authentication( |
|
2996 state->get_send_network_id()); |
|
2997 if (status != eap_status_ok) |
|
2998 { |
|
2999 EAP_TRACE_DEBUG( |
|
3000 m_am_tools, |
|
3001 TRACE_FLAGS_DEFAULT, |
|
3002 (EAPL("WARNING: eapol_core_c::state_notification(): ") |
|
3003 EAPL("indicate_eapol_key_state_started_eap_authentication(), eap_status_e %d\n"), |
|
3004 status)); |
|
3005 } |
|
3006 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3007 } |
|
3008 |
|
3009 } |
|
3010 else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) |
|
3011 { |
|
3012 EAP_TRACE_DEBUG( |
|
3013 m_am_tools, |
|
3014 TRACE_FLAGS_DEFAULT, |
|
3015 (EAPL("ERROR: eapol_core_c::state_notification(): %s: EAP-authentication FAILED\n"), |
|
3016 (state->get_is_client() == true ? "client": "server"))); |
|
3017 |
|
3018 #if defined(USE_EAPOL_KEY_STATE) |
|
3019 // Remove possible EAPOL Key state. |
|
3020 status = remove_eapol_key_state( |
|
3021 state->get_send_network_id()); |
|
3022 if (status != eap_status_ok) |
|
3023 { |
|
3024 EAP_TRACE_DEBUG( |
|
3025 m_am_tools, |
|
3026 TRACE_FLAGS_DEFAULT, |
|
3027 (EAPL("WARNING: eapol_core_c::state_notification(): ") |
|
3028 EAPL("remove_eapol_key_state(), eap_status_e %d\n"), |
|
3029 status)); |
|
3030 } |
|
3031 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3032 |
|
3033 } |
|
3034 else if (state->get_current_state() == eap_state_authentication_finished_successfully) |
|
3035 { |
|
3036 EAP_TRACE_DEBUG( |
|
3037 m_am_tools, |
|
3038 TRACE_FLAGS_DEFAULT, |
|
3039 (EAPL("eapol_core_c::state_notification(): %s: EAP authentication SUCCESS\n"), |
|
3040 (state->get_is_client() == true ? "client": "server"))); |
|
3041 |
|
3042 #if defined(USE_EAPOL_KEY_STATE) |
|
3043 eap_network_id_selector_c state_selector( |
|
3044 m_am_tools, |
|
3045 state->get_send_network_id()); |
|
3046 |
|
3047 if (state_selector.get_is_valid() == false) |
|
3048 { |
|
3049 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3050 return; |
|
3051 } |
|
3052 |
|
3053 EAP_TRACE_DATA_DEBUG( |
|
3054 m_am_tools, |
|
3055 TRACE_FLAGS_DEFAULT, |
|
3056 (EAPL("state_notification(): EAPOL-Key session"), |
|
3057 state_selector.get_data(state_selector.get_data_length()), |
|
3058 state_selector.get_data_length())); |
|
3059 |
|
3060 eapol_key_state_c *eapol_key_state |
|
3061 = m_eapol_key_state_map.get_handler(&state_selector); |
|
3062 |
|
3063 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
3064 if (m_is_client == false) |
|
3065 { |
|
3066 // server |
|
3067 if (eapol_key_state != 0) |
|
3068 { |
|
3069 // Here we swap the addresses. |
|
3070 eap_am_network_id_c receive_network_id( |
|
3071 m_am_tools, |
|
3072 state->get_send_network_id()->get_destination_id(), |
|
3073 state->get_send_network_id()->get_source_id(), |
|
3074 state->get_send_network_id()->get_type()); |
|
3075 if (receive_network_id.get_is_valid_data() == false) |
|
3076 { |
|
3077 EAP_TRACE_DEBUG( |
|
3078 m_am_tools, |
|
3079 TRACE_FLAGS_DEFAULT, |
|
3080 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3081 EAPL("start_4_way_handshake() failed, allocation error\n"), |
|
3082 status)); |
|
3083 return; |
|
3084 } |
|
3085 |
|
3086 if (m_skip_start_4_way_handshake == true |
|
3087 && (m_authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
3088 || m_authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
3089 || m_authentication_type == eapol_key_authentication_type_WPA_EAP |
|
3090 || m_authentication_type == eapol_key_authentication_type_WPA_PSK |
|
3091 || m_authentication_type == eapol_key_authentication_type_WPXM)) |
|
3092 { |
|
3093 // This is test to skip 4-Way Handshake start. |
|
3094 EAP_TRACE_DEBUG( |
|
3095 m_am_tools, |
|
3096 TRACE_FLAGS_DEFAULT, |
|
3097 (EAPL("WARNING: eapol_core_c::state_notification(): ") |
|
3098 EAPL("skips start_4_way_handshake()\n"))); |
|
3099 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3100 return; |
|
3101 } |
|
3102 else |
|
3103 { |
|
3104 status = eapol_key_state->start_4_way_handshake( |
|
3105 &receive_network_id); |
|
3106 } |
|
3107 |
|
3108 if (status != eap_status_ok) |
|
3109 { |
|
3110 EAP_TRACE_DEBUG( |
|
3111 m_am_tools, |
|
3112 TRACE_FLAGS_DEFAULT, |
|
3113 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3114 EAPL("start_4_way_handshake() failed, eap_status_e %d\n"), |
|
3115 status)); |
|
3116 } |
|
3117 else |
|
3118 { |
|
3119 EAP_TRACE_DEBUG( |
|
3120 m_am_tools, |
|
3121 TRACE_FLAGS_DEFAULT, |
|
3122 (EAPL("eapol_core_c::state_notification(): ") |
|
3123 EAPL("start_4_way_handshake(), eap_status_e %d\n"), |
|
3124 status)); |
|
3125 } |
|
3126 } |
|
3127 else |
|
3128 { |
|
3129 EAP_TRACE_DEBUG( |
|
3130 m_am_tools, |
|
3131 TRACE_FLAGS_DEFAULT, |
|
3132 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3133 EAPL("start_4_way_handshake() failed, no eapol_key_state_c object\n"))); |
|
3134 } |
|
3135 } |
|
3136 else |
|
3137 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
3138 { |
|
3139 if (eapol_key_state != 0) |
|
3140 { |
|
3141 eap_status_e status = eapol_key_state->allow_4_way_handshake(); |
|
3142 if (status != eap_status_ok) |
|
3143 { |
|
3144 EAP_TRACE_DEBUG( |
|
3145 m_am_tools, |
|
3146 TRACE_FLAGS_DEFAULT, |
|
3147 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3148 EAPL("allow_4_way_handshake() failed, eap_status_e %d\n"), |
|
3149 status)); |
|
3150 } |
|
3151 else |
|
3152 { |
|
3153 EAP_TRACE_DEBUG( |
|
3154 m_am_tools, |
|
3155 TRACE_FLAGS_DEFAULT, |
|
3156 (EAPL("eapol_core_c::state_notification(): ") |
|
3157 EAPL("allow_4_way_handshake(), eap_status_e %d\n"), |
|
3158 status)); |
|
3159 } |
|
3160 } |
|
3161 else |
|
3162 { |
|
3163 EAP_TRACE_DEBUG( |
|
3164 m_am_tools, |
|
3165 TRACE_FLAGS_DEFAULT, |
|
3166 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3167 EAPL("allow_4_way_handshake() failed, no eapol_key_state_c object\n"))); |
|
3168 } |
|
3169 } |
|
3170 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3171 } |
|
3172 else |
|
3173 { |
|
3174 EAP_TRACE_DEBUG( |
|
3175 m_am_tools, |
|
3176 TRACE_FLAGS_DEFAULT, |
|
3177 (EAPL("eapol_core_c::state_notification(): Unknown notification: ") |
|
3178 EAPL("Protocol layer %d, Protocol %d, State transition ") |
|
3179 EAPL("from %d=%s to %d=%s, client %d\n"), |
|
3180 state->get_protocol_layer(), |
|
3181 state->get_protocol(), |
|
3182 state->get_previous_state(), |
|
3183 state->get_previous_state_string(), |
|
3184 state->get_current_state(), |
|
3185 state->get_current_state_string(), |
|
3186 state->get_is_client())); |
|
3187 } |
|
3188 } |
|
3189 #if defined(USE_EAPOL_KEY_STATE) |
|
3190 else if (state->get_protocol_layer() == eap_protocol_layer_eapol_key) |
|
3191 { |
|
3192 // This nofifation is from eapol_key_state_c object. |
|
3193 if (state->get_current_state() |
|
3194 == eapol_key_state_802_11i_authentication_terminated_unsuccessfull) |
|
3195 { |
|
3196 if (state->get_protocol() == eapol_key_handshake_type_4_way_handshake) |
|
3197 { |
|
3198 // 4-Way Handshake failed. |
|
3199 EAP_TRACE_DEBUG( |
|
3200 m_am_tools, |
|
3201 TRACE_FLAGS_DEFAULT, |
|
3202 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3203 EAPL("%s: 4-Way Handshake FAILED\n"), |
|
3204 (state->get_is_client() == true ? "client": "server"))); |
|
3205 } |
|
3206 else if (state->get_protocol() == eapol_key_handshake_type_group_key_handshake) |
|
3207 { |
|
3208 // Group Key Handshake failed. |
|
3209 EAP_TRACE_DEBUG( |
|
3210 m_am_tools, |
|
3211 TRACE_FLAGS_DEFAULT, |
|
3212 (EAPL("ERROR: eapol_core_c::state_notification(): ") |
|
3213 EAPL("%s: Group Key Handshake FAILED\n"), |
|
3214 (state->get_is_client() == true ? "client": "server"))); |
|
3215 } |
|
3216 } |
|
3217 else if (state->get_current_state() |
|
3218 == eapol_key_state_802_11i_authentication_finished_successfull) |
|
3219 { |
|
3220 if (state->get_protocol() == eapol_key_handshake_type_4_way_handshake) |
|
3221 { |
|
3222 // 4-Way Handshake succesfull. |
|
3223 EAP_TRACE_DEBUG( |
|
3224 m_am_tools, |
|
3225 TRACE_FLAGS_DEFAULT, |
|
3226 (EAPL("eapol_core_c::state_notification(): %s: 4-Way Handshake SUCCESS.\n"), |
|
3227 (state->get_is_client() == true ? "client": "server"))); |
|
3228 } |
|
3229 else if (state->get_protocol() == eapol_key_handshake_type_group_key_handshake) |
|
3230 { |
|
3231 // Group Key Handshake succesfull. |
|
3232 EAP_TRACE_DEBUG( |
|
3233 m_am_tools, |
|
3234 TRACE_FLAGS_DEFAULT, |
|
3235 (EAPL("eapol_core_c::state_notification(): %s: Group Key Handshake SUCCESS.\n"), |
|
3236 (state->get_is_client() == true ? "client": "server"))); |
|
3237 } |
|
3238 else if (state->get_protocol() == eapol_key_handshake_type_802_11i_handshake) |
|
3239 { |
|
3240 // Full 802.11i authentication succesfull. |
|
3241 EAP_TRACE_DEBUG( |
|
3242 m_am_tools, |
|
3243 TRACE_FLAGS_DEFAULT, |
|
3244 (EAPL("eapol_core_c::state_notification(): %s: ") |
|
3245 EAPL("Full 802.11i authentication SUCCESS.\n"), |
|
3246 (state->get_is_client() == true ? "client": "server"))); |
|
3247 } |
|
3248 else |
|
3249 { |
|
3250 EAP_TRACE_DEBUG( |
|
3251 m_am_tools, |
|
3252 TRACE_FLAGS_DEFAULT, |
|
3253 (EAPL("eapol_core_c::state_notification(): Unknown notification: ") |
|
3254 EAPL("Protocol layer %d, Protocol %d, State transition ") |
|
3255 EAPL("from %d=%s to %d=%s, client %d\n"), |
|
3256 state->get_protocol_layer(), |
|
3257 state->get_protocol(), |
|
3258 state->get_previous_state(), |
|
3259 state->get_previous_state_string(), |
|
3260 state->get_current_state(), |
|
3261 state->get_current_state_string(), |
|
3262 state->get_is_client())); |
|
3263 } |
|
3264 } |
|
3265 #if defined(EAP_USE_WPXM) |
|
3266 else if (state->get_current_state() |
|
3267 == eapol_key_state_wpxm_reassociation_finished_successfull) |
|
3268 { |
|
3269 if (state->get_protocol() == eapol_key_handshake_type_WPXM_reassociation) |
|
3270 { |
|
3271 // WPXM reassociation succesfull. |
|
3272 EAP_TRACE_DEBUG( |
|
3273 m_am_tools, |
|
3274 TRACE_FLAGS_DEFAULT, |
|
3275 (EAPL("eapol_core_c::state_notification(): %s: ") |
|
3276 EAPL("WPXM reassociation SUCCESS.\n"), |
|
3277 (state->get_is_client() == true ? "client": "server"))); |
|
3278 } |
|
3279 else |
|
3280 { |
|
3281 EAP_TRACE_DEBUG( |
|
3282 m_am_tools, |
|
3283 TRACE_FLAGS_DEFAULT, |
|
3284 (EAPL("eapol_core_c::state_notification(): Unknown notification: ") |
|
3285 EAPL("Protocol layer %d, Protocol %d, State transition ") |
|
3286 EAPL("from %d=%s to %d=%s, client %d\n"), |
|
3287 state->get_protocol_layer(), |
|
3288 state->get_protocol(), |
|
3289 state->get_previous_state(), |
|
3290 state->get_previous_state_string(), |
|
3291 state->get_current_state(), |
|
3292 state->get_current_state_string(), |
|
3293 state->get_is_client())); |
|
3294 } |
|
3295 } |
|
3296 #endif //#if defined(EAP_USE_WPXM) |
|
3297 else if (state->get_current_state() |
|
3298 == eapol_key_state_group_key_handshake_successfull) |
|
3299 { |
|
3300 if (state->get_protocol() == eapol_key_handshake_type_group_key_handshake) |
|
3301 { |
|
3302 // Group Key Handshake succesfull. |
|
3303 EAP_TRACE_DEBUG( |
|
3304 m_am_tools, |
|
3305 TRACE_FLAGS_DEFAULT, |
|
3306 (EAPL("eapol_core_c::state_notification(): %s: Group Key Handshake SUCCESS.\n"), |
|
3307 (state->get_is_client() == true ? "client": "server"))); |
|
3308 } |
|
3309 else |
|
3310 { |
|
3311 EAP_TRACE_DEBUG( |
|
3312 m_am_tools, |
|
3313 TRACE_FLAGS_DEFAULT, |
|
3314 (EAPL("eapol_core_c::state_notification(): Unknown notification: ") |
|
3315 EAPL("Protocol layer %d, Protocol %d, State transition ") |
|
3316 EAPL("from %d=%s to %d=%s, client %d\n"), |
|
3317 state->get_protocol_layer(), |
|
3318 state->get_protocol(), |
|
3319 state->get_previous_state(), |
|
3320 state->get_previous_state_string(), |
|
3321 state->get_current_state(), |
|
3322 state->get_current_state_string(), |
|
3323 state->get_is_client())); |
|
3324 } |
|
3325 } |
|
3326 else |
|
3327 { |
|
3328 EAP_TRACE_DEBUG( |
|
3329 m_am_tools, |
|
3330 TRACE_FLAGS_DEFAULT, |
|
3331 (EAPL("eapol_core_c::state_notification(): Unknown notification: ") |
|
3332 EAPL("Protocol layer %d, Protocol %d, State transition ") |
|
3333 EAPL("from %d=%s to %d=%s, client %d\n"), |
|
3334 state->get_protocol_layer(), |
|
3335 state->get_protocol(), |
|
3336 state->get_previous_state(), |
|
3337 state->get_previous_state_string(), |
|
3338 state->get_current_state(), |
|
3339 state->get_current_state_string(), |
|
3340 state->get_is_client())); |
|
3341 } |
|
3342 } |
|
3343 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3344 |
|
3345 |
|
3346 m_partner->state_notification(state); |
|
3347 } |
|
3348 |
|
3349 //-------------------------------------------------- |
|
3350 |
|
3351 // |
|
3352 EAP_FUNC_EXPORT eap_status_e eapol_core_c::asynchronous_init_remove_eap_session( |
|
3353 const eap_am_network_id_c * const /* send_network_id */) |
|
3354 { |
|
3355 // eapol_core_c object does not support asynchronous_init_remove_eap_session(). |
|
3356 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
3357 } |
|
3358 |
|
3359 //-------------------------------------------------- |
|
3360 |
|
3361 // |
|
3362 EAP_FUNC_EXPORT eap_status_e eapol_core_c::asynchronous_start_authentication( |
|
3363 const eap_am_network_id_c * const /* receive_network_id */, |
|
3364 const bool /* is_client_when_true */) |
|
3365 { |
|
3366 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
3367 } |
|
3368 |
|
3369 //-------------------------------------------------- |
|
3370 |
|
3371 // |
|
3372 EAP_FUNC_EXPORT eap_status_e eapol_core_c::set_timer( |
|
3373 abs_eap_base_timer_c * const p_initializer, |
|
3374 const u32_t p_id, |
|
3375 void * const p_data, |
|
3376 const u32_t p_time_ms) |
|
3377 { |
|
3378 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3379 |
|
3380 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3381 |
|
3382 const eap_status_e status = m_partner->set_timer( |
|
3383 p_initializer, |
|
3384 p_id, |
|
3385 p_data, |
|
3386 p_time_ms); |
|
3387 |
|
3388 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3389 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3390 } |
|
3391 |
|
3392 //-------------------------------------------------- |
|
3393 |
|
3394 // |
|
3395 EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_timer( |
|
3396 abs_eap_base_timer_c * const p_initializer, |
|
3397 const u32_t p_id) |
|
3398 { |
|
3399 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3400 |
|
3401 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3402 |
|
3403 const eap_status_e status = m_partner->cancel_timer( |
|
3404 p_initializer, |
|
3405 p_id); |
|
3406 |
|
3407 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3408 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3409 } |
|
3410 |
|
3411 //-------------------------------------------------- |
|
3412 |
|
3413 // |
|
3414 EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_all_timers() |
|
3415 { |
|
3416 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3417 |
|
3418 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3419 |
|
3420 const eap_status_e status = m_partner->cancel_all_timers(); |
|
3421 |
|
3422 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3423 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3424 } |
|
3425 |
|
3426 //-------------------------------------------------- |
|
3427 |
|
3428 EAP_FUNC_EXPORT eap_status_e eapol_core_c::check_is_valid_eap_type( |
|
3429 const eap_type_value_e eap_type) |
|
3430 { |
|
3431 eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); |
|
3432 |
|
3433 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3434 } |
|
3435 |
|
3436 //-------------------------------------------------- |
|
3437 |
|
3438 EAP_FUNC_EXPORT eap_status_e eapol_core_c::get_eap_type_list( |
|
3439 eap_array_c<eap_type_value_e> * const eap_type_list) |
|
3440 { |
|
3441 eap_status_e status = m_partner->get_eap_type_list(eap_type_list); |
|
3442 |
|
3443 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3444 } |
|
3445 |
|
3446 //-------------------------------------------------- |
|
3447 |
|
3448 #if defined(USE_EAPOL_KEY_STATE) |
|
3449 |
|
3450 // |
|
3451 EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_authentication_session( |
|
3452 eapol_key_state_c * const handler, |
|
3453 abs_eap_am_tools_c * const m_am_tools) |
|
3454 { |
|
3455 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3456 |
|
3457 EAP_TRACE_DEBUG( |
|
3458 m_am_tools, |
|
3459 TRACE_FLAGS_DEFAULT, |
|
3460 (EAPL("eapol_core_c::cancel_authentication_session(): this = 0x%08x => 0x%08x.\n"), |
|
3461 handler, |
|
3462 dynamic_cast<abs_eap_base_timer_c *>(handler))); |
|
3463 |
|
3464 EAP_UNREFERENCED_PARAMETER(m_am_tools); |
|
3465 |
|
3466 eap_status_e status = handler->cancel_authentication_session(); |
|
3467 |
|
3468 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3469 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3470 } |
|
3471 |
|
3472 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3473 |
|
3474 //-------------------------------------------------- |
|
3475 |
|
3476 EAP_FUNC_EXPORT eap_status_e eapol_core_c::cancel_all_authentication_sessions() |
|
3477 { |
|
3478 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3479 |
|
3480 EAP_TRACE_DEBUG( |
|
3481 m_am_tools, |
|
3482 TRACE_FLAGS_DEFAULT, |
|
3483 (EAPL("eapol_core_c::cancel_all_authentication_sessions(): this = 0x%08x => 0x%08x.\n"), |
|
3484 this, |
|
3485 dynamic_cast<abs_eap_base_timer_c *>(this))); |
|
3486 |
|
3487 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::cancel_all_authentication_sessions()"); |
|
3488 |
|
3489 eap_status_e status(eap_status_ok); |
|
3490 |
|
3491 |
|
3492 bool previous_block = m_block_state_notifications; |
|
3493 m_block_state_notifications = true; |
|
3494 |
|
3495 #if !defined(NO_EAP_SESSION_CORE) |
|
3496 if (m_eap_core != 0) |
|
3497 { |
|
3498 status = m_eap_core->synchronous_cancel_all_eap_sessions(); |
|
3499 } |
|
3500 #endif //#if !defined(NO_EAP_SESSION_CORE) |
|
3501 |
|
3502 |
|
3503 #if defined(USE_EAPOL_KEY_STATE) |
|
3504 status = m_eapol_key_state_map.for_each(cancel_authentication_session, true); |
|
3505 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3506 |
|
3507 m_block_state_notifications = previous_block; |
|
3508 |
|
3509 |
|
3510 // This will cancel all timers of this object. |
|
3511 m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); |
|
3512 #if defined(USE_EAPOL_KEY_STATE) |
|
3513 m_partner->cancel_timer(this, EAPOL_REMOVE_EAPOL_KEY_HANDSHAKE_ID); |
|
3514 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3515 |
|
3516 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3517 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3518 } |
|
3519 |
|
3520 //-------------------------------------------------- |
|
3521 |
|
3522 #if defined(USE_EAPOL_KEY_STATE) |
|
3523 |
|
3524 EAP_FUNC_EXPORT eap_status_e eapol_core_c::get_and_increment_global_key_counter( |
|
3525 eap_variable_data_c * const key_counter) |
|
3526 { |
|
3527 key_counter->reset(); |
|
3528 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
3529 } |
|
3530 |
|
3531 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3532 |
|
3533 //-------------------------------------------------- |
|
3534 |
|
3535 #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3536 /** |
|
3537 * Function creates a state for later use. This is for optimazing 4-Way Handshake. |
|
3538 * @param receive_network_id carries the MAC addresses. |
|
3539 * MAC address of Authenticator should be in source address. MAC address of |
|
3540 * Supplicant should be in destination address. |
|
3541 * @param authentication_type is the selected authentication type. |
|
3542 */ |
|
3543 EAP_FUNC_EXPORT eap_status_e eapol_core_c::create_state( |
|
3544 const eap_am_network_id_c * const receive_network_id, |
|
3545 const eapol_key_authentication_type_e authentication_type |
|
3546 ) |
|
3547 { |
|
3548 eap_status_e status = eap_status_process_general_error; |
|
3549 |
|
3550 EAP_TRACE_DEBUG( |
|
3551 m_am_tools, |
|
3552 TRACE_FLAGS_DEFAULT, |
|
3553 (EAPL("%s: eapol_core_c::create_state().\n"), |
|
3554 (m_is_client == true) ? "client": "server")); |
|
3555 |
|
3556 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::create_state()"); |
|
3557 |
|
3558 if (receive_network_id->get_type() != eapol_ethernet_type_pae) |
|
3559 { |
|
3560 EAP_TRACE_DEBUG( |
|
3561 m_am_tools, |
|
3562 TRACE_FLAGS_DEFAULT, |
|
3563 (EAPL("WARNING: eapol_core_c::create_state(): Illegal Ethernet type %d\n"), |
|
3564 receive_network_id->get_type())); |
|
3565 |
|
3566 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3567 return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); |
|
3568 } |
|
3569 |
|
3570 // Here we swap the addresses. |
|
3571 eap_am_network_id_c send_network_id( |
|
3572 m_am_tools, |
|
3573 receive_network_id->get_destination_id(), |
|
3574 receive_network_id->get_source_id(), |
|
3575 receive_network_id->get_type()); |
|
3576 if (send_network_id.get_is_valid_data() == false) |
|
3577 { |
|
3578 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3579 } |
|
3580 |
|
3581 eap_network_id_selector_c state_selector( |
|
3582 m_am_tools, |
|
3583 &send_network_id); |
|
3584 |
|
3585 if (state_selector.get_is_valid() == false) |
|
3586 { |
|
3587 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3588 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3589 } |
|
3590 |
|
3591 m_authentication_type = authentication_type; |
|
3592 |
|
3593 EAP_TRACE_DATA_DEBUG( |
|
3594 m_am_tools, |
|
3595 TRACE_FLAGS_DEFAULT, |
|
3596 (EAPL("create_state(): EAPOL-Key session"), |
|
3597 state_selector.get_data(state_selector.get_data_length()), |
|
3598 state_selector.get_data_length())); |
|
3599 |
|
3600 |
|
3601 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
3602 |
|
3603 if (eapol_key_state != 0) |
|
3604 { |
|
3605 // Reuse the session. |
|
3606 eapol_key_state->unset_marked_removed(); |
|
3607 |
|
3608 if (m_is_client == false) |
|
3609 { |
|
3610 // In test version do not reset server. |
|
3611 } |
|
3612 else |
|
3613 { |
|
3614 status = eapol_key_state->reset(); |
|
3615 if (status != eap_status_ok) |
|
3616 { |
|
3617 // We cannot reuse the session. |
|
3618 EAP_TRACE_ERROR( |
|
3619 m_am_tools, |
|
3620 TRACE_FLAGS_ERROR, |
|
3621 (EAPL("eapol_core_c::create_state(): eapol_key_state NOT reused.\n"))); |
|
3622 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3623 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3624 } |
|
3625 } |
|
3626 } |
|
3627 |
|
3628 |
|
3629 if (eapol_key_state == 0) |
|
3630 { |
|
3631 eapol_key_state = new eapol_key_state_c( |
|
3632 m_am_tools, |
|
3633 this, |
|
3634 m_partner, |
|
3635 m_is_client, |
|
3636 receive_network_id, |
|
3637 authentication_type); |
|
3638 if (eapol_key_state == 0 |
|
3639 || eapol_key_state->get_is_valid() == false) |
|
3640 { |
|
3641 if (eapol_key_state != 0) |
|
3642 { |
|
3643 eapol_key_state->shutdown(); |
|
3644 } |
|
3645 else |
|
3646 { |
|
3647 EAP_TRACE_DEBUG( |
|
3648 m_am_tools, |
|
3649 TRACE_FLAGS_DEFAULT, |
|
3650 (EAPL("WARNING: eapol_core_c::create_state(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), |
|
3651 eapol_key_state)); |
|
3652 } |
|
3653 delete eapol_key_state; |
|
3654 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3655 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3656 } |
|
3657 |
|
3658 status = eapol_key_state->initialize( |
|
3659 receive_network_id, |
|
3660 authentication_type); |
|
3661 if (status != eap_status_ok) |
|
3662 { |
|
3663 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3664 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3665 } |
|
3666 |
|
3667 status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); |
|
3668 if (status != eap_status_ok) |
|
3669 { |
|
3670 if (eapol_key_state != 0) |
|
3671 { |
|
3672 eapol_key_state->shutdown(); |
|
3673 } |
|
3674 else |
|
3675 { |
|
3676 EAP_TRACE_DEBUG( |
|
3677 m_am_tools, |
|
3678 TRACE_FLAGS_DEFAULT, |
|
3679 (EAPL("WARNING: eapol_core_c::create_state(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), |
|
3680 eapol_key_state)); |
|
3681 } |
|
3682 delete eapol_key_state; |
|
3683 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3684 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3685 } |
|
3686 } |
|
3687 else |
|
3688 { |
|
3689 status = eapol_key_state->initialize( |
|
3690 receive_network_id, |
|
3691 authentication_type); |
|
3692 if (status != eap_status_ok) |
|
3693 { |
|
3694 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3695 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3696 } |
|
3697 } |
|
3698 |
|
3699 status = eapol_key_state->configure(); |
|
3700 if (status != eap_status_ok) |
|
3701 { |
|
3702 status = remove_eapol_key_state( |
|
3703 &send_network_id); |
|
3704 if (status != eap_status_ok) |
|
3705 { |
|
3706 EAP_TRACE_DEBUG( |
|
3707 m_am_tools, |
|
3708 TRACE_FLAGS_DEFAULT, |
|
3709 (EAPL("WARNING: eapol_core_c::create_state(): ") |
|
3710 EAPL("remove_eapol_key_state(), eap_status_e %d\n"), |
|
3711 status)); |
|
3712 } |
|
3713 |
|
3714 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3715 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3716 } |
|
3717 |
|
3718 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3719 } |
|
3720 |
|
3721 #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3722 |
|
3723 //-------------------------------------------------- |
|
3724 |
|
3725 #if defined(USE_EAPOL_KEY_STATE) |
|
3726 /** |
|
3727 * @param receive_network_id carries the MAC addresses. |
|
3728 * MAC address of Authenticator should be in source address. MAC address of |
|
3729 * Supplicant should be in destination address. |
|
3730 * @param authenticator_RSNA_IE is RSN IE of authenticator. Authenticator |
|
3731 * sends this in Beacon or Probe message. |
|
3732 * @param supplicant_RSNA_IE is RSN IE of supplicant. Supplicant sends |
|
3733 * this in (re)association request message. |
|
3734 * @param eapol_pairwise_cipher is the selected pairwise cipher. |
|
3735 * @param eapol_group_cipher is the selected group cipher. |
|
3736 */ |
|
3737 EAP_FUNC_EXPORT eap_status_e eapol_core_c::association( |
|
3738 const eap_am_network_id_c * const receive_network_id, |
|
3739 const eapol_key_authentication_type_e authentication_type, |
|
3740 const eap_variable_data_c * const authenticator_RSNA_IE, |
|
3741 const eap_variable_data_c * const supplicant_RSNA_IE, |
|
3742 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_pairwise_cipher, |
|
3743 const eapol_RSNA_key_header_c::eapol_RSNA_cipher_e eapol_group_cipher, |
|
3744 const eap_variable_data_c * const pre_shared_key_PSK |
|
3745 ) |
|
3746 { |
|
3747 eap_status_e status = eap_status_process_general_error; |
|
3748 |
|
3749 EAP_TRACE_DEBUG( |
|
3750 m_am_tools, |
|
3751 TRACE_FLAGS_DEFAULT, |
|
3752 (EAPL("%s: eapol_core_c::association().\n"), |
|
3753 (m_is_client == true) ? "client": "server")); |
|
3754 |
|
3755 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::association()"); |
|
3756 |
|
3757 if (receive_network_id->get_type() != eapol_ethernet_type_pae) |
|
3758 { |
|
3759 EAP_TRACE_DEBUG( |
|
3760 m_am_tools, |
|
3761 TRACE_FLAGS_DEFAULT, |
|
3762 (EAPL("WARNING: eapol_core_c::association(): Illegal Ethernet type %d\n"), |
|
3763 receive_network_id->get_type())); |
|
3764 |
|
3765 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3766 return EAP_STATUS_RETURN(m_am_tools, eap_status_ethernet_type_not_supported); |
|
3767 } |
|
3768 |
|
3769 // Here we swap the addresses. |
|
3770 eap_am_network_id_c send_network_id( |
|
3771 m_am_tools, |
|
3772 receive_network_id->get_destination_id(), |
|
3773 receive_network_id->get_source_id(), |
|
3774 receive_network_id->get_type()); |
|
3775 if (send_network_id.get_is_valid_data() == false) |
|
3776 { |
|
3777 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3778 } |
|
3779 |
|
3780 eap_network_id_selector_c state_selector( |
|
3781 m_am_tools, |
|
3782 &send_network_id); |
|
3783 |
|
3784 if (state_selector.get_is_valid() == false) |
|
3785 { |
|
3786 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3787 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3788 } |
|
3789 |
|
3790 m_authentication_type = authentication_type; |
|
3791 |
|
3792 EAP_TRACE_DATA_DEBUG( |
|
3793 m_am_tools, |
|
3794 TRACE_FLAGS_DEFAULT, |
|
3795 (EAPL("association(): EAPOL-Key session"), |
|
3796 state_selector.get_data(state_selector.get_data_length()), |
|
3797 state_selector.get_data_length())); |
|
3798 |
|
3799 |
|
3800 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
3801 |
|
3802 #if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3803 if (eapol_key_state != 0) |
|
3804 { |
|
3805 // Reuse the session. |
|
3806 eapol_key_state->unset_marked_removed(); |
|
3807 |
|
3808 if (m_is_client == false) |
|
3809 { |
|
3810 // In test version do not reset server. |
|
3811 } |
|
3812 else |
|
3813 { |
|
3814 status = eapol_key_state->reset(); |
|
3815 if (status != eap_status_ok) |
|
3816 { |
|
3817 // We cannot reuse the session. |
|
3818 EAP_TRACE_ERROR( |
|
3819 m_am_tools, |
|
3820 TRACE_FLAGS_ERROR, |
|
3821 (EAPL("eapol_core_c::association(): eapol_key_state NOT reused.\n"))); |
|
3822 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3823 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3824 } |
|
3825 } |
|
3826 } |
|
3827 #endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3828 |
|
3829 |
|
3830 if (eapol_key_state == 0) |
|
3831 { |
|
3832 |
|
3833 #if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3834 |
|
3835 eapol_key_state = new eapol_key_state_c( |
|
3836 m_am_tools, |
|
3837 this, |
|
3838 m_partner, |
|
3839 m_is_client, |
|
3840 receive_network_id, |
|
3841 authentication_type, |
|
3842 authenticator_RSNA_IE, |
|
3843 supplicant_RSNA_IE, |
|
3844 eapol_pairwise_cipher, |
|
3845 eapol_group_cipher, |
|
3846 pre_shared_key_PSK); |
|
3847 if (eapol_key_state == 0 |
|
3848 || eapol_key_state->get_is_valid() == false) |
|
3849 { |
|
3850 if (eapol_key_state != 0) |
|
3851 { |
|
3852 eapol_key_state->shutdown(); |
|
3853 } |
|
3854 else |
|
3855 { |
|
3856 EAP_TRACE_DEBUG( |
|
3857 m_am_tools, |
|
3858 TRACE_FLAGS_DEFAULT, |
|
3859 (EAPL("WARNING: eapol_core_c::association(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), |
|
3860 eapol_key_state)); |
|
3861 } |
|
3862 delete eapol_key_state; |
|
3863 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3864 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3865 } |
|
3866 |
|
3867 status = eapol_key_state->initialize( |
|
3868 receive_network_id, |
|
3869 authentication_type, |
|
3870 authenticator_RSNA_IE, |
|
3871 supplicant_RSNA_IE, |
|
3872 eapol_pairwise_cipher, |
|
3873 eapol_group_cipher, |
|
3874 pre_shared_key_PSK); |
|
3875 if (status != eap_status_ok) |
|
3876 { |
|
3877 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3878 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3879 } |
|
3880 |
|
3881 status = m_eapol_key_state_map.add_handler(&state_selector, eapol_key_state); |
|
3882 if (status != eap_status_ok) |
|
3883 { |
|
3884 if (eapol_key_state != 0) |
|
3885 { |
|
3886 eapol_key_state->shutdown(); |
|
3887 } |
|
3888 else |
|
3889 { |
|
3890 EAP_TRACE_DEBUG( |
|
3891 m_am_tools, |
|
3892 TRACE_FLAGS_DEFAULT, |
|
3893 (EAPL("WARNING: eapol_core_c::association(): Cannot run eapol_key_state->shutdown() 0x%08x\n"), |
|
3894 eapol_key_state)); |
|
3895 } |
|
3896 delete eapol_key_state; |
|
3897 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3898 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3899 } |
|
3900 |
|
3901 #else |
|
3902 |
|
3903 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3904 return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); |
|
3905 |
|
3906 #endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3907 |
|
3908 } |
|
3909 else |
|
3910 { |
|
3911 status = eapol_key_state->initialize( |
|
3912 receive_network_id, |
|
3913 authentication_type, |
|
3914 authenticator_RSNA_IE, |
|
3915 supplicant_RSNA_IE, |
|
3916 eapol_pairwise_cipher, |
|
3917 eapol_group_cipher, |
|
3918 pre_shared_key_PSK); |
|
3919 if (status != eap_status_ok) |
|
3920 { |
|
3921 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3922 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3923 } |
|
3924 } |
|
3925 |
|
3926 |
|
3927 #if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3928 status = eapol_key_state->configure(); |
|
3929 if (status != eap_status_ok) |
|
3930 { |
|
3931 status = remove_eapol_key_state( |
|
3932 &send_network_id); |
|
3933 if (status != eap_status_ok) |
|
3934 { |
|
3935 EAP_TRACE_DEBUG( |
|
3936 m_am_tools, |
|
3937 TRACE_FLAGS_DEFAULT, |
|
3938 (EAPL("WARNING: eapol_core_c::association(): ") |
|
3939 EAPL("remove_eapol_key_state(), eap_status_e %d\n"), |
|
3940 status)); |
|
3941 } |
|
3942 |
|
3943 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3944 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3945 } |
|
3946 #endif //#if !defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3947 |
|
3948 |
|
3949 if (authentication_type == eapol_key_authentication_type_RSNA_PSK |
|
3950 || authentication_type == eapol_key_authentication_type_WPA_PSK) |
|
3951 { |
|
3952 |
|
3953 #if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
3954 if (m_is_client == false) |
|
3955 { |
|
3956 #if defined(USE_EAPOL_KEY_STATE) |
|
3957 if (m_skip_start_4_way_handshake == true) |
|
3958 { |
|
3959 // This is test to skip 4-Way Handshake start. |
|
3960 EAP_TRACE_DEBUG( |
|
3961 m_am_tools, |
|
3962 TRACE_FLAGS_DEFAULT, |
|
3963 (EAPL("WARNING: eapol_core_c::association(): ") |
|
3964 EAPL("skips start_4_way_handshake()\n"))); |
|
3965 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3966 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3967 } |
|
3968 else |
|
3969 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
3970 { |
|
3971 status = eapol_key_state->start_4_way_handshake( |
|
3972 receive_network_id); |
|
3973 } |
|
3974 |
|
3975 if (status != eap_status_ok) |
|
3976 { |
|
3977 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3978 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3979 } |
|
3980 } |
|
3981 else |
|
3982 #endif //#if !defined(NO_EAPOL_KEY_STATE_SERVER) |
|
3983 { |
|
3984 eapol_key_state->allow_4_way_handshake(); |
|
3985 } |
|
3986 } |
|
3987 #if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
3988 else if (authentication_type == eapol_key_authentication_type_RSNA_EAP |
|
3989 || authentication_type == eapol_key_authentication_type_WPA_EAP |
|
3990 || authentication_type == eapol_key_authentication_type_802_1X |
|
3991 || authentication_type == eapol_key_authentication_type_WPXM |
|
3992 || authentication_type == eapol_key_authentication_type_WFA_SC) |
|
3993 { |
|
3994 // Creates a EAP-session. |
|
3995 status = m_eap_core->synchronous_create_eap_session(receive_network_id); |
|
3996 if (status != eap_status_ok) |
|
3997 { |
|
3998 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3999 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4000 } |
|
4001 } |
|
4002 #endif //#if defined(USE_EAPOL_KEY_STATE_OPTIMIZED_4_WAY_HANDSHAKE) |
|
4003 |
|
4004 |
|
4005 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4006 } |
|
4007 |
|
4008 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
4009 |
|
4010 //-------------------------------------------------- |
|
4011 |
|
4012 #if defined(USE_EAPOL_KEY_STATE) |
|
4013 /** |
|
4014 * @param receive_network_id carries the MAC addresses. |
|
4015 * MAC address of Authenticator should be in source address. |
|
4016 * MAC address of Supplicant should be in destination address. |
|
4017 */ |
|
4018 EAP_FUNC_EXPORT eap_status_e eapol_core_c::disassociation( |
|
4019 const eap_am_network_id_c * const receive_network_id |
|
4020 ) |
|
4021 { |
|
4022 eap_status_e status = eap_status_process_general_error; |
|
4023 |
|
4024 EAP_TRACE_DEBUG( |
|
4025 m_am_tools, |
|
4026 TRACE_FLAGS_DEFAULT, |
|
4027 (EAPL("%s: eapol_core_c::disassociation().\n"), |
|
4028 (m_is_client == true) ? "client": "server")); |
|
4029 |
|
4030 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eapol_core_c::disassociation()"); |
|
4031 |
|
4032 if (receive_network_id == 0) |
|
4033 { |
|
4034 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4035 } |
|
4036 |
|
4037 // Here we swap the addresses. |
|
4038 eap_am_network_id_c send_network_id( |
|
4039 m_am_tools, |
|
4040 receive_network_id->get_destination_id(), |
|
4041 receive_network_id->get_source_id(), |
|
4042 receive_network_id->get_type()); |
|
4043 if (send_network_id.get_is_valid_data() == false) |
|
4044 { |
|
4045 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4046 } |
|
4047 |
|
4048 |
|
4049 (void) m_partner->cancel_timer(this, EAPOL_CORE_TIMER_SEND_START_AGAIN_ID); |
|
4050 |
|
4051 #if !defined(NO_EAP_SESSION_CORE) |
|
4052 // First we remove possible EAP session. |
|
4053 (void) m_eap_core->synchronous_remove_eap_session(receive_network_id); |
|
4054 #endif |
|
4055 |
|
4056 status = init_eapol_key_pmksa_caching_timeout( |
|
4057 &send_network_id); |
|
4058 if (status != eap_status_ok) |
|
4059 { |
|
4060 EAP_TRACE_DEBUG( |
|
4061 m_am_tools, |
|
4062 TRACE_FLAGS_DEFAULT, |
|
4063 (EAPL("WARNING: eapol_core_c::disassociation(): ") |
|
4064 EAPL("init_eapol_key_pmksa_caching_timeout(), eap_status_e %d\n"), |
|
4065 status)); |
|
4066 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4067 } |
|
4068 |
|
4069 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4070 } |
|
4071 |
|
4072 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
4073 |
|
4074 //-------------------------------------------------- |
|
4075 |
|
4076 /// @see abs_eap_core_c::add_rogue_ap(). |
|
4077 EAP_FUNC_EXPORT eap_status_e eapol_core_c::add_rogue_ap( |
|
4078 eap_array_c<eap_rogue_ap_entry_c> & rogue_ap_list) |
|
4079 { |
|
4080 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4081 |
|
4082 EAP_TRACE_DEBUG( |
|
4083 m_am_tools, |
|
4084 TRACE_FLAGS_DEFAULT, |
|
4085 (EAPL("%s: eapol_core_c::add_rogue_ap().\n"), |
|
4086 (m_is_client == true) ? "client": "server")); |
|
4087 |
|
4088 const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); |
|
4089 |
|
4090 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4091 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4092 } |
|
4093 |
|
4094 //-------------------------------------------------- |
|
4095 |
|
4096 EAP_FUNC_EXPORT eap_status_e eapol_core_c::tkip_mic_failure( |
|
4097 const eap_am_network_id_c * const receive_network_id, |
|
4098 const bool fatal_failure_when_true, |
|
4099 const eapol_RSNA_key_header_c::eapol_tkip_mic_failure_type_e tkip_mic_failure_type) |
|
4100 { |
|
4101 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4102 |
|
4103 EAP_TRACE_DEBUG( |
|
4104 m_am_tools, |
|
4105 TRACE_FLAGS_DEFAULT, |
|
4106 (EAPL("%s: eapol_core_c::tkip_mic_failure().\n"), |
|
4107 (m_is_client == true) ? "client": "server")); |
|
4108 |
|
4109 eap_status_e status = eap_status_process_general_error; |
|
4110 |
|
4111 #if defined(USE_EAPOL_KEY_STATE) |
|
4112 |
|
4113 // Here we swap the addresses. |
|
4114 eap_am_network_id_c send_network_id( |
|
4115 m_am_tools, |
|
4116 receive_network_id->get_destination_id(), |
|
4117 receive_network_id->get_source_id(), |
|
4118 receive_network_id->get_type()); |
|
4119 if (send_network_id.get_is_valid_data() == false) |
|
4120 { |
|
4121 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4122 } |
|
4123 |
|
4124 eap_network_id_selector_c state_selector( |
|
4125 m_am_tools, |
|
4126 &send_network_id); |
|
4127 |
|
4128 if (state_selector.get_is_valid() == false) |
|
4129 { |
|
4130 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4131 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4132 } |
|
4133 |
|
4134 EAP_TRACE_DATA_DEBUG( |
|
4135 m_am_tools, |
|
4136 TRACE_FLAGS_DEFAULT, |
|
4137 (EAPL("tkip_mic_failure(): EAPOL-Key session"), |
|
4138 state_selector.get_data(state_selector.get_data_length()), |
|
4139 state_selector.get_data_length())); |
|
4140 |
|
4141 |
|
4142 eapol_key_state_c *eapol_key_state = m_eapol_key_state_map.get_handler(&state_selector); |
|
4143 |
|
4144 if (eapol_key_state != 0) |
|
4145 { |
|
4146 status = eapol_key_state->tkip_mic_failure( |
|
4147 fatal_failure_when_true, |
|
4148 tkip_mic_failure_type); |
|
4149 } |
|
4150 else |
|
4151 { |
|
4152 status = eap_status_handler_does_not_exists_error; |
|
4153 } |
|
4154 |
|
4155 #else |
|
4156 |
|
4157 status = eap_status_not_supported; |
|
4158 |
|
4159 #endif //#if defined(USE_EAPOL_KEY_STATE) |
|
4160 |
|
4161 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4162 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4163 } |
|
4164 |
|
4165 //-------------------------------------------------- |
|
4166 |
|
4167 // |
|
4168 EAP_FUNC_EXPORT eap_status_e eapol_core_c::set_session_timeout( |
|
4169 const u32_t /* session_timeout_ms */) |
|
4170 { |
|
4171 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4172 |
|
4173 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
4174 |
|
4175 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4176 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
4177 } |
|
4178 |
|
4179 //-------------------------------------------------- |
|
4180 |
|
4181 |
|
4182 |
|
4183 // End. |