|
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 44 |
|
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 "eap_core.h" |
|
32 #include "eap_core_nak_info.h" |
|
33 #include "eap_state_notification.h" |
|
34 #include "eap_network_id_selector.h" |
|
35 #include "eap_buffer.h" |
|
36 #include "eap_header_string.h" |
|
37 #include "eap_automatic_variable.h" |
|
38 |
|
39 |
|
40 /** |
|
41 * This is the character that separates routing realms. |
|
42 */ |
|
43 const u8_t EAP_NAI_ROUTING_REALM_SEPARATOR[] = "!"; |
|
44 |
|
45 /** |
|
46 * This is the at character of NAI. |
|
47 */ |
|
48 const u8_t EAP_NAI_AT_CHARACTER[] = "@"; |
|
49 |
|
50 |
|
51 //-------------------------------------------------- |
|
52 |
|
53 // |
|
54 EAP_FUNC_EXPORT eap_core_c::~eap_core_c() |
|
55 { |
|
56 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
57 |
|
58 EAP_TRACE_DEBUG( |
|
59 m_am_tools, |
|
60 TRACE_FLAGS_DEFAULT, |
|
61 (EAPL("eap_core_c::~eap_core_c(): %s, %s, this = 0x%08x => 0x%08x.\n"), |
|
62 (m_is_client == true) ? "client": "server", |
|
63 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
64 this, |
|
65 dynamic_cast<abs_eap_base_timer_c *>(this))); |
|
66 |
|
67 EAP_ASSERT(m_shutdown_was_called == true); |
|
68 |
|
69 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
70 } |
|
71 |
|
72 //-------------------------------------------------- |
|
73 |
|
74 #if defined(_WIN32) && !defined(__GNUC__) |
|
75 #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list |
|
76 #endif |
|
77 |
|
78 // |
|
79 EAP_FUNC_EXPORT eap_core_c::eap_core_c( |
|
80 abs_eap_am_tools_c * const tools, |
|
81 abs_eap_core_c * const partner, |
|
82 const bool is_client_when_true, |
|
83 const eap_am_network_id_c * const receive_network_id, |
|
84 const bool is_tunneled_eap) |
|
85 : m_partner(partner) |
|
86 , m_am_tools(tools) |
|
87 , m_type_map(tools, this) |
|
88 , m_current_eap_type(eap_type_none) |
|
89 , m_default_eap_type(eap_type_none) |
|
90 , m_eap_identity(tools) |
|
91 , m_eap_header_offset(0u) |
|
92 , m_MTU(0u) |
|
93 , m_trailer_length(0u) |
|
94 , m_receive_network_id(tools) |
|
95 , m_retransmission(0) |
|
96 , m_retransmission_time(EAP_CORE_RETRANSMISSION_TIME) |
|
97 , m_retransmission_counter(EAP_CORE_RETRANSMISSION_COUNTER) |
|
98 , m_session_timeout(EAP_CORE_SESSION_TIMEOUT) |
|
99 , m_eap_core_failure_received_timeout(EAP_CORE_FAILURE_RECEIVED_TIMEOUT) |
|
100 , m_remove_session_timeout(EAP_CORE_REMOVE_SESSION_TIMEOUT) |
|
101 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
102 , m_wait_eap_request_type_timeout(EAP_CORE_WAIT_EAP_REQUEST_TYPE_TIMEOUT) |
|
103 , m_wait_eap_request_type_timeout_set(false) |
|
104 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
105 , m_eap_identity_request_identifier_client(0) |
|
106 , m_is_client(is_client_when_true) |
|
107 , m_is_client_role(is_client_when_true) |
|
108 , m_is_valid(false) |
|
109 , m_client_restart_authentication_initiated(false) |
|
110 , m_marked_removed(false) |
|
111 , m_eap_identity_response_accepted(false) |
|
112 , m_shutdown_was_called(false) |
|
113 , m_eap_type_response_sent(false) |
|
114 , m_is_tunneled_eap(is_tunneled_eap) |
|
115 #if defined(USE_EAP_CORE_SERVER) |
|
116 , m_process_eap_nak_immediately(EAP_CORE_PROCESS_EAP_NAK_IMMEDIATELY) |
|
117 , m_nak_process_timer_active(false) |
|
118 , m_eap_identity_request_send(false) |
|
119 , m_eap_identity_response_received(false) |
|
120 , m_eap_failure_sent(false) |
|
121 , m_send_eap_success_after_notification(false) |
|
122 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
123 , m_skip_eap_request_identity(false) |
|
124 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
125 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
126 , m_use_eap_expanded_type(false) |
|
127 , m_ignore_eap_failure(false) |
|
128 , m_ignore_notifications(false) |
|
129 { |
|
130 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
131 |
|
132 EAP_TRACE_DEBUG( |
|
133 m_am_tools, |
|
134 TRACE_FLAGS_DEFAULT, |
|
135 (EAPL("eap_core_c::eap_core_c(): %s, %s, this = 0x%08x => 0x%08x, compiled %s %s.\n"), |
|
136 (m_is_client == true) ? "client": "server", |
|
137 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
138 this, |
|
139 dynamic_cast<abs_eap_base_timer_c *>(this), |
|
140 __DATE__, |
|
141 __TIME__)); |
|
142 |
|
143 eap_status_e status = m_receive_network_id.set_copy_of_network_id(receive_network_id); |
|
144 if (status != eap_status_ok) |
|
145 { |
|
146 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
147 return; |
|
148 } |
|
149 |
|
150 set_is_valid(); |
|
151 |
|
152 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
153 } |
|
154 |
|
155 //-------------------------------------------------- |
|
156 |
|
157 // |
|
158 EAP_FUNC_EXPORT abs_eap_core_c * eap_core_c::get_partner() |
|
159 { |
|
160 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
161 |
|
162 return m_partner; |
|
163 } |
|
164 |
|
165 //-------------------------------------------------- |
|
166 |
|
167 // |
|
168 EAP_FUNC_EXPORT void eap_core_c::set_partner(abs_eap_core_c * const partner) |
|
169 { |
|
170 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
171 |
|
172 m_partner = partner; |
|
173 } |
|
174 |
|
175 //-------------------------------------------------- |
|
176 |
|
177 // |
|
178 EAP_FUNC_EXPORT void eap_core_c::set_is_valid() |
|
179 { |
|
180 m_is_valid = true; |
|
181 } |
|
182 |
|
183 //-------------------------------------------------- |
|
184 |
|
185 // |
|
186 EAP_FUNC_EXPORT bool eap_core_c::get_is_valid() |
|
187 { |
|
188 return m_is_valid; |
|
189 } |
|
190 |
|
191 //-------------------------------------------------- |
|
192 |
|
193 // |
|
194 EAP_FUNC_EXPORT void eap_core_c::object_increase_reference_count() |
|
195 { |
|
196 } |
|
197 |
|
198 //-------------------------------------------------- |
|
199 |
|
200 // |
|
201 EAP_FUNC_EXPORT u32_t eap_core_c::object_decrease_reference_count() |
|
202 { |
|
203 return 0u; |
|
204 } |
|
205 |
|
206 //-------------------------------------------------- |
|
207 |
|
208 // |
|
209 EAP_FUNC_EXPORT bool eap_core_c::get_marked_removed() |
|
210 { |
|
211 return m_marked_removed; |
|
212 } |
|
213 |
|
214 //-------------------------------------------------- |
|
215 |
|
216 // |
|
217 EAP_FUNC_EXPORT void eap_core_c::set_marked_removed() |
|
218 { |
|
219 m_marked_removed = true; |
|
220 } |
|
221 |
|
222 //-------------------------------------------------- |
|
223 |
|
224 // |
|
225 EAP_FUNC_EXPORT void eap_core_c::unset_marked_removed() |
|
226 { |
|
227 m_marked_removed = false; |
|
228 } |
|
229 |
|
230 |
|
231 //-------------------------------------------------- |
|
232 |
|
233 // |
|
234 EAP_FUNC_EXPORT void eap_core_c::ignore_notifications() |
|
235 { |
|
236 m_ignore_notifications = true; |
|
237 } |
|
238 |
|
239 //-------------------------------------------------- |
|
240 |
|
241 // |
|
242 eap_status_e eap_core_c::initialize_asynchronous_init_remove_eap_session( |
|
243 const u32_t remove_session_timeout) |
|
244 { |
|
245 EAP_TRACE_DEBUG( |
|
246 m_am_tools, |
|
247 TRACE_FLAGS_DEFAULT, |
|
248 (EAPL("eap_core_c::initialize_asynchronous_init_remove_eap_session(): %s.\n"), |
|
249 (m_is_client == true) ? "client": "server")); |
|
250 |
|
251 eap_status_e status = eap_status_process_general_error; |
|
252 |
|
253 |
|
254 if (m_is_client_role == false) |
|
255 { |
|
256 // Server stops re-transmissions. |
|
257 // Client can re-transmit until session is removed. |
|
258 cancel_retransmission(); |
|
259 } |
|
260 |
|
261 cancel_eap_failure_timeout(); |
|
262 |
|
263 cancel_session_timeout(); |
|
264 |
|
265 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
266 if (m_is_tunneled_eap == false |
|
267 && m_is_client_role == true) |
|
268 { |
|
269 cancel_wait_eap_request_type_timeout(); |
|
270 } |
|
271 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
272 |
|
273 set_marked_removed(); |
|
274 |
|
275 |
|
276 if (remove_session_timeout == 0ul) |
|
277 { |
|
278 status = asynchronous_init_remove_eap_session(); |
|
279 } |
|
280 else |
|
281 { |
|
282 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
283 |
|
284 cancel_asynchronous_init_remove_eap_session(); |
|
285 |
|
286 status = m_partner->set_timer( |
|
287 this, |
|
288 EAP_CORE_REMOVE_SESSION_TIMEOUT_ID, |
|
289 0, |
|
290 remove_session_timeout); |
|
291 |
|
292 if (status != eap_status_ok) |
|
293 { |
|
294 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
295 return EAP_STATUS_RETURN(m_am_tools, status); |
|
296 } |
|
297 |
|
298 EAP_TRACE_DEBUG( |
|
299 m_am_tools, |
|
300 TRACE_FLAGS_DEFAULT, |
|
301 (EAPL("TIMER: %s: %s, EAP_CORE_REMOVE_SESSION_TIMEOUT_ID set %d ms, this = 0x%08x.\n"), |
|
302 (m_is_client == true) ? "client": "server", |
|
303 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
304 remove_session_timeout, |
|
305 this)); |
|
306 } |
|
307 |
|
308 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
309 return EAP_STATUS_RETURN(m_am_tools, status); |
|
310 } |
|
311 |
|
312 //-------------------------------------------------- |
|
313 |
|
314 eap_status_e eap_core_c::cancel_asynchronous_init_remove_eap_session() |
|
315 { |
|
316 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
317 |
|
318 if (m_partner != 0) |
|
319 { |
|
320 eap_status_e status = m_partner->cancel_timer( |
|
321 this, |
|
322 EAP_CORE_REMOVE_SESSION_TIMEOUT_ID); |
|
323 |
|
324 EAP_UNREFERENCED_PARAMETER(status); // in release |
|
325 |
|
326 EAP_TRACE_DEBUG( |
|
327 m_am_tools, |
|
328 TRACE_FLAGS_DEFAULT, |
|
329 (EAPL("TIMER: %s: %s, EAP_CORE_REMOVE_SESSION_TIMEOUT_ID cancelled status %d, this = 0x%08x.\n"), |
|
330 (m_is_client == true ? "client": "server"), |
|
331 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
332 status, |
|
333 this)); |
|
334 } |
|
335 |
|
336 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
337 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
338 } |
|
339 |
|
340 //-------------------------------------------------- |
|
341 |
|
342 // |
|
343 eap_status_e eap_core_c::asynchronous_init_remove_eap_session() |
|
344 { |
|
345 EAP_TRACE_DEBUG( |
|
346 m_am_tools, |
|
347 TRACE_FLAGS_DEFAULT, |
|
348 (EAPL("eap_core_c::asynchronous_init_remove_eap_session(): %s.\n"), |
|
349 (m_is_client == true) ? "client": "server")); |
|
350 |
|
351 eap_am_network_id_c send_network_id( |
|
352 m_am_tools, |
|
353 m_receive_network_id.get_destination_id(), |
|
354 m_receive_network_id.get_source_id(), |
|
355 m_receive_network_id.get_type()); |
|
356 |
|
357 eap_status_e status = m_partner->asynchronous_init_remove_eap_session( |
|
358 &send_network_id); |
|
359 |
|
360 return EAP_STATUS_RETURN(m_am_tools, status); |
|
361 } |
|
362 |
|
363 //-------------------------------------------------- |
|
364 |
|
365 // |
|
366 eap_status_e eap_core_c::init_end_of_session( |
|
367 const abs_eap_state_notification_c * const state) |
|
368 { |
|
369 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
370 |
|
371 EAP_TRACE_DEBUG( |
|
372 m_am_tools, |
|
373 TRACE_FLAGS_DEFAULT, |
|
374 (EAPL("eap_core_c::init_end_of_session(): %s.\n"), |
|
375 (m_is_client == true) ? "client": "server")); |
|
376 |
|
377 eap_status_e status(eap_status_process_general_error); |
|
378 |
|
379 // Normally we will remove session after authentication ends. |
|
380 // Remove session only if the stack is not already being deleted |
|
381 if (m_shutdown_was_called == false) |
|
382 { |
|
383 #if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAP_CORE_RESTART_AUTHENTICATION) |
|
384 #error ERROR: USE_EAPOL_KEY_STATE and USE_EAP_CORE_RESTART_AUTHENTICATION cannot be used same time. |
|
385 #endif //#if defined(USE_EAPOL_KEY_STATE) && defined(USE_EAP_CORE_RESTART_AUTHENTICATION) |
|
386 |
|
387 #if defined(USE_EAP_CORE_SIMULATOR_VERSION) && defined(USE_EAP_CORE_RESTART_AUTHENTICATION) |
|
388 |
|
389 // Simulator reuses current session. |
|
390 status = restart_authentication( |
|
391 state->get_send_network_id(), |
|
392 m_is_client); |
|
393 if (status != eap_status_ok) |
|
394 { |
|
395 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
396 return EAP_STATUS_RETURN(m_am_tools, status); |
|
397 } |
|
398 |
|
399 #elif defined(USE_EAP_CORE_SIMULATOR_VERSION) && defined(USE_EAPOL_KEY_STATE) |
|
400 |
|
401 EAP_TRACE_DEBUG( |
|
402 m_am_tools, |
|
403 TRACE_FLAGS_DEFAULT, |
|
404 (EAPL("eap_core_c::state_notification(): %s, %s, Ignored notification: ") |
|
405 EAPL("Protocol layer %d, EAP type 0x%02x, State transition from ") |
|
406 EAPL("%d=%s to %d=%s, client %d.\n"), |
|
407 (m_is_client == true) ? "client": "server", |
|
408 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
409 state->get_protocol_layer(), |
|
410 state->get_protocol(), |
|
411 state->get_previous_state(), |
|
412 state->get_previous_state_string(), |
|
413 state->get_current_state(), |
|
414 state->get_current_state_string(), |
|
415 state->get_is_client())); |
|
416 |
|
417 #endif //#if defined(USE_EAP_CORE_SIMULATOR_VERSION) |
|
418 |
|
419 status = initialize_asynchronous_init_remove_eap_session(m_remove_session_timeout); |
|
420 if (status != eap_status_ok) |
|
421 { |
|
422 EAP_UNREFERENCED_PARAMETER(state); |
|
423 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
424 return EAP_STATUS_RETURN(m_am_tools, status); |
|
425 } |
|
426 } |
|
427 else |
|
428 { |
|
429 EAP_TRACE_DEBUG( |
|
430 m_am_tools, |
|
431 TRACE_FLAGS_DEFAULT, |
|
432 (EAPL("eap_core_c::state_notification(): %s, %s, Ignored notification: ") |
|
433 EAPL("Protocol layer %d, EAP type 0x%02x, State transition from ") |
|
434 EAPL("%d=%s to %d=%s, client %d when shutdown was called.\n"), |
|
435 (m_is_client == true) ? "client": "server", |
|
436 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
437 state->get_protocol_layer(), |
|
438 state->get_protocol(), |
|
439 state->get_previous_state(), |
|
440 state->get_previous_state_string(), |
|
441 state->get_current_state(), |
|
442 state->get_current_state_string(), |
|
443 state->get_is_client())); |
|
444 |
|
445 status = eap_status_ok; |
|
446 } |
|
447 |
|
448 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
449 return EAP_STATUS_RETURN(m_am_tools, status); |
|
450 } |
|
451 |
|
452 //-------------------------------------------------- |
|
453 |
|
454 EAP_FUNC_EXPORT void eap_core_c::state_notification( |
|
455 const abs_eap_state_notification_c * const state) |
|
456 { |
|
457 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
458 |
|
459 eap_status_string_c status_string; |
|
460 eap_header_string_c eap_string; |
|
461 EAP_UNREFERENCED_PARAMETER(status_string); // in release |
|
462 EAP_UNREFERENCED_PARAMETER(eap_string); // in release |
|
463 |
|
464 EAP_TRACE_DEBUG( |
|
465 m_am_tools, |
|
466 TRACE_FLAGS_DEFAULT, |
|
467 (EAPL("eap_core_c::state_notification(), %s, %s, protocol_layer %d=%s, protocol %d=%s, EAP-type 0x%08x=%s.\n"), |
|
468 (m_is_client == true) ? "client": "server", |
|
469 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
470 state->get_protocol_layer(), |
|
471 state->get_protocol_layer_string(), |
|
472 state->get_protocol(), |
|
473 state->get_protocol_string(), |
|
474 convert_eap_type_to_u32_t(state->get_eap_type()), |
|
475 eap_string.get_eap_type_string(state->get_eap_type()))); |
|
476 |
|
477 EAP_TRACE_DEBUG( |
|
478 m_am_tools, |
|
479 TRACE_FLAGS_DEFAULT, |
|
480 (EAPL("eap_core_c::state_notification(), %s, %s, current_state %d=%s, error %d=%s.\n"), |
|
481 (m_is_client == true) ? "client": "server", |
|
482 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
483 state->get_current_state(), |
|
484 state->get_current_state_string(), |
|
485 state->get_authentication_error(), |
|
486 status_string.get_status_string(state->get_authentication_error()))); |
|
487 |
|
488 if (m_ignore_notifications == true |
|
489 || m_partner == 0) |
|
490 { |
|
491 return; |
|
492 } |
|
493 |
|
494 // Check if the notification is from the current active type |
|
495 if (state->get_protocol_layer() == eap_protocol_layer_general) |
|
496 { |
|
497 // These notications are allowed always. |
|
498 } |
|
499 else if (state->get_protocol_layer() == eap_protocol_layer_eap |
|
500 && state->get_eap_type() != m_current_eap_type) |
|
501 { |
|
502 EAP_TRACE_DEBUG( |
|
503 m_am_tools, |
|
504 TRACE_FLAGS_DEFAULT, |
|
505 (EAPL("eap_core_c::state_notification(): %s, %s, Ignored notification: ") |
|
506 EAPL("Protocol layer %d, non-active EAP type 0x%02x, current EAP type 0x%08x, State transition from ") |
|
507 EAPL("%d=%s to %d=%s, client %d\n"), |
|
508 (m_is_client == true) ? "client": "server", |
|
509 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
510 state->get_protocol_layer(), |
|
511 state->get_protocol(), |
|
512 convert_eap_type_to_u32_t(m_current_eap_type), |
|
513 state->get_previous_state(), |
|
514 state->get_previous_state_string(), |
|
515 state->get_current_state(), |
|
516 state->get_current_state_string(), |
|
517 state->get_is_client())); |
|
518 return; |
|
519 } |
|
520 |
|
521 if (state->get_protocol_layer() == eap_protocol_layer_eap) |
|
522 { |
|
523 if (state->get_current_state() == eap_state_identity_response_received) |
|
524 { |
|
525 m_eap_identity_response_accepted = true; |
|
526 |
|
527 EAP_TRACE_DEBUG( |
|
528 m_am_tools, |
|
529 TRACE_FLAGS_DEFAULT, |
|
530 (EAPL("EAP-Response/Identity received: %s, %s\n"), |
|
531 (m_is_client == true) ? "client": "server", |
|
532 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
533 )); |
|
534 } |
|
535 else if (state->get_current_state() == eap_state_identity_request_received) |
|
536 { |
|
537 EAP_TRACE_DEBUG( |
|
538 m_am_tools, |
|
539 TRACE_FLAGS_DEFAULT, |
|
540 (EAPL("EAP-Request/Identity received: %s, %s\n"), |
|
541 (m_is_client == true) ? "client": "server", |
|
542 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
543 )); |
|
544 } |
|
545 else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) |
|
546 { |
|
547 EAP_TRACE_DEBUG( |
|
548 m_am_tools, |
|
549 TRACE_FLAGS_DEFAULT, |
|
550 (EAPL("ERROR: eap_core_c::state_notification(): %s, %s: EAP-authentication terminated unsuccessfully.\n"), |
|
551 (m_is_client == true) ? "client": "server", |
|
552 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
553 )); |
|
554 |
|
555 #if defined(USE_EAP_CORE_SERVER) |
|
556 if (m_is_client == false |
|
557 && (m_eap_type_response_sent == true |
|
558 || m_eap_identity_response_received == true) |
|
559 && m_send_eap_success_after_notification == false) |
|
560 { |
|
561 /** |
|
562 * 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2. |
|
563 * Extensible Authentication Protocol (EAP): |
|
564 * The authenticator MUST NOT send a Success or Failure packet when retransmitting |
|
565 * or when it fails to get a response from the peer. |
|
566 * In the case eap_state_authentication_terminated_unsuccessfully we will need a flag |
|
567 * that indicates whether there was a response from client or not. |
|
568 * If there was a response server must send EAP-Failure. |
|
569 * If there was NO response from client server |
|
570 * does NOT send EAP-Failure. |
|
571 */ |
|
572 send_eap_failure( |
|
573 state->get_send_network_id(), |
|
574 state->get_eap_identifier()); |
|
575 } |
|
576 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
577 |
|
578 (void) init_end_of_session(state); |
|
579 } |
|
580 else if (state->get_current_state() == eap_state_authentication_finished_successfully) |
|
581 { |
|
582 EAP_TRACE_DEBUG( |
|
583 m_am_tools, |
|
584 TRACE_FLAGS_DEFAULT, |
|
585 (EAPL("eap_core_c::state_notification(): %s, %s: EAP-authentication finished successfully.\n"), |
|
586 (m_is_client == true) ? "client": "server", |
|
587 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
588 )); |
|
589 |
|
590 |
|
591 #if defined(USE_EAP_CORE_SERVER) |
|
592 if (m_is_client == false |
|
593 && m_eap_type_response_sent == true |
|
594 && m_send_eap_success_after_notification == false) |
|
595 { |
|
596 // Here we test whether the EAP-type allow send EAP-Success. |
|
597 // For example PEAP v1 does not allow send EAP-Success. |
|
598 if (state->get_allow_send_eap_success() == true) |
|
599 { |
|
600 send_eap_success( |
|
601 state->get_send_network_id(), |
|
602 state->get_eap_identifier()); |
|
603 } |
|
604 |
|
605 // Now we can send a new EAP-Request/Identity. |
|
606 m_eap_identity_request_send = false; |
|
607 } |
|
608 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
609 |
|
610 (void) init_end_of_session(state); |
|
611 } |
|
612 else if (m_is_client == true |
|
613 && state->get_current_state() == eap_state_use_eap_failure_in_termination) |
|
614 { |
|
615 // Client should accept EAP-Failure quietly. |
|
616 m_ignore_eap_failure = true; |
|
617 |
|
618 (void) init_end_of_session(state); |
|
619 } |
|
620 #if defined(USE_EAP_CORE_SERVER) |
|
621 else if (m_is_client == false |
|
622 && state->get_current_state() == eap_state_use_eap_failure_in_termination) |
|
623 { |
|
624 send_eap_failure( |
|
625 state->get_send_network_id(), |
|
626 state->get_eap_identifier()); |
|
627 |
|
628 (void) init_end_of_session(state); |
|
629 } |
|
630 else if (m_current_eap_type == eap_type_peap |
|
631 && state->get_current_state() == eap_state_authentication_wait_tppd_peapv1_empty_acknowledge) |
|
632 { |
|
633 send_eap_success( |
|
634 state->get_send_network_id(), |
|
635 state->get_eap_identifier()); |
|
636 |
|
637 return; |
|
638 } |
|
639 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
640 } |
|
641 |
|
642 |
|
643 m_partner->state_notification(state); |
|
644 |
|
645 |
|
646 #if defined(USE_EAP_CORE_SERVER) |
|
647 // EAP-Success is send after the success notification is forwarded to lower layer. |
|
648 // This allows to combine success notification and sent EAP-success packet. |
|
649 if (state->get_current_state() == eap_state_authentication_finished_successfully) |
|
650 { |
|
651 if (m_is_client == false |
|
652 && m_eap_type_response_sent == true |
|
653 && m_send_eap_success_after_notification == true) |
|
654 { |
|
655 // Here we test whether the EAP-type allow send EAP-Success. |
|
656 // For example PEAP v1 does not allow send EAP-Success. |
|
657 if (state->get_allow_send_eap_success() == true) |
|
658 { |
|
659 send_eap_success( |
|
660 state->get_send_network_id(), |
|
661 state->get_eap_identifier()); |
|
662 } |
|
663 |
|
664 // Now we can send a new EAP-Request/Identity. |
|
665 m_eap_identity_request_send = false; |
|
666 } |
|
667 } |
|
668 else if (state->get_current_state() == eap_state_authentication_terminated_unsuccessfully) |
|
669 { |
|
670 if (m_is_client == false |
|
671 && (m_eap_type_response_sent == true |
|
672 || m_eap_identity_response_received == true) |
|
673 && m_send_eap_success_after_notification == true) |
|
674 { |
|
675 /** |
|
676 * 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2. |
|
677 * Extensible Authentication Protocol (EAP): |
|
678 * The authenticator MUST NOT send a Success or Failure packet when retransmitting |
|
679 * or when it fails to get a response from the peer. |
|
680 * In the case eap_state_authentication_terminated_unsuccessfully we will need a flag |
|
681 * that indicates whether there was a response from client or not. |
|
682 * If there was a response server must send EAP-Failure. |
|
683 * If there was NO response from client server |
|
684 * does NOT send EAP-Failure. |
|
685 */ |
|
686 send_eap_failure( |
|
687 state->get_send_network_id(), |
|
688 state->get_eap_identifier()); |
|
689 } |
|
690 } |
|
691 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
692 |
|
693 |
|
694 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
695 } |
|
696 |
|
697 //-------------------------------------------------- |
|
698 |
|
699 // |
|
700 EAP_FUNC_EXPORT eap_base_type_c * eap_core_c::load_type( |
|
701 const eap_type_value_e type, |
|
702 const eap_type_value_e tunneling_type, |
|
703 const eap_am_network_id_c * const receive_network_id) |
|
704 { |
|
705 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
706 |
|
707 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
708 |
|
709 eap_base_type_c *handler = 0; |
|
710 |
|
711 eap_status_e status = m_partner->load_module( |
|
712 type, |
|
713 tunneling_type, |
|
714 this, |
|
715 &handler, |
|
716 m_is_client, |
|
717 receive_network_id); |
|
718 if (status != eap_status_ok) |
|
719 { |
|
720 if (handler != 0) |
|
721 { |
|
722 handler->shutdown(); |
|
723 delete handler; |
|
724 } |
|
725 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
726 return 0; |
|
727 } |
|
728 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
729 return handler; |
|
730 } |
|
731 |
|
732 //-------------------------------------------------- |
|
733 |
|
734 EAP_FUNC_EXPORT eap_status_e eap_core_c::check_is_valid_eap_type(const eap_type_value_e eap_type) |
|
735 { |
|
736 eap_status_e status = m_partner->check_is_valid_eap_type(eap_type); |
|
737 |
|
738 return EAP_STATUS_RETURN(m_am_tools, status); |
|
739 } |
|
740 |
|
741 //-------------------------------------------------- |
|
742 |
|
743 EAP_FUNC_EXPORT eap_status_e eap_core_c::get_eap_type_list( |
|
744 eap_array_c<eap_type_value_e> * const eap_type_list) |
|
745 { |
|
746 eap_status_e status = m_partner->get_eap_type_list(eap_type_list); |
|
747 |
|
748 return EAP_STATUS_RETURN(m_am_tools, status); |
|
749 } |
|
750 |
|
751 //-------------------------------------------------- |
|
752 |
|
753 // |
|
754 EAP_FUNC_EXPORT eap_status_e eap_core_c::initialize_session_timeout(const u32_t session_timeout_ms) |
|
755 { |
|
756 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
757 |
|
758 cancel_session_timeout(); |
|
759 |
|
760 eap_status_e status = m_partner->set_timer( |
|
761 this, |
|
762 EAP_CORE_SESSION_TIMEOUT_ID, |
|
763 0, |
|
764 session_timeout_ms); |
|
765 |
|
766 if (status != eap_status_ok) |
|
767 { |
|
768 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
769 return EAP_STATUS_RETURN(m_am_tools, status); |
|
770 } |
|
771 |
|
772 EAP_TRACE_DEBUG( |
|
773 m_am_tools, |
|
774 TRACE_FLAGS_DEFAULT, |
|
775 (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID set %d ms, this = 0x%08x.\n"), |
|
776 (m_is_client == true) ? "client": "server", |
|
777 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
778 session_timeout_ms, |
|
779 this)); |
|
780 |
|
781 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
782 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
783 } |
|
784 |
|
785 //-------------------------------------------------- |
|
786 |
|
787 EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_session_timeout() |
|
788 { |
|
789 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
790 |
|
791 eap_status_e status = m_partner->cancel_timer( |
|
792 this, |
|
793 EAP_CORE_SESSION_TIMEOUT_ID); |
|
794 |
|
795 EAP_UNREFERENCED_PARAMETER(status); // in release |
|
796 |
|
797 EAP_TRACE_DEBUG( |
|
798 m_am_tools, |
|
799 TRACE_FLAGS_DEFAULT, |
|
800 (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID cancelled status %d, this = 0x%08x.\n"), |
|
801 (m_is_client == true ? "client": "server"), |
|
802 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
803 status, |
|
804 this)); |
|
805 |
|
806 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
807 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
808 } |
|
809 |
|
810 //-------------------------------------------------- |
|
811 |
|
812 EAP_FUNC_EXPORT void eap_core_c::trace_eap_packet( |
|
813 eap_const_string prefix, |
|
814 const eap_header_wr_c * const eap_header) |
|
815 { |
|
816 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
817 |
|
818 // Get rid of warnings in release version |
|
819 EAP_UNREFERENCED_PARAMETER(eap_header); |
|
820 EAP_UNREFERENCED_PARAMETER(prefix); |
|
821 |
|
822 EAP_TRACE_DEBUG( |
|
823 m_am_tools, |
|
824 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
825 (EAPL("%s EAP_Core: %s, %s, code=0x%02x=%s, identifier=0x%02x, length=0x%04x, type=0x%08x=%s, packet length 0x%04x\n"), |
|
826 prefix, |
|
827 (m_is_client == true) ? "client": "server", |
|
828 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
829 eap_header->get_code(), |
|
830 eap_header->get_code_string(), |
|
831 eap_header->get_identifier(), |
|
832 eap_header->get_length(), |
|
833 convert_eap_type_to_u32_t(eap_header->get_type()), |
|
834 eap_header->get_type_string(), |
|
835 eap_header->get_length())); |
|
836 } |
|
837 |
|
838 |
|
839 //-------------------------------------------------- |
|
840 |
|
841 #if defined(USE_EAP_CORE_SERVER) |
|
842 |
|
843 EAP_FUNC_EXPORT eap_status_e eap_core_c::restart_with_new_type( |
|
844 const eap_type_value_e used_eap_type, |
|
845 const eap_am_network_id_c * const receive_network_id, |
|
846 const u8_t eap_identifier) |
|
847 { |
|
848 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
849 |
|
850 EAP_TRACE_DEBUG( |
|
851 m_am_tools, |
|
852 TRACE_FLAGS_DEFAULT, |
|
853 (EAPL("eap_core_c::restart_with_new_type(): %s\n"), |
|
854 (m_is_client == true) ? "client": "server")); |
|
855 |
|
856 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::restart_with_new_type()"); |
|
857 |
|
858 // Here we need to re-create the received EAP-Response/Identity message. |
|
859 |
|
860 if (m_eap_identity.get_is_valid_data() == false) |
|
861 { |
|
862 // No saved EAP-Identity. Cannot continue. |
|
863 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
864 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); |
|
865 } |
|
866 |
|
867 eap_status_e status = eap_status_process_general_error; |
|
868 |
|
869 eap_buf_chain_wr_c response_packet( |
|
870 eap_write_buffer, |
|
871 m_am_tools, |
|
872 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
873 |
|
874 if (response_packet.get_is_valid() == false) |
|
875 { |
|
876 EAP_TRACE_ERROR( |
|
877 m_am_tools, |
|
878 TRACE_FLAGS_DEFAULT, |
|
879 (EAPL("packet buffer corrupted: %s, %s\n"), |
|
880 (m_is_client == true) ? "client": "server", |
|
881 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
882 )); |
|
883 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
884 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
885 } |
|
886 |
|
887 status = create_eap_identity_response( |
|
888 &response_packet, |
|
889 &m_eap_identity, |
|
890 eap_identifier); |
|
891 if (status != eap_status_ok) |
|
892 { |
|
893 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
894 return EAP_STATUS_RETURN(m_am_tools, status); |
|
895 } |
|
896 |
|
897 |
|
898 eap_header_wr_c eap( |
|
899 m_am_tools, |
|
900 response_packet.get_data_offset(m_eap_header_offset, response_packet.get_data_length()), |
|
901 response_packet.get_data_length()); |
|
902 if (eap.get_is_valid() == false) |
|
903 { |
|
904 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
905 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
906 } |
|
907 |
|
908 // Bacause we start with a new EAP-type EAP-Response/Identity is prosessed again. |
|
909 m_eap_identity_response_accepted = false; |
|
910 |
|
911 m_ignore_eap_failure = false; |
|
912 |
|
913 status = packet_process_type( |
|
914 used_eap_type, |
|
915 receive_network_id, |
|
916 &eap, |
|
917 eap.get_length()); |
|
918 |
|
919 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
920 return EAP_STATUS_RETURN(m_am_tools, status); |
|
921 } |
|
922 |
|
923 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
924 |
|
925 //-------------------------------------------------- |
|
926 |
|
927 EAP_FUNC_EXPORT eap_status_e eap_core_c::client_proposes_eap_types( |
|
928 const eap_am_network_id_c * const receive_network_id, |
|
929 const u8_t eap_identifier) |
|
930 { |
|
931 eap_array_c<eap_type_value_e> eap_type_list(m_am_tools); |
|
932 |
|
933 /** |
|
934 * @{ 2005-04-19 complete Expanded Nak Type to client_proposes_eap_types(). } |
|
935 */ |
|
936 eap_status_e status = get_eap_type_list(&eap_type_list); |
|
937 if (status != eap_status_ok) |
|
938 { |
|
939 eap_type_list.reset(); |
|
940 |
|
941 eap_type_value_e * default_eap_type = new eap_type_value_e(m_default_eap_type); |
|
942 if (default_eap_type == 0) |
|
943 { |
|
944 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
945 return EAP_STATUS_RETURN(m_am_tools, status); |
|
946 } |
|
947 |
|
948 status = eap_type_list.add_object(default_eap_type, true); |
|
949 if (status != eap_status_ok) |
|
950 { |
|
951 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
952 return EAP_STATUS_RETURN(m_am_tools, status); |
|
953 } |
|
954 } |
|
955 |
|
956 status = send_eap_nak_response( |
|
957 receive_network_id, |
|
958 eap_identifier, |
|
959 &eap_type_list); |
|
960 |
|
961 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
962 return EAP_STATUS_RETURN(m_am_tools, status); |
|
963 } |
|
964 |
|
965 //-------------------------------------------------- |
|
966 |
|
967 EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_process_type( |
|
968 const eap_type_value_e used_eap_type, |
|
969 const eap_am_network_id_c * const receive_network_id, |
|
970 eap_general_header_base_c * const packet_data, |
|
971 const u32_t packet_length) |
|
972 { |
|
973 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
974 |
|
975 EAP_TRACE_DEBUG( |
|
976 m_am_tools, |
|
977 TRACE_FLAGS_DEFAULT, |
|
978 (EAPL("eap_core_c::packet_process_type(): %s\n"), |
|
979 (m_is_client == true) ? "client": "server")); |
|
980 |
|
981 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::packet_process_type()"); |
|
982 |
|
983 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
984 |
|
985 if (packet_data == 0) |
|
986 { |
|
987 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
988 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
989 } |
|
990 |
|
991 if (packet_length < eap_header_base_c::get_header_length()) |
|
992 { |
|
993 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
994 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
995 } |
|
996 |
|
997 eap_header_wr_c eap( |
|
998 m_am_tools, |
|
999 packet_data->get_header_buffer(packet_data->get_header_buffer_length()), |
|
1000 packet_data->get_header_buffer_length()); |
|
1001 |
|
1002 if (eap.get_is_valid() == false) |
|
1003 { |
|
1004 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1005 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
1006 } |
|
1007 |
|
1008 if (packet_length < eap.get_length()) |
|
1009 { |
|
1010 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1011 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
1012 } |
|
1013 |
|
1014 if (eap.get_code() == eap_code_none) |
|
1015 { |
|
1016 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1017 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
1018 } |
|
1019 |
|
1020 EAP_TRACE_DEBUG( |
|
1021 m_am_tools, |
|
1022 TRACE_TEST_VECTORS, |
|
1023 (EAPL("--------------------------------------------------------\n"))); |
|
1024 |
|
1025 eap_status_e status = eap.check_header(); |
|
1026 if (status != eap_status_ok) |
|
1027 { |
|
1028 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1029 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1030 } |
|
1031 |
|
1032 |
|
1033 |
|
1034 status = eap_status_process_general_error; |
|
1035 |
|
1036 if (m_eap_type_response_sent == false |
|
1037 && m_current_eap_type != used_eap_type) |
|
1038 { |
|
1039 status = check_is_valid_eap_type(used_eap_type); |
|
1040 if (status != eap_status_ok) |
|
1041 { |
|
1042 if (m_is_client_role == true) |
|
1043 { |
|
1044 // Client does not accept proposed EAP type. |
|
1045 // We must send EAP-Response/Nak message with list of our own preferred EAP-Types. |
|
1046 status = client_proposes_eap_types( |
|
1047 receive_network_id, |
|
1048 eap.get_identifier()); |
|
1049 |
|
1050 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1051 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1052 } |
|
1053 else |
|
1054 { |
|
1055 // Not acceptable EAP-type in the server. |
|
1056 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1057 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1058 } |
|
1059 } |
|
1060 |
|
1061 // Now the current EAP-type is used_eap_type. |
|
1062 |
|
1063 // First remove current EAP-type. |
|
1064 eap_variable_data_c selector(m_am_tools); |
|
1065 status = selector.set_copy_of_buffer(&m_current_eap_type, sizeof(m_current_eap_type)); |
|
1066 if (status != eap_status_ok) |
|
1067 { |
|
1068 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1069 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1070 } |
|
1071 eap_base_type_c *handler = m_type_map.get_handler(&selector); |
|
1072 |
|
1073 // Change the current EAP-type here because shutdown could cause state notifications from old EAP-type. |
|
1074 m_current_eap_type = used_eap_type; |
|
1075 |
|
1076 if (handler != 0) |
|
1077 { |
|
1078 status = handler->shutdown(); |
|
1079 if (status != eap_status_ok) |
|
1080 { |
|
1081 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1082 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1083 } |
|
1084 |
|
1085 status = m_type_map.remove_handler(&selector, true); |
|
1086 if (status != eap_status_ok) |
|
1087 { |
|
1088 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1089 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1090 } |
|
1091 } |
|
1092 } |
|
1093 |
|
1094 // Here we query the desired EAP-type. |
|
1095 eap_variable_data_c selector(m_am_tools); |
|
1096 u64_t selector_eap_type = convert_eap_type_to_u64_t(used_eap_type); |
|
1097 status = selector.set_buffer(&selector_eap_type, sizeof(selector_eap_type), false, false); |
|
1098 if (status != eap_status_ok) |
|
1099 { |
|
1100 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1101 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1102 } |
|
1103 eap_base_type_c *handler = m_type_map.get_handler(&selector); |
|
1104 |
|
1105 // Check if we already have this type loaded. |
|
1106 if (handler == 0) |
|
1107 { |
|
1108 // No. Load it. |
|
1109 if (m_eap_type_response_sent == false |
|
1110 && eap.get_type() != eap_type_identity |
|
1111 && (eap.get_code() == eap_code_request |
|
1112 || eap.get_code() == eap_code_response)) |
|
1113 { |
|
1114 // Here we need a check that proposed EAP type is valid for us. |
|
1115 status = check_is_valid_eap_type(used_eap_type); |
|
1116 if (status != eap_status_ok) |
|
1117 { |
|
1118 if (m_is_client_role == true) |
|
1119 { |
|
1120 // Client does not accept proposed EAP type. |
|
1121 // We must send EAP-Response/Nak message with list of our own preferred EAP-Types. |
|
1122 status = client_proposes_eap_types( |
|
1123 receive_network_id, |
|
1124 eap.get_identifier()); |
|
1125 |
|
1126 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1127 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1128 } |
|
1129 else |
|
1130 { |
|
1131 // Not acceptable EAP-type in the server. |
|
1132 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1133 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1134 } |
|
1135 } |
|
1136 // Change the current eap type. |
|
1137 m_current_eap_type = used_eap_type; |
|
1138 } |
|
1139 else if (eap.get_code() == eap_code_success |
|
1140 || eap.get_code() == eap_code_failure) |
|
1141 { |
|
1142 // EAP-Success or EAP-Failure is not allowed at this state. |
|
1143 // This packet is dropped quietly. |
|
1144 EAP_TRACE_DEBUG( |
|
1145 m_am_tools, |
|
1146 TRACE_FLAGS_DEFAULT, |
|
1147 (EAPL("WARNING: eap_core_c::packet_process_type(): %s, %s, drops %s quietly.\n"), |
|
1148 (m_is_client_role == true) ? "client": "server", |
|
1149 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1150 eap.get_code_string() |
|
1151 )); |
|
1152 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1153 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1154 } |
|
1155 else if (m_eap_type_response_sent == false |
|
1156 && eap.get_type() == eap_type_identity |
|
1157 && (eap.get_code() == eap_code_request |
|
1158 || eap.get_code() == eap_code_response)) |
|
1159 { |
|
1160 // EAP-Request/Identity is allowed at this state. |
|
1161 EAP_ASSERT(used_eap_type != eap_type_none); |
|
1162 } |
|
1163 else |
|
1164 { |
|
1165 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1166 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
1167 } |
|
1168 |
|
1169 // A new EAP-type is needed. The load_type() allocates new object. |
|
1170 handler = load_type( |
|
1171 used_eap_type, |
|
1172 eap_type_none, |
|
1173 receive_network_id); |
|
1174 if (handler != 0 |
|
1175 && handler->get_is_valid() == true) |
|
1176 { |
|
1177 status = handler->configure(); |
|
1178 if (status != eap_status_ok) |
|
1179 { |
|
1180 handler->shutdown(); |
|
1181 delete handler; |
|
1182 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1183 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1184 } |
|
1185 |
|
1186 status = m_type_map.add_handler(&selector, handler); |
|
1187 if (status != eap_status_ok) |
|
1188 { |
|
1189 handler->shutdown(); |
|
1190 delete handler; |
|
1191 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1192 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1193 } |
|
1194 } |
|
1195 else |
|
1196 { |
|
1197 if (handler != 0) |
|
1198 { |
|
1199 // Handler not constructed successfully. |
|
1200 handler->shutdown(); |
|
1201 delete handler; |
|
1202 status = eap_status_allocation_error; |
|
1203 } |
|
1204 else |
|
1205 { |
|
1206 status = eap_status_type_does_not_exists_error; |
|
1207 } |
|
1208 |
|
1209 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1210 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1211 } |
|
1212 } |
|
1213 |
|
1214 #if defined(USE_EAP_CORE_SERVER) |
|
1215 // We now have handler. Process packet |
|
1216 if (m_nak_process_timer_active == true) |
|
1217 { |
|
1218 m_partner->cancel_timer( |
|
1219 this, |
|
1220 EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID); |
|
1221 |
|
1222 EAP_TRACE_DEBUG( |
|
1223 m_am_tools, |
|
1224 TRACE_FLAGS_DEFAULT, |
|
1225 (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID cancelled, this = 0x%08x.\n"), |
|
1226 (m_is_client_role == true ? "client": "server"), |
|
1227 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1228 this)); |
|
1229 |
|
1230 m_nak_process_timer_active = false; |
|
1231 } |
|
1232 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
1233 |
|
1234 |
|
1235 if (m_is_client_role == true |
|
1236 && eap.get_code() == eap_code_request |
|
1237 && (eap.get_type() == eap_type_identity |
|
1238 || eap.get_type() == eap_type_notification)) |
|
1239 { |
|
1240 // Client handles this packet, which is EAP-Request/Identity or EAP-Request/Notification. |
|
1241 |
|
1242 if (eap.get_type() == eap_type_identity) |
|
1243 { |
|
1244 status = handle_eap_identity_request( |
|
1245 used_eap_type, |
|
1246 eap.get_identifier(), |
|
1247 receive_network_id); |
|
1248 } |
|
1249 else if (eap.get_type() == eap_type_notification) |
|
1250 { |
|
1251 // Here we swap the addresses. |
|
1252 eap_am_network_id_c send_network_id(m_am_tools, |
|
1253 receive_network_id->get_destination_id(), |
|
1254 receive_network_id->get_source_id(), |
|
1255 receive_network_id->get_type()); |
|
1256 |
|
1257 /** |
|
1258 * @{ 2003-10-02 draft-ietf-eap-rfc2284bis-06.txt chapter 5.2 Notification: |
|
1259 * The peer SHOULD display this message to the user or log it if it |
|
1260 * cannot be displayed. The Notification Type is intended to provide |
|
1261 * an acknowledged notification of some imperative nature, but it is |
|
1262 * not an error indication, and therefore does not change the state |
|
1263 * of the peer. Examples include a password with an expiration time |
|
1264 * that is about to expire, an OTP sequence integer which is nearing |
|
1265 * 0, an authentication failure warning, etc. In most circumstances, |
|
1266 * Notification should not be required. |
|
1267 * } |
|
1268 */ |
|
1269 status = send_eap_notification_response( |
|
1270 &send_network_id, |
|
1271 eap.get_identifier()); |
|
1272 } |
|
1273 } |
|
1274 #if defined(USE_EAP_CORE_SERVER) |
|
1275 else if (m_is_client_role == false |
|
1276 && eap.get_code() == eap_code_response |
|
1277 && eap.get_type() == eap_type_identity) |
|
1278 { |
|
1279 // Server handles this EAP-Response/Identity packet. |
|
1280 |
|
1281 if (m_eap_identity_response_accepted == false) |
|
1282 { |
|
1283 m_eap_identity_response_received = true; |
|
1284 |
|
1285 status = handle_eap_identity_response( |
|
1286 handler, |
|
1287 used_eap_type, |
|
1288 receive_network_id, |
|
1289 &eap, |
|
1290 packet_length); |
|
1291 |
|
1292 EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); |
|
1293 } |
|
1294 else |
|
1295 { |
|
1296 // Do not accept multiple EAP-Response/Identity messages. |
|
1297 EAP_TRACE_DEBUG( |
|
1298 m_am_tools, |
|
1299 TRACE_FLAGS_DEFAULT, |
|
1300 (EAPL("WARNING: EAP_Core: %s,%s, packet dropped quietly. m_eap_type_response_sent %d, ") |
|
1301 EAPL("EAP-Type 0x%08x, m_current_eap_type 0x%08x\n"), |
|
1302 (m_is_client_role == true) ? "client": "server", |
|
1303 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1304 m_eap_type_response_sent, |
|
1305 convert_eap_type_to_u32_t(eap.get_type()), |
|
1306 convert_eap_type_to_u32_t(m_current_eap_type))); |
|
1307 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1308 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
1309 } |
|
1310 } |
|
1311 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
1312 else if ((eap.get_code() == eap_code_request |
|
1313 || eap.get_code() == eap_code_response) |
|
1314 && eap.get_type() == used_eap_type |
|
1315 || eap.get_code() == eap_code_success |
|
1316 || eap.get_code() == eap_code_failure) |
|
1317 { |
|
1318 // Client and server handles this packet. |
|
1319 // Packet is EAP-Request, EAP-Response, EAP-Success or EAP-Failure. |
|
1320 // EAP-Request and EAP-Response must be of the used EAP-type. |
|
1321 |
|
1322 if (m_is_client_role == false) |
|
1323 { |
|
1324 // Server received EAP-Response from client. |
|
1325 // Now server could send EAP-Failure or EAP-success to client. |
|
1326 // See draft-ietf-eap-rfc2284bis-06.txt chapter 2. Extensible Authentication Protocol (EAP). |
|
1327 if (m_eap_type_response_sent == false) |
|
1328 { |
|
1329 // Here we swap the addresses. |
|
1330 eap_am_network_id_c send_network_id(m_am_tools, |
|
1331 receive_network_id->get_destination_id(), |
|
1332 receive_network_id->get_source_id(), |
|
1333 receive_network_id->get_type()); |
|
1334 |
|
1335 // Send state change notification |
|
1336 eap_state_notification_c notification( |
|
1337 m_am_tools, |
|
1338 &send_network_id, |
|
1339 m_is_client, |
|
1340 eap_state_notification_eap, |
|
1341 eap_protocol_layer_eap, |
|
1342 m_current_eap_type, |
|
1343 eap_state_none, |
|
1344 eap_state_eap_response_sent, |
|
1345 eap.get_identifier(), |
|
1346 false); |
|
1347 state_notification(¬ification); |
|
1348 } |
|
1349 m_eap_type_response_sent = true; |
|
1350 } |
|
1351 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
1352 else |
|
1353 { |
|
1354 if (eap.get_code() == eap_code_request |
|
1355 && m_is_tunneled_eap == false |
|
1356 && m_is_client_role == true) |
|
1357 { |
|
1358 // We got the response. Now we let the session timer handle rest of timeout cases. |
|
1359 cancel_wait_eap_request_type_timeout(); |
|
1360 } |
|
1361 } |
|
1362 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
1363 |
|
1364 if (m_ignore_eap_failure == false |
|
1365 && eap.get_code() == eap_code_failure) |
|
1366 { |
|
1367 // Set timer to delay EAP-Failure handling. |
|
1368 // If no other packet is received session will be |
|
1369 // terminated after timeout. |
|
1370 set_eap_failure_timeout(); |
|
1371 } |
|
1372 else |
|
1373 { |
|
1374 cancel_eap_failure_timeout(); |
|
1375 } |
|
1376 |
|
1377 status = handler->packet_process( |
|
1378 receive_network_id, |
|
1379 &eap, |
|
1380 packet_length); |
|
1381 |
|
1382 EAP_GENERAL_HEADER_COPY_ERROR_PARAMETERS(packet_data, &eap); |
|
1383 |
|
1384 if (status == eap_status_success) |
|
1385 { |
|
1386 // NOTE state_notification() will send EAP-Success message. |
|
1387 } |
|
1388 } |
|
1389 else |
|
1390 { |
|
1391 EAP_TRACE_DEBUG( |
|
1392 m_am_tools, |
|
1393 TRACE_FLAGS_DEFAULT, |
|
1394 (EAPL("ERROR: %s, %s, Illegal EAP-Code %d=0x%02x=%s, EAP-Type 0x%08x=%s\n"), |
|
1395 (m_is_client_role == true) ? "client": "server", |
|
1396 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1397 eap.get_code(), |
|
1398 eap.get_code(), |
|
1399 eap.get_code_string(), |
|
1400 convert_eap_type_to_u32_t(eap.get_type()), |
|
1401 eap.get_type_string())); |
|
1402 |
|
1403 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1404 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
1405 } |
|
1406 |
|
1407 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1408 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1409 } |
|
1410 |
|
1411 //-------------------------------------------------- |
|
1412 |
|
1413 /** |
|
1414 * @{ 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2.1 Support for sequences: |
|
1415 * An EAP conversation MAY utilize a sequence of methods. A common |
|
1416 * example of this is an Identity request followed by a single EAP |
|
1417 * authentication method such as an MD5-Challenge. However the peer and |
|
1418 * authenticator MUST utilize only one authentication method (Type 4 or |
|
1419 * greater) within an EAP conversation, after which the authenticator |
|
1420 * MUST send a Success or Failure packet. |
|
1421 * Once a peer has sent a Response of the same Type as the initial |
|
1422 * Request, an authenticator MUST NOT send a Request of a different Type |
|
1423 * prior to completion of the final round of a given method (with the |
|
1424 * exception of a Notification-Request) and MUST NOT send a Request for |
|
1425 * an additional method of any Type after completion of the initial |
|
1426 * authentication method; a peer receiving such Requests MUST treat them |
|
1427 * as invalid, and silently discard them. As a result, Identity Requery |
|
1428 * is not supported. |
|
1429 * A peer MUST NOT send a Nak (legacy or expanded) in reply to a |
|
1430 * Request, after an initial non-Nak Response has been sent. Since |
|
1431 * spoofed EAP Request packets may be sent by an attacker, an |
|
1432 * authenticator receiving an unexpected Nak SHOULD discard it and log |
|
1433 * the event. |
|
1434 * Multiple authentication methods within an EAP conversation are not |
|
1435 * supported due to their vulnerability to man-in-the-middle attacks |
|
1436 * (see Section 7.4) and incompatibility with existing implementations. |
|
1437 * } |
|
1438 */ |
|
1439 EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_process( |
|
1440 const eap_am_network_id_c * const receive_network_id, |
|
1441 eap_general_header_base_c * const packet_data, |
|
1442 const u32_t packet_length) |
|
1443 { |
|
1444 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1445 |
|
1446 EAP_TRACE_DEBUG( |
|
1447 m_am_tools, |
|
1448 TRACE_FLAGS_DEFAULT, |
|
1449 (EAPL("eap_core_c::packet_process(): %s\n"), |
|
1450 (m_is_client == true) ? "client": "server")); |
|
1451 |
|
1452 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::packet_process()"); |
|
1453 |
|
1454 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
1455 |
|
1456 if (packet_data == 0 |
|
1457 || packet_data->get_is_valid() == false) |
|
1458 { |
|
1459 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1460 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
1461 } |
|
1462 |
|
1463 if (receive_network_id == 0 |
|
1464 || receive_network_id->get_is_valid_data() == false) |
|
1465 { |
|
1466 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1467 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1468 } |
|
1469 |
|
1470 if (packet_length < eap_header_base_c::get_header_length()) |
|
1471 { |
|
1472 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1473 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
1474 } |
|
1475 |
|
1476 eap_header_wr_c eap( |
|
1477 m_am_tools, |
|
1478 packet_data->get_header_buffer(packet_data->get_header_buffer_length()), |
|
1479 packet_data->get_header_buffer_length()); |
|
1480 |
|
1481 if (eap.get_is_valid() == false) |
|
1482 { |
|
1483 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1484 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_illegal_packet_error); |
|
1485 } |
|
1486 |
|
1487 if (packet_length < eap.get_length()) |
|
1488 { |
|
1489 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1490 return EAP_STATUS_RETURN(m_am_tools, eap_status_too_short_message); |
|
1491 } |
|
1492 |
|
1493 if (eap.get_code() == eap_code_none) |
|
1494 { |
|
1495 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1496 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
1497 } |
|
1498 |
|
1499 EAP_TRACE_DEBUG( |
|
1500 m_am_tools, |
|
1501 TRACE_TEST_VECTORS, |
|
1502 (EAPL("--------------------------------------------------------\n"))); |
|
1503 |
|
1504 EAP_TRACE_DATA_DEBUG( |
|
1505 m_am_tools, |
|
1506 EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, |
|
1507 (EAPL("EAP-packet"), |
|
1508 eap.get_header_buffer(packet_length), |
|
1509 packet_length)); |
|
1510 |
|
1511 trace_eap_packet("->", &eap); |
|
1512 |
|
1513 eap_status_e status = eap.check_header(); |
|
1514 if (status != eap_status_ok) |
|
1515 { |
|
1516 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1517 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1518 } |
|
1519 |
|
1520 |
|
1521 #if defined (_DEBUG) |
|
1522 if (m_retransmission != 0) |
|
1523 { |
|
1524 eap_header_string_c eap_string; |
|
1525 |
|
1526 EAP_TRACE_DEBUG( |
|
1527 m_am_tools, |
|
1528 TRACE_FLAGS_DEFAULT, |
|
1529 (EAPL("EAP_Core: eap_core_c::packet_process(): %s, retransmission counter %d, retrans EAP-type %s, retrans EAP-Id %d, current EAP-type %s, current EAP-Id %d, session 0x%08x.\n"), |
|
1530 (m_is_client_role == true) ? "client": "server", |
|
1531 m_retransmission->get_retransmission_counter(), |
|
1532 eap_string.get_eap_type_string(m_retransmission->get_eap_type()), |
|
1533 m_retransmission->get_eap_identifier(), |
|
1534 eap_string.get_eap_type_string(eap.get_type()), |
|
1535 eap.get_identifier(), |
|
1536 this)); |
|
1537 } |
|
1538 else |
|
1539 { |
|
1540 EAP_TRACE_DEBUG( |
|
1541 m_am_tools, |
|
1542 TRACE_FLAGS_DEFAULT, |
|
1543 (EAPL("EAP_Core: eap_core_c::packet_process(): %s, retransmission NULL, session 0x%08x.\n"), |
|
1544 (m_is_client_role == true) ? "client": "server", |
|
1545 this)); |
|
1546 } |
|
1547 #endif //#if defined (_DEBUG) |
|
1548 |
|
1549 |
|
1550 if (m_is_client_role == true |
|
1551 && m_retransmission != 0 |
|
1552 && m_retransmission->get_eap_type() == eap.get_type() |
|
1553 && m_retransmission->get_eap_identifier() == eap.get_identifier()) |
|
1554 { |
|
1555 if (m_retransmission->get_retransmission_counter() > 0) |
|
1556 { |
|
1557 EAP_TRACE_DEBUG( |
|
1558 m_am_tools, |
|
1559 TRACE_FLAGS_DEFAULT, |
|
1560 (EAPL("EAP_Core: eap_core_c::packet_process(): %s, retransmits previous packet, counter %d, session 0x%08x.\n"), |
|
1561 (m_is_client_role == true) ? "client": "server", |
|
1562 m_retransmission->get_retransmission_counter(), |
|
1563 this)); |
|
1564 |
|
1565 // We have the previous send EAP-packet stored. |
|
1566 // It does match to the current query. |
|
1567 // We could send the previous EAP-packet again. |
|
1568 status = resend_packet( |
|
1569 m_retransmission->get_send_network_id(), |
|
1570 m_retransmission->get_sent_packet(), |
|
1571 m_retransmission->get_header_offset(), |
|
1572 m_retransmission->get_data_length(), |
|
1573 m_retransmission->get_buffer_size(), |
|
1574 m_retransmission->get_retransmission_counter() |
|
1575 ); |
|
1576 |
|
1577 m_retransmission->get_next_retransmission_counter(); // This decrements the counter. |
|
1578 } |
|
1579 else |
|
1580 { |
|
1581 EAP_TRACE_DEBUG( |
|
1582 m_am_tools, |
|
1583 TRACE_FLAGS_DEFAULT, |
|
1584 (EAPL("EAP_Core: eap_core_c::packet_process(): %s, Does not retransmit previous packet, counter %d, session 0x%08x.\n"), |
|
1585 (m_is_client_role == true) ? "client": "server", |
|
1586 m_retransmission->get_retransmission_counter(), |
|
1587 this)); |
|
1588 |
|
1589 status = eap_status_unexpected_message; |
|
1590 } |
|
1591 |
|
1592 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1593 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1594 } |
|
1595 #if defined(USE_EAP_CORE_SERVER) |
|
1596 else if (m_is_client_role == false |
|
1597 && m_retransmission != 0 |
|
1598 && m_retransmission->get_eap_type() == eap.get_type() |
|
1599 && m_retransmission->get_eap_identifier() > eap.get_identifier()) |
|
1600 { |
|
1601 // Here we assume the EAP-Identifier increases. This is for testing purposes. |
|
1602 // This packet is old response, drop it. |
|
1603 EAP_TRACE_DEBUG( |
|
1604 m_am_tools, |
|
1605 TRACE_FLAGS_DEFAULT, |
|
1606 (EAPL("EAP_Core: eap_core_c::packet_process(): %s, Does not process old packet, EAP-Identifier of last received response %d, EAP-Identifier of the packet %d, session 0x%08x.\n"), |
|
1607 (m_is_client_role == true) ? "client": "server", |
|
1608 m_retransmission->get_eap_identifier(), |
|
1609 eap.get_identifier(), |
|
1610 this)); |
|
1611 |
|
1612 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1613 return EAP_STATUS_RETURN(m_am_tools, eap_status_unexpected_message); |
|
1614 } |
|
1615 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
1616 else if (get_marked_removed() == true |
|
1617 && eap.get_code() != eap_code_success |
|
1618 && eap.get_code() != eap_code_failure) |
|
1619 { |
|
1620 // NOTE, this delayed reset of session is used bacause in some cases cannot be responsed |
|
1621 // 4-Way Handshake message fast enough. |
|
1622 |
|
1623 EAP_TRACE_DEBUG( |
|
1624 m_am_tools, |
|
1625 TRACE_FLAGS_DEFAULT, |
|
1626 (EAPL("eap_core_c::packet_process(): %s, resets session, session 0x%08x.\n"), |
|
1627 (m_is_client_role == true) ? "client": "server", |
|
1628 this)); |
|
1629 |
|
1630 unset_marked_removed(); |
|
1631 |
|
1632 reset(); |
|
1633 } |
|
1634 |
|
1635 |
|
1636 eap_type_value_e used_eap_type = eap_type_none; |
|
1637 |
|
1638 if (eap.get_code() == eap_code_request |
|
1639 && m_is_client_role == true) |
|
1640 { |
|
1641 // Send ID using default EAP type, this is our best quess of other peer's EAP type. |
|
1642 // Other peer will sent the real EAP type later and we can NAK it then |
|
1643 // and send our own EAP type. |
|
1644 if (m_current_eap_type == eap_type_none) |
|
1645 { |
|
1646 // In Symbian implementation the default type is the highest priority EAP type. |
|
1647 // At the moment it is always used to reply to the identity request. |
|
1648 m_current_eap_type = m_default_eap_type; |
|
1649 used_eap_type = m_current_eap_type; |
|
1650 } |
|
1651 |
|
1652 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
1653 |
|
1654 if (eap.get_length() > eap_header_base_c::get_header_length()) |
|
1655 { |
|
1656 if (m_eap_type_response_sent == true |
|
1657 && eap.get_type() != m_current_eap_type) |
|
1658 { |
|
1659 if (eap.get_type() == eap_type_tlv_extensions) |
|
1660 { |
|
1661 // Send EAP-Response/Nak to show this is not supported. |
|
1662 |
|
1663 eap_array_c<eap_type_value_e> eap_type_list(m_am_tools); |
|
1664 |
|
1665 status = send_eap_nak_response( |
|
1666 receive_network_id, |
|
1667 eap.get_identifier(), |
|
1668 &eap_type_list); |
|
1669 |
|
1670 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1671 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1672 } |
|
1673 else |
|
1674 { |
|
1675 /* |
|
1676 * 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 2.1 Support for sequences: |
|
1677 * An EAP conversation MAY utilize a sequence of methods. A common |
|
1678 * example of this is an Identity request followed by a single EAP |
|
1679 * authentication method such as an MD5-Challenge. However the peer and |
|
1680 * authenticator MUST utilize only one authentication method (Type 4 or |
|
1681 * greater) within an EAP conversation, after which the authenticator |
|
1682 * MUST send a Success or Failure packet. |
|
1683 * Once a peer has sent a Response of the same Type as the initial |
|
1684 * Request, an authenticator MUST NOT send a Request of a different Type |
|
1685 * prior to completion of the final round of a given method (with the |
|
1686 * exception of a Notification-Request) and MUST NOT send a Request for |
|
1687 * an additional method of any Type after completion of the initial |
|
1688 * authentication method; a peer receiving such Requests MUST treat them |
|
1689 * as invalid, and silently discard them. As a result, Identity Requery |
|
1690 * is not supported. |
|
1691 */ |
|
1692 EAP_TRACE_DEBUG( |
|
1693 m_am_tools, |
|
1694 TRACE_FLAGS_DEFAULT, |
|
1695 (EAPL("WARNING: EAP_Core: %s, %s, packet dropped quietly. m_eap_type_response_sent %d, ") |
|
1696 EAPL("EAP-Type 0x%08x, m_current_eap_type 0x%08x\n"), |
|
1697 (m_is_client_role == true) ? "client": "server", |
|
1698 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1699 m_eap_type_response_sent, |
|
1700 convert_eap_type_to_u32_t(eap.get_type()), |
|
1701 convert_eap_type_to_u32_t(m_current_eap_type))); |
|
1702 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1703 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
1704 } |
|
1705 } |
|
1706 else if (eap.get_type() == eap_type_identity) |
|
1707 { |
|
1708 // Should we respond here with another type? |
|
1709 /** |
|
1710 * @{ Check if this is a re-transmission or a new request. |
|
1711 * If this is re-transmission respond using the same type as previously. |
|
1712 * Otherwise assume that peer did not like our previous identity and |
|
1713 * try another configured type. |
|
1714 * At the moment just try the last type that was used. |
|
1715 * } |
|
1716 */ |
|
1717 used_eap_type = m_current_eap_type; |
|
1718 } |
|
1719 else if (eap.get_type() == eap_type_notification) |
|
1720 { |
|
1721 // Here we are again on thin ice. |
|
1722 // Best ques is the las used EAP type. |
|
1723 used_eap_type = m_current_eap_type; |
|
1724 } |
|
1725 else |
|
1726 { |
|
1727 // Here we know what the server really wants |
|
1728 // use this EAP-Type. |
|
1729 used_eap_type = eap.get_type(); |
|
1730 } |
|
1731 } |
|
1732 else |
|
1733 { |
|
1734 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1735 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
1736 } |
|
1737 } |
|
1738 #if defined(USE_EAP_CORE_SERVER) |
|
1739 else if (eap.get_code() == eap_code_response |
|
1740 && m_is_client_role == false) |
|
1741 { |
|
1742 // Received ID using some EAP type, this may be other than our current type. |
|
1743 |
|
1744 if (m_current_eap_type == eap_type_none) |
|
1745 { |
|
1746 m_current_eap_type = m_default_eap_type; |
|
1747 used_eap_type = m_default_eap_type; |
|
1748 } |
|
1749 else if (eap.get_length() > eap_header_base_c::get_header_length()) |
|
1750 { |
|
1751 if (eap.get_type() == eap_type_identity) |
|
1752 { |
|
1753 used_eap_type = m_default_eap_type; |
|
1754 } |
|
1755 else |
|
1756 { |
|
1757 used_eap_type = eap.get_type(); |
|
1758 |
|
1759 if (used_eap_type == eap_type_nak |
|
1760 || eap_expanded_type_nak.get_type() == used_eap_type |
|
1761 ) |
|
1762 { |
|
1763 // Server received EAP-Response from client. |
|
1764 // Now server could send EAP-Failure or EAP-success to client. |
|
1765 // See draft-ietf-eap-rfc2284bis-06.txt chapter 2. Extensible Authentication Protocol (EAP). |
|
1766 |
|
1767 /** |
|
1768 * @{ 2003-10-02 draft-ietf-eap-rfc2284bis-06.txt chapter 5.3.1 Legacy Nak: |
|
1769 * The legacy Nak Type is valid only in Response messages. It is |
|
1770 * sent in reply to a Request where the desired authentication Type |
|
1771 * is unacceptable. Authentication Types are numbered 4 and above. |
|
1772 * The Response contains one or more authentication Types desired by |
|
1773 * the Peer. Type zero (0) is used to indicate that the sender has |
|
1774 * no viable alternatives, and therefore the authenticator SHOULD NOT |
|
1775 * send another Request after receiving a Nak Response containing a |
|
1776 * zero value. |
|
1777 * Since the legacy Nak Type is valid only in Responses and has very |
|
1778 * limited functionality, it MUST NOT be used as a general purpose |
|
1779 * error indication, such as for communication of error messages, or |
|
1780 * negotiation of parameters specific to a particular EAP method. |
|
1781 * } |
|
1782 */ |
|
1783 |
|
1784 /** |
|
1785 * @{ 2003-10-02 draft-ietf-eap-rfc2284bis-06.txt chapter 5.3.2 Expanded Nak: |
|
1786 * The Expanded Nak Type is valid only in Response messages. It MUST |
|
1787 * be sent only in reply to a Request of Type 254 (Expanded Type) |
|
1788 * where the authentication Type is unacceptable. The Expanded Nak |
|
1789 * Type uses the Expanded Type format itself, and the Response |
|
1790 * contains one or more authentication Types desired by the peer, all |
|
1791 * in Expanded Type format. Type zero (0) is used to indicate that |
|
1792 * the sender has no viable alternatives. The general format of the |
|
1793 * Expanded Type is described in Section 5.7. |
|
1794 * Since the Expanded Nak Type is valid only in Responses and has |
|
1795 * very limited functionality, it MUST NOT be used as a general |
|
1796 * purpose error indication, such as for communication of error |
|
1797 * messages, or negotiation of parameters specific to a particular |
|
1798 * EAP method. |
|
1799 * } |
|
1800 */ |
|
1801 |
|
1802 // Only server should receive this packet. |
|
1803 if (eap.get_type_data_length() >= sizeof(u8_t)) |
|
1804 { |
|
1805 // EAP-Response/Nak includes list of new proposal for EAP type. |
|
1806 // Now we need to know does the proposed EAP type need separate identity. |
|
1807 // In that case we must restart the authentication. |
|
1808 // If the same identity is valid, we could continue. |
|
1809 |
|
1810 u32_t proposal_length = eap.get_type_data_length(); |
|
1811 for (u32_t ind = 0ul; ind < proposal_length; ind++) |
|
1812 { |
|
1813 /** |
|
1814 * @{ 2005-04-19 complete Expanded Nak Type to packet_process(). } |
|
1815 */ |
|
1816 status = eap_expanded_type_c::read_type( |
|
1817 m_am_tools, |
|
1818 ind, |
|
1819 eap.get_type_data(eap.get_type_data_length()), |
|
1820 eap.get_type_data_length(), |
|
1821 &used_eap_type); |
|
1822 if (status != eap_status_ok) |
|
1823 { |
|
1824 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1825 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1826 } |
|
1827 |
|
1828 // Here we need a check that proposed EAP type is valid for us. |
|
1829 status = check_is_valid_eap_type(used_eap_type); |
|
1830 if (status == eap_status_ok) |
|
1831 { |
|
1832 // Let's use this EAP-type. |
|
1833 break; |
|
1834 } |
|
1835 else |
|
1836 { |
|
1837 used_eap_type = eap_type_none; |
|
1838 } |
|
1839 } // for() |
|
1840 |
|
1841 if (used_eap_type == eap_type_none) |
|
1842 { |
|
1843 EAP_TRACE_DEBUG( |
|
1844 m_am_tools, |
|
1845 TRACE_FLAGS_DEFAULT, |
|
1846 (EAPL("TIMER: %s: %s, EAP-Reponse/Nak did not include any valid EAp-type.\n"), |
|
1847 (m_is_client_role == true ? "client": "server"), |
|
1848 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
1849 )); |
|
1850 } |
|
1851 |
|
1852 // Here we swap the addresses. |
|
1853 eap_am_network_id_c send_network_id(m_am_tools, |
|
1854 receive_network_id->get_destination_id(), |
|
1855 receive_network_id->get_source_id(), |
|
1856 receive_network_id->get_type()); |
|
1857 |
|
1858 if (m_process_eap_nak_immediately == true) |
|
1859 { |
|
1860 if (used_eap_type == eap_type_none) |
|
1861 { |
|
1862 // No acceptable EAP-type. |
|
1863 // Send a EAP-Failure. |
|
1864 status = send_eap_failure( |
|
1865 &send_network_id, |
|
1866 static_cast<u8_t>(eap.get_identifier()+1ul)); |
|
1867 |
|
1868 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1869 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); |
|
1870 } |
|
1871 else |
|
1872 { |
|
1873 // First remove current EAP-type. |
|
1874 eap_variable_data_c selector(m_am_tools); |
|
1875 status = selector.set_copy_of_buffer( |
|
1876 &m_current_eap_type, |
|
1877 sizeof(m_current_eap_type)); |
|
1878 if (status != eap_status_ok) |
|
1879 { |
|
1880 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1881 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1882 } |
|
1883 eap_base_type_c *handler = m_type_map.get_handler(&selector); |
|
1884 |
|
1885 // Change the current EAP-type here because shutdown could |
|
1886 // cause state notifications from old EAP-type. |
|
1887 m_current_eap_type = used_eap_type; |
|
1888 |
|
1889 if (handler != 0) |
|
1890 { |
|
1891 status = handler->shutdown(); |
|
1892 if (status != eap_status_ok) |
|
1893 { |
|
1894 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1895 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1896 } |
|
1897 |
|
1898 status = m_type_map.remove_handler(&selector, true); |
|
1899 if (status != eap_status_ok) |
|
1900 { |
|
1901 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1902 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1903 } |
|
1904 } |
|
1905 |
|
1906 // Now restart authentication with proposed EAP type. |
|
1907 status = restart_with_new_type( |
|
1908 used_eap_type, |
|
1909 receive_network_id, |
|
1910 eap.get_identifier()); |
|
1911 |
|
1912 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1913 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1914 } |
|
1915 } |
|
1916 else //if (m_process_eap_nak_immediately == false) |
|
1917 { |
|
1918 status = eap_status_illegal_eap_type; |
|
1919 |
|
1920 if (m_nak_process_timer_active == false) |
|
1921 { |
|
1922 eap_core_nak_info_c * const nak_info |
|
1923 = new eap_core_nak_info_c( |
|
1924 m_am_tools, |
|
1925 receive_network_id, |
|
1926 used_eap_type, |
|
1927 eap.get_identifier()); |
|
1928 |
|
1929 status = m_partner->set_timer( |
|
1930 this, |
|
1931 EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID, |
|
1932 nak_info, |
|
1933 EAP_CORE_DELAYED_EAP_NAK_PROCESS_TIMEOUT); |
|
1934 if (status == eap_status_ok) |
|
1935 { |
|
1936 m_nak_process_timer_active = true; |
|
1937 } |
|
1938 else |
|
1939 { |
|
1940 // ERROR. |
|
1941 // NOTE: timer queue did call timer_delete_data() function to free nak_info. |
|
1942 } |
|
1943 |
|
1944 EAP_TRACE_DEBUG( |
|
1945 m_am_tools, |
|
1946 TRACE_FLAGS_DEFAULT, |
|
1947 (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID set %d ms.\n"), |
|
1948 (m_is_client_role == true ? "client": "server"), |
|
1949 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1950 EAP_CORE_DELAYED_EAP_NAK_PROCESS_TIMEOUT |
|
1951 )); |
|
1952 } |
|
1953 } |
|
1954 |
|
1955 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1956 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1957 |
|
1958 } // if (eap.get_type_data_length() >= sizeof(u8_t)) |
|
1959 else |
|
1960 { |
|
1961 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1962 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_type); |
|
1963 } |
|
1964 } |
|
1965 } |
|
1966 } |
|
1967 else |
|
1968 { |
|
1969 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1970 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
1971 } |
|
1972 } |
|
1973 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
1974 else if (eap.get_code() == eap_code_success |
|
1975 || eap.get_code() == eap_code_failure) |
|
1976 { |
|
1977 if (m_current_eap_type != eap_type_none) |
|
1978 { |
|
1979 // Here we are again on thin ice. |
|
1980 // Use saved EAP type, this is our best quess of other peer's EAP type. |
|
1981 // Other peer just informs status of authentication. |
|
1982 used_eap_type = m_current_eap_type; |
|
1983 } |
|
1984 else |
|
1985 { |
|
1986 // No EAP-type loaded, drop message quietly. |
|
1987 EAP_TRACE_DEBUG( |
|
1988 m_am_tools, |
|
1989 TRACE_FLAGS_DEFAULT, |
|
1990 (EAPL("WARNING: EAP_Core: %s,%s, %s packet dropped quietly. m_eap_type_response_sent %d, ") |
|
1991 EAPL("m_current_eap_type 0x%08x\n"), |
|
1992 (m_is_client_role == true) ? "client": "server", |
|
1993 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
1994 eap.get_code_string(), |
|
1995 m_eap_type_response_sent, |
|
1996 convert_eap_type_to_u32_t(m_current_eap_type))); |
|
1997 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1998 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
1999 } |
|
2000 } |
|
2001 else |
|
2002 { |
|
2003 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2004 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_code); |
|
2005 } |
|
2006 |
|
2007 |
|
2008 status = packet_process_type( |
|
2009 used_eap_type, |
|
2010 receive_network_id, |
|
2011 packet_data, |
|
2012 packet_length); |
|
2013 |
|
2014 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2015 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2016 } |
|
2017 |
|
2018 //-------------------------------------------------- |
|
2019 |
|
2020 // |
|
2021 EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_send( |
|
2022 const eap_am_network_id_c * const send_network_id, |
|
2023 eap_buf_chain_wr_c * const sent_packet, |
|
2024 const u32_t header_offset, |
|
2025 const u32_t data_length, |
|
2026 const u32_t buffer_length) |
|
2027 { |
|
2028 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2029 |
|
2030 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2031 |
|
2032 eap_header_wr_c eap( |
|
2033 m_am_tools, |
|
2034 sent_packet->get_data_offset( |
|
2035 header_offset, data_length), |
|
2036 data_length); |
|
2037 |
|
2038 if (eap.get_is_valid() == false) |
|
2039 { |
|
2040 EAP_TRACE_ERROR( |
|
2041 m_am_tools, |
|
2042 TRACE_FLAGS_DEFAULT, |
|
2043 (EAPL("packet_send: %s, %s, packet buffer corrupted.\n"), |
|
2044 (m_is_client_role == true) ? "client": "server", |
|
2045 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2046 )); |
|
2047 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2048 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2049 } |
|
2050 |
|
2051 EAP_ASSERT(header_offset < sent_packet->get_data_length()); |
|
2052 EAP_ASSERT(data_length <= sent_packet->get_data_length()); |
|
2053 EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); |
|
2054 |
|
2055 EAP_TRACE_DATA_DEBUG( |
|
2056 m_am_tools, |
|
2057 EAP_TRACE_FLAGS_MESSAGE_DATA|TRACE_TEST_VECTORS, |
|
2058 (EAPL("EAP-packet"), |
|
2059 eap.get_header_buffer(data_length), |
|
2060 data_length)); |
|
2061 |
|
2062 trace_eap_packet("<-", &eap); |
|
2063 |
|
2064 if (m_shutdown_was_called == true |
|
2065 && m_is_client_role == true) |
|
2066 { |
|
2067 EAP_TRACE_DEBUG( |
|
2068 m_am_tools, |
|
2069 TRACE_FLAGS_DEFAULT, |
|
2070 (EAPL("WARNING: EAP_Core: %s,%s, eap_core_c::packet_send(): %s packet dropped quietly because shutdown was already called. m_eap_type_response_sent %d, ") |
|
2071 EAPL("m_current_eap_type 0x%08x\n"), |
|
2072 (m_is_client_role == true) ? "client": "server", |
|
2073 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2074 eap.get_code_string(), |
|
2075 m_eap_type_response_sent, |
|
2076 convert_eap_type_to_u32_t(m_current_eap_type))); |
|
2077 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2078 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
2079 } |
|
2080 |
|
2081 EAP_TRACE_DEBUG( |
|
2082 m_am_tools, |
|
2083 TRACE_TEST_VECTORS, |
|
2084 (EAPL("--------------------------------------------------------\n"))); |
|
2085 |
|
2086 |
|
2087 cancel_retransmission(); |
|
2088 |
|
2089 if (sent_packet->get_do_packet_retransmission() == true) |
|
2090 { |
|
2091 // Both EAP-client and EAP-server initializes re-transmission. |
|
2092 // EAP-client will respond to re-transmitted EAP-request with the matching packet. |
|
2093 // EAP-server will re-transmit the packet when timer elapses and no response is received. |
|
2094 // Note the EAP-type could do re-transmission itself too. When EAP-type do re-transmission |
|
2095 // itself EAP-type should set flag of re-transmission in the packet to true with the |
|
2096 // set_do_packet_retransmission(true) function. |
|
2097 init_retransmission( |
|
2098 send_network_id, |
|
2099 sent_packet, |
|
2100 header_offset, |
|
2101 data_length, |
|
2102 eap.get_code(), |
|
2103 eap.get_identifier(), |
|
2104 eap.get_type()); |
|
2105 } |
|
2106 |
|
2107 |
|
2108 eap_status_e status = m_partner->packet_send( |
|
2109 send_network_id, sent_packet, header_offset, data_length, buffer_length); |
|
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 if (m_is_client_role == true |
|
2117 && eap.get_type() == m_current_eap_type |
|
2118 && m_current_eap_type != eap_type_none) |
|
2119 { |
|
2120 /* |
|
2121 * Once a peer has sent a Response of the same Type as the initial |
|
2122 * Request, an authenticator MUST NOT send a Request of a different Type |
|
2123 * prior to completion of the final round of a given method (with the |
|
2124 * exception of a Notification-Request) and MUST NOT send a Request for |
|
2125 * an additional method of any Type after completion of the initial |
|
2126 * authentication method; a peer receiving such Requests MUST treat them |
|
2127 * as invalid, and silently discard them. As a result, Identity Requery |
|
2128 * is not supported. |
|
2129 */ |
|
2130 if (m_eap_type_response_sent == false) |
|
2131 { |
|
2132 // Send state change notification |
|
2133 eap_state_notification_c notification( |
|
2134 m_am_tools, |
|
2135 send_network_id, |
|
2136 m_is_client, |
|
2137 eap_state_notification_eap, |
|
2138 eap_protocol_layer_eap, |
|
2139 m_current_eap_type, |
|
2140 eap_state_none, |
|
2141 eap_state_eap_response_sent, |
|
2142 eap.get_identifier(), |
|
2143 false); |
|
2144 state_notification(¬ification); |
|
2145 } |
|
2146 m_eap_type_response_sent = true; |
|
2147 } |
|
2148 |
|
2149 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2150 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2151 } |
|
2152 |
|
2153 //-------------------------------------------------- |
|
2154 |
|
2155 EAP_FUNC_EXPORT eap_status_e eap_core_c::resend_packet( |
|
2156 const eap_am_network_id_c * const send_network_id, |
|
2157 eap_buf_chain_wr_c * const sent_packet, |
|
2158 const u32_t header_offset, |
|
2159 const u32_t data_length, |
|
2160 const u32_t buffer_length, |
|
2161 const u32_t retransmission_counter) |
|
2162 { |
|
2163 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2164 |
|
2165 EAP_UNREFERENCED_PARAMETER(retransmission_counter); // Only trace uses this. |
|
2166 |
|
2167 EAP_TRACE_DEBUG( |
|
2168 m_am_tools, |
|
2169 TRACE_FLAGS_DEFAULT, |
|
2170 (EAPL("<- EAP_Core: %s: %s, eap_core_c::resend_packet(), counter %d.\n"), |
|
2171 (m_is_client_role == true) ? "client": "server", |
|
2172 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2173 retransmission_counter |
|
2174 )); |
|
2175 |
|
2176 // We make a copy because random error test may corrupt the data. |
|
2177 eap_buf_chain_wr_c * const copy_packet = sent_packet->copy(); |
|
2178 |
|
2179 if (copy_packet == 0) |
|
2180 { |
|
2181 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2182 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2183 } |
|
2184 |
|
2185 EAP_ASSERT(m_eap_header_offset < sent_packet->get_data_length()); |
|
2186 EAP_ASSERT(data_length <= sent_packet->get_data_length()); |
|
2187 EAP_ASSERT(sent_packet->get_data_length() <= buffer_length); |
|
2188 |
|
2189 // NOTE: send packet directly to partner object. |
|
2190 // This will skip initialization of re-transmission tfor re-transmitted packet. |
|
2191 eap_status_e status = m_partner->packet_send( |
|
2192 send_network_id, |
|
2193 copy_packet, |
|
2194 header_offset, |
|
2195 data_length, |
|
2196 buffer_length |
|
2197 ); |
|
2198 |
|
2199 delete copy_packet; |
|
2200 |
|
2201 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2202 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2203 } |
|
2204 |
|
2205 //-------------------------------------------------- |
|
2206 |
|
2207 EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_retransmission() |
|
2208 { |
|
2209 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2210 |
|
2211 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2212 |
|
2213 //if (m_retransmission != 0) |
|
2214 { |
|
2215 EAP_TRACE_DEBUG( |
|
2216 m_am_tools, |
|
2217 TRACE_FLAGS_DEFAULT, |
|
2218 (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID cancelled.\n"), |
|
2219 (m_is_client_role == true ? "client": "server"), |
|
2220 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2221 )); |
|
2222 |
|
2223 if (m_is_client_role == false) |
|
2224 { |
|
2225 // Only EAP-server uses timer to re-transmits EAP-packets. |
|
2226 m_partner->cancel_timer(this, EAP_CORE_TIMER_RETRANSMISSION_ID); |
|
2227 } |
|
2228 |
|
2229 if (m_retransmission != 0) |
|
2230 { |
|
2231 delete m_retransmission; |
|
2232 m_retransmission = 0; |
|
2233 } |
|
2234 } |
|
2235 |
|
2236 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2237 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2238 } |
|
2239 |
|
2240 //-------------------------------------------------- |
|
2241 |
|
2242 EAP_FUNC_EXPORT eap_status_e eap_core_c::init_retransmission( |
|
2243 const eap_am_network_id_c * const send_network_id, |
|
2244 eap_buf_chain_wr_c * const sent_packet, |
|
2245 const u32_t header_offset, |
|
2246 const u32_t data_length, |
|
2247 const eap_code_value_e eap_code, |
|
2248 const u8_t eap_identifier, |
|
2249 const eap_type_value_e eap_type |
|
2250 ) |
|
2251 { |
|
2252 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2253 |
|
2254 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2255 |
|
2256 if (m_is_client_role == false) |
|
2257 { |
|
2258 if (m_retransmission_time == 0u |
|
2259 || m_retransmission_counter == 0u) |
|
2260 { |
|
2261 // No retransmission. |
|
2262 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2263 } |
|
2264 } |
|
2265 |
|
2266 EAP_ASSERT(send_network_id->get_source() != 0); |
|
2267 EAP_ASSERT(send_network_id->get_destination() != 0); |
|
2268 |
|
2269 if (m_retransmission != 0) |
|
2270 { |
|
2271 delete m_retransmission; |
|
2272 m_retransmission = 0; |
|
2273 } |
|
2274 |
|
2275 m_retransmission = new eap_core_retransmission_c( |
|
2276 m_am_tools, |
|
2277 send_network_id, |
|
2278 sent_packet, |
|
2279 header_offset, |
|
2280 data_length, |
|
2281 m_retransmission_time, |
|
2282 m_retransmission_counter, |
|
2283 eap_code, |
|
2284 eap_identifier, |
|
2285 eap_type |
|
2286 ); |
|
2287 |
|
2288 if (m_is_client_role == false) |
|
2289 { |
|
2290 // Only EAP-server uses timer to re-transmits EAP-packets. |
|
2291 m_partner->cancel_timer(this, EAP_CORE_TIMER_RETRANSMISSION_ID); |
|
2292 |
|
2293 EAP_TRACE_DEBUG( |
|
2294 m_am_tools, |
|
2295 TRACE_FLAGS_DEFAULT, |
|
2296 (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID cancelled.\n"), |
|
2297 (m_is_client_role == true ? "client": "server"), |
|
2298 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2299 )); |
|
2300 } |
|
2301 |
|
2302 if (m_retransmission == 0) |
|
2303 { |
|
2304 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2305 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2306 } |
|
2307 |
|
2308 if (m_retransmission->get_is_valid() == true) |
|
2309 { |
|
2310 // Because this object do re-transmission other layers must not do re-transmission of this packet. |
|
2311 sent_packet->set_do_packet_retransmission(false); |
|
2312 |
|
2313 if (m_is_client_role == false) |
|
2314 { |
|
2315 // Only EAP-server uses timer to re-transmits EAP-packets. |
|
2316 u32_t next_retransmission_time = m_retransmission->get_next_retransmission_time(); |
|
2317 |
|
2318 eap_status_e status = m_partner->set_timer(this, EAP_CORE_TIMER_RETRANSMISSION_ID, 0, |
|
2319 next_retransmission_time); |
|
2320 if (status != eap_status_ok) |
|
2321 { |
|
2322 delete m_retransmission; |
|
2323 m_retransmission = 0; |
|
2324 } |
|
2325 |
|
2326 EAP_TRACE_DEBUG( |
|
2327 m_am_tools, |
|
2328 TRACE_FLAGS_DEFAULT, |
|
2329 (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID set %d ms.\n"), |
|
2330 (m_is_client_role == true ? "client": "server"), |
|
2331 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2332 next_retransmission_time)); |
|
2333 |
|
2334 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2335 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2336 } |
|
2337 else |
|
2338 { |
|
2339 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2340 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2341 } |
|
2342 } |
|
2343 else |
|
2344 { |
|
2345 delete m_retransmission; |
|
2346 m_retransmission = 0; |
|
2347 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2348 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2349 } |
|
2350 |
|
2351 } |
|
2352 |
|
2353 //-------------------------------------------------- |
|
2354 |
|
2355 // |
|
2356 EAP_FUNC_EXPORT eap_status_e eap_core_c::set_eap_failure_timeout() |
|
2357 { |
|
2358 eap_status_e status = m_partner->set_timer( |
|
2359 this, |
|
2360 EAP_CORE_FAILURE_RECEIVED_ID, |
|
2361 0, |
|
2362 m_eap_core_failure_received_timeout); |
|
2363 if (status != eap_status_ok) |
|
2364 { |
|
2365 EAP_TRACE_ERROR( |
|
2366 m_am_tools, |
|
2367 TRACE_FLAGS_DEFAULT, |
|
2368 (EAPL("ERROR: TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID failed.\n"), |
|
2369 (m_is_client_role == true ? "client": "server"), |
|
2370 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2371 )); |
|
2372 |
|
2373 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2374 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2375 } |
|
2376 else |
|
2377 { |
|
2378 EAP_TRACE_DEBUG( |
|
2379 m_am_tools, |
|
2380 TRACE_FLAGS_DEFAULT, |
|
2381 (EAPL("TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID set %d ms.\n"), |
|
2382 (m_is_client_role == true ? "client": "server"), |
|
2383 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2384 m_eap_core_failure_received_timeout |
|
2385 )); |
|
2386 } |
|
2387 |
|
2388 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2389 } |
|
2390 |
|
2391 //-------------------------------------------------- |
|
2392 |
|
2393 // |
|
2394 EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_eap_failure_timeout() |
|
2395 { |
|
2396 EAP_TRACE_DEBUG( |
|
2397 m_am_tools, |
|
2398 TRACE_FLAGS_DEFAULT, |
|
2399 (EAPL("TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID cancelled.\n"), |
|
2400 (m_is_client_role == true ? "client": "server"), |
|
2401 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2402 )); |
|
2403 |
|
2404 return m_partner->cancel_timer( |
|
2405 this, |
|
2406 EAP_CORE_FAILURE_RECEIVED_ID); |
|
2407 } |
|
2408 |
|
2409 //-------------------------------------------------- |
|
2410 |
|
2411 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
2412 |
|
2413 // |
|
2414 eap_status_e eap_core_c::set_wait_eap_request_type_timeout() |
|
2415 { |
|
2416 EAP_ASSERT_TOOLS(m_am_tools, (m_wait_eap_request_type_timeout_set == false)); |
|
2417 |
|
2418 eap_status_e status = m_partner->set_timer( |
|
2419 this, |
|
2420 EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID, |
|
2421 0, |
|
2422 m_wait_eap_request_type_timeout); |
|
2423 if (status != eap_status_ok) |
|
2424 { |
|
2425 EAP_TRACE_ERROR( |
|
2426 m_am_tools, |
|
2427 TRACE_FLAGS_DEFAULT, |
|
2428 (EAPL("ERROR: TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID failed.\n"), |
|
2429 (m_is_client_role == true ? "client": "server"), |
|
2430 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2431 )); |
|
2432 |
|
2433 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2434 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2435 } |
|
2436 else |
|
2437 { |
|
2438 EAP_TRACE_DEBUG( |
|
2439 m_am_tools, |
|
2440 TRACE_FLAGS_DEFAULT, |
|
2441 (EAPL("TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID set %d ms.\n"), |
|
2442 (m_is_client_role == true ? "client": "server"), |
|
2443 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2444 m_wait_eap_request_type_timeout |
|
2445 )); |
|
2446 |
|
2447 m_wait_eap_request_type_timeout_set = true; |
|
2448 } |
|
2449 |
|
2450 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2451 } |
|
2452 |
|
2453 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
2454 |
|
2455 //-------------------------------------------------- |
|
2456 |
|
2457 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
2458 |
|
2459 // |
|
2460 eap_status_e eap_core_c::cancel_wait_eap_request_type_timeout() |
|
2461 { |
|
2462 if (m_wait_eap_request_type_timeout_set == true) |
|
2463 { |
|
2464 EAP_TRACE_DEBUG( |
|
2465 m_am_tools, |
|
2466 TRACE_FLAGS_DEFAULT, |
|
2467 (EAPL("TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID cancelled.\n"), |
|
2468 (m_is_client_role == true ? "client": "server"), |
|
2469 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
2470 )); |
|
2471 |
|
2472 m_wait_eap_request_type_timeout_set = false; |
|
2473 |
|
2474 return m_partner->cancel_timer( |
|
2475 this, |
|
2476 EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID); |
|
2477 } |
|
2478 else |
|
2479 { |
|
2480 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
2481 } |
|
2482 } |
|
2483 |
|
2484 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
2485 |
|
2486 //-------------------------------------------------- |
|
2487 |
|
2488 // |
|
2489 EAP_FUNC_EXPORT u32_t eap_core_c::get_header_offset( |
|
2490 u32_t * const MTU, |
|
2491 u32_t * const trailer_length) |
|
2492 { |
|
2493 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2494 |
|
2495 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2496 |
|
2497 const u32_t offset = m_partner->get_header_offset(MTU, trailer_length); |
|
2498 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2499 |
|
2500 EAP_TRACE_DEBUG( |
|
2501 m_am_tools, |
|
2502 TRACE_FLAGS_DEFAULT, |
|
2503 (EAPL("eap_core_c::get_header_offset(): offset=%d, MTU=%d, trailer_length=%d\n"), |
|
2504 offset, |
|
2505 *MTU, |
|
2506 *trailer_length)); |
|
2507 |
|
2508 return offset; |
|
2509 } |
|
2510 |
|
2511 //-------------------------------------------------- |
|
2512 |
|
2513 // |
|
2514 EAP_FUNC_EXPORT eap_status_e eap_core_c::load_module( |
|
2515 const eap_type_value_e type, |
|
2516 const eap_type_value_e tunneling_type, |
|
2517 abs_eap_base_type_c * const partner, |
|
2518 eap_base_type_c ** const handler, |
|
2519 const bool is_client_when_true, |
|
2520 const eap_am_network_id_c * const receive_network_id) |
|
2521 { |
|
2522 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2523 |
|
2524 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2525 |
|
2526 const eap_status_e status = m_partner->load_module( |
|
2527 type, |
|
2528 tunneling_type, |
|
2529 partner, |
|
2530 handler, |
|
2531 is_client_when_true, |
|
2532 receive_network_id); |
|
2533 |
|
2534 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2535 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2536 } |
|
2537 |
|
2538 //-------------------------------------------------- |
|
2539 |
|
2540 // |
|
2541 EAP_FUNC_EXPORT eap_status_e eap_core_c::configure() |
|
2542 { |
|
2543 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2544 |
|
2545 #if !defined(USE_EAP_DEBUG_TRACE) |
|
2546 EAP_TRACE_ALWAYS( |
|
2547 m_am_tools, |
|
2548 TRACE_FLAGS_DEFAULT, |
|
2549 (EAPL("eap_core_c::configure(): %s: %s.\n"), |
|
2550 ((m_is_client == true) ? "client": "server"), |
|
2551 (m_is_tunneled_eap == true) ? "tunneled": "outer most")); |
|
2552 #else |
|
2553 EAP_TRACE_ALWAYS( |
|
2554 m_am_tools, |
|
2555 TRACE_FLAGS_DEFAULT, |
|
2556 (EAPL("eap_core_c::configure(): %s: %s, this = 0x%08x => 0x%08x.\n"), |
|
2557 ((m_is_client == true) ? "client": "server"), |
|
2558 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2559 this, |
|
2560 dynamic_cast<abs_eap_base_timer_c *>(this))); |
|
2561 #endif |
|
2562 |
|
2563 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::configure()"); |
|
2564 |
|
2565 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
2566 |
|
2567 eap_status_e status(eap_status_process_general_error); |
|
2568 |
|
2569 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
2570 |
|
2571 { |
|
2572 eap_variable_data_c data(m_am_tools); |
|
2573 |
|
2574 status = m_partner->read_configure( |
|
2575 cf_str_EAP_default_type_hex_data.get_field(), |
|
2576 &data); |
|
2577 if (status == eap_status_illegal_configure_type) |
|
2578 { |
|
2579 status = m_partner->read_configure( |
|
2580 cf_str_EAP_default_type_u32_t.get_field(), |
|
2581 &data); |
|
2582 } |
|
2583 |
|
2584 #if defined(USE_EAP_CORE_SERVER) |
|
2585 if (m_is_client == false) |
|
2586 { |
|
2587 // This option is only applicable in server. |
|
2588 |
|
2589 eap_variable_data_c server_data(m_am_tools); |
|
2590 |
|
2591 eap_status_e server_status = m_partner->read_configure( |
|
2592 cf_str_EAP_server_default_type_hex_data.get_field(), |
|
2593 &server_data); |
|
2594 if (server_status == eap_status_illegal_configure_type) |
|
2595 { |
|
2596 server_status = m_partner->read_configure( |
|
2597 cf_str_EAP_server_default_type_u32_t.get_field(), |
|
2598 &server_data); |
|
2599 } |
|
2600 |
|
2601 if (server_status == eap_status_ok |
|
2602 && server_data.get_is_valid_data() == true) |
|
2603 { |
|
2604 status = data.set_copy_of_buffer(&server_data); |
|
2605 } |
|
2606 } |
|
2607 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
2608 |
|
2609 if (status != eap_status_ok) |
|
2610 { |
|
2611 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2612 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2613 } |
|
2614 else if (data.get_data_length() == sizeof(u32_t) |
|
2615 && data.get_data(data.get_data_length()) != 0) |
|
2616 { |
|
2617 m_default_eap_type |
|
2618 = *(reinterpret_cast<eap_type_ietf_values_e *>( |
|
2619 data.get_data(data.get_data_length()))); |
|
2620 } |
|
2621 else if (data.get_data_length() == eap_expanded_type_c::get_eap_expanded_type_size() |
|
2622 && data.get_data(data.get_data_length()) != 0) |
|
2623 { |
|
2624 eap_expanded_type_c eap_type(eap_type_none); |
|
2625 |
|
2626 status = eap_type.set_expanded_type_data( |
|
2627 m_am_tools, |
|
2628 &data); |
|
2629 if (status != eap_status_ok) |
|
2630 { |
|
2631 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2632 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2633 } |
|
2634 |
|
2635 status = eap_type.get_type_data( |
|
2636 m_am_tools, |
|
2637 &m_default_eap_type); |
|
2638 if (status != eap_status_ok) |
|
2639 { |
|
2640 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2641 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2642 } |
|
2643 } |
|
2644 else |
|
2645 { |
|
2646 EAP_TRACE_DEBUG( |
|
2647 m_am_tools, |
|
2648 TRACE_FLAGS_DEFAULT, |
|
2649 (EAPL("ERROR: %s: %s, No EAP-type configured, %s.\n"), |
|
2650 (m_is_client == true ? "client": "server"), |
|
2651 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
2652 cf_str_EAP_default_type_hex_data.get_field()->get_field())); |
|
2653 |
|
2654 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2655 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_configure_field); |
|
2656 } |
|
2657 } |
|
2658 |
|
2659 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
2660 |
|
2661 #if defined(USE_EAP_TEST_VECTORS) |
|
2662 |
|
2663 { |
|
2664 eap_variable_data_c data(m_am_tools); |
|
2665 |
|
2666 status = m_partner->read_configure( |
|
2667 cf_str_EAP_TRACE_only_trace_messages.get_field(), |
|
2668 &data); |
|
2669 if (status == eap_status_ok |
|
2670 && data.get_data_length() == sizeof(u32_t) |
|
2671 && data.get_data(data.get_data_length()) != 0) |
|
2672 { |
|
2673 if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u) |
|
2674 { |
|
2675 // Activate only EAP message traces. |
|
2676 m_am_tools->set_trace_mask( |
|
2677 eap_am_tools_c::eap_trace_mask_always |
|
2678 | eap_am_tools_c::eap_trace_mask_eap_messages); |
|
2679 } |
|
2680 else |
|
2681 { |
|
2682 // Disable only EAP message traces. |
|
2683 m_am_tools->set_trace_mask( |
|
2684 m_am_tools->get_trace_mask() & (~eap_am_tools_c::eap_trace_mask_eap_messages)); |
|
2685 } |
|
2686 } |
|
2687 else |
|
2688 { |
|
2689 // Disable only EAP message traces. |
|
2690 m_am_tools->set_trace_mask( |
|
2691 m_am_tools->get_trace_mask() & (~eap_am_tools_c::eap_trace_mask_eap_messages)); |
|
2692 } |
|
2693 } |
|
2694 |
|
2695 |
|
2696 { |
|
2697 eap_variable_data_c data(m_am_tools); |
|
2698 |
|
2699 status = m_partner->read_configure( |
|
2700 cf_str_EAP_TRACE_only_test_vectors.get_field(), |
|
2701 &data); |
|
2702 if (status == eap_status_ok |
|
2703 && data.get_data_length() == sizeof(u32_t) |
|
2704 && data.get_data(data.get_data_length()) != 0) |
|
2705 { |
|
2706 if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u) |
|
2707 { |
|
2708 // Activates only EAP test vector traces. |
|
2709 m_am_tools->set_trace_mask(eap_am_tools_c::eap_trace_mask_test_vectors); |
|
2710 } |
|
2711 } |
|
2712 } |
|
2713 |
|
2714 |
|
2715 { |
|
2716 eap_variable_data_c data(m_am_tools); |
|
2717 |
|
2718 status = m_partner->read_configure( |
|
2719 cf_str_EAP_TRACE_crypto_test_vectors_sha1.get_field(), |
|
2720 &data); |
|
2721 if (status == eap_status_ok |
|
2722 && data.get_data_length() == sizeof(u32_t) |
|
2723 && data.get_data(data.get_data_length()) != 0) |
|
2724 { |
|
2725 if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u) |
|
2726 { |
|
2727 // Activates SHA1 EAP test vector traces. |
|
2728 m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() |
|
2729 | eap_am_tools_c::eap_trace_mask_crypto_sha1); |
|
2730 } |
|
2731 } |
|
2732 } |
|
2733 |
|
2734 |
|
2735 { |
|
2736 eap_variable_data_c data(m_am_tools); |
|
2737 |
|
2738 status = m_partner->read_configure( |
|
2739 cf_str_EAP_TRACE_crypto_test_vectors_rc4.get_field(), |
|
2740 &data); |
|
2741 if (status == eap_status_ok |
|
2742 && data.get_data_length() == sizeof(u32_t) |
|
2743 && data.get_data(data.get_data_length()) != 0) |
|
2744 { |
|
2745 if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u) |
|
2746 { |
|
2747 // Activates RC4 EAP test vector traces. |
|
2748 m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() |
|
2749 | eap_am_tools_c::eap_trace_mask_crypto_rc4); |
|
2750 } |
|
2751 } |
|
2752 } |
|
2753 |
|
2754 |
|
2755 { |
|
2756 eap_variable_data_c data(m_am_tools); |
|
2757 |
|
2758 status = m_partner->read_configure( |
|
2759 cf_str_EAP_TRACE_crypto_test_vectors_md4.get_field(), |
|
2760 &data); |
|
2761 if (status == eap_status_ok |
|
2762 && data.get_data_length() == sizeof(u32_t) |
|
2763 && data.get_data(data.get_data_length()) != 0) |
|
2764 { |
|
2765 if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u) |
|
2766 { |
|
2767 // Activates MD4 EAP test vector traces. |
|
2768 m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() |
|
2769 | eap_am_tools_c::eap_trace_mask_crypto_md4); |
|
2770 } |
|
2771 } |
|
2772 } |
|
2773 |
|
2774 |
|
2775 { |
|
2776 eap_variable_data_c data(m_am_tools); |
|
2777 |
|
2778 status = m_partner->read_configure( |
|
2779 cf_str_EAP_TRACE_crypto_test_vectors_test_random.get_field(), |
|
2780 &data); |
|
2781 if (status == eap_status_ok |
|
2782 && data.get_data_length() == sizeof(u32_t) |
|
2783 && data.get_data(data.get_data_length()) != 0) |
|
2784 { |
|
2785 if (*(reinterpret_cast<u32_t *>(data.get_data(data.get_data_length()))) != 0u) |
|
2786 { |
|
2787 // Activates test random generator EAP test vector traces. |
|
2788 m_am_tools->set_trace_mask(m_am_tools->get_trace_mask() |
|
2789 | eap_am_tools_c::eap_trace_mask_crypto_test_random |
|
2790 | eap_am_tools_c::eap_trace_mask_crypto_sha1); |
|
2791 } |
|
2792 } |
|
2793 } |
|
2794 |
|
2795 #endif //#if defined(USE_EAP_TEST_VECTORS) |
|
2796 |
|
2797 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
2798 |
|
2799 #if defined(USE_EAP_CORE_SERVER) |
|
2800 if (m_is_client == false) |
|
2801 { |
|
2802 eap_variable_data_c data(m_am_tools); |
|
2803 |
|
2804 status = m_partner->read_configure( |
|
2805 cf_str_EAP_CORE_process_EAP_Nak_immediately.get_field(), |
|
2806 &data); |
|
2807 if (status == eap_status_ok |
|
2808 && data.get_data_length() == sizeof(u32_t) |
|
2809 && data.get_data(data.get_data_length()) != 0) |
|
2810 { |
|
2811 u32_t *flag = reinterpret_cast<u32_t *>(data.get_data(data.get_data_length())); |
|
2812 |
|
2813 if (flag != 0) |
|
2814 { |
|
2815 if ((*flag) != 0ul) |
|
2816 { |
|
2817 m_process_eap_nak_immediately = true; |
|
2818 } |
|
2819 else |
|
2820 { |
|
2821 m_process_eap_nak_immediately = false; |
|
2822 } |
|
2823 } |
|
2824 } |
|
2825 } |
|
2826 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
2827 |
|
2828 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
2829 |
|
2830 #if defined(USE_EAP_CORE_SERVER) |
|
2831 if (m_is_client == false) |
|
2832 { |
|
2833 eap_variable_data_c retransmission_time(m_am_tools); |
|
2834 |
|
2835 status = read_configure( |
|
2836 cf_str_EAP_CORE_retransmission_time.get_field(), |
|
2837 &retransmission_time); |
|
2838 if (status == eap_status_ok |
|
2839 && retransmission_time.get_is_valid_data() == true) |
|
2840 { |
|
2841 u32_t *retransmission_time_value = reinterpret_cast<u32_t *>( |
|
2842 retransmission_time.get_data(sizeof(u32_t))); |
|
2843 if (retransmission_time_value != 0) |
|
2844 { |
|
2845 m_retransmission_time = *retransmission_time_value; |
|
2846 } |
|
2847 else |
|
2848 { |
|
2849 m_retransmission_time = EAP_CORE_RETRANSMISSION_TIME; |
|
2850 } |
|
2851 } |
|
2852 else |
|
2853 { |
|
2854 m_retransmission_time = EAP_CORE_RETRANSMISSION_TIME; |
|
2855 } |
|
2856 } |
|
2857 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
2858 |
|
2859 //if (m_is_client == false) |
|
2860 { |
|
2861 eap_variable_data_c retransmission_counter(m_am_tools); |
|
2862 |
|
2863 status = read_configure( |
|
2864 cf_str_EAP_CORE_retransmission_counter.get_field(), |
|
2865 &retransmission_counter); |
|
2866 if (status == eap_status_ok |
|
2867 && retransmission_counter.get_is_valid_data() == true) |
|
2868 { |
|
2869 u32_t *retransmission_counter_value = reinterpret_cast<u32_t *>( |
|
2870 retransmission_counter.get_data(sizeof(u32_t))); |
|
2871 if (retransmission_counter_value != 0) |
|
2872 { |
|
2873 m_retransmission_counter = *retransmission_counter_value; |
|
2874 } |
|
2875 else |
|
2876 { |
|
2877 m_retransmission_counter = EAP_CORE_RETRANSMISSION_COUNTER; |
|
2878 } |
|
2879 } |
|
2880 else |
|
2881 { |
|
2882 m_retransmission_counter = EAP_CORE_RETRANSMISSION_COUNTER; |
|
2883 } |
|
2884 } |
|
2885 |
|
2886 //---------------------------------------------------------- |
|
2887 |
|
2888 { |
|
2889 eap_variable_data_c session_timeout(m_am_tools); |
|
2890 |
|
2891 status = read_configure( |
|
2892 cf_str_EAP_CORE_session_timeout.get_field(), |
|
2893 &session_timeout); |
|
2894 if (status == eap_status_ok |
|
2895 && session_timeout.get_is_valid_data() == true) |
|
2896 { |
|
2897 u32_t *handler_timeout = reinterpret_cast<u32_t *>( |
|
2898 session_timeout.get_data(sizeof(u32_t))); |
|
2899 if (handler_timeout != 0) |
|
2900 { |
|
2901 m_session_timeout = *handler_timeout; |
|
2902 } |
|
2903 else |
|
2904 { |
|
2905 m_session_timeout = EAP_CORE_SESSION_TIMEOUT; |
|
2906 } |
|
2907 } |
|
2908 else |
|
2909 { |
|
2910 m_session_timeout = EAP_CORE_SESSION_TIMEOUT; |
|
2911 } |
|
2912 } |
|
2913 |
|
2914 |
|
2915 #if defined(USE_EAP_CORE_SERVER) |
|
2916 |
|
2917 if (m_is_client == false) |
|
2918 { |
|
2919 eap_variable_data_c session_timeout(m_am_tools); |
|
2920 |
|
2921 status = read_configure( |
|
2922 cf_str_EAP_CORE_server_session_timeout.get_field(), |
|
2923 &session_timeout); |
|
2924 if (status == eap_status_ok |
|
2925 && session_timeout.get_is_valid_data() == true) |
|
2926 { |
|
2927 u32_t *handler_timeout = reinterpret_cast<u32_t *>( |
|
2928 session_timeout.get_data(sizeof(u32_t))); |
|
2929 if (handler_timeout != 0) |
|
2930 { |
|
2931 // This is optional. |
|
2932 m_session_timeout = *handler_timeout; |
|
2933 } |
|
2934 } |
|
2935 } |
|
2936 |
|
2937 if (m_is_client == false) |
|
2938 { |
|
2939 eap_variable_data_c data(m_am_tools); |
|
2940 |
|
2941 status = m_partner->read_configure( |
|
2942 cf_str_EAP_CORE_send_eap_success_after_notification.get_field(), |
|
2943 &data); |
|
2944 if (status == eap_status_ok |
|
2945 && data.get_data_length() == sizeof(u32_t) |
|
2946 && data.get_data(data.get_data_length()) != 0) |
|
2947 { |
|
2948 u32_t *flag = reinterpret_cast<u32_t *>(data.get_data(data.get_data_length())); |
|
2949 |
|
2950 if (flag != 0) |
|
2951 { |
|
2952 if ((*flag) != 0ul) |
|
2953 { |
|
2954 m_send_eap_success_after_notification = true; |
|
2955 } |
|
2956 else |
|
2957 { |
|
2958 m_send_eap_success_after_notification = false; |
|
2959 } |
|
2960 } |
|
2961 } |
|
2962 } |
|
2963 |
|
2964 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
2965 |
|
2966 //---------------------------------------------------------- |
|
2967 |
|
2968 { |
|
2969 eap_variable_data_c failure_received_timeout(m_am_tools); |
|
2970 |
|
2971 status = read_configure( |
|
2972 cf_str_EAP_CORE_failure_received_timeout.get_field(), |
|
2973 &failure_received_timeout); |
|
2974 if (status == eap_status_ok |
|
2975 && failure_received_timeout.get_is_valid_data() == true) |
|
2976 { |
|
2977 u32_t *timeout = reinterpret_cast<u32_t *>( |
|
2978 failure_received_timeout.get_data(sizeof(u32_t))); |
|
2979 if (timeout != 0) |
|
2980 { |
|
2981 m_eap_core_failure_received_timeout = *timeout; |
|
2982 } |
|
2983 } |
|
2984 } |
|
2985 |
|
2986 //---------------------------------------------------------- |
|
2987 |
|
2988 if (m_is_tunneled_eap == false) |
|
2989 { |
|
2990 eap_variable_data_c remove_session_timeout(m_am_tools); |
|
2991 |
|
2992 status = read_configure( |
|
2993 cf_str_EAP_CORE_remove_session_timeout.get_field(), |
|
2994 &remove_session_timeout); |
|
2995 if (status == eap_status_ok |
|
2996 && remove_session_timeout.get_is_valid_data() == true) |
|
2997 { |
|
2998 u32_t *remove_session_timeout_value = reinterpret_cast<u32_t *>( |
|
2999 remove_session_timeout.get_data(sizeof(u32_t))); |
|
3000 if (remove_session_timeout_value != 0) |
|
3001 { |
|
3002 m_remove_session_timeout = *remove_session_timeout_value; |
|
3003 } |
|
3004 } |
|
3005 } |
|
3006 else |
|
3007 { |
|
3008 // Inside the tunnel we do not need any timeout. |
|
3009 m_remove_session_timeout = 0ul; |
|
3010 } |
|
3011 |
|
3012 //---------------------------------------------------------- |
|
3013 |
|
3014 #if defined(USE_EAP_EXPANDED_TYPES) |
|
3015 { |
|
3016 eap_variable_data_c use_eap_expanded_type(m_am_tools); |
|
3017 |
|
3018 status = m_partner->read_configure( |
|
3019 cf_str_EAP_CORE_use_eap_expanded_type.get_field(), |
|
3020 &use_eap_expanded_type); |
|
3021 if (status == eap_status_ok |
|
3022 && use_eap_expanded_type.get_data_length() == sizeof(u32_t) |
|
3023 && use_eap_expanded_type.get_data() != 0) |
|
3024 { |
|
3025 u32_t *flag = reinterpret_cast<u32_t *>(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); |
|
3026 |
|
3027 if (flag != 0) |
|
3028 { |
|
3029 if ((*flag) != 0ul) |
|
3030 { |
|
3031 m_use_eap_expanded_type = true; |
|
3032 } |
|
3033 else |
|
3034 { |
|
3035 m_use_eap_expanded_type = false; |
|
3036 } |
|
3037 } |
|
3038 } |
|
3039 } |
|
3040 #endif //#if defined(USE_EAP_EXPANDED_TYPES) |
|
3041 |
|
3042 //---------------------------------------------------------- |
|
3043 |
|
3044 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3045 { |
|
3046 eap_variable_data_c wait_eap_request_type_timeout(m_am_tools); |
|
3047 |
|
3048 status = read_configure( |
|
3049 cf_str_EAP_CORE_wait_eap_request_type_timeout.get_field(), |
|
3050 &wait_eap_request_type_timeout); |
|
3051 if (status == eap_status_ok |
|
3052 && wait_eap_request_type_timeout.get_is_valid_data() == true) |
|
3053 { |
|
3054 u32_t *timeout = reinterpret_cast<u32_t *>( |
|
3055 wait_eap_request_type_timeout.get_data(sizeof(u32_t))); |
|
3056 if (timeout != 0) |
|
3057 { |
|
3058 m_wait_eap_request_type_timeout = *timeout; |
|
3059 } |
|
3060 } |
|
3061 } |
|
3062 |
|
3063 #if defined(USE_EAP_CORE_SERVER) |
|
3064 if (m_is_tunneled_eap == false) |
|
3065 { |
|
3066 |
|
3067 eap_variable_data_c skip_eap_request_identity(m_am_tools); |
|
3068 |
|
3069 status = m_partner->read_configure( |
|
3070 cf_str_EAP_CORE_skip_eap_request_identity.get_field(), |
|
3071 &skip_eap_request_identity); |
|
3072 if (status == eap_status_ok |
|
3073 && skip_eap_request_identity.get_data_length() == sizeof(u32_t) |
|
3074 && skip_eap_request_identity.get_data() != 0) |
|
3075 { |
|
3076 u32_t *flag = reinterpret_cast<u32_t *>(skip_eap_request_identity.get_data(skip_eap_request_identity.get_data_length())); |
|
3077 |
|
3078 if (flag != 0) |
|
3079 { |
|
3080 if ((*flag) != 0ul) |
|
3081 { |
|
3082 m_skip_eap_request_identity = true; |
|
3083 } |
|
3084 else |
|
3085 { |
|
3086 m_skip_eap_request_identity = false; |
|
3087 } |
|
3088 } |
|
3089 } |
|
3090 } |
|
3091 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
3092 |
|
3093 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3094 |
|
3095 //---------------------------------------------------------- |
|
3096 |
|
3097 m_eap_header_offset = m_partner->get_header_offset(&m_MTU, &m_trailer_length); |
|
3098 |
|
3099 |
|
3100 // Add session timeout. |
|
3101 status = initialize_session_timeout(m_session_timeout); |
|
3102 if (status != eap_status_ok) |
|
3103 { |
|
3104 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3105 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3106 } |
|
3107 |
|
3108 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3109 |
|
3110 if (m_is_tunneled_eap == false |
|
3111 && m_is_client_role == true) |
|
3112 { |
|
3113 status = cancel_wait_eap_request_type_timeout(); |
|
3114 if (status != eap_status_ok) |
|
3115 { |
|
3116 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3117 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3118 } |
|
3119 |
|
3120 status = set_wait_eap_request_type_timeout(); |
|
3121 } |
|
3122 |
|
3123 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3124 |
|
3125 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3126 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3127 } |
|
3128 |
|
3129 //-------------------------------------------------- |
|
3130 |
|
3131 // |
|
3132 EAP_FUNC_EXPORT eap_status_e eap_core_c::shutdown_operation( |
|
3133 eap_base_type_c * const handler, |
|
3134 abs_eap_am_tools_c * const m_am_tools) |
|
3135 { |
|
3136 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3137 |
|
3138 EAP_UNREFERENCED_PARAMETER(m_am_tools); |
|
3139 |
|
3140 EAP_TRACE_ALWAYS( |
|
3141 m_am_tools, |
|
3142 TRACE_FLAGS_DEFAULT, |
|
3143 (EAPL("eap_core_c::shutdown_operation(): handler=0x%08x.\n"), |
|
3144 handler)); |
|
3145 |
|
3146 eap_status_e status = handler->shutdown(); |
|
3147 |
|
3148 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3149 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3150 } |
|
3151 |
|
3152 //-------------------------------------------------- |
|
3153 |
|
3154 // |
|
3155 EAP_FUNC_EXPORT eap_status_e eap_core_c::shutdown() |
|
3156 { |
|
3157 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3158 |
|
3159 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3160 |
|
3161 #if !defined(USE_EAP_DEBUG_TRACE) |
|
3162 EAP_TRACE_ALWAYS( |
|
3163 m_am_tools, |
|
3164 TRACE_FLAGS_DEFAULT, |
|
3165 (EAPL("eap_core_c::shutdown(): %s: %s, m_shutdown_was_called=%d.\n"), |
|
3166 ((m_is_client == true) ? "client": "server"), |
|
3167 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3168 m_shutdown_was_called)); |
|
3169 #else |
|
3170 EAP_TRACE_ALWAYS( |
|
3171 m_am_tools, |
|
3172 TRACE_FLAGS_DEFAULT, |
|
3173 (EAPL("eap_core_c::shutdown(): %s: %s, this = 0x%08x => 0x%08x, ") |
|
3174 EAPL("m_shutdown_was_called=%d.\n"), |
|
3175 ((m_is_client == true) ? "client": "server"), |
|
3176 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3177 this, |
|
3178 dynamic_cast<abs_eap_base_timer_c *>(this), |
|
3179 m_shutdown_was_called)); |
|
3180 #endif |
|
3181 |
|
3182 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::shutdown()"); |
|
3183 |
|
3184 if (m_shutdown_was_called == true) |
|
3185 { |
|
3186 // Shutdown was already called once. |
|
3187 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3188 } |
|
3189 m_shutdown_was_called = true; |
|
3190 |
|
3191 if (m_partner == 0) |
|
3192 { |
|
3193 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
3194 } |
|
3195 |
|
3196 EAP_TRACE_DEBUG( |
|
3197 m_am_tools, |
|
3198 TRACE_FLAGS_DEFAULT, |
|
3199 (EAPL("eap_core_c::shutdown(): m_is_tunneled_eap=%d, m_eap_type_response_sent=%d\n"), |
|
3200 m_is_tunneled_eap, |
|
3201 m_eap_type_response_sent)); |
|
3202 |
|
3203 if (m_is_client == true |
|
3204 && m_is_tunneled_eap == false |
|
3205 && m_eap_type_response_sent == false) |
|
3206 { |
|
3207 // EAP-authentication failed before any EAP-messages. |
|
3208 |
|
3209 EAP_TRACE_DEBUG( |
|
3210 m_am_tools, |
|
3211 TRACE_FLAGS_DEFAULT, |
|
3212 (EAPL("eap_core_c::shutdown(): EAP-authentication failed before any EAP-messages.\n"))); |
|
3213 |
|
3214 eap_am_network_id_c send_network_id(m_am_tools, |
|
3215 m_receive_network_id.get_destination_id(), |
|
3216 m_receive_network_id.get_source_id(), |
|
3217 m_receive_network_id.get_type()); |
|
3218 |
|
3219 eap_state_notification_c notification( |
|
3220 m_am_tools, |
|
3221 &send_network_id, |
|
3222 m_is_client, |
|
3223 eap_state_notification_eap, |
|
3224 eap_protocol_layer_eap, |
|
3225 m_current_eap_type, |
|
3226 eap_state_none, |
|
3227 eap_state_authentication_terminated_unsuccessfully, |
|
3228 m_eap_identity_request_identifier_client, |
|
3229 false); |
|
3230 |
|
3231 notification.set_authentication_error(eap_status_authentication_failure); |
|
3232 |
|
3233 state_notification(¬ification); |
|
3234 } |
|
3235 |
|
3236 eap_status_e status = m_type_map.for_each(shutdown_operation, true); |
|
3237 |
|
3238 |
|
3239 cancel_retransmission(); |
|
3240 |
|
3241 cancel_session_timeout(); |
|
3242 |
|
3243 cancel_eap_failure_timeout(); |
|
3244 |
|
3245 cancel_asynchronous_init_remove_eap_session(); |
|
3246 |
|
3247 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3248 if (m_is_tunneled_eap == false |
|
3249 && m_is_client_role == true) |
|
3250 { |
|
3251 cancel_wait_eap_request_type_timeout(); |
|
3252 } |
|
3253 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3254 |
|
3255 |
|
3256 if (m_partner != 0) |
|
3257 { |
|
3258 |
|
3259 #if defined(USE_EAP_CORE_SERVER) |
|
3260 m_partner->cancel_timer(this, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID); |
|
3261 |
|
3262 EAP_TRACE_DEBUG( |
|
3263 m_am_tools, |
|
3264 TRACE_FLAGS_DEFAULT, |
|
3265 (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID ") |
|
3266 EAPL("cancelled, this = 0x%08x.\n"), |
|
3267 (m_is_client == true ? "client": "server"), |
|
3268 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3269 this)); |
|
3270 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
3271 |
|
3272 m_partner->cancel_timer(this, EAP_CORE_SESSION_TIMEOUT_ID); |
|
3273 |
|
3274 EAP_TRACE_DEBUG( |
|
3275 m_am_tools, |
|
3276 TRACE_FLAGS_DEFAULT, |
|
3277 (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID cancelled, this = 0x%08x.\n"), |
|
3278 (m_is_client == true ? "client": "server"), |
|
3279 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3280 this)); |
|
3281 } |
|
3282 |
|
3283 #if !defined(USE_EAP_DEBUG_TRACE) |
|
3284 EAP_TRACE_ALWAYS( |
|
3285 m_am_tools, |
|
3286 TRACE_FLAGS_DEFAULT, |
|
3287 (EAPL("eap_core_c::shutdown(): %s: %s, m_shutdown_was_called=%d, status=%d returns.\n"), |
|
3288 ((m_is_client == true) ? "client": "server"), |
|
3289 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3290 m_shutdown_was_called, |
|
3291 status)); |
|
3292 #else |
|
3293 EAP_TRACE_ALWAYS( |
|
3294 m_am_tools, |
|
3295 TRACE_FLAGS_DEFAULT, |
|
3296 (EAPL("eap_core_c::shutdown(): %s: %s, this = 0x%08x => 0x%08x, ") |
|
3297 EAPL("m_shutdown_was_called=%d, status=%d returns.\n"), |
|
3298 ((m_is_client == true) ? "client": "server"), |
|
3299 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3300 this, |
|
3301 dynamic_cast<abs_eap_base_timer_c *>(this), |
|
3302 m_shutdown_was_called, |
|
3303 status)); |
|
3304 #endif |
|
3305 |
|
3306 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3307 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3308 } |
|
3309 |
|
3310 //-------------------------------------------------- |
|
3311 |
|
3312 // |
|
3313 EAP_FUNC_EXPORT eap_status_e eap_core_c::unload_module(const eap_type_value_e type) |
|
3314 { |
|
3315 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3316 |
|
3317 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3318 |
|
3319 const eap_status_e status = m_partner->unload_module(type); |
|
3320 |
|
3321 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3322 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3323 } |
|
3324 |
|
3325 //-------------------------------------------------- |
|
3326 |
|
3327 EAP_FUNC_EXPORT eap_status_e eap_core_c::eap_acknowledge( |
|
3328 const eap_am_network_id_c * const receive_network_id) |
|
3329 { |
|
3330 // Any Network Protocol packet is accepted as a success indication. |
|
3331 // This is described in RFC 2284 "PPP Extensible Authentication Protocol (EAP)". |
|
3332 |
|
3333 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3334 |
|
3335 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3336 |
|
3337 eap_status_e status(eap_status_process_general_error); |
|
3338 |
|
3339 /** |
|
3340 * @{ 2003-10-01 draft-ietf-eap-rfc2284bis-06.txt chapter 3.4 Lower layer indications: |
|
3341 * To improve reliability, if a peer receives a lower layer success |
|
3342 * indication as defined in Section 7.2, it MAY conclude that a Success |
|
3343 * packet has been lost, and behave as if it had actually received a |
|
3344 * Success packet. This includes choosing to ignore the Success in some |
|
3345 * circumstances as described in Section 4.2. |
|
3346 * Add call to current EAP-type. Maybe the EAP-Success packet could |
|
3347 * be created here and send to EAP-type. |
|
3348 * } |
|
3349 */ |
|
3350 |
|
3351 if (m_current_eap_type != eap_type_none) |
|
3352 { |
|
3353 // Here we query the current EAP-type. |
|
3354 eap_variable_data_c selector(m_am_tools); |
|
3355 u64_t selector_eap_type = convert_eap_type_to_u64_t(m_current_eap_type); |
|
3356 status = selector.set_buffer(&selector_eap_type, sizeof(selector_eap_type), false, false); |
|
3357 if (status != eap_status_ok) |
|
3358 { |
|
3359 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3360 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3361 } |
|
3362 eap_base_type_c *handler = m_type_map.get_handler(&selector); |
|
3363 |
|
3364 // Check if we already have this type loaded. |
|
3365 if (handler != 0) |
|
3366 { |
|
3367 status = handler->eap_acknowledge(receive_network_id); |
|
3368 |
|
3369 if (status == eap_status_not_supported) |
|
3370 { |
|
3371 // This is too noisy. |
|
3372 /** |
|
3373 * @{ 2004-09-02 Fix all eap_acknowledge() functions. } |
|
3374 */ |
|
3375 status = eap_status_ok; |
|
3376 } |
|
3377 } |
|
3378 else |
|
3379 { |
|
3380 // Here we do not care of missing handler. |
|
3381 // Acknowledge is meaningfull only for existing handler. |
|
3382 status = eap_status_ok; |
|
3383 } |
|
3384 } |
|
3385 else |
|
3386 { |
|
3387 // Here we do not care of missing handler. |
|
3388 // Acknowledge is meaningfull only for existing handler. |
|
3389 status = eap_status_ok; |
|
3390 } |
|
3391 |
|
3392 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3393 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3394 } |
|
3395 |
|
3396 //-------------------------------------------------- |
|
3397 |
|
3398 // |
|
3399 EAP_FUNC_EXPORT eap_status_e eap_core_c::restart_authentication( |
|
3400 const eap_am_network_id_c * const send_network_id, |
|
3401 const bool is_client_when_true) |
|
3402 { |
|
3403 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3404 |
|
3405 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3406 |
|
3407 // Here we swap the addresses. |
|
3408 eap_am_network_id_c receive_network_id(m_am_tools, |
|
3409 send_network_id->get_destination_id(), |
|
3410 send_network_id->get_source_id(), |
|
3411 send_network_id->get_type()); |
|
3412 |
|
3413 eap_status_e status = eap_status_process_general_error; |
|
3414 |
|
3415 initialize_session_timeout(m_session_timeout); |
|
3416 |
|
3417 if (is_client_when_true == false) |
|
3418 { |
|
3419 // This is much faster. |
|
3420 status = m_partner->restart_authentication( |
|
3421 &receive_network_id, |
|
3422 is_client_when_true, |
|
3423 true); |
|
3424 if (status != eap_status_ok) |
|
3425 { |
|
3426 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3427 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3428 } |
|
3429 |
|
3430 m_client_restart_authentication_initiated = true; |
|
3431 } |
|
3432 else |
|
3433 { |
|
3434 if (m_client_restart_authentication_initiated == true) |
|
3435 { |
|
3436 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3437 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3438 } |
|
3439 |
|
3440 // This is much faster. |
|
3441 status = m_partner->restart_authentication( |
|
3442 &receive_network_id, |
|
3443 is_client_when_true, |
|
3444 true); |
|
3445 if (status != eap_status_ok) |
|
3446 { |
|
3447 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3448 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3449 } |
|
3450 |
|
3451 m_client_restart_authentication_initiated = true; |
|
3452 } |
|
3453 |
|
3454 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3455 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3456 } |
|
3457 |
|
3458 //-------------------------------------------------- |
|
3459 |
|
3460 #if defined(USE_EAP_CORE_SERVER) |
|
3461 |
|
3462 // |
|
3463 EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_identity_request( |
|
3464 const eap_am_network_id_c * const receive_network_id) |
|
3465 { |
|
3466 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3467 |
|
3468 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3469 |
|
3470 EAP_ASSERT(m_is_client == false); |
|
3471 |
|
3472 eap_status_e status = eap_status_process_general_error; |
|
3473 |
|
3474 EAP_TRACE_DEBUG( |
|
3475 m_am_tools, |
|
3476 TRACE_FLAGS_DEFAULT, |
|
3477 (EAPL("eap_core_c::send_eap_identity_request(): %s, %s\n"), |
|
3478 (m_is_client == true) ? "client": "server", |
|
3479 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3480 )); |
|
3481 |
|
3482 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_core_c::send_eap_identity_request()"); |
|
3483 |
|
3484 if (receive_network_id->get_is_valid_data() == false) |
|
3485 { |
|
3486 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3487 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3488 } |
|
3489 |
|
3490 // Here we swap the addresses. |
|
3491 eap_am_network_id_c send_network_id(m_am_tools, |
|
3492 receive_network_id->get_destination_id(), |
|
3493 receive_network_id->get_source_id(), |
|
3494 receive_network_id->get_type()); |
|
3495 |
|
3496 if (send_network_id.get_is_valid_data() == false) |
|
3497 { |
|
3498 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3499 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3500 } |
|
3501 |
|
3502 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3503 |
|
3504 EAP_TRACE_DEBUG( |
|
3505 m_am_tools, |
|
3506 TRACE_FLAGS_DEFAULT, |
|
3507 (EAPL("eap_core_c::send_eap_identity_request(): %s, %s, m_skip_eap_request_identity=%d, m_eap_identity_request_send=%d, m_eap_identity_response_accepted=%d\n"), |
|
3508 (m_is_client == true) ? "client": "server", |
|
3509 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3510 m_skip_eap_request_identity, |
|
3511 m_eap_identity_request_send, |
|
3512 m_eap_identity_response_accepted |
|
3513 )); |
|
3514 |
|
3515 if (m_skip_eap_request_identity == true) |
|
3516 { |
|
3517 if (m_eap_identity_request_send == true) |
|
3518 { |
|
3519 // Do nothing, this have been done already. |
|
3520 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3521 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
3522 } |
|
3523 |
|
3524 if (m_eap_identity.get_is_valid_data() == false) |
|
3525 { |
|
3526 // No saved EAP-Identity. Set an empty EAP-Identity. |
|
3527 status = m_eap_identity.init(0ul); |
|
3528 if (status != eap_status_ok) |
|
3529 { |
|
3530 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3531 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3532 } |
|
3533 } |
|
3534 |
|
3535 // We will skip EAP-Request/Identity and EAP-Response/Identity for testing purposes. |
|
3536 // Now restart authentication with proposed EAP type. |
|
3537 status = restart_with_new_type( |
|
3538 m_default_eap_type, |
|
3539 receive_network_id, |
|
3540 0ul); |
|
3541 if (status != eap_status_ok) |
|
3542 { |
|
3543 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3544 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3545 } |
|
3546 |
|
3547 m_eap_identity_request_send = true; |
|
3548 m_eap_identity_response_accepted = true; |
|
3549 } |
|
3550 else |
|
3551 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
3552 { |
|
3553 // Creates a identity request message. |
|
3554 eap_buf_chain_wr_c request_packet( |
|
3555 eap_write_buffer, |
|
3556 m_am_tools, |
|
3557 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
3558 |
|
3559 if (request_packet.get_is_valid() == false) |
|
3560 { |
|
3561 EAP_TRACE_ERROR( |
|
3562 m_am_tools, |
|
3563 TRACE_FLAGS_DEFAULT, |
|
3564 (EAPL("send_eap_identity_request(): %s, %s, packet buffer corrupted.\n"), |
|
3565 (m_is_client == true) ? "client": "server", |
|
3566 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3567 )); |
|
3568 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3569 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3570 } |
|
3571 |
|
3572 u32_t buffer_size = EAP_CORE_PACKET_BUFFER_LENGTH; |
|
3573 EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length); |
|
3574 if (m_MTU-m_trailer_length < buffer_size) |
|
3575 { |
|
3576 buffer_size = m_MTU-m_trailer_length; |
|
3577 } |
|
3578 |
|
3579 EAP_ASSERT_ALWAYS(buffer_size >= m_eap_header_offset); |
|
3580 eap_header_wr_c eap_request( |
|
3581 m_am_tools, |
|
3582 request_packet.get_data_offset( |
|
3583 m_eap_header_offset, |
|
3584 (buffer_size-m_eap_header_offset)), |
|
3585 (buffer_size-m_eap_header_offset)); |
|
3586 |
|
3587 if (eap_request.get_is_valid() == false) |
|
3588 { |
|
3589 EAP_TRACE_ERROR( |
|
3590 m_am_tools, |
|
3591 TRACE_FLAGS_DEFAULT, |
|
3592 (EAPL("send_eap_identity_request(): %s, %s, packet buffer corrupted.\n"), |
|
3593 (m_is_client == true) ? "client": "server", |
|
3594 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3595 )); |
|
3596 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3597 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3598 } |
|
3599 |
|
3600 eap_request.set_length( |
|
3601 static_cast<u16_t>((EAP_CORE_PACKET_BUFFER_LENGTH-m_eap_header_offset)), |
|
3602 m_use_eap_expanded_type); |
|
3603 eap_request.set_code(eap_code_request); |
|
3604 eap_request.set_identifier(0); |
|
3605 eap_request.set_type_data_length(0ul, m_use_eap_expanded_type); |
|
3606 eap_request.set_type(eap_type_identity, m_use_eap_expanded_type); |
|
3607 |
|
3608 request_packet.set_data_length(m_eap_header_offset+eap_request.get_length()); |
|
3609 request_packet.set_do_packet_retransmission(true); |
|
3610 |
|
3611 EAP_ASSERT(m_eap_header_offset < request_packet.get_data_length()); |
|
3612 EAP_ASSERT(eap_request.get_length() <= request_packet.get_data_length()); |
|
3613 EAP_ASSERT(request_packet.get_data_length() <= EAP_CORE_PACKET_BUFFER_LENGTH); |
|
3614 |
|
3615 status = packet_send( |
|
3616 &send_network_id, &request_packet, m_eap_header_offset, |
|
3617 eap_request.get_length(), |
|
3618 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
3619 |
|
3620 if (status == eap_status_ok) |
|
3621 { |
|
3622 eap_state_notification_c notification( |
|
3623 m_am_tools, |
|
3624 &send_network_id, |
|
3625 m_is_client, |
|
3626 eap_state_notification_eap, |
|
3627 eap_protocol_layer_eap, |
|
3628 m_current_eap_type, |
|
3629 eap_state_none, |
|
3630 eap_state_identity_request_sent, |
|
3631 eap_request.get_identifier(), |
|
3632 false); |
|
3633 state_notification(¬ification); |
|
3634 } |
|
3635 |
|
3636 m_eap_identity_request_send = true; |
|
3637 } |
|
3638 |
|
3639 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3640 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3641 } |
|
3642 |
|
3643 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
3644 |
|
3645 //-------------------------------------------------- |
|
3646 |
|
3647 // |
|
3648 EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_nak_response( |
|
3649 const eap_am_network_id_c * const receive_network_id, |
|
3650 const u8_t eap_identifier, |
|
3651 const eap_array_c<eap_type_value_e> * const eap_type_list) |
|
3652 { |
|
3653 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3654 |
|
3655 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3656 |
|
3657 eap_status_e status = eap_status_process_general_error; |
|
3658 |
|
3659 EAP_TRACE_DEBUG( |
|
3660 m_am_tools, |
|
3661 TRACE_FLAGS_DEFAULT, |
|
3662 (EAPL("eap_core_c::send_eap_nak_response(): %s, %s\n"), |
|
3663 (m_is_client == true) ? "client": "server", |
|
3664 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3665 )); |
|
3666 |
|
3667 // Here we swap the addresses. |
|
3668 eap_am_network_id_c send_network_id(m_am_tools, |
|
3669 receive_network_id->get_destination_id(), |
|
3670 receive_network_id->get_source_id(), |
|
3671 receive_network_id->get_type()); |
|
3672 |
|
3673 // Creates a identity request message. |
|
3674 eap_buf_chain_wr_c nak_packet( |
|
3675 eap_write_buffer, |
|
3676 m_am_tools, |
|
3677 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
3678 |
|
3679 if (nak_packet.get_is_valid() == false) |
|
3680 { |
|
3681 EAP_TRACE_ERROR( |
|
3682 m_am_tools, |
|
3683 TRACE_FLAGS_DEFAULT, |
|
3684 (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, packet buffer corrupted.\n"), |
|
3685 (m_is_client == true) ? "client": "server", |
|
3686 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3687 )); |
|
3688 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3689 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3690 } |
|
3691 |
|
3692 u32_t buffer_size = EAP_CORE_PACKET_BUFFER_LENGTH; |
|
3693 EAP_ASSERT_ALWAYS(m_MTU > m_trailer_length); |
|
3694 if (m_MTU-m_trailer_length < buffer_size) |
|
3695 { |
|
3696 buffer_size = m_MTU-m_trailer_length; |
|
3697 } |
|
3698 |
|
3699 EAP_ASSERT_ALWAYS(buffer_size >= m_eap_header_offset); |
|
3700 eap_header_wr_c eap_nak_hdr( |
|
3701 m_am_tools, |
|
3702 nak_packet.get_data_offset( |
|
3703 m_eap_header_offset, |
|
3704 (buffer_size-m_eap_header_offset)), |
|
3705 (buffer_size-m_eap_header_offset) |
|
3706 ); |
|
3707 |
|
3708 if (eap_nak_hdr.get_is_valid() == false) |
|
3709 { |
|
3710 EAP_TRACE_ERROR( |
|
3711 m_am_tools, |
|
3712 TRACE_FLAGS_DEFAULT, |
|
3713 (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, packet buffer corrupted.\n"), |
|
3714 (m_is_client == true) ? "client": "server", |
|
3715 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3716 )); |
|
3717 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3718 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3719 } |
|
3720 |
|
3721 bool write_expanded_type(false); |
|
3722 u32_t ind = 0ul; |
|
3723 u32_t count_of_eap_types = eap_type_list->get_object_count(); |
|
3724 |
|
3725 for (ind = 0ul; ind < count_of_eap_types; ind++) |
|
3726 { |
|
3727 const eap_type_value_e * const type = eap_type_list->get_object(ind); |
|
3728 if (type != 0 |
|
3729 && eap_expanded_type_c::is_ietf_type(*type) == false) |
|
3730 { |
|
3731 write_expanded_type = true; |
|
3732 break; |
|
3733 } |
|
3734 } |
|
3735 |
|
3736 eap_nak_hdr.set_length( |
|
3737 static_cast<u16_t>((EAP_CORE_PACKET_BUFFER_LENGTH-m_eap_header_offset)), |
|
3738 write_expanded_type); |
|
3739 eap_nak_hdr.set_code(eap_code_response); |
|
3740 eap_nak_hdr.set_identifier(eap_identifier); |
|
3741 eap_nak_hdr.set_type_data_length(eap_nak_hdr.get_length(), write_expanded_type); |
|
3742 eap_nak_hdr.set_type(eap_type_nak, write_expanded_type); |
|
3743 |
|
3744 u32_t required_data_length = count_of_eap_types |
|
3745 *eap_expanded_type_c::get_eap_expanded_type_size(); |
|
3746 |
|
3747 if (eap_nak_hdr.get_length() < required_data_length) |
|
3748 { |
|
3749 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3750 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3751 } |
|
3752 |
|
3753 u32_t type_length = eap_expanded_type_c::m_ietf_type_size; |
|
3754 if (write_expanded_type == true) |
|
3755 { |
|
3756 type_length = eap_expanded_type_c::m_eap_expanded_type_size; |
|
3757 } |
|
3758 |
|
3759 u8_t * const type_data = eap_nak_hdr.get_data_offset(type_length, required_data_length); |
|
3760 |
|
3761 if (type_data == 0) |
|
3762 { |
|
3763 EAP_TRACE_ERROR( |
|
3764 m_am_tools, |
|
3765 TRACE_FLAGS_DEFAULT, |
|
3766 (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, packet buffer corrupted.\n"), |
|
3767 (m_is_client == true) ? "client": "server", |
|
3768 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3769 )); |
|
3770 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3771 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3772 } |
|
3773 |
|
3774 |
|
3775 u8_t * const data = type_data; |
|
3776 |
|
3777 for (ind = 0ul; ind < count_of_eap_types; ind++) |
|
3778 { |
|
3779 const eap_type_value_e * const type = eap_type_list->get_object(ind); |
|
3780 |
|
3781 if (type != 0) |
|
3782 { |
|
3783 EAP_TRACE_DEBUG( |
|
3784 m_am_tools, |
|
3785 TRACE_FLAGS_DEFAULT, |
|
3786 (EAPL("%s: eap_core_c::send_eap_nak_response(): allowed EAP-type %d.\n"), |
|
3787 (m_is_client == true ? "client": "server"), |
|
3788 convert_eap_type_to_u32_t(*type))); |
|
3789 |
|
3790 status = eap_expanded_type_c::write_type( |
|
3791 m_am_tools, |
|
3792 ind, |
|
3793 data, |
|
3794 eap_nak_hdr.get_type_data_length() |
|
3795 -eap_expanded_type_c::get_eap_expanded_type_size()*ind, |
|
3796 write_expanded_type, |
|
3797 *type); |
|
3798 } |
|
3799 else |
|
3800 { |
|
3801 EAP_TRACE_ERROR( |
|
3802 m_am_tools, |
|
3803 TRACE_FLAGS_DEFAULT, |
|
3804 (EAPL("eap_core_c::send_eap_nak_response(): %s, %s, ") |
|
3805 EAPL("No EAP-type supported.\n"), |
|
3806 (m_is_client == true) ? "client": "server", |
|
3807 (m_is_tunneled_eap == true) ? "tunneled": "outer most")); |
|
3808 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3809 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_supported); |
|
3810 } |
|
3811 } // for() |
|
3812 |
|
3813 eap_nak_hdr.set_type_data_length( |
|
3814 static_cast<u16_t>(count_of_eap_types*type_length), |
|
3815 write_expanded_type); |
|
3816 nak_packet.set_data_length(m_eap_header_offset+eap_nak_hdr.get_length()); |
|
3817 |
|
3818 EAP_ASSERT(m_eap_header_offset < nak_packet.get_data_length()); |
|
3819 EAP_ASSERT(eap_nak_hdr.get_length() <= nak_packet.get_data_length()); |
|
3820 EAP_ASSERT(nak_packet.get_data_length() <= EAP_CORE_PACKET_BUFFER_LENGTH); |
|
3821 |
|
3822 status = packet_send( |
|
3823 &send_network_id, &nak_packet, m_eap_header_offset, |
|
3824 eap_nak_hdr.get_length(), |
|
3825 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
3826 |
|
3827 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3828 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3829 } |
|
3830 |
|
3831 //-------------------------------------------------- |
|
3832 |
|
3833 EAP_FUNC_EXPORT eap_status_e eap_core_c::packet_data_crypto_keys( |
|
3834 const eap_am_network_id_c * const send_network_id, |
|
3835 const eap_master_session_key_c * const master_session_key |
|
3836 ) |
|
3837 { |
|
3838 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3839 |
|
3840 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3841 |
|
3842 const eap_status_e status = m_partner->packet_data_crypto_keys( |
|
3843 send_network_id, |
|
3844 master_session_key); |
|
3845 |
|
3846 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3847 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3848 } |
|
3849 |
|
3850 //-------------------------------------------------- |
|
3851 |
|
3852 EAP_FUNC_EXPORT eap_status_e eap_core_c::read_configure( |
|
3853 const eap_configuration_field_c * const field, |
|
3854 eap_variable_data_c * const data) |
|
3855 { |
|
3856 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3857 |
|
3858 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3859 |
|
3860 const eap_status_e status = m_partner->read_configure(field, data); |
|
3861 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3862 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3863 } |
|
3864 |
|
3865 //-------------------------------------------------- |
|
3866 |
|
3867 EAP_FUNC_EXPORT eap_status_e eap_core_c::write_configure( |
|
3868 const eap_configuration_field_c * const field, |
|
3869 eap_variable_data_c * const data) |
|
3870 { |
|
3871 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3872 |
|
3873 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3874 |
|
3875 const eap_status_e status = m_partner->write_configure(field, data); |
|
3876 |
|
3877 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3878 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3879 } |
|
3880 |
|
3881 //-------------------------------------------------- |
|
3882 |
|
3883 // |
|
3884 EAP_FUNC_EXPORT eap_status_e eap_core_c::timer_expired( |
|
3885 const u32_t id, void *data) |
|
3886 { |
|
3887 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3888 |
|
3889 EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this. |
|
3890 |
|
3891 EAP_TRACE_DEBUG( |
|
3892 m_am_tools, |
|
3893 TRACE_FLAGS_DEFAULT, |
|
3894 (EAPL("TIMER: [0x%08x]->eap_core_c::timer_expired(id 0x%02x, data 0x%08x), %s, %s.\n"), |
|
3895 this, |
|
3896 id, |
|
3897 data, |
|
3898 (m_is_client == true) ? "client": "server", |
|
3899 (m_is_tunneled_eap == true) ? "tunneled": "outer most")); |
|
3900 |
|
3901 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
3902 |
|
3903 eap_status_e status = eap_status_process_general_error; |
|
3904 |
|
3905 if (id == EAP_CORE_FAILURE_RECEIVED_ID) |
|
3906 { |
|
3907 EAP_TRACE_DEBUG( |
|
3908 m_am_tools, |
|
3909 TRACE_FLAGS_DEFAULT, |
|
3910 (EAPL("TIMER: %s: %s, EAP_CORE_FAILURE_RECEIVED_ID elapsed.\n"), |
|
3911 (m_is_client == true ? "client": "server"), |
|
3912 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3913 )); |
|
3914 |
|
3915 { |
|
3916 eap_am_network_id_c send_network_id(m_am_tools, |
|
3917 m_receive_network_id.get_destination_id(), |
|
3918 m_receive_network_id.get_source_id(), |
|
3919 m_receive_network_id.get_type()); |
|
3920 |
|
3921 eap_state_notification_c notification( |
|
3922 m_am_tools, |
|
3923 &send_network_id, |
|
3924 m_is_client, |
|
3925 eap_state_notification_eap, |
|
3926 eap_protocol_layer_eap, |
|
3927 m_current_eap_type, |
|
3928 eap_state_none, |
|
3929 eap_state_authentication_terminated_unsuccessfully, |
|
3930 m_eap_identity_request_identifier_client, |
|
3931 false); |
|
3932 |
|
3933 notification.set_authentication_error(eap_status_authentication_failure); |
|
3934 |
|
3935 state_notification(¬ification); |
|
3936 } |
|
3937 |
|
3938 status = eap_status_ok; |
|
3939 } |
|
3940 else if (id == EAP_CORE_TIMER_RETRANSMISSION_ID) |
|
3941 { |
|
3942 EAP_TRACE_DEBUG( |
|
3943 m_am_tools, |
|
3944 TRACE_FLAGS_DEFAULT, |
|
3945 (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID elapsed.\n"), |
|
3946 (m_is_client == true ? "client": "server"), |
|
3947 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
3948 )); |
|
3949 |
|
3950 if (m_retransmission != 0 |
|
3951 && m_retransmission->get_is_valid() == true |
|
3952 && m_retransmission->get_retransmission_counter() > 0) |
|
3953 { |
|
3954 EAP_TRACE_DEBUG( |
|
3955 m_am_tools, |
|
3956 TRACE_FLAGS_DEFAULT, |
|
3957 (EAPL("TIMER: %s, %s, new retransmission, m_retransmission->get_is_valid()=%d, ") |
|
3958 EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), |
|
3959 (m_is_client == true) ? "client": "server", |
|
3960 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
3961 m_retransmission->get_is_valid(), |
|
3962 m_retransmission->get_retransmission_counter())); |
|
3963 |
|
3964 // This packet send is initialized by timer event. |
|
3965 |
|
3966 status = resend_packet( |
|
3967 m_retransmission->get_send_network_id(), |
|
3968 m_retransmission->get_sent_packet(), |
|
3969 m_retransmission->get_header_offset(), |
|
3970 m_retransmission->get_data_length(), |
|
3971 m_retransmission->get_buffer_size(), |
|
3972 m_retransmission->get_retransmission_counter() |
|
3973 ); |
|
3974 |
|
3975 if (status == eap_status_ok) |
|
3976 { |
|
3977 if (m_retransmission->get_retransmission_counter() > 0u) |
|
3978 { |
|
3979 // OK, initialize the next time to retransmit. |
|
3980 u32_t next_retransmission_time |
|
3981 = m_retransmission->get_next_retransmission_time(); |
|
3982 |
|
3983 status = m_partner->set_timer( |
|
3984 this, |
|
3985 EAP_CORE_TIMER_RETRANSMISSION_ID, |
|
3986 0, |
|
3987 next_retransmission_time); |
|
3988 if (status != eap_status_ok) |
|
3989 { |
|
3990 delete m_retransmission; |
|
3991 m_retransmission = 0; |
|
3992 } |
|
3993 else |
|
3994 { |
|
3995 m_retransmission->get_next_retransmission_counter(); // This decrements the counter. |
|
3996 |
|
3997 EAP_TRACE_DEBUG( |
|
3998 m_am_tools, |
|
3999 TRACE_FLAGS_DEFAULT, |
|
4000 (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID ") |
|
4001 EAPL("set %d ms, retransmission_counter %d.\n"), |
|
4002 (m_is_client == true ? "client": "server"), |
|
4003 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
4004 next_retransmission_time, |
|
4005 m_retransmission->get_retransmission_counter())); |
|
4006 } |
|
4007 } |
|
4008 |
|
4009 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4010 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4011 } |
|
4012 else |
|
4013 { |
|
4014 delete m_retransmission; |
|
4015 m_retransmission = 0; |
|
4016 |
|
4017 status = eap_status_ok; |
|
4018 |
|
4019 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4020 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4021 } |
|
4022 } |
|
4023 else |
|
4024 { |
|
4025 EAP_TRACE_DEBUG( |
|
4026 m_am_tools, |
|
4027 TRACE_FLAGS_DEFAULT, |
|
4028 (EAPL("TIMER: %s, %s, no retransmission, m_retransmission=0x%08x.\n"), |
|
4029 (m_is_client == true) ? "client": "server", |
|
4030 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
4031 m_retransmission)); |
|
4032 if (m_retransmission != 0) |
|
4033 { |
|
4034 EAP_TRACE_DEBUG( |
|
4035 m_am_tools, |
|
4036 TRACE_FLAGS_DEFAULT, |
|
4037 (EAPL("TIMER: %s, %s, no retransmission, m_retransmission->get_is_valid()=%d, ") |
|
4038 EAPL("m_retransmission->get_retransmission_counter()=%d.\n"), |
|
4039 (m_is_client == true) ? "client": "server", |
|
4040 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
4041 m_retransmission->get_is_valid(), |
|
4042 m_retransmission->get_retransmission_counter())); |
|
4043 } |
|
4044 |
|
4045 // No good EAP-Response received to EAP-Requests. |
|
4046 // Terminate the session. |
|
4047 |
|
4048 { |
|
4049 eap_am_network_id_c send_network_id(m_am_tools, |
|
4050 m_receive_network_id.get_destination_id(), |
|
4051 m_receive_network_id.get_source_id(), |
|
4052 m_receive_network_id.get_type()); |
|
4053 |
|
4054 eap_state_notification_c notification( |
|
4055 m_am_tools, |
|
4056 &send_network_id, |
|
4057 m_is_client, |
|
4058 eap_state_notification_eap, |
|
4059 eap_protocol_layer_eap, |
|
4060 m_current_eap_type, |
|
4061 eap_state_none, |
|
4062 eap_state_authentication_terminated_unsuccessfully, |
|
4063 m_eap_identity_request_identifier_client, |
|
4064 false); |
|
4065 |
|
4066 notification.set_authentication_error(eap_status_authentication_failure); |
|
4067 |
|
4068 state_notification(¬ification); |
|
4069 } |
|
4070 |
|
4071 status = eap_status_ok; |
|
4072 } |
|
4073 } |
|
4074 #if defined(USE_EAP_CORE_SERVER) |
|
4075 else if (id == EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID) |
|
4076 { |
|
4077 // Now restart authentication with proposed EAP type. |
|
4078 const eap_core_nak_info_c * const nak_info |
|
4079 = reinterpret_cast<const eap_core_nak_info_c *>(data); |
|
4080 |
|
4081 EAP_TRACE_DEBUG( |
|
4082 m_am_tools, |
|
4083 TRACE_FLAGS_DEFAULT, |
|
4084 (EAPL("TIMER: %s: %s, EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID elapsed.\n"), |
|
4085 (m_is_client == true ? "client": "server"), |
|
4086 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4087 )); |
|
4088 |
|
4089 eap_type_value_e used_eap_type = nak_info->get_proposed_eap_type(); |
|
4090 |
|
4091 m_nak_process_timer_active = false; |
|
4092 |
|
4093 { |
|
4094 // First remove current EAP-type. |
|
4095 eap_variable_data_c selector(m_am_tools); |
|
4096 status = selector.set_copy_of_buffer( |
|
4097 &m_current_eap_type, |
|
4098 sizeof(m_current_eap_type)); |
|
4099 if (status != eap_status_ok) |
|
4100 { |
|
4101 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4102 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4103 } |
|
4104 eap_base_type_c *handler = m_type_map.get_handler(&selector); |
|
4105 |
|
4106 // Change the current EAP-type here because shutdown could |
|
4107 // cause state notifications from old EAP-type. |
|
4108 m_current_eap_type = used_eap_type; |
|
4109 |
|
4110 if (handler != 0) |
|
4111 { |
|
4112 status = handler->shutdown(); |
|
4113 if (status != eap_status_ok) |
|
4114 { |
|
4115 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4116 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4117 } |
|
4118 |
|
4119 status = m_type_map.remove_handler(&selector, true); |
|
4120 if (status != eap_status_ok) |
|
4121 { |
|
4122 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4123 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4124 } |
|
4125 } |
|
4126 |
|
4127 // Now restart authentication with proposed EAP type. |
|
4128 status = restart_with_new_type( |
|
4129 used_eap_type, |
|
4130 nak_info->get_network_id(), |
|
4131 nak_info->get_eap_identifier()); |
|
4132 |
|
4133 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4134 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4135 } |
|
4136 } |
|
4137 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
4138 else if (id == EAP_CORE_SESSION_TIMEOUT_ID |
|
4139 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4140 || id == EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID |
|
4141 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4142 ) |
|
4143 { |
|
4144 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4145 if (id == EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID) |
|
4146 { |
|
4147 EAP_TRACE_DEBUG( |
|
4148 m_am_tools, |
|
4149 TRACE_FLAGS_DEFAULT, |
|
4150 (EAPL("TIMER: %s: %s, EAP_CORE_WAIT_EAP_REQUEST_TYPE_ID elapsed.\n"), |
|
4151 (m_is_client == true ? "client": "server"), |
|
4152 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4153 )); |
|
4154 } |
|
4155 else |
|
4156 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4157 { |
|
4158 EAP_TRACE_DEBUG( |
|
4159 m_am_tools, |
|
4160 TRACE_FLAGS_DEFAULT, |
|
4161 (EAPL("TIMER: %s: %s, EAP_CORE_SESSION_TIMEOUT_ID elapsed.\n"), |
|
4162 (m_is_client == true ? "client": "server"), |
|
4163 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4164 )); |
|
4165 } |
|
4166 |
|
4167 // we will remove this session immediately. |
|
4168 status = initialize_asynchronous_init_remove_eap_session(0ul); |
|
4169 |
|
4170 eap_am_network_id_c send_network_id(m_am_tools, |
|
4171 m_receive_network_id.get_destination_id(), |
|
4172 m_receive_network_id.get_source_id(), |
|
4173 m_receive_network_id.get_type()); |
|
4174 |
|
4175 eap_state_notification_c notification( |
|
4176 m_am_tools, |
|
4177 &send_network_id, |
|
4178 m_is_client, |
|
4179 eap_state_notification_eap, |
|
4180 eap_protocol_layer_eap, |
|
4181 m_current_eap_type, |
|
4182 eap_state_none, |
|
4183 eap_state_authentication_terminated_unsuccessfully, |
|
4184 m_eap_identity_request_identifier_client, |
|
4185 false); |
|
4186 |
|
4187 notification.set_authentication_error(eap_status_authentication_failure); |
|
4188 |
|
4189 state_notification(¬ification); |
|
4190 |
|
4191 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4192 } |
|
4193 else if (id == EAP_CORE_REMOVE_SESSION_TIMEOUT_ID) |
|
4194 { |
|
4195 EAP_TRACE_DEBUG( |
|
4196 m_am_tools, |
|
4197 TRACE_FLAGS_DEFAULT, |
|
4198 (EAPL("TIMER: %s: %s, EAP_CORE_REMOVE_SESSION_TIMEOUT_ID elapsed.\n"), |
|
4199 (m_is_client == true ? "client": "server"), |
|
4200 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4201 )); |
|
4202 |
|
4203 status = asynchronous_init_remove_eap_session(); |
|
4204 } |
|
4205 |
|
4206 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4207 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4208 } |
|
4209 |
|
4210 //-------------------------------------------------- |
|
4211 |
|
4212 // |
|
4213 EAP_FUNC_EXPORT eap_status_e eap_core_c::timer_delete_data( |
|
4214 const u32_t id, void *data) |
|
4215 { |
|
4216 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4217 |
|
4218 EAP_UNREFERENCED_PARAMETER(data); // Only trace uses this. |
|
4219 |
|
4220 EAP_TRACE_DEBUG( |
|
4221 m_am_tools, |
|
4222 TRACE_FLAGS_DEFAULT, |
|
4223 (EAPL("TIMER: [0x%08x]->eap_core_c::timer_delete_data(id 0x%02x, data 0x%08x): %s, %s.\n"), |
|
4224 this, |
|
4225 id, |
|
4226 data, |
|
4227 (m_is_client == true) ? "client": "server", |
|
4228 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4229 )); |
|
4230 |
|
4231 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
4232 |
|
4233 if (id == EAP_CORE_TIMER_RETRANSMISSION_ID) |
|
4234 { |
|
4235 EAP_TRACE_DEBUG( |
|
4236 m_am_tools, |
|
4237 TRACE_FLAGS_DEFAULT, |
|
4238 (EAPL("TIMER: %s: %s, EAP_CORE_TIMER_RETRANSMISSION_ID delete data.\n"), |
|
4239 (m_is_client == true ? "client": "server"), |
|
4240 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4241 )); |
|
4242 |
|
4243 if (m_retransmission != 0 |
|
4244 && m_retransmission->get_is_valid() == true |
|
4245 && m_retransmission->get_retransmission_counter() > 0) |
|
4246 { |
|
4247 // Do not delete yet. |
|
4248 // cancel_retransmission() will delete m_retransmission. |
|
4249 } |
|
4250 else if (m_retransmission != 0) |
|
4251 { |
|
4252 delete m_retransmission; |
|
4253 m_retransmission = 0; |
|
4254 } |
|
4255 } |
|
4256 #if defined(USE_EAP_CORE_SERVER) |
|
4257 else if (id == EAP_CORE_DELAYED_EAP_NAK_PROCESS_ID) |
|
4258 { |
|
4259 const eap_core_nak_info_c * const nak_info |
|
4260 = reinterpret_cast<const eap_core_nak_info_c *>(data); |
|
4261 delete nak_info; |
|
4262 } |
|
4263 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
4264 else if (id == EAP_CORE_REMOVE_SESSION_TIMEOUT_ID) |
|
4265 { |
|
4266 // Nothing to do. |
|
4267 } |
|
4268 |
|
4269 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4270 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
4271 } |
|
4272 |
|
4273 //-------------------------------------------------- |
|
4274 |
|
4275 // |
|
4276 EAP_FUNC_EXPORT eap_status_e eap_core_c::reset_operation( |
|
4277 eap_base_type_c * const handler, |
|
4278 abs_eap_am_tools_c * const m_am_tools) |
|
4279 { |
|
4280 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4281 |
|
4282 EAP_UNREFERENCED_PARAMETER(m_am_tools); |
|
4283 |
|
4284 EAP_TRACE_ALWAYS( |
|
4285 m_am_tools, |
|
4286 TRACE_FLAGS_DEFAULT, |
|
4287 (EAPL("eap_core_c::reset_operation(): handler=0x%08x.\n"), |
|
4288 handler)); |
|
4289 |
|
4290 eap_status_e status = handler->reset(); |
|
4291 |
|
4292 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4293 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4294 } |
|
4295 |
|
4296 //-------------------------------------------------- |
|
4297 |
|
4298 // |
|
4299 EAP_FUNC_EXPORT eap_status_e eap_core_c::reset() |
|
4300 { |
|
4301 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4302 |
|
4303 #if !defined(USE_EAP_DEBUG_TRACE) |
|
4304 EAP_TRACE_ALWAYS( |
|
4305 m_am_tools, |
|
4306 TRACE_FLAGS_DEFAULT, |
|
4307 (EAPL("eap_core_c::reset(): %s: %s.\n"), |
|
4308 ((m_is_client == true) ? "client": "server"), |
|
4309 (m_is_tunneled_eap == true) ? "tunneled": "outer most")); |
|
4310 #else |
|
4311 EAP_TRACE_ALWAYS( |
|
4312 m_am_tools, |
|
4313 TRACE_FLAGS_DEFAULT, |
|
4314 (EAPL("eap_core_c::reset(): %s: %s, this = 0x%08x => 0x%08x.\n"), |
|
4315 ((m_is_client == true) ? "client": "server"), |
|
4316 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
4317 this, |
|
4318 dynamic_cast<abs_eap_base_timer_c *>(this))); |
|
4319 #endif |
|
4320 |
|
4321 eap_status_e status = eap_status_ok; |
|
4322 |
|
4323 eap_variable_data_c selector(m_am_tools); |
|
4324 u64_t tmp_eap_type = convert_eap_type_to_u64_t(m_current_eap_type); |
|
4325 status = selector.set_buffer(&tmp_eap_type, sizeof(tmp_eap_type), false, false); |
|
4326 if (status != eap_status_ok) |
|
4327 { |
|
4328 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4329 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4330 } |
|
4331 |
|
4332 cancel_retransmission(); |
|
4333 |
|
4334 cancel_session_timeout(); |
|
4335 |
|
4336 cancel_eap_failure_timeout(); |
|
4337 |
|
4338 cancel_asynchronous_init_remove_eap_session(); |
|
4339 |
|
4340 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4341 |
|
4342 if (m_is_tunneled_eap == false |
|
4343 && m_is_client_role == true) |
|
4344 { |
|
4345 status = cancel_wait_eap_request_type_timeout(); |
|
4346 if (status != eap_status_ok) |
|
4347 { |
|
4348 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4349 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4350 } |
|
4351 |
|
4352 status = set_wait_eap_request_type_timeout(); |
|
4353 if (status != eap_status_ok) |
|
4354 { |
|
4355 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4356 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4357 } |
|
4358 } |
|
4359 |
|
4360 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4361 |
|
4362 m_eap_identity_response_accepted = false; |
|
4363 m_eap_type_response_sent = false; |
|
4364 |
|
4365 #if defined(USE_EAP_CORE_SERVER) |
|
4366 m_eap_identity_request_send = false; |
|
4367 m_eap_identity_response_received = false; |
|
4368 m_eap_failure_sent = false; |
|
4369 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
4370 |
|
4371 m_ignore_eap_failure = false; |
|
4372 |
|
4373 status = m_type_map.for_each(reset_operation, true); |
|
4374 if (status != eap_status_ok) |
|
4375 { |
|
4376 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4377 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4378 } |
|
4379 |
|
4380 m_current_eap_type = eap_type_none; |
|
4381 m_eap_identity.reset(); |
|
4382 |
|
4383 // Add session timeout. |
|
4384 initialize_session_timeout(m_session_timeout); |
|
4385 |
|
4386 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4387 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4388 } |
|
4389 |
|
4390 //-------------------------------------------------- |
|
4391 |
|
4392 // |
|
4393 EAP_FUNC_EXPORT eap_status_e eap_core_c::handle_eap_identity_request( |
|
4394 const eap_type_value_e used_eap_type, |
|
4395 const u8_t eap_identifier, |
|
4396 const eap_am_network_id_c * const receive_network_id) |
|
4397 { |
|
4398 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4399 |
|
4400 eap_status_e status = eap_status_process_general_error; |
|
4401 |
|
4402 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
4403 |
|
4404 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4405 |
|
4406 if (m_is_tunneled_eap == false |
|
4407 && m_is_client_role == true) |
|
4408 { |
|
4409 status = cancel_wait_eap_request_type_timeout(); |
|
4410 if (status != eap_status_ok) |
|
4411 { |
|
4412 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4413 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4414 } |
|
4415 } |
|
4416 |
|
4417 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
4418 |
|
4419 // Here we query the desired EAP-type. |
|
4420 eap_variable_data_c selector(m_am_tools); |
|
4421 u64_t tmp_used_eap_type = convert_eap_type_to_u64_t(used_eap_type); |
|
4422 status = selector.set_buffer(&tmp_used_eap_type, sizeof(tmp_used_eap_type), false, false); |
|
4423 if (status != eap_status_ok) |
|
4424 { |
|
4425 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4426 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4427 } |
|
4428 |
|
4429 eap_base_type_c *handler = m_type_map.get_handler(&selector); |
|
4430 |
|
4431 if (handler == 0 |
|
4432 || handler->get_is_valid() == false) |
|
4433 { |
|
4434 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4435 return EAP_STATUS_RETURN(m_am_tools, eap_status_type_does_not_exists_error); |
|
4436 } |
|
4437 |
|
4438 m_client_restart_authentication_initiated = false; |
|
4439 |
|
4440 // Here we swap the addresses. |
|
4441 eap_am_network_id_c send_network_id(m_am_tools, |
|
4442 receive_network_id->get_destination_id(), |
|
4443 receive_network_id->get_source_id(), |
|
4444 receive_network_id->get_type()); |
|
4445 |
|
4446 |
|
4447 // Send state change notification |
|
4448 eap_state_notification_c notification( |
|
4449 m_am_tools, |
|
4450 &send_network_id, |
|
4451 m_is_client, |
|
4452 eap_state_notification_eap, |
|
4453 eap_protocol_layer_eap, |
|
4454 m_current_eap_type, |
|
4455 eap_state_none, |
|
4456 eap_state_identity_request_received, |
|
4457 eap_identifier, |
|
4458 false); |
|
4459 state_notification(¬ification); |
|
4460 |
|
4461 // Save EAP-identifier |
|
4462 m_eap_identity_request_identifier_client = eap_identifier; |
|
4463 |
|
4464 status = handler->query_eap_identity( |
|
4465 false, |
|
4466 &m_eap_identity, |
|
4467 receive_network_id, |
|
4468 eap_identifier); |
|
4469 if (status == eap_status_drop_packet_quietly) |
|
4470 { |
|
4471 // This packet was dropped. |
|
4472 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4473 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4474 } |
|
4475 else if (status == eap_status_pending_request) |
|
4476 { |
|
4477 // This is pending query, that will be completed by complete_eap_identity_query() call. |
|
4478 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4479 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4480 } |
|
4481 else if (status == eap_status_completed_request) |
|
4482 { |
|
4483 // This is already completed by complete_eap_identity_query() call. |
|
4484 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4485 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
4486 } |
|
4487 else if (status != eap_status_ok) |
|
4488 { |
|
4489 // Send failure notification |
|
4490 eap_state_notification_c notification( |
|
4491 m_am_tools, |
|
4492 &send_network_id, |
|
4493 m_is_client, |
|
4494 eap_state_notification_eap, |
|
4495 eap_protocol_layer_eap, |
|
4496 m_current_eap_type, |
|
4497 eap_state_none, |
|
4498 eap_state_authentication_terminated_unsuccessfully, |
|
4499 eap_identifier, |
|
4500 false); |
|
4501 |
|
4502 notification.set_authentication_error(eap_status_authentication_failure); |
|
4503 |
|
4504 state_notification(¬ification); |
|
4505 |
|
4506 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4507 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4508 } |
|
4509 else // status == eap_status_ok |
|
4510 { |
|
4511 // The query_eap_identity() function call is synchronous. |
|
4512 // We must call send_eap_identity_response(). |
|
4513 |
|
4514 status = send_eap_identity_response( |
|
4515 &send_network_id, |
|
4516 &m_eap_identity, |
|
4517 m_eap_identity_request_identifier_client); // Uses the EAP-Identifier from the latest EAP-Request/Identity. |
|
4518 } |
|
4519 |
|
4520 |
|
4521 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4522 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4523 } |
|
4524 |
|
4525 //-------------------------------------------------- |
|
4526 |
|
4527 #if defined(USE_EAP_CORE_SERVER) |
|
4528 |
|
4529 // |
|
4530 EAP_FUNC_EXPORT eap_status_e eap_core_c::handle_eap_identity_response( |
|
4531 eap_base_type_c * const handler, |
|
4532 const eap_type_value_e used_eap_type, |
|
4533 const eap_am_network_id_c * const receive_network_id, |
|
4534 eap_header_wr_c * const eap, |
|
4535 const u32_t packet_length) |
|
4536 { |
|
4537 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4538 EAP_UNREFERENCED_PARAMETER(used_eap_type); |
|
4539 |
|
4540 eap_status_e status = eap_status_process_general_error; |
|
4541 |
|
4542 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
4543 |
|
4544 EAP_ASSERT(m_is_client == false); |
|
4545 |
|
4546 if (handler == 0) |
|
4547 { |
|
4548 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4549 return EAP_STATUS_RETURN(m_am_tools, eap_status_type_does_not_exists_error); |
|
4550 } |
|
4551 |
|
4552 status = handler->packet_process( |
|
4553 receive_network_id, |
|
4554 eap, |
|
4555 packet_length); |
|
4556 |
|
4557 if (status == eap_status_ok) |
|
4558 { |
|
4559 // We need to copy EAP-Identity for later use. |
|
4560 |
|
4561 const u8_t * identity = eap->get_type_data(eap->get_type_data_length()); |
|
4562 const u32_t identity_length = eap->get_type_data_length(); |
|
4563 const u8_t empty_identity[] = ""; |
|
4564 |
|
4565 if (identity == 0 |
|
4566 || identity_length == 0ul) |
|
4567 { |
|
4568 identity = empty_identity; |
|
4569 } |
|
4570 |
|
4571 status = m_eap_identity.set_copy_of_buffer( |
|
4572 identity, |
|
4573 identity_length); |
|
4574 } |
|
4575 |
|
4576 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4577 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4578 } |
|
4579 |
|
4580 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
4581 |
|
4582 //-------------------------------------------------- |
|
4583 |
|
4584 #if defined(USE_EAP_CORE_SERVER) |
|
4585 |
|
4586 // |
|
4587 EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_success( |
|
4588 const eap_am_network_id_c * const send_network_id, |
|
4589 const u8_t eap_identifier) |
|
4590 { |
|
4591 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4592 |
|
4593 eap_buf_chain_wr_c eap_success_packet( |
|
4594 eap_write_buffer, |
|
4595 m_am_tools, |
|
4596 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
4597 |
|
4598 if (eap_success_packet.get_is_valid() == false) |
|
4599 { |
|
4600 EAP_TRACE_ERROR( |
|
4601 m_am_tools, |
|
4602 TRACE_FLAGS_DEFAULT, |
|
4603 (EAPL("eap_core_c::send_eap_success(): packet buffer corrupted: %s, %s\n"), |
|
4604 (m_is_client == true) ? "client": "server", |
|
4605 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4606 )); |
|
4607 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4608 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4609 } |
|
4610 |
|
4611 EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); |
|
4612 u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
4613 |
|
4614 if (m_eap_header_offset+m_MTU < packet_buffer_free) |
|
4615 { |
|
4616 packet_buffer_free = m_eap_header_offset+m_MTU; |
|
4617 } |
|
4618 |
|
4619 eap_header_wr_c eap_response( |
|
4620 m_am_tools, |
|
4621 eap_success_packet.get_data_offset( |
|
4622 m_eap_header_offset, |
|
4623 (packet_buffer_free-m_eap_header_offset)), |
|
4624 (packet_buffer_free-m_eap_header_offset)); |
|
4625 |
|
4626 if (eap_response.get_is_valid() == false) |
|
4627 { |
|
4628 EAP_TRACE_ERROR( |
|
4629 m_am_tools, |
|
4630 TRACE_FLAGS_DEFAULT, |
|
4631 (EAPL("eap_core_c::send_eap_success(): %s, %s, packet buffer corrupted.\n"), |
|
4632 (m_is_client == true) ? "client": "server", |
|
4633 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4634 )); |
|
4635 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
4636 } |
|
4637 |
|
4638 eap_response.reset_header( |
|
4639 static_cast<u16_t>((packet_buffer_free-m_eap_header_offset)), |
|
4640 m_use_eap_expanded_type); |
|
4641 eap_response.set_length( |
|
4642 static_cast<u16_t>((eap_header_wr_c::get_header_length())), |
|
4643 m_use_eap_expanded_type); |
|
4644 eap_response.set_code(eap_code_success); |
|
4645 eap_response.set_identifier(eap_identifier); |
|
4646 |
|
4647 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4648 |
|
4649 eap_status_e status = eap_status_process_general_error; |
|
4650 |
|
4651 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4652 |
|
4653 eap_success_packet.set_data_length(m_eap_header_offset+eap_response.get_header_length()); |
|
4654 |
|
4655 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-success packet"), |
|
4656 eap_response.get_header_buffer(eap_response.get_length()), |
|
4657 eap_response.get_length())); |
|
4658 |
|
4659 status = packet_send( |
|
4660 send_network_id, |
|
4661 &eap_success_packet, |
|
4662 m_eap_header_offset, |
|
4663 eap_response.get_length(), |
|
4664 EAP_CORE_PACKET_BUFFER_LENGTH |
|
4665 ); |
|
4666 |
|
4667 if (status == eap_status_ok) |
|
4668 { |
|
4669 // After EAP-Success is sent no re-transmissions must occur. |
|
4670 cancel_retransmission(); |
|
4671 } |
|
4672 |
|
4673 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4674 |
|
4675 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4676 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4677 } |
|
4678 |
|
4679 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
4680 |
|
4681 //-------------------------------------------------- |
|
4682 |
|
4683 #if defined(USE_EAP_CORE_SERVER) |
|
4684 |
|
4685 // |
|
4686 EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_failure( |
|
4687 const eap_am_network_id_c * const send_network_id, |
|
4688 const u8_t eap_identifier) |
|
4689 { |
|
4690 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4691 |
|
4692 if (m_eap_failure_sent == true) |
|
4693 { |
|
4694 EAP_TRACE_ERROR( |
|
4695 m_am_tools, |
|
4696 TRACE_FLAGS_DEFAULT, |
|
4697 (EAPL("eap_core_c::send_eap_failure(): %s, %s, EAP-Failure already sent.\n"), |
|
4698 (m_is_client == true) ? "client": "server", |
|
4699 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4700 )); |
|
4701 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4702 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
4703 } |
|
4704 |
|
4705 eap_buf_chain_wr_c eap_failure_packet( |
|
4706 eap_write_buffer, |
|
4707 m_am_tools, |
|
4708 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
4709 |
|
4710 if (eap_failure_packet.get_is_valid() == false) |
|
4711 { |
|
4712 EAP_TRACE_ERROR( |
|
4713 m_am_tools, |
|
4714 TRACE_FLAGS_DEFAULT, |
|
4715 (EAPL("eap_core_c::send_eap_failure(): %s, %s, packet buffer corrupted.\n"), |
|
4716 (m_is_client == true) ? "client": "server", |
|
4717 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4718 )); |
|
4719 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4720 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4721 } |
|
4722 |
|
4723 EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); |
|
4724 u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
4725 |
|
4726 if (m_eap_header_offset+m_MTU < packet_buffer_free) |
|
4727 { |
|
4728 packet_buffer_free = m_eap_header_offset+m_MTU; |
|
4729 } |
|
4730 |
|
4731 eap_header_wr_c eap_response( |
|
4732 m_am_tools, |
|
4733 eap_failure_packet.get_data_offset( |
|
4734 m_eap_header_offset, |
|
4735 (packet_buffer_free-m_eap_header_offset)), |
|
4736 (packet_buffer_free-m_eap_header_offset)); |
|
4737 |
|
4738 if (eap_response.get_is_valid() == false) |
|
4739 { |
|
4740 EAP_TRACE_ERROR( |
|
4741 m_am_tools, |
|
4742 TRACE_FLAGS_DEFAULT, |
|
4743 (EAPL("eap_core_c::send_eap_failure(): %s, %s, packet buffer corrupted.\n"), |
|
4744 (m_is_client == true) ? "client": "server", |
|
4745 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4746 )); |
|
4747 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
4748 } |
|
4749 |
|
4750 eap_response.reset_header( |
|
4751 static_cast<u16_t>((packet_buffer_free-m_eap_header_offset)), |
|
4752 m_use_eap_expanded_type); |
|
4753 eap_response.set_length( |
|
4754 static_cast<u16_t>((eap_header_wr_c::get_header_length())), |
|
4755 m_use_eap_expanded_type); |
|
4756 eap_response.set_code(eap_code_failure); |
|
4757 eap_response.set_identifier(eap_identifier); |
|
4758 |
|
4759 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4760 |
|
4761 eap_status_e status = eap_status_process_general_error; |
|
4762 |
|
4763 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4764 |
|
4765 eap_failure_packet.set_data_length(m_eap_header_offset+eap_response.get_header_length()); |
|
4766 |
|
4767 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-failure packet"), |
|
4768 eap_response.get_header_buffer(eap_response.get_length()), |
|
4769 eap_response.get_length())); |
|
4770 |
|
4771 status = packet_send( |
|
4772 send_network_id, |
|
4773 &eap_failure_packet, |
|
4774 m_eap_header_offset, |
|
4775 eap_response.get_length(), |
|
4776 EAP_CORE_PACKET_BUFFER_LENGTH |
|
4777 ); |
|
4778 |
|
4779 if (status == eap_status_ok) |
|
4780 { |
|
4781 m_eap_failure_sent = true; |
|
4782 |
|
4783 // After EAP-Failure is sent no re-transmissions must occur. |
|
4784 cancel_retransmission(); |
|
4785 } |
|
4786 |
|
4787 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4788 |
|
4789 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4790 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4791 } |
|
4792 |
|
4793 #endif //#if defined(USE_EAP_CORE_SERVER) |
|
4794 |
|
4795 //-------------------------------------------------- |
|
4796 |
|
4797 // |
|
4798 EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_notification_response( |
|
4799 const eap_am_network_id_c * const send_network_id, |
|
4800 const u8_t eap_identifier) |
|
4801 { |
|
4802 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4803 |
|
4804 eap_buf_chain_wr_c eap_notification_packet( |
|
4805 eap_write_buffer, |
|
4806 m_am_tools, |
|
4807 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
4808 |
|
4809 if (eap_notification_packet.get_is_valid() == false) |
|
4810 { |
|
4811 EAP_TRACE_ERROR( |
|
4812 m_am_tools, |
|
4813 TRACE_FLAGS_DEFAULT, |
|
4814 (EAPL("eap_core_c::send_eap_notification_response(): ") |
|
4815 EAPL("%s, %s, packet buffer corrupted.\n"), |
|
4816 (m_is_client == true) ? "client": "server", |
|
4817 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4818 )); |
|
4819 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4820 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4821 } |
|
4822 |
|
4823 EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); |
|
4824 u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
4825 |
|
4826 if (m_eap_header_offset+m_MTU < packet_buffer_free) |
|
4827 { |
|
4828 packet_buffer_free = m_eap_header_offset+m_MTU; |
|
4829 } |
|
4830 |
|
4831 eap_header_wr_c eap_response( |
|
4832 m_am_tools, |
|
4833 eap_notification_packet.get_data_offset( |
|
4834 m_eap_header_offset, |
|
4835 (packet_buffer_free-m_eap_header_offset)), |
|
4836 (packet_buffer_free-m_eap_header_offset)); |
|
4837 |
|
4838 if (eap_response.get_is_valid() == false) |
|
4839 { |
|
4840 EAP_TRACE_ERROR( |
|
4841 m_am_tools, |
|
4842 TRACE_FLAGS_DEFAULT, |
|
4843 (EAPL("eap_core_c::send_eap_notification_response(): ") |
|
4844 EAPL("%s, %s, packet buffer corrupted.\n"), |
|
4845 (m_is_client == true) ? "client": "server", |
|
4846 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4847 )); |
|
4848 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
4849 } |
|
4850 |
|
4851 eap_response.reset_header( |
|
4852 static_cast<u16_t>((packet_buffer_free-m_eap_header_offset)), |
|
4853 m_use_eap_expanded_type); |
|
4854 eap_response.set_length( |
|
4855 static_cast<u16_t>((eap_header_base_c::get_header_length()+1u)), |
|
4856 m_use_eap_expanded_type); |
|
4857 eap_response.set_code(eap_code_response); |
|
4858 eap_response.set_identifier(eap_identifier); |
|
4859 eap_response.set_type(eap_type_notification, m_use_eap_expanded_type); |
|
4860 |
|
4861 |
|
4862 eap_status_e status = eap_status_process_general_error; |
|
4863 |
|
4864 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4865 |
|
4866 eap_notification_packet.set_data_length( |
|
4867 m_eap_header_offset+eap_response.get_header_length()+1u); |
|
4868 |
|
4869 EAP_TRACE_DATA_DEBUG( |
|
4870 m_am_tools, |
|
4871 TRACE_FLAGS_DEFAULT, |
|
4872 (EAPL(" send: EAP-Response/Notification packet"), |
|
4873 eap_response.get_header_buffer(eap_response.get_length()), |
|
4874 eap_response.get_length())); |
|
4875 |
|
4876 status = packet_send( |
|
4877 send_network_id, |
|
4878 &eap_notification_packet, |
|
4879 m_eap_header_offset, |
|
4880 eap_response.get_length(), |
|
4881 EAP_CORE_PACKET_BUFFER_LENGTH |
|
4882 ); |
|
4883 |
|
4884 if (status == eap_status_ok) |
|
4885 { |
|
4886 // After EAP-Notification is sent no re-transmissions must occur. |
|
4887 cancel_retransmission(); |
|
4888 } |
|
4889 |
|
4890 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4891 |
|
4892 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4893 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4894 } |
|
4895 |
|
4896 |
|
4897 //-------------------------------------------------- |
|
4898 |
|
4899 // |
|
4900 EAP_FUNC_EXPORT eap_status_e eap_core_c::create_eap_identity_response( |
|
4901 eap_buf_chain_wr_c * const response_packet, |
|
4902 const eap_variable_data_c * const identity, |
|
4903 const u8_t eap_identifier |
|
4904 ) |
|
4905 { |
|
4906 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4907 |
|
4908 if (identity == 0 |
|
4909 || identity->get_is_valid_data() == false) |
|
4910 { |
|
4911 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4912 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
4913 } |
|
4914 |
|
4915 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4916 |
|
4917 if (response_packet == 0 |
|
4918 || response_packet->get_is_valid() == false) |
|
4919 { |
|
4920 EAP_TRACE_ERROR( |
|
4921 m_am_tools, |
|
4922 TRACE_FLAGS_DEFAULT, |
|
4923 (EAPL("packet buffer corrupted: %s, %s\n"), |
|
4924 (m_is_client == true) ? "client": "server", |
|
4925 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4926 )); |
|
4927 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4928 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4929 } |
|
4930 |
|
4931 EAP_ASSERT_ALWAYS(EAP_CORE_PACKET_BUFFER_LENGTH >= (m_eap_header_offset+m_trailer_length)); |
|
4932 u32_t packet_buffer_free = EAP_CORE_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
4933 u32_t packet_buffer_offset = 0u; |
|
4934 |
|
4935 if (m_eap_header_offset+m_MTU < packet_buffer_free) |
|
4936 { |
|
4937 packet_buffer_free = m_eap_header_offset+m_MTU; |
|
4938 } |
|
4939 |
|
4940 eap_header_wr_c eap_response( |
|
4941 m_am_tools, |
|
4942 response_packet->get_data_offset( |
|
4943 m_eap_header_offset, |
|
4944 (EAP_CORE_PACKET_BUFFER_LENGTH-(m_eap_header_offset+m_trailer_length))), |
|
4945 EAP_CORE_PACKET_BUFFER_LENGTH-(m_eap_header_offset+m_trailer_length)); |
|
4946 |
|
4947 if (eap_response.get_is_valid() == false) |
|
4948 { |
|
4949 EAP_TRACE_ERROR( |
|
4950 m_am_tools, |
|
4951 TRACE_FLAGS_DEFAULT, |
|
4952 (EAPL("send_eap_identity_response: %s, %s, packet buffer corrupted.\n"), |
|
4953 (m_is_client == true) ? "client": "server", |
|
4954 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4955 )); |
|
4956 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
4957 } |
|
4958 |
|
4959 eap_response.reset_header( |
|
4960 static_cast<u16_t>((packet_buffer_free-m_eap_header_offset)), |
|
4961 m_use_eap_expanded_type); |
|
4962 |
|
4963 eap_response.set_length( |
|
4964 static_cast<u16_t>((packet_buffer_free-m_eap_header_offset)), |
|
4965 m_use_eap_expanded_type); |
|
4966 eap_response.set_code(eap_code_response); |
|
4967 eap_response.set_identifier(eap_identifier); |
|
4968 eap_response.set_type(eap_type_identity, m_use_eap_expanded_type); |
|
4969 |
|
4970 packet_buffer_offset += eap_response.get_header_length(); |
|
4971 |
|
4972 u8_t * const target_nai = eap_response.get_type_data( |
|
4973 identity->get_data_length()); |
|
4974 if (target_nai == 0) |
|
4975 { |
|
4976 EAP_TRACE_ERROR( |
|
4977 m_am_tools, |
|
4978 TRACE_FLAGS_DEFAULT, |
|
4979 (EAPL("send_eap_identity_response: %s, %s, too long EAP-Identity.\n"), |
|
4980 (m_is_client == true) ? "client": "server", |
|
4981 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
4982 )); |
|
4983 |
|
4984 EAP_TRACE_DATA_DEBUG( |
|
4985 m_am_tools, |
|
4986 TRACE_FLAGS_DEFAULT, |
|
4987 (EAPL("Identity"), |
|
4988 identity->get_data(identity->get_data_length()), |
|
4989 identity->get_data_length())); |
|
4990 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4991 } |
|
4992 |
|
4993 m_am_tools->memmove( |
|
4994 target_nai, |
|
4995 identity->get_data(identity->get_data_length()), |
|
4996 identity->get_data_length()); |
|
4997 |
|
4998 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
4999 |
|
5000 eap_response.set_type_data_length( |
|
5001 static_cast<u16_t>(identity->get_data_length()), |
|
5002 m_use_eap_expanded_type); |
|
5003 |
|
5004 response_packet->set_data_length(m_eap_header_offset+eap_response.get_length()); |
|
5005 |
|
5006 EAP_TRACE_DATA_DEBUG( |
|
5007 m_am_tools, |
|
5008 TRACE_FLAGS_DEFAULT, |
|
5009 (EAPL("send EAP-identity NAI"), |
|
5010 eap_response.get_type_data(eap_response.get_type_data_length()), |
|
5011 eap_response.get_type_data_length())); |
|
5012 |
|
5013 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5014 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5015 } |
|
5016 |
|
5017 //-------------------------------------------------- |
|
5018 |
|
5019 // |
|
5020 EAP_FUNC_EXPORT eap_status_e eap_core_c::send_eap_identity_response( |
|
5021 const eap_am_network_id_c * const send_network_id, |
|
5022 const eap_variable_data_c * const identity, |
|
5023 const u8_t eap_identifier |
|
5024 ) |
|
5025 { |
|
5026 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5027 |
|
5028 eap_status_e status = eap_status_process_general_error; |
|
5029 |
|
5030 if (send_network_id == 0 |
|
5031 || identity == 0) |
|
5032 { |
|
5033 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5034 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
5035 } |
|
5036 |
|
5037 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
5038 |
|
5039 eap_buf_chain_wr_c response_packet( |
|
5040 eap_write_buffer, |
|
5041 m_am_tools, |
|
5042 EAP_CORE_PACKET_BUFFER_LENGTH); |
|
5043 |
|
5044 if (response_packet.get_is_valid() == false) |
|
5045 { |
|
5046 EAP_TRACE_ERROR( |
|
5047 m_am_tools, |
|
5048 TRACE_FLAGS_DEFAULT, |
|
5049 (EAPL("packet buffer corrupted: %s, %s.\n"), |
|
5050 (m_is_client == true) ? "client": "server", |
|
5051 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
5052 )); |
|
5053 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5054 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5055 } |
|
5056 |
|
5057 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
5058 |
|
5059 // Get add possible NAI decoration and |
|
5060 // extra routing info to identity |
|
5061 |
|
5062 eap_variable_data_c local_identity(m_am_tools); |
|
5063 status = local_identity.set_copy_of_buffer(identity); |
|
5064 if (status != eap_status_ok) |
|
5065 { |
|
5066 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5067 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5068 } |
|
5069 |
|
5070 status = set_eap_identity_routing_info_and_nai_decoration(&local_identity); |
|
5071 if (status != eap_status_ok) |
|
5072 { |
|
5073 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5074 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5075 } |
|
5076 |
|
5077 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
5078 |
|
5079 status = create_eap_identity_response( |
|
5080 &response_packet, |
|
5081 &local_identity, |
|
5082 eap_identifier); |
|
5083 if (status != eap_status_ok) |
|
5084 { |
|
5085 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5086 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5087 } |
|
5088 |
|
5089 eap_header_wr_c eap_response( |
|
5090 m_am_tools, |
|
5091 response_packet.get_data_offset( |
|
5092 m_eap_header_offset, |
|
5093 (response_packet.get_buffer_length()-(m_eap_header_offset+m_trailer_length))), |
|
5094 response_packet.get_buffer_length()-(m_eap_header_offset+m_trailer_length)); |
|
5095 if (eap_response.get_is_valid() == false) |
|
5096 { |
|
5097 EAP_TRACE_ERROR( |
|
5098 m_am_tools, |
|
5099 TRACE_FLAGS_DEFAULT, |
|
5100 (EAPL("send_eap_identity_response: %s, %s, packet buffer corrupted.\n"), |
|
5101 (m_is_client == true) ? "client": "server", |
|
5102 (m_is_tunneled_eap == true) ? "tunneled": "outer most" |
|
5103 )); |
|
5104 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5105 } |
|
5106 |
|
5107 status = packet_send( |
|
5108 send_network_id, |
|
5109 &response_packet, |
|
5110 m_eap_header_offset, |
|
5111 eap_response.get_length(), |
|
5112 response_packet.get_buffer_length()); |
|
5113 if (status != eap_status_ok) |
|
5114 { |
|
5115 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5116 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5117 } |
|
5118 |
|
5119 |
|
5120 #if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
5121 |
|
5122 if (m_is_tunneled_eap == false |
|
5123 && m_is_client_role == true) |
|
5124 { |
|
5125 status = cancel_wait_eap_request_type_timeout(); |
|
5126 if (status != eap_status_ok) |
|
5127 { |
|
5128 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5129 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5130 } |
|
5131 |
|
5132 status = set_wait_eap_request_type_timeout(); |
|
5133 } |
|
5134 |
|
5135 #endif //#if defined(USE_EAP_CORE_WAIT_REQUEST_TYPE_TIMER) |
|
5136 |
|
5137 |
|
5138 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5139 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5140 } |
|
5141 |
|
5142 //-------------------------------------------------- |
|
5143 |
|
5144 // |
|
5145 eap_status_e eap_core_c::set_eap_identity_routing_info_and_nai_decoration( |
|
5146 eap_variable_data_c * const identity) |
|
5147 { |
|
5148 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5149 |
|
5150 if (identity == 0 |
|
5151 || identity->get_is_valid_data() == false) |
|
5152 { |
|
5153 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5154 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
5155 } |
|
5156 |
|
5157 bool routing_info_available(true); |
|
5158 bool nai_decoration_available(true); |
|
5159 |
|
5160 eap_status_e status(eap_status_process_general_error); |
|
5161 |
|
5162 // read routing info from AM |
|
5163 eap_variable_data_c routing_info(m_am_tools); |
|
5164 status = read_configure( |
|
5165 cf_str_EAP_outer_identity_routing.get_field(), |
|
5166 &routing_info); |
|
5167 if (status != eap_status_ok |
|
5168 || routing_info.get_is_valid_data() == false |
|
5169 || routing_info.get_data_length() == 0) |
|
5170 { |
|
5171 routing_info_available = false; |
|
5172 } |
|
5173 |
|
5174 // read NAI decoration from AM |
|
5175 eap_variable_data_c nai_decoration(m_am_tools); |
|
5176 status = read_configure( |
|
5177 cf_str_EAP_outer_identity_decoration.get_field(), |
|
5178 &nai_decoration); |
|
5179 if (status != eap_status_ok |
|
5180 || nai_decoration.get_is_valid_data() == false |
|
5181 || nai_decoration.get_data_length() == 0) |
|
5182 { |
|
5183 nai_decoration_available = false; |
|
5184 } |
|
5185 |
|
5186 // nothing to be added (which is ok) |
|
5187 if(routing_info_available == false |
|
5188 && nai_decoration_available == false) |
|
5189 { |
|
5190 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5191 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5192 } |
|
5193 |
|
5194 eap_variable_data_c username(m_am_tools); |
|
5195 eap_variable_data_c home_realm(m_am_tools); |
|
5196 |
|
5197 // get username and home realm from the current NAI |
|
5198 status = m_am_tools->parse_nai( |
|
5199 identity, |
|
5200 &username, |
|
5201 &home_realm); |
|
5202 if (status != eap_status_ok) |
|
5203 { |
|
5204 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5205 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5206 } |
|
5207 |
|
5208 // username must be present |
|
5209 if (username.get_is_valid_data() == false |
|
5210 /* || home_realm.get_is_valid_data() == false */) |
|
5211 { |
|
5212 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5213 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
5214 } |
|
5215 |
|
5216 // original NAI can be cleared, |
|
5217 // the new one is constructed to the same place |
|
5218 identity->reset(); |
|
5219 |
|
5220 // routing_info contains a string in format |
|
5221 // "RoutingRealm1!RoutingRealm2!RoutingRealm3" |
|
5222 // in which RoutingRealm3 is replaced with the home |
|
5223 // realm and RoutingRealm1 is appended after @-sign in NAI |
|
5224 if(routing_info_available == true) |
|
5225 { |
|
5226 // this points to the last byte of routing_info |
|
5227 const u8_t* const p_last = |
|
5228 routing_info.get_data() + |
|
5229 (routing_info.get_data_length() - 1); |
|
5230 |
|
5231 // first and last characters cannot be !-signs |
|
5232 if(*p_last == EAP_NAI_ROUTING_REALM_SEPARATOR[0] |
|
5233 || *(routing_info.get_data()) == EAP_NAI_ROUTING_REALM_SEPARATOR[0]) |
|
5234 { |
|
5235 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5236 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
5237 } |
|
5238 |
|
5239 // find first !-sign |
|
5240 const u8_t *separator = reinterpret_cast<const u8_t *>( |
|
5241 m_am_tools->memchr( |
|
5242 routing_info.get_data(), |
|
5243 EAP_NAI_ROUTING_REALM_SEPARATOR[0], |
|
5244 routing_info.get_data_length()) |
|
5245 ); |
|
5246 |
|
5247 // !-sign found, more than one realm present |
|
5248 // (the sign is not first or last character) |
|
5249 if (separator != 0) |
|
5250 { |
|
5251 // others except the first realm are put in front |
|
5252 status = identity->add_data( |
|
5253 separator + 1, |
|
5254 p_last - separator); |
|
5255 if (status != eap_status_ok) |
|
5256 { |
|
5257 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5258 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5259 } |
|
5260 |
|
5261 // add !-sign |
|
5262 status = identity->add_data(EAP_NAI_ROUTING_REALM_SEPARATOR, 1); |
|
5263 if (status != eap_status_ok) |
|
5264 { |
|
5265 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5266 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5267 } |
|
5268 |
|
5269 } |
|
5270 |
|
5271 // add home realm if it existed |
|
5272 if(home_realm.get_is_valid_data() == true) |
|
5273 { |
|
5274 status = identity->add_data( |
|
5275 home_realm.get_data(), |
|
5276 home_realm.get_data_length()); |
|
5277 if (status != eap_status_ok) |
|
5278 { |
|
5279 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5280 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5281 } |
|
5282 |
|
5283 // add !-sign |
|
5284 status = identity->add_data(EAP_NAI_ROUTING_REALM_SEPARATOR, 1); |
|
5285 if (status != eap_status_ok) |
|
5286 { |
|
5287 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5288 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5289 } |
|
5290 } |
|
5291 |
|
5292 // store the first realm of routing info here |
|
5293 home_realm.reset(); |
|
5294 |
|
5295 // more than one realm in routing info |
|
5296 if (separator != 0) |
|
5297 { |
|
5298 status = home_realm.add_data( |
|
5299 routing_info.get_data(), |
|
5300 separator - routing_info.get_data() |
|
5301 ); |
|
5302 } |
|
5303 // only one realm in routing info |
|
5304 else |
|
5305 { |
|
5306 status = home_realm.add_data( |
|
5307 routing_info.get_data(), |
|
5308 routing_info.get_data_length()); |
|
5309 } |
|
5310 |
|
5311 if (status != eap_status_ok) |
|
5312 { |
|
5313 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5314 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5315 } |
|
5316 } |
|
5317 |
|
5318 // nai_decoration contains a string which is placed |
|
5319 // in front of the username in NAI |
|
5320 if(nai_decoration_available == true) |
|
5321 { |
|
5322 status = identity->add_data(nai_decoration.get_data(), nai_decoration.get_data_length()); |
|
5323 if (status != eap_status_ok) |
|
5324 { |
|
5325 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5326 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5327 } |
|
5328 } |
|
5329 |
|
5330 status = identity->add_data(username.get_data(), username.get_data_length()); |
|
5331 if (status != eap_status_ok) |
|
5332 { |
|
5333 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5334 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5335 } |
|
5336 |
|
5337 // add realm if it exists |
|
5338 if (home_realm.get_is_valid_data() == true) { |
|
5339 // add @-sign |
|
5340 status = identity->add_data(EAP_NAI_AT_CHARACTER, 1); |
|
5341 if (status != eap_status_ok) |
|
5342 { |
|
5343 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5344 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5345 } |
|
5346 |
|
5347 status = identity->add_data(home_realm.get_data(), home_realm.get_data_length()); |
|
5348 } |
|
5349 |
|
5350 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5351 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5352 |
|
5353 } |
|
5354 |
|
5355 //-------------------------------------------------- |
|
5356 |
|
5357 // |
|
5358 EAP_FUNC_EXPORT eap_status_e eap_core_c::complete_eap_identity_query( |
|
5359 const eap_am_network_id_c * const send_network_id, |
|
5360 const eap_variable_data_c * const identity, |
|
5361 const u8_t /*eap_identifier*/) // Remove eap_identifier parameter. |
|
5362 { |
|
5363 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5364 eap_status_e status(eap_status_illegal_eap_identity); |
|
5365 |
|
5366 if (identity != 0) |
|
5367 { |
|
5368 status = m_eap_identity.set_copy_of_buffer(identity); |
|
5369 if (status != eap_status_ok) |
|
5370 { |
|
5371 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5372 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5373 } |
|
5374 |
|
5375 status = send_eap_identity_response( |
|
5376 send_network_id, |
|
5377 identity, |
|
5378 m_eap_identity_request_identifier_client); // Uses the EAP-Identifier from the latest EAP-Request/Identity. |
|
5379 } |
|
5380 |
|
5381 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5382 } |
|
5383 |
|
5384 //-------------------------------------------------- |
|
5385 |
|
5386 // |
|
5387 EAP_FUNC_EXPORT eap_status_e eap_core_c::get_saved_eap_identity( |
|
5388 eap_variable_data_c * const identity) |
|
5389 { |
|
5390 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5391 |
|
5392 eap_status_e status = eap_status_illegal_eap_identity; |
|
5393 |
|
5394 if (m_eap_identity.get_is_valid_data() == true) |
|
5395 { |
|
5396 status = identity->set_copy_of_buffer(&m_eap_identity); |
|
5397 } |
|
5398 else |
|
5399 { |
|
5400 EAP_TRACE_DEBUG( |
|
5401 m_am_tools, |
|
5402 TRACE_FLAGS_DEFAULT, |
|
5403 (EAPL("WARNING: %s, %s, EAP-identity is unknown: current EAP-type 0x%08x\n"), |
|
5404 (m_is_client == true) ? "client": "server", |
|
5405 (m_is_tunneled_eap == true) ? "tunneled": "outer most", |
|
5406 convert_eap_type_to_u32_t(m_current_eap_type))); |
|
5407 } |
|
5408 |
|
5409 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5410 return EAP_STATUS_RETURN_WARNING(m_am_tools, status); |
|
5411 } |
|
5412 |
|
5413 //-------------------------------------------------- |
|
5414 |
|
5415 // |
|
5416 EAP_FUNC_EXPORT eap_status_e eap_core_c::set_session_timeout( |
|
5417 const u32_t session_timeout_ms) |
|
5418 { |
|
5419 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5420 |
|
5421 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5422 |
|
5423 eap_status_e status = initialize_session_timeout(session_timeout_ms); |
|
5424 if (status != eap_status_ok) |
|
5425 { |
|
5426 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5427 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5428 } |
|
5429 |
|
5430 if (m_is_tunneled_eap == true) |
|
5431 { |
|
5432 status = m_partner->set_session_timeout(session_timeout_ms); |
|
5433 if (status != eap_status_ok) |
|
5434 { |
|
5435 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5436 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5437 } |
|
5438 } |
|
5439 |
|
5440 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5441 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5442 } |
|
5443 |
|
5444 //-------------------------------------------------- |
|
5445 |
|
5446 // |
|
5447 EAP_FUNC_EXPORT eap_status_e eap_core_c::set_timer( |
|
5448 abs_eap_base_timer_c * const p_initializer, |
|
5449 const u32_t p_id, |
|
5450 void * const p_data, |
|
5451 const u32_t p_time_ms) |
|
5452 { |
|
5453 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5454 |
|
5455 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5456 |
|
5457 const eap_status_e status = m_partner->set_timer( |
|
5458 p_initializer, |
|
5459 p_id, |
|
5460 p_data, |
|
5461 p_time_ms); |
|
5462 |
|
5463 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5464 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5465 } |
|
5466 |
|
5467 //-------------------------------------------------- |
|
5468 |
|
5469 // |
|
5470 EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_timer( |
|
5471 abs_eap_base_timer_c * const p_initializer, |
|
5472 const u32_t p_id) |
|
5473 { |
|
5474 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5475 |
|
5476 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5477 |
|
5478 const eap_status_e status = m_partner->cancel_timer( |
|
5479 p_initializer, |
|
5480 p_id); |
|
5481 |
|
5482 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5483 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5484 } |
|
5485 |
|
5486 //-------------------------------------------------- |
|
5487 |
|
5488 // |
|
5489 EAP_FUNC_EXPORT eap_status_e eap_core_c::cancel_all_timers() |
|
5490 { |
|
5491 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5492 |
|
5493 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
5494 |
|
5495 const eap_status_e status = m_partner->cancel_all_timers(); |
|
5496 |
|
5497 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5498 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5499 } |
|
5500 |
|
5501 //-------------------------------------------------- |
|
5502 |
|
5503 EAP_FUNC_EXPORT eap_status_e eap_core_c::set_authentication_role(const bool when_true_set_client) |
|
5504 { |
|
5505 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5506 |
|
5507 cancel_retransmission(); |
|
5508 |
|
5509 cancel_eap_failure_timeout(); |
|
5510 |
|
5511 m_is_client_role = when_true_set_client; |
|
5512 |
|
5513 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5514 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
5515 } |
|
5516 |
|
5517 //-------------------------------------------------- |
|
5518 |
|
5519 EAP_FUNC_EXPORT eap_status_e eap_core_c::add_rogue_ap( |
|
5520 eap_array_c<eap_rogue_ap_entry_c> & rogue_ap_list) |
|
5521 { |
|
5522 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5523 |
|
5524 const eap_status_e status = m_partner->add_rogue_ap(rogue_ap_list); |
|
5525 |
|
5526 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5527 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5528 } |
|
5529 |
|
5530 //-------------------------------------------------- |
|
5531 |
|
5532 EAP_FUNC_EXPORT bool eap_core_c::get_is_tunneled_eap() const |
|
5533 { |
|
5534 return m_is_tunneled_eap; |
|
5535 } |
|
5536 |
|
5537 //-------------------------------------------------- |
|
5538 //-------------------------------------------------- |
|
5539 |
|
5540 |
|
5541 |
|
5542 // End. |