static struct wpabuf * eap_fast_process_pac(struct eap_sm *sm, struct eap_fast_data *data, struct eap_method_ret *ret, u8 *pac, size_t pac_len) { struct eap_peer_config *config = eap_get_config(sm); struct eap_fast_pac entry; os_memset(&entry, 0, sizeof(entry)); if (eap_fast_process_pac_tlv(&entry, pac, pac_len) || eap_fast_process_pac_info(&entry)) return NULL; eap_fast_add_pac(&data->pac, &data->current_pac, &entry); eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len); if (data->use_pac_binary_format) eap_fast_save_pac_bin(sm, data->pac, config->pac_file); else eap_fast_save_pac(sm, data->pac, config->pac_file); if (data->provisioning) { if (data->anon_provisioning) { /* * Unauthenticated provisioning does not provide keying * material and must end with an EAP-Failure. * Authentication will be done separately after this. */ data->success = 0; ret->decision = DECISION_FAIL; } else { /* * Server may or may not allow authenticated * provisioning also for key generation. */ ret->decision = DECISION_COND_SUCC; } wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV " "- Provisioning completed successfully"); //add for eap-fast begin #ifdef MTK_EAP_FAST wpa_printf(MSG_DEBUG, "EAP-FAST: EAP_FAST_PAC_UPDATED to Android Framework"); wpa_msg(sm->msg_ctx, MSG_INFO, EAP_FAST_PAC_UPDATED); #endif //add for eap-fast end } else { /* * This is PAC refreshing, i.e., normal authentication that is * expected to be completed with an EAP-Success. However, * RFC 5422, Section 3.5 allows EAP-Failure to be sent even * after protected success exchange in case of EAP-Fast * provisioning, so we better use DECISION_COND_SUCC here * instead of DECISION_UNCOND_SUCC. */ wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV " "- PAC refreshing completed successfully"); ret->decision = DECISION_COND_SUCC; } ret->methodState = METHOD_DONE; return eap_fast_tlv_pac_ack(); }
static struct wpabuf * eap_fast_process_pac(struct eap_sm *sm, struct eap_fast_data *data, struct eap_method_ret *ret, u8 *pac, size_t pac_len) { struct eap_peer_config *config = eap_get_config(sm); struct eap_fast_pac entry; os_memset(&entry, 0, sizeof(entry)); if (eap_fast_process_pac_tlv(&entry, pac, pac_len) || eap_fast_process_pac_info(&entry)) return NULL; eap_fast_add_pac(&data->pac, &data->current_pac, &entry); eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len); if (data->use_pac_binary_format) eap_fast_save_pac_bin(sm, data->pac, config->pac_file); else eap_fast_save_pac(sm, data->pac, config->pac_file); if (data->provisioning) { if (data->anon_provisioning) { /* * Unauthenticated provisioning does not provide keying * material and must end with an EAP-Failure. * Authentication will be done separately after this. */ data->success = 0; ret->decision = DECISION_FAIL; } else { /* * Server may or may not allow authenticated * provisioning also for key generation. */ ret->decision = DECISION_COND_SUCC; } wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV " "- Provisioning completed successfully"); } else { /* * This is PAC refreshing, i.e., normal authentication that is * expected to be completed with an EAP-Success. */ wpa_printf(MSG_DEBUG, "EAP-FAST: Send PAC-Acknowledgement TLV " "- PAC refreshing completed successfully"); ret->decision = DECISION_UNCOND_SUCC; } ret->methodState = METHOD_DONE; return eap_fast_tlv_pac_ack(); }
static void * eap_fast_init(struct eap_sm *sm) { struct eap_fast_data *data; struct eap_peer_config *config = eap_get_config(sm); data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->fast_version = EAP_FAST_VERSION; data->max_pac_list_len = 10; if (config && config->phase1 && eap_fast_parse_phase1(data, config->phase1) < 0) { eap_fast_deinit(sm, data); return NULL; } if (eap_peer_select_phase2_methods(config, "auth=", &data->phase2_types, &data->num_phase2_types) < 0) { eap_fast_deinit(sm, data); return NULL; } data->phase2_type.vendor = EAP_VENDOR_IETF; data->phase2_type.method = EAP_TYPE_NONE; if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) { wpa_printf(MSG_INFO, "EAP-FAST: Failed to initialize SSL."); eap_fast_deinit(sm, data); return NULL; } if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn, eap_fast_session_ticket_cb, data) < 0) { wpa_printf(MSG_INFO, "EAP-FAST: Failed to set SessionTicket " "callback"); eap_fast_deinit(sm, data); return NULL; } /* * The local RADIUS server in a Cisco AP does not seem to like empty * fragments before data, so disable that workaround for CBC. * TODO: consider making this configurable */ if (tls_connection_enable_workaround(sm->ssl_ctx, data->ssl.conn)) { wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to enable TLS " "workarounds"); } if (data->use_pac_binary_format && eap_fast_load_pac_bin(sm, &data->pac, config->pac_file) < 0) { eap_fast_deinit(sm, data); return NULL; } if (!data->use_pac_binary_format && eap_fast_load_pac(sm, &data->pac, config->pac_file) < 0) { eap_fast_deinit(sm, data); return NULL; } eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len); if (data->pac == NULL && !data->provisioning_allowed) { wpa_printf(MSG_INFO, "EAP-FAST: No PAC configured and " "provisioning disabled"); eap_fast_deinit(sm, data); return NULL; } return data; }