static int wpa_config_validate_network(struct wpa_ssid *ssid, int line) { int errors = 0; if (ssid->passphrase) { if (ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: both PSK and " "passphrase configured.", line); errors++; } wpa_config_update_psk(ssid); } if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set) { wpa_printf(MSG_ERROR, "Line %d: WPA-PSK accepted for key " "management, but no PSK configured.", line); errors++; } if ((ssid->group_cipher & WPA_CIPHER_CCMP) && !(ssid->pairwise_cipher & WPA_CIPHER_CCMP) && !(ssid->pairwise_cipher & WPA_CIPHER_NONE)) { /* Group cipher cannot be stronger than the pairwise cipher. */ wpa_printf(MSG_DEBUG, "Line %d: removed CCMP from group cipher" " list since it was not allowed for pairwise " "cipher", line); ssid->group_cipher &= ~WPA_CIPHER_CCMP; } return errors; }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, u16 reason_code) { const u8 *bssid; int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpas_connection_failed(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR " reason=%d", MAC2STR(bssid), reason_code); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } if (wpa_s->wpa_state == WPA_DISCONNECTED) { wpa_s->disconnect_count++; if (!eloop_is_timeout_registered(wpa_disconnect_spam_handle, wpa_s, NULL)) { eloop_register_timeout(6, 0, wpa_disconnect_spam_handle, wpa_s, NULL); wpa_printf(MSG_DEBUG, "%s: scheduled DISCONNECT spam handler", __FUNCTION__); } } wpa_supplicant_mark_disassoc(wpa_s); bgscan_deinit(wpa_s); wpa_s->bgscan_ssid = NULL; if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) sme_disassoc_while_authenticating(wpa_s, prev_pending_bssid); }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; #ifdef CONFIG_SME int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); #endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); bgscan_deinit(wpa_s); #ifdef CONFIG_SME if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)) { /* * mac80211-workaround to force deauth on failed auth cmd, * requires us to remain in authenticating state to allow the * second authentication attempt to be continued properly. */ wpa_printf(MSG_DEBUG, "SME: Allow pending authentication to " "proceed after disconnection event"); wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING); os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN); } #endif /* CONFIG_SME */ }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s, u16 reason_code) { const u8 *bssid; #ifdef CONFIG_SME int authenticating; u8 prev_pending_bssid[ETH_ALEN]; authenticating = wpa_s->wpa_state == WPA_AUTHENTICATING; os_memcpy(prev_pending_bssid, wpa_s->pending_bssid, ETH_ALEN); #endif /* CONFIG_SME */ if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } if (!wpa_s->auto_reconnect_disabled || wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) { wpa_printf(MSG_DEBUG, "WPA: Auto connect enabled: try to " "reconnect (wps=%d)", wpa_s->key_mgmt == WPA_KEY_MGMT_WPS); if (wpa_s->wpa_state >= WPA_ASSOCIATING) wpa_supplicant_req_scan(wpa_s, 0, 100000); } else { wpa_printf(MSG_DEBUG, "WPA: Auto connect disabled: do not try " "to re-connect"); wpa_s->reassociate = 0; wpa_s->disconnected = 1; } bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR " reason=%d", MAC2STR(bssid), reason_code); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_printf(MSG_DEBUG, "Disconnect event - remove keys"); wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
int wpa_config_write(const char *name, struct wpa_config *config) { #ifndef CONFIG_NO_CONFIG_WRITE FILE *f; struct wpa_ssid *ssid; struct wpa_cred *cred; #ifndef CONFIG_NO_CONFIG_BLOBS struct wpa_config_blob *blob; #endif /* CONFIG_NO_CONFIG_BLOBS */ int ret = 0; wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); f = fopen(name, "w"); if (f == NULL) { wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); return -1; } wpa_config_write_global(f, config); for (cred = config->cred; cred; cred = cred->next) { fprintf(f, "\ncred={\n"); wpa_config_write_cred(f, cred); fprintf(f, "}\n"); } for (ssid = config->ssid; ssid; ssid = ssid->next) { if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) continue; /* do not save temporary networks */ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && !ssid->passphrase) continue; /* do not save invalid network */ fprintf(f, "\nnetwork={\n"); wpa_config_write_network(f, ssid); fprintf(f, "}\n"); } #ifndef CONFIG_NO_CONFIG_BLOBS for (blob = config->blobs; blob; blob = blob->next) { ret = wpa_config_write_blob(f, blob); if (ret) break; } #endif /* CONFIG_NO_CONFIG_BLOBS */ fclose(f); wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", name, ret ? "un" : ""); return ret; #else /* CONFIG_NO_CONFIG_WRITE */ return -1; #endif /* CONFIG_NO_CONFIG_WRITE */ }
/** * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator * @ctx: Pointer to wpa_supplicant data (wpa_s) * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*) * @buf: EAPOL payload (after IEEE 802.1X header) * @len: EAPOL payload length * Returns: >=0 on success, <0 on failure * * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame * to the current Authenticator. */ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf, size_t len) { struct wpa_supplicant *wpa_s = ctx; u8 *msg, *dst, bssid[ETH_ALEN]; size_t msglen; int res; /* TODO: could add l2_packet_sendmsg that allows fragments to avoid * extra copy here */ if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { /* Current SSID is not using IEEE 802.1X/EAP, so drop possible * EAPOL frames (mainly, EAPOL-Start) from EAPOL state * machines. */ wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X " "mode (type=%d len=%lu)", type, (unsigned long) len); return -1; } if (is_zero_ether_addr(wpa_s->bssid)) { wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an " "EAPOL frame"); if (wpa_drv_get_bssid(wpa_s, bssid) == 0 && !is_zero_ether_addr(bssid)) { dst = bssid; wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR " from the driver as the EAPOL destination", MAC2STR(dst)); } else { dst = wpa_s->last_eapol_src; wpa_printf(MSG_DEBUG, "Using the source address of the" " last received EAPOL frame " MACSTR " as " "the EAPOL destination", MAC2STR(dst)); } } else { /* BSSID was already set (from (Re)Assoc event, so use it as * the EAPOL destination. */ dst = wpa_s->bssid; } msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL); if (msg == NULL) return -1; wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst)); wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen); res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen); os_free(msg); return res; }
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) { wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); wpa_s->ap_ies_from_associnfo = 0; }
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) { #if ICS_LEGACY_WLAN_SUPPORT if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) return; #endif wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); wpa_s->conf->ap_scan = DEFAULT_AP_SCAN; os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); wpa_s->ap_ies_from_associnfo = 0; }
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s) { int bssid_changed; wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); bssid_changed = !is_zero_ether_addr(wpa_s->bssid); os_memset(wpa_s->bssid, 0, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); wpa_s->current_bss = NULL; if (bssid_changed) wpas_notify_bssid_changed(wpa_s); eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); wpa_s->ap_ies_from_associnfo = 0; }
static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm, const u8 *addr, int secure) { wpa_msg(sm->ctx->msg_ctx, MSG_INFO, "WPA: Key negotiation completed with " MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr), wpa_cipher_txt(sm->pairwise_cipher), wpa_cipher_txt(sm->group_cipher)); wpa_sm_cancel_auth_timeout(sm); wpa_sm_set_state(sm, WPA_COMPLETED); if (secure) { wpa_sm_mlme_setprotection( sm, addr, MLME_SETPROTECTION_PROTECT_TYPE_RX_TX, MLME_SETPROTECTION_KEY_TYPE_PAIRWISE); eapol_sm_notify_portValid(sm->eapol, TRUE); if (wpa_key_mgmt_wpa_psk(sm->key_mgmt)) eapol_sm_notify_eap_success(sm->eapol, TRUE); /* * Start preauthentication after a short wait to avoid a * possible race condition between the data receive and key * configuration after the 4-Way Handshake. This increases the * likelyhood of the first preauth EAPOL-Start frame getting to * the target AP. */ eloop_register_timeout(1, 0, wpa_sm_start_preauth, sm, NULL); } if (sm->cur_pmksa && sm->cur_pmksa->opportunistic) { wpa_printf(MSG_DEBUG, "RSN: Authenticator accepted " "opportunistic PMKSA entry - marking it valid"); sm->cur_pmksa->opportunistic = 0; } #ifdef CONFIG_IEEE80211R if (wpa_key_mgmt_ft(sm->key_mgmt)) { /* Prepare for the next transition */ wpa_ft_prepare_auth_request(sm, NULL); } #endif /* CONFIG_IEEE80211R */ }
static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { u8 bssid[ETH_ALEN]; int ft_completed = wpa_ft_is_completed(wpa_s->wpa); if (data) wpa_supplicant_event_associnfo(wpa_s, data); wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); if (wpa_s->use_client_mlme) os_memcpy(bssid, wpa_s->bssid, ETH_ALEN); if (wpa_s->use_client_mlme || (wpa_drv_get_bssid(wpa_s, bssid) >= 0 && os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) { wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" MACSTR, MAC2STR(bssid)); os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) { wpa_clear_keys(wpa_s, bssid); } if (wpa_supplicant_select_config(wpa_s) < 0) { wpa_supplicant_disassociate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); return; } } wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid)); if (wpa_s->current_ssid) { /* When using scanning (ap_scan=1), SIM PC/SC interface can be * initialized before association, but for other modes, * initialize PC/SC here, if the current configuration needs * smartcard or SIM/USIM. */ wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid); } wpa_sm_notify_assoc(wpa_s->wpa, bssid); l2_packet_notify_auth_start(wpa_s->l2); /* * Set portEnabled first to FALSE in order to get EAP state machine out * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE * state machine may transit to AUTHENTICATING state based on obsolete * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to * AUTHENTICATED without ever giving chance to EAP state machine to * reset the state. */ if (!ft_completed) { eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); } if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed) eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); wpa_s->eapol_received = 0; if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); } else if (!ft_completed) { /* Timeout for receiving the first EAPOL packet */ wpa_supplicant_req_auth_timeout(wpa_s, 10, 0); } wpa_supplicant_cancel_scan(wpa_s); if (wpa_s->driver_4way_handshake && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { /* * We are done; the driver will take care of RSN 4-way * handshake. */ wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); eapol_sm_notify_portValid(wpa_s->eapol, TRUE); eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); } if (wpa_s->pending_eapol_rx) { struct os_time now, age; os_get_time(&now); os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age); if (age.sec == 0 && age.usec < 100000 && os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) == 0) { wpa_printf(MSG_DEBUG, "Process pending EAPOL frame " "that was received just before association " "notification"); wpa_supplicant_rx_eapol( wpa_s, wpa_s->pending_eapol_rx_src, wpabuf_head(wpa_s->pending_eapol_rx), wpabuf_len(wpa_s->pending_eapol_rx)); } wpabuf_free(wpa_s->pending_eapol_rx); wpa_s->pending_eapol_rx = NULL; } }
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s) { const u8 *bssid; if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { /* * At least Host AP driver and a Prism3 card seemed to be * generating streams of disconnected events when configuring * IBSS for WPA-None. Ignore them for now. */ wpa_printf(MSG_DEBUG, "Disconnect event - ignore in " "IBSS/WPA-None mode"); return; } if (wpa_s->wpa_state == WPA_4WAY_HANDSHAKE && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { wpa_msg(wpa_s, MSG_INFO, "WPA: 4-Way Handshake failed - " "pre-shared key may be incorrect"); } #ifdef CONFIG_WAPI_SUPPORT if (wpa_s->key_mgmt == WAPI_KEY_MGMT_CERT || wpa_s->key_mgmt == WAPI_KEY_MGMT_PSK) { MAC_ADDRESS bssid_s; MAC_ADDRESS own_s; wpa_printf(MSG_DEBUG,"[Debug-WAPI] Own MAC address "MACSTR" "MACSTR"!!", MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->own_addr)); memcpy(bssid_s.v, wpa_s->bssid, sizeof(bssid_s.v)); memcpy(own_s.v, wpa_s->own_addr, sizeof(own_s.v)); wpa_printf(MSG_DEBUG,"[Debug-WAPI ^_^!!] Ready send Disassociate complete evert to WAPI Modules!!!"); wapi_set_msg(CONN_DISASSOC, &bssid_s, &own_s, wpa_s->bss_wapi_ie , wpa_s->bss_wapi_ie_len); /*state changed, and trigger the next scanning to connect the another remembered AP*/ /*++ patch CR: [ALPS00125697] [WAPI Support] WLAN status always show "connected"*/ if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); #if 0 bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_printf(MSG_DEBUG,"[Debug-WAPI] Add "MACSTR "to blacklist!!", MAC2STR(wpa_s->bssid)); wpa_blacklist_add(wpa_s, bssid); #endif wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); wpa_supplicant_mark_disassoc(wpa_s); /*--*/ return; } #endif if (wpa_s->wpa_state >= WPA_ASSOCIATED) wpa_supplicant_req_scan(wpa_s, 0, 100000); bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_blacklist_add(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - " "remove keys"); if (wpa_supplicant_dynamic_keys(wpa_s)) { wpa_s->keys_cleared = 0; wpa_clear_keys(wpa_s, wpa_s->bssid); } wpa_supplicant_mark_disassoc(wpa_s); }
static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { u8 bssid[ETH_ALEN]; int ft_completed = wpa_ft_is_completed(wpa_s->wpa); if (data) wpa_supplicant_event_associnfo(wpa_s, data); #ifdef CONFIG_WAPI_SUPPORT if (wpa_s->key_mgmt == WAPI_KEY_MGMT_CERT || wpa_s->key_mgmt == WAPI_KEY_MGMT_PSK) { static int loop = 0; /* To avoiding state LOOP case, otherwise HAL will disable interface*/ /*[ALPS00127420][Wi-Fi] Can not auto-reconnect WAPI-PSK AP after power off--> power on WAPI AP*/ if((wpa_s->wpa_state == WPA_4WAY_HANDSHAKE || wpa_s->wpa_state == WPA_GROUP_HANDSHAKE) && (loop >= 1 && loop <= 20)){ /*dont set state*/ wpa_printf(MSG_INFO, "%s: [Loop = %d] dont set_state", __FUNCTION__, loop); loop++; }else{ wpa_printf(MSG_INFO, "%s: [Loop = %d] set_state", __FUNCTION__, loop); loop=1; wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); } } else { wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); } #else wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); #endif if (wpa_s->use_client_mlme) os_memcpy(bssid, wpa_s->bssid, ETH_ALEN); if (wpa_s->use_client_mlme || (wpa_drv_get_bssid(wpa_s, bssid) >= 0 && os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) { wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" MACSTR, MAC2STR(bssid)); os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) { wpa_clear_keys(wpa_s, bssid); } if (wpa_supplicant_select_config(wpa_s) < 0) { wpa_supplicant_disassociate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); return; } } wpa_msg(wpa_s, MSG_INFO, "associated with " MACSTR, MAC2STR(bssid)); #ifdef CONFIG_WAPI_SUPPORT if (wpa_s->key_mgmt == WAPI_KEY_MGMT_CERT || wpa_s->key_mgmt == WAPI_KEY_MGMT_PSK) { MAC_ADDRESS bssid_s; MAC_ADDRESS own_s; /* stop WPA and other time out use WAPI time only */ wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_printf(MSG_DEBUG,"[Debug-WAPI] AP MAC address "MACSTR" Own MAC address"MACSTR"!!", MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->own_addr)); if (is_zero_ether_addr(wpa_s->bssid)){ wpa_printf(MSG_DEBUG,"[Debug-WAPI] Not to set msg to WAPI SM\n"); /*Have been disassociated with the WAPI AP*/ return; } memcpy(bssid_s.v, wpa_s->bssid, sizeof(bssid_s.v)); memcpy(own_s.v, wpa_s->own_addr, sizeof(own_s.v)); wpa_printf(MSG_DEBUG,"[Debug-WAPI ^_^!!] Ready send associate complete evert to WAPI Modules!!!"); wapi_set_msg(CONN_ASSOC, &bssid_s, &own_s, wpa_s->bss_wapi_ie , wpa_s->bss_wapi_ie_len); return; } #endif if (wpa_s->current_ssid) { /* When using scanning (ap_scan=1), SIM PC/SC interface can be * initialized before association, but for other modes, * initialize PC/SC here, if the current configuration needs * smartcard or SIM/USIM. */ wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid); } wpa_sm_notify_assoc(wpa_s->wpa, bssid); l2_packet_notify_auth_start(wpa_s->l2); /* * Set portEnabled first to FALSE in order to get EAP state machine out * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE * state machine may transit to AUTHENTICATING state based on obsolete * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to * AUTHENTICATED without ever giving chance to EAP state machine to * reset the state. */ if (!ft_completed) { eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); } if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed) eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); wpa_s->eapol_received = 0; if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) { wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); } else if (!ft_completed) { /* Timeout for receiving the first EAPOL packet */ wpa_supplicant_req_auth_timeout(wpa_s, 10, 0); } wpa_supplicant_cancel_scan(wpa_s); if (wpa_s->driver_4way_handshake && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { /* * We are done; the driver will take care of RSN 4-way * handshake. */ wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); eapol_sm_notify_portValid(wpa_s->eapol, TRUE); eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); } if (wpa_s->pending_eapol_rx) { struct os_time now, age; os_get_time(&now); os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age); if (age.sec == 0 && age.usec < 100000 && os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) == 0) { wpa_printf(MSG_DEBUG, "Process pending EAPOL frame " "that was received just before association " "notification"); wpa_supplicant_rx_eapol( wpa_s, wpa_s->pending_eapol_rx_src, wpabuf_head(wpa_s->pending_eapol_rx), wpabuf_len(wpa_s->pending_eapol_rx)); } wpabuf_free(wpa_s->pending_eapol_rx); wpa_s->pending_eapol_rx = NULL; } }
/** * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator * @ctx: Pointer to wpa_supplicant data (wpa_s) * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*) * @buf: EAPOL payload (after IEEE 802.1X header) * @len: EAPOL payload length * Returns: >=0 on success, <0 on failure * * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame * to the current Authenticator. */ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf, size_t len) { struct wpa_supplicant *wpa_s = ctx; u8 *msg, *dst, bssid[ETH_ALEN]; size_t msglen; int res; /* TODO: could add l2_packet_sendmsg that allows fragments to avoid * extra copy here */ if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { /* Current SSID is not using IEEE 802.1X/EAP, so drop possible * EAPOL frames (mainly, EAPOL-Start) from EAPOL state * machines. */ wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X " "mode (type=%d len=%lu)", type, (unsigned long) len); return -1; } if (pmksa_cache_get_current(wpa_s->wpa) && type == IEEE802_1X_TYPE_EAPOL_START) { /* * We were trying to use PMKSA caching and sending EAPOL-Start * would abort that and trigger full EAPOL authentication. * However, we've already waited for the AP/Authenticator to * start 4-way handshake or EAP authentication, and apparently * it has not done so since the startWhen timer has reached zero * to get the state machine sending EAPOL-Start. This is not * really supposed to happen, but an interoperability issue with * a deployed AP has been identified where the connection fails * due to that AP failing to operate correctly if PMKID is * included in the Association Request frame. To work around * this, assume PMKSA caching failed and try to initiate full * EAP authentication. */ if (!wpa_s->current_ssid || wpa_s->current_ssid->eap_workaround) { wpa_printf(MSG_DEBUG, "RSN: Timeout on waiting for the AP to initiate 4-way handshake for PMKSA caching or EAP authentication - try to force it to start EAP authentication"); } else { wpa_printf(MSG_DEBUG, "RSN: PMKSA caching - do not send EAPOL-Start"); return -1; } } if (is_zero_ether_addr(wpa_s->bssid)) { wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an " "EAPOL frame"); if (wpa_drv_get_bssid(wpa_s, bssid) == 0 && !is_zero_ether_addr(bssid)) { dst = bssid; wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR " from the driver as the EAPOL destination", MAC2STR(dst)); } else { dst = wpa_s->last_eapol_src; wpa_printf(MSG_DEBUG, "Using the source address of the" " last received EAPOL frame " MACSTR " as " "the EAPOL destination", MAC2STR(dst)); } } else { /* BSSID was already set (from (Re)Assoc event, so use it as * the EAPOL destination. */ dst = wpa_s->bssid; } msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL); if (msg == NULL) return -1; wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst)); wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen); res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen); os_free(msg); return res; }
int wpa_config_write(const char *name, struct wpa_config *config) { #ifndef CONFIG_NO_CONFIG_WRITE FILE *f; struct wpa_ssid *ssid; #ifndef CONFIG_NO_CONFIG_BLOBS struct wpa_config_blob *blob; #endif /* CONFIG_NO_CONFIG_BLOBS */ int ret = 0; #define PERSISTENT_CONFIG_MAX 8 int persistent_num = 0; int persistent_skip_num = 0; wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); f = fopen(name, "w"); if (f == NULL) { wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); return -1; } #ifdef CONFIG_P2P /* Eddie remove the older psersistent profile */ if( strstr(name,"p2p_")) { wpa_printf(MSG_DEBUG, "p2p config writing"); for (ssid = config->ssid; ssid; ssid = ssid->next) { if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) { continue; /* do not save temporary networks */ } if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && !ssid->passphrase) { continue; /* do not save invalid network */ } persistent_num++; } if(persistent_num > PERSISTENT_CONFIG_MAX ) { persistent_skip_num = persistent_num - PERSISTENT_CONFIG_MAX; } wpa_printf(MSG_DEBUG, "p2p config skip number %d", persistent_skip_num); } #endif wpa_config_write_global(f, config); for (ssid = config->ssid; ssid; ssid = ssid->next) { if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) { continue; /* do not save temporary networks */ } if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && !ssid->passphrase) { continue; /* do not save invalid network */ } #ifdef CONFIG_P2P if( persistent_skip_num > 0 ) { persistent_skip_num--; wpa_printf(MSG_DEBUG, "Skip id %u ssid %s",ssid->id, ssid->ssid ); continue; } #endif fprintf(f, "\nnetwork={\n"); wpa_config_write_network(f, ssid); fprintf(f, "}\n"); } #ifndef CONFIG_NO_CONFIG_BLOBS for (blob = config->blobs; blob; blob = blob->next) { ret = wpa_config_write_blob(f, blob); if (ret) break; } #endif /* CONFIG_NO_CONFIG_BLOBS */ fclose(f); wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", name, ret ? "un" : ""); return ret; #else /* CONFIG_NO_CONFIG_WRITE */ return -1; #endif /* CONFIG_NO_CONFIG_WRITE */ }
int wpa_config_write(const char *name, struct wpa_config *config) { #ifndef CONFIG_NO_CONFIG_WRITE FILE *f; struct wpa_ssid *ssid; struct wpa_cred *cred; #ifndef CONFIG_NO_CONFIG_BLOBS struct wpa_config_blob *blob; #endif /* CONFIG_NO_CONFIG_BLOBS */ int ret = 0; const char *orig_name = name; int tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */ char *tmp_name = os_malloc(tmp_len); if (tmp_name) { os_snprintf(tmp_name, tmp_len, "%s.tmp", name); name = tmp_name; } wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); f = fopen(name, "w"); if (f == NULL) { wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); os_free(tmp_name); return -1; } wpa_config_write_global(f, config); for (cred = config->cred; cred; cred = cred->next) { if (cred->temporary) continue; fprintf(f, "\ncred={\n"); wpa_config_write_cred(f, cred); fprintf(f, "}\n"); } for (ssid = config->ssid; ssid; ssid = ssid->next) { if (ssid->key_mgmt == WPA_KEY_MGMT_WPS || ssid->temporary) continue; /* do not save temporary networks */ if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set && !ssid->passphrase) continue; /* do not save invalid network */ fprintf(f, "\nnetwork={\n"); wpa_config_write_network(f, ssid); fprintf(f, "}\n"); } #ifndef CONFIG_NO_CONFIG_BLOBS for (blob = config->blobs; blob; blob = blob->next) { ret = wpa_config_write_blob(f, blob); if (ret) break; } #endif /* CONFIG_NO_CONFIG_BLOBS */ os_fdatasync(f); fclose(f); if (tmp_name) { int chmod_ret = 0; #ifdef ANDROID chmod_ret = chmod(tmp_name, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); #endif /* ANDROID */ if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0) ret = -1; os_free(tmp_name); } wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", orig_name, ret ? "un" : ""); return ret; #else /* CONFIG_NO_CONFIG_WRITE */ return -1; #endif /* CONFIG_NO_CONFIG_WRITE */ }
static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { u8 bssid[ETH_ALEN]; int ft_completed; int bssid_changed; struct wpa_driver_capa capa; #ifdef CONFIG_AP if (wpa_s->ap_iface) { hostapd_notif_assoc(wpa_s->ap_iface->bss[0], data->assoc_info.addr, data->assoc_info.req_ies, data->assoc_info.req_ies_len); return; } #endif /* CONFIG_AP */ ft_completed = wpa_ft_is_completed(wpa_s->wpa); if (data && wpa_supplicant_event_associnfo(wpa_s, data) < 0) return; wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED); if (wpa_drv_get_bssid(wpa_s, bssid) >= 0 && os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) { wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID=" MACSTR, MAC2STR(bssid)); bssid_changed = os_memcmp(wpa_s->bssid, bssid, ETH_ALEN); os_memcpy(wpa_s->bssid, bssid, ETH_ALEN); os_memset(wpa_s->pending_bssid, 0, ETH_ALEN); if (bssid_changed) wpas_notify_bssid_changed(wpa_s); if (wpa_supplicant_dynamic_keys(wpa_s) && !ft_completed) { wpa_clear_keys(wpa_s, bssid); } if (wpa_supplicant_select_config(wpa_s) < 0) { wpa_supplicant_disassociate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); return; } if (wpa_s->current_ssid) { struct wpa_bss *bss = NULL; struct wpa_ssid *ssid = wpa_s->current_ssid; if (ssid->ssid_len > 0) bss = wpa_bss_get(wpa_s, bssid, ssid->ssid, ssid->ssid_len); if (!bss) bss = wpa_bss_get_bssid(wpa_s, bssid); if (bss) wpa_s->current_bss = bss; } } #ifdef CONFIG_SME os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN); wpa_s->sme.prev_bssid_set = 1; #endif /* CONFIG_SME */ wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid)); if (wpa_s->current_ssid) { /* When using scanning (ap_scan=1), SIM PC/SC interface can be * initialized before association, but for other modes, * initialize PC/SC here, if the current configuration needs * smartcard or SIM/USIM. */ wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid); } wpa_sm_notify_assoc(wpa_s->wpa, bssid); if (wpa_s->l2) l2_packet_notify_auth_start(wpa_s->l2); /* * Set portEnabled first to FALSE in order to get EAP state machine out * of the SUCCESS state and eapSuccess cleared. Without this, EAPOL PAE * state machine may transit to AUTHENTICATING state based on obsolete * eapSuccess and then trigger BE_AUTH to SUCCESS and PAE to * AUTHENTICATED without ever giving chance to EAP state machine to * reset the state. */ if (!ft_completed) { eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE); eapol_sm_notify_portValid(wpa_s->eapol, FALSE); } if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt) || ft_completed) eapol_sm_notify_eap_success(wpa_s->eapol, FALSE); /* 802.1X::portControl = Auto */ eapol_sm_notify_portEnabled(wpa_s->eapol, TRUE); wpa_s->eapol_received = 0; if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE || (wpa_s->current_ssid && wpa_s->current_ssid->mode == IEEE80211_MODE_IBSS)) { wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); } else if (!ft_completed) { /* Timeout for receiving the first EAPOL packet */ wpa_supplicant_req_auth_timeout(wpa_s, 10, 0); } wpa_supplicant_cancel_scan(wpa_s); if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE) && wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) { /* * We are done; the driver will take care of RSN 4-way * handshake. */ wpa_supplicant_cancel_auth_timeout(wpa_s); wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); eapol_sm_notify_portValid(wpa_s->eapol, TRUE); eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); } if (wpa_s->pending_eapol_rx) { struct os_time now, age; os_get_time(&now); os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age); if (age.sec == 0 && age.usec < 100000 && os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) == 0) { wpa_printf(MSG_DEBUG, "Process pending EAPOL frame " "that was received just before association " "notification"); wpa_supplicant_rx_eapol( wpa_s, wpa_s->pending_eapol_rx_src, wpabuf_head(wpa_s->pending_eapol_rx), wpabuf_len(wpa_s->pending_eapol_rx)); } wpabuf_free(wpa_s->pending_eapol_rx); wpa_s->pending_eapol_rx = NULL; } if ((wpa_s->key_mgmt == WPA_KEY_MGMT_NONE || wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) && wpa_s->current_ssid && wpa_drv_get_capa(wpa_s, &capa) == 0 && capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE) { /* Set static WEP keys again */ wpa_set_wep_keys(wpa_s, wpa_s->current_ssid); } }
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_config *conf) { struct hostapd_bss_config *bss = &conf->bss[0]; conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency, &conf->channel); if (conf->hw_mode == NUM_HOSTAPD_MODES) { wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", ssid->frequency); return -1; } /* TODO: enable HT40 if driver supports it; * drop to 11b if driver does not support 11g */ #ifdef CONFIG_IEEE80211N /* * Enable HT20 if the driver supports it, by setting conf->ieee80211n * and a mask of allowed capabilities within conf->ht_capab. * Using default config settings for: conf->ht_op_mode_fixed, * conf->secondary_channel, conf->require_ht */ if (wpa_s->hw.modes) { struct hostapd_hw_modes *mode = NULL; int i, no_ht = 0; for (i = 0; i < wpa_s->hw.num_modes; i++) { if (wpa_s->hw.modes[i].mode == conf->hw_mode) { mode = &wpa_s->hw.modes[i]; break; } } #ifdef CONFIG_HT_OVERRIDES if (ssid->disable_ht) { conf->ieee80211n = 0; conf->ht_capab = 0; no_ht = 1; } #endif /* CONFIG_HT_OVERRIDES */ if (!no_ht && mode && mode->ht_capab) { conf->ieee80211n = 1; #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && (mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) && ssid->ht40) conf->secondary_channel = wpas_p2p_get_ht40_mode(wpa_s, mode, conf->channel); if (conf->secondary_channel) conf->ht_capab |= HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET; #endif /* CONFIG_P2P */ /* * white-list capabilities that won't cause issues * to connecting stations, while leaving the current * capabilities intact (currently disabled SMPS). */ conf->ht_capab |= mode->ht_capab & (HT_CAP_INFO_GREEN_FIELD | HT_CAP_INFO_SHORT_GI20MHZ | HT_CAP_INFO_SHORT_GI40MHZ | HT_CAP_INFO_RX_STBC_MASK | HT_CAP_INFO_MAX_AMSDU_SIZE); } } #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G && (ssid->mode == WPAS_MODE_P2P_GO || ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) { /* Remove 802.11b rates from supported and basic rate sets */ int *list = os_malloc(4 * sizeof(int)); if (list) { list[0] = 60; list[1] = 120; list[2] = 240; list[3] = -1; } conf->basic_rates = list; list = os_malloc(9 * sizeof(int)); if (list) { list[0] = 60; list[1] = 90; list[2] = 120; list[3] = 180; list[4] = 240; list[5] = 360; list[6] = 480; list[7] = 540; list[8] = -1; } conf->supported_rates = list; } bss->isolate = !wpa_s->conf->p2p_intra_bss; bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk; #endif /* CONFIG_P2P */ if (ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); bss->ssid.ssid_len = ssid->ssid_len; bss->ssid.ssid_set = 1; bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid; if (ssid->auth_alg) bss->auth_algs = ssid->auth_alg; if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) bss->wpa = ssid->proto; bss->wpa_key_mgmt = ssid->key_mgmt; bss->wpa_pairwise = ssid->pairwise_cipher; if (ssid->psk_set) { os_free(bss->ssid.wpa_psk); bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (bss->ssid.wpa_psk == NULL) return -1; os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); bss->ssid.wpa_psk->group = 1; } else if (ssid->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] || ssid->wep_key_len[2] || ssid->wep_key_len[3]) { struct hostapd_wep_keys *wep = &bss->ssid.wep; int i; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i] == 0) continue; wep->key[i] = os_malloc(ssid->wep_key_len[i]); if (wep->key[i] == NULL) return -1; os_memcpy(wep->key[i], ssid->wep_key[i], ssid->wep_key_len[i]); wep->len[i] = ssid->wep_key_len[i]; } wep->idx = ssid->wep_tx_keyidx; wep->keys_set = 1; } if (ssid->ap_max_inactivity) bss->ap_max_inactivity = ssid->ap_max_inactivity; if (ssid->dtim_period) bss->dtim_period = ssid->dtim_period; else if (wpa_s->conf->dtim_period) bss->dtim_period = wpa_s->conf->dtim_period; if (ssid->beacon_int) conf->beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int) conf->beacon_int = wpa_s->conf->beacon_int; if ((bss->wpa & 2) && bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise, bss->rsn_pairwise); if (bss->wpa && bss->ieee802_1x) bss->ssid.security_policy = SECURITY_WPA; else if (bss->wpa) bss->ssid.security_policy = SECURITY_WPA_PSK; else if (bss->ieee802_1x) { int cipher = WPA_CIPHER_NONE; bss->ssid.security_policy = SECURITY_IEEE_802_1X; bss->ssid.wep.default_len = bss->default_wep_key_len; if (bss->default_wep_key_len) cipher = bss->default_wep_key_len >= 13 ? WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else if (bss->ssid.wep.keys_set) { int cipher = WPA_CIPHER_WEP40; if (bss->ssid.wep.len[0] >= 13) cipher = WPA_CIPHER_WEP104; bss->ssid.security_policy = SECURITY_STATIC_WEP; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else { bss->ssid.security_policy = SECURITY_PLAINTEXT; bss->wpa_group = WPA_CIPHER_NONE; bss->wpa_pairwise = WPA_CIPHER_NONE; bss->rsn_pairwise = WPA_CIPHER_NONE; } if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) && (bss->wpa_group == WPA_CIPHER_CCMP || bss->wpa_group == WPA_CIPHER_GCMP)) { /* * Strong ciphers do not need frequent rekeying, so increase * the default GTK rekeying period to 24 hours. */ bss->wpa_group_rekey = 86400; } #ifdef CONFIG_WPS /* * Enable WPS by default for open and WPA/WPA2-Personal network, but * require user interaction to actually use it. Only the internal * Registrar is supported. */ if (bss->ssid.security_policy != SECURITY_WPA_PSK && bss->ssid.security_policy != SECURITY_PLAINTEXT) goto no_wps; #ifdef CONFIG_WPS2 if (bss->ssid.security_policy == SECURITY_WPA_PSK && (!(bss->rsn_pairwise & WPA_CIPHER_CCMP) || !(bss->wpa & 2))) goto no_wps; /* WPS2 does not allow WPA/TKIP-only * configuration */ #endif /* CONFIG_WPS2 */ bss->eap_server = 1; if (!ssid->ignore_broadcast_ssid) bss->wps_state = 2; bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); os_memcpy(bss->device_type, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); } if (wpa_s->conf->manufacturer) bss->manufacturer = os_strdup(wpa_s->conf->manufacturer); if (wpa_s->conf->model_name) bss->model_name = os_strdup(wpa_s->conf->model_name); if (wpa_s->conf->model_number) bss->model_number = os_strdup(wpa_s->conf->model_number); if (wpa_s->conf->serial_number) bss->serial_number = os_strdup(wpa_s->conf->serial_number); if (is_nil_uuid(wpa_s->conf->uuid)) os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN); else os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); os_memcpy(bss->os_version, wpa_s->conf->os_version, 4); bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1; no_wps: #endif /* CONFIG_WPS */ if (wpa_s->max_stations && wpa_s->max_stations < wpa_s->conf->max_num_sta) bss->max_num_sta = wpa_s->max_stations; else bss->max_num_sta = wpa_s->conf->max_num_sta; bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; if (wpa_s->conf->ap_vendor_elements) { bss->vendor_elements = wpabuf_dup(wpa_s->conf->ap_vendor_elements); } return 0; }
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_config *conf) { struct hostapd_bss_config *bss = conf->bss[0]; conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf)) return -1; if (ssid->pbss > 1) { wpa_printf(MSG_ERROR, "Invalid pbss value(%d) for AP mode", ssid->pbss); return -1; } bss->pbss = ssid->pbss; #ifdef CONFIG_ACS if (ssid->acs) { /* Setting channel to 0 in order to enable ACS */ conf->channel = 0; wpa_printf(MSG_DEBUG, "Use automatic channel selection"); } #endif /* CONFIG_ACS */ if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) { conf->ieee80211h = 1; conf->ieee80211d = 1; conf->country[0] = wpa_s->conf->country[0]; conf->country[1] = wpa_s->conf->country[1]; } #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G && (ssid->mode == WPAS_MODE_P2P_GO || ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) { /* Remove 802.11b rates from supported and basic rate sets */ int *list = os_malloc(4 * sizeof(int)); if (list) { list[0] = 60; list[1] = 120; list[2] = 240; list[3] = -1; } conf->basic_rates = list; list = os_malloc(9 * sizeof(int)); if (list) { list[0] = 60; list[1] = 90; list[2] = 120; list[3] = 180; list[4] = 240; list[5] = 360; list[6] = 480; list[7] = 540; list[8] = -1; } conf->supported_rates = list; } bss->isolate = !wpa_s->conf->p2p_intra_bss; bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk; if (ssid->p2p_group) { os_memcpy(bss->ip_addr_go, wpa_s->p2pdev->conf->ip_addr_go, 4); os_memcpy(bss->ip_addr_mask, wpa_s->p2pdev->conf->ip_addr_mask, 4); os_memcpy(bss->ip_addr_start, wpa_s->p2pdev->conf->ip_addr_start, 4); os_memcpy(bss->ip_addr_end, wpa_s->p2pdev->conf->ip_addr_end, 4); } #endif /* CONFIG_P2P */ if (ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); bss->ssid.ssid_len = ssid->ssid_len; bss->ssid.ssid_set = 1; bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid; if (ssid->auth_alg) bss->auth_algs = ssid->auth_alg; if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) bss->wpa = ssid->proto; if (ssid->key_mgmt == DEFAULT_KEY_MGMT) bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK; else bss->wpa_key_mgmt = ssid->key_mgmt; bss->wpa_pairwise = ssid->pairwise_cipher; if (ssid->psk_set) { bin_clear_free(bss->ssid.wpa_psk, sizeof(*bss->ssid.wpa_psk)); bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (bss->ssid.wpa_psk == NULL) return -1; os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); bss->ssid.wpa_psk->group = 1; bss->ssid.wpa_psk_set = 1; } else if (ssid->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] || ssid->wep_key_len[2] || ssid->wep_key_len[3]) { struct hostapd_wep_keys *wep = &bss->ssid.wep; int i; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i] == 0) continue; wep->key[i] = os_malloc(ssid->wep_key_len[i]); if (wep->key[i] == NULL) return -1; os_memcpy(wep->key[i], ssid->wep_key[i], ssid->wep_key_len[i]); wep->len[i] = ssid->wep_key_len[i]; } wep->idx = ssid->wep_tx_keyidx; wep->keys_set = 1; } if (ssid->ap_max_inactivity) bss->ap_max_inactivity = ssid->ap_max_inactivity; if (ssid->dtim_period) bss->dtim_period = ssid->dtim_period; else if (wpa_s->conf->dtim_period) bss->dtim_period = wpa_s->conf->dtim_period; if (ssid->beacon_int) conf->beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int) conf->beacon_int = wpa_s->conf->beacon_int; #ifdef CONFIG_P2P if (ssid->mode == WPAS_MODE_P2P_GO || ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) { if (wpa_s->conf->p2p_go_ctwindow > conf->beacon_int) { wpa_printf(MSG_INFO, "CTWindow (%d) is bigger than beacon interval (%d) - avoid configuring it", wpa_s->conf->p2p_go_ctwindow, conf->beacon_int); conf->p2p_go_ctwindow = 0; } else { conf->p2p_go_ctwindow = wpa_s->conf->p2p_go_ctwindow; } } #endif /* CONFIG_P2P */ if ((bss->wpa & 2) && bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise, bss->rsn_pairwise); if (bss->wpa && bss->ieee802_1x) bss->ssid.security_policy = SECURITY_WPA; else if (bss->wpa) bss->ssid.security_policy = SECURITY_WPA_PSK; else if (bss->ieee802_1x) { int cipher = WPA_CIPHER_NONE; bss->ssid.security_policy = SECURITY_IEEE_802_1X; bss->ssid.wep.default_len = bss->default_wep_key_len; if (bss->default_wep_key_len) cipher = bss->default_wep_key_len >= 13 ? WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else if (bss->ssid.wep.keys_set) { int cipher = WPA_CIPHER_WEP40; if (bss->ssid.wep.len[0] >= 13) cipher = WPA_CIPHER_WEP104; bss->ssid.security_policy = SECURITY_STATIC_WEP; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else { bss->ssid.security_policy = SECURITY_PLAINTEXT; bss->wpa_group = WPA_CIPHER_NONE; bss->wpa_pairwise = WPA_CIPHER_NONE; bss->rsn_pairwise = WPA_CIPHER_NONE; } if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) && (bss->wpa_group == WPA_CIPHER_CCMP || bss->wpa_group == WPA_CIPHER_GCMP || bss->wpa_group == WPA_CIPHER_CCMP_256 || bss->wpa_group == WPA_CIPHER_GCMP_256)) { /* * Strong ciphers do not need frequent rekeying, so increase * the default GTK rekeying period to 24 hours. */ bss->wpa_group_rekey = 86400; } #ifdef CONFIG_IEEE80211W if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT) bss->ieee80211w = ssid->ieee80211w; #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_WPS /* * Enable WPS by default for open and WPA/WPA2-Personal network, but * require user interaction to actually use it. Only the internal * Registrar is supported. */ if (bss->ssid.security_policy != SECURITY_WPA_PSK && bss->ssid.security_policy != SECURITY_PLAINTEXT) goto no_wps; if (bss->ssid.security_policy == SECURITY_WPA_PSK && (!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) || !(bss->wpa & 2))) goto no_wps; /* WPS2 does not allow WPA/TKIP-only * configuration */ if (ssid->wps_disabled) goto no_wps; bss->eap_server = 1; if (!ssid->ignore_broadcast_ssid) bss->wps_state = 2; bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); os_memcpy(bss->device_type, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); } if (wpa_s->conf->manufacturer) bss->manufacturer = os_strdup(wpa_s->conf->manufacturer); if (wpa_s->conf->model_name) bss->model_name = os_strdup(wpa_s->conf->model_name); if (wpa_s->conf->model_number) bss->model_number = os_strdup(wpa_s->conf->model_number); if (wpa_s->conf->serial_number) bss->serial_number = os_strdup(wpa_s->conf->serial_number); if (is_nil_uuid(wpa_s->conf->uuid)) os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN); else os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); os_memcpy(bss->os_version, wpa_s->conf->os_version, 4); bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1; if (ssid->eap.fragment_size != DEFAULT_FRAGMENT_SIZE) bss->fragment_size = ssid->eap.fragment_size; no_wps: #endif /* CONFIG_WPS */ if (wpa_s->max_stations && wpa_s->max_stations < wpa_s->conf->max_num_sta) bss->max_num_sta = wpa_s->max_stations; else bss->max_num_sta = wpa_s->conf->max_num_sta; bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; if (wpa_s->conf->ap_vendor_elements) { bss->vendor_elements = wpabuf_dup(wpa_s->conf->ap_vendor_elements); } bss->ftm_responder = wpa_s->conf->ftm_responder; bss->ftm_initiator = wpa_s->conf->ftm_initiator; return 0; }
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_config *conf) { struct hostapd_bss_config *bss = &conf->bss[0]; int pairwise; conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); if (ssid->frequency == 0) { /* default channel 11 */ conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = 11; } else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) { conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = (ssid->frequency - 2407) / 5; } else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) || (ssid->frequency >= 5745 && ssid->frequency <= 5825)) { conf->hw_mode = HOSTAPD_MODE_IEEE80211A; conf->channel = (ssid->frequency - 5000) / 5; } else { wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", ssid->frequency); return -1; } /* TODO: enable HT40 if driver supports it; * drop to 11b if driver does not support 11g */ #ifdef CONFIG_IEEE80211N /* * Enable HT20 if the driver supports it, by setting conf->ieee80211n. * Using default config settings for: conf->ht_op_mode_fixed, * conf->ht_capab, conf->secondary_channel, conf->require_ht */ if (wpa_s->hw.modes) { struct hostapd_hw_modes *mode = NULL; int i; for (i = 0; i < wpa_s->hw.num_modes; i++) { if (wpa_s->hw.modes[i].mode == conf->hw_mode) { mode = &wpa_s->hw.modes[i]; break; } } if (mode && mode->ht_capab) conf->ieee80211n = 1; } #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) { /* Remove 802.11b rates from supported and basic rate sets */ int *list = os_malloc(4 * sizeof(int)); if (list) { list[0] = 60; list[1] = 120; list[2] = 240; list[3] = -1; } conf->basic_rates = list; list = os_malloc(9 * sizeof(int)); if (list) { list[0] = 60; list[1] = 90; list[2] = 120; list[3] = 180; list[4] = 240; list[5] = 360; list[6] = 480; list[7] = 540; list[8] = -1; } conf->supported_rates = list; } bss->isolate = !wpa_s->conf->p2p_intra_bss; #endif /* CONFIG_P2P */ if (ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); bss->ssid.ssid[ssid->ssid_len] = '\0'; bss->ssid.ssid_len = ssid->ssid_len; bss->ssid.ssid_set = 1; if (ssid->auth_alg) bss->auth_algs = ssid->auth_alg; if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) bss->wpa = ssid->proto; bss->wpa_key_mgmt = ssid->key_mgmt; bss->wpa_pairwise = ssid->pairwise_cipher; if (ssid->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } else if (ssid->psk_set) { os_free(bss->ssid.wpa_psk); bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (bss->ssid.wpa_psk == NULL) return -1; os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); bss->ssid.wpa_psk->group = 1; } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] || ssid->wep_key_len[2] || ssid->wep_key_len[3]) { struct hostapd_wep_keys *wep = &bss->ssid.wep; int i; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i] == 0) continue; wep->key[i] = os_malloc(ssid->wep_key_len[i]); if (wep->key[i] == NULL) return -1; os_memcpy(wep->key[i], ssid->wep_key[i], ssid->wep_key_len[i]); wep->len[i] = ssid->wep_key_len[i]; } wep->idx = ssid->wep_tx_keyidx; wep->keys_set = 1; } /* Select group cipher based on the enabled pairwise cipher suites */ pairwise = 0; if (bss->wpa & 1) pairwise |= bss->wpa_pairwise; if (bss->wpa & 2) { if (bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; pairwise |= bss->rsn_pairwise; } if (pairwise & WPA_CIPHER_TKIP) bss->wpa_group = WPA_CIPHER_TKIP; else bss->wpa_group = WPA_CIPHER_CCMP; if (bss->wpa && bss->ieee802_1x) bss->ssid.security_policy = SECURITY_WPA; else if (bss->wpa) bss->ssid.security_policy = SECURITY_WPA_PSK; else if (bss->ieee802_1x) { int cipher = WPA_CIPHER_NONE; bss->ssid.security_policy = SECURITY_IEEE_802_1X; bss->ssid.wep.default_len = bss->default_wep_key_len; if (bss->default_wep_key_len) cipher = bss->default_wep_key_len >= 13 ? WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else if (bss->ssid.wep.keys_set) { int cipher = WPA_CIPHER_WEP40; if (bss->ssid.wep.len[0] >= 13) cipher = WPA_CIPHER_WEP104; bss->ssid.security_policy = SECURITY_STATIC_WEP; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else { bss->ssid.security_policy = SECURITY_PLAINTEXT; bss->wpa_group = WPA_CIPHER_NONE; bss->wpa_pairwise = WPA_CIPHER_NONE; bss->rsn_pairwise = WPA_CIPHER_NONE; } #ifdef CONFIG_WPS /* * Enable WPS by default for open and WPA/WPA2-Personal network, but * require user interaction to actually use it. Only the internal * Registrar is supported. */ if (bss->ssid.security_policy != SECURITY_WPA_PSK && bss->ssid.security_policy != SECURITY_PLAINTEXT) goto no_wps; #ifdef CONFIG_WPS2 if (bss->ssid.security_policy == SECURITY_WPA_PSK && (!(pairwise & WPA_CIPHER_CCMP) || !(bss->wpa & 2))) goto no_wps; /* WPS2 does not allow WPA/TKIP-only * configuration */ #endif /* CONFIG_WPS2 */ bss->eap_server = 1; bss->wps_state = 2; bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); os_memcpy(bss->device_type, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); } if (wpa_s->conf->manufacturer) bss->manufacturer = os_strdup(wpa_s->conf->manufacturer); if (wpa_s->conf->model_name) bss->model_name = os_strdup(wpa_s->conf->model_name); if (wpa_s->conf->model_number) bss->model_number = os_strdup(wpa_s->conf->model_number); if (wpa_s->conf->serial_number) bss->serial_number = os_strdup(wpa_s->conf->serial_number); if (is_nil_uuid(wpa_s->conf->uuid)) os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN); else os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); os_memcpy(bss->os_version, wpa_s->conf->os_version, 4); no_wps: #endif /* CONFIG_WPS */ if (wpa_s->max_stations && wpa_s->max_stations < wpa_s->conf->max_num_sta) bss->max_num_sta = wpa_s->max_stations; else bss->max_num_sta = wpa_s->conf->max_num_sta; bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; return 0; }
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_config *conf) { struct hostapd_bss_config *bss = &conf->bss[0]; int pairwise; conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); if (ssid->frequency == 0) { /* default channel 11 */ conf->hw_mode = HOSTAPD_MODE_IEEE80211G; if(!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT)) conf->channel = 11; } else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) { conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = (ssid->frequency - 2407) / 5; } else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) || (ssid->frequency >= 5745 && ssid->frequency <= 5825)) { conf->hw_mode = HOSTAPD_MODE_IEEE80211A; conf->channel = (ssid->frequency - 5000) / 5; } else { wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", ssid->frequency); return -1; } /* TODO: enable HT if driver supports it; * drop to 11b if driver does not support 11g */ #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) { /* Remove 802.11b rates from supported and basic rate sets */ int *list = os_malloc(4 * sizeof(int)); if (list) { list[0] = 60; list[1] = 120; list[2] = 240; list[3] = -1; } conf->basic_rates = list; list = os_malloc(9 * sizeof(int)); if (list) { list[0] = 60; list[1] = 90; list[2] = 120; list[3] = 180; list[4] = 240; list[5] = 360; list[6] = 480; list[7] = 540; list[8] = -1; } conf->supported_rates = list; } #endif /* CONFIG_P2P */ if (ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); bss->ssid.ssid[ssid->ssid_len] = '\0'; bss->ssid.ssid_len = ssid->ssid_len; bss->ssid.ssid_set = 1; if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) bss->wpa = ssid->proto; bss->wpa_key_mgmt = ssid->key_mgmt; bss->wpa_pairwise = ssid->pairwise_cipher; if (ssid->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } else if (ssid->psk_set) { os_free(bss->ssid.wpa_psk); bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (bss->ssid.wpa_psk == NULL) return -1; os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); bss->ssid.wpa_psk->group = 1; } /* Select group cipher based on the enabled pairwise cipher suites */ pairwise = 0; if (bss->wpa & 1) pairwise |= bss->wpa_pairwise; if (bss->wpa & 2) { if (bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; pairwise |= bss->rsn_pairwise; } if (pairwise & WPA_CIPHER_TKIP) bss->wpa_group = WPA_CIPHER_TKIP; else bss->wpa_group = WPA_CIPHER_CCMP; if (bss->wpa && bss->ieee802_1x) bss->ssid.security_policy = SECURITY_WPA; else if (bss->wpa) bss->ssid.security_policy = SECURITY_WPA_PSK; else if (bss->ieee802_1x) { bss->ssid.security_policy = SECURITY_IEEE_802_1X; bss->ssid.wep.default_len = bss->default_wep_key_len; } else if (bss->ssid.wep.keys_set) bss->ssid.security_policy = SECURITY_STATIC_WEP; else bss->ssid.security_policy = SECURITY_PLAINTEXT; #ifdef CONFIG_WPS /* * Enable WPS by default, but require user interaction to actually use * it. Only the internal Registrar is supported. */ bss->eap_server = 1; bss->wps_state = 2; bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); os_memcpy(bss->device_type, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); } if (wpa_s->conf->manufacturer) bss->manufacturer = os_strdup(wpa_s->conf->manufacturer); if (wpa_s->conf->model_name) bss->model_name = os_strdup(wpa_s->conf->model_name); if (wpa_s->conf->model_number) bss->model_number = os_strdup(wpa_s->conf->model_number); if (wpa_s->conf->serial_number) bss->serial_number = os_strdup(wpa_s->conf->serial_number); if (is_nil_uuid(wpa_s->conf->uuid)) os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN); else os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); os_memcpy(bss->os_version, wpa_s->conf->os_version, 4); #endif /* CONFIG_WPS */ if (wpa_s->max_stations && wpa_s->max_stations < wpa_s->conf->p2p_max_clients) bss->max_num_sta = wpa_s->max_stations; else bss->max_num_sta = wpa_s->conf->p2p_max_clients; bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; return 0; }
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_config *conf) { struct hostapd_bss_config *bss = &conf->bss[0]; int pairwise; #ifdef CONFIG_IEEE80211N struct hostapd_hw_modes *modes; u16 num_modes, flags; #endif /* CONFIG_IEEE80211N */ conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); if (ssid->frequency == 0) { /* default channel 11 */ conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = 11; } else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) { conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = (ssid->frequency - 2407) / 5; } else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) || (ssid->frequency >= 5745 && ssid->frequency <= 5825)) { conf->hw_mode = HOSTAPD_MODE_IEEE80211A; conf->channel = (ssid->frequency - 5000) / 5; } else { wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", ssid->frequency); return -1; } /* TODO: enable HT40 if driver supports it; * drop to 11b if driver does not support 11g */ #ifdef CONFIG_IEEE80211N /* * Enable HT20 if the driver supports it, by setting conf->ieee80211n. * Using default config settings for: conf->ht_op_mode_fixed, * conf->ht_capab, conf->secondary_channel, conf->require_ht */ modes = wpa_drv_get_hw_feature_data(wpa_s, &num_modes, &flags); if (modes) { struct hostapd_hw_modes *mode = NULL; int i; for (i = 0; i < num_modes; i++) { if (modes[i].mode == conf->hw_mode) { mode = &modes[i]; break; } } if (mode && mode->ht_capab) conf->ieee80211n = 1; ieee80211_sta_free_hw_features(modes, num_modes); modes = NULL; } #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) { if (!wpa_s->fgHotspot/* P2P only, no tethering */) { /* Remove 802.11b rates from supported and basic rate sets */ int *list = os_malloc(4 * sizeof(int)); if (list) { list[0] = 60; list[1] = 120; list[2] = 240; list[3] = -1; } conf->basic_rates = list; list = os_malloc(9 * sizeof(int)); if (list) { list[0] = 60; list[1] = 90; list[2] = 120; list[3] = 180; list[4] = 240; list[5] = 360; list[6] = 480; list[7] = 540; list[8] = -1; } conf->supported_rates = list; } else { int *list = os_malloc(5 * sizeof(int)); if (list) { list[0] = 10; list[1] = 20; list[2] = 55; list[3] = 110; list[4] = -1; } conf->basic_rates = list; list = os_malloc(13 * sizeof(int)); if (list) { list[0] = 10; list[1] = 20; list[2] = 55; list[3] = 110; list[4] = 60; list[5] = 90; list[6] = 120; list[7] = 180; list[8] = 240; list[9] = 360; list[10] = 480; list[11] = 540; list[12] = -1; } conf->supported_rates = list; } } #endif /* CONFIG_P2P */ if (ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); bss->ssid.ssid[ssid->ssid_len] = '\0'; bss->ssid.ssid_len = ssid->ssid_len; bss->ssid.ssid_set = 1; if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) bss->wpa = ssid->proto; bss->wpa_key_mgmt = ssid->key_mgmt; bss->wpa_pairwise = ssid->pairwise_cipher; if (ssid->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } else if (ssid->psk_set) { os_free(bss->ssid.wpa_psk); bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (bss->ssid.wpa_psk == NULL) return -1; os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); bss->ssid.wpa_psk->group = 1; } /* Select group cipher based on the enabled pairwise cipher suites */ pairwise = 0; if (bss->wpa & 1) pairwise |= bss->wpa_pairwise; if (bss->wpa & 2) { if (bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; pairwise |= bss->rsn_pairwise; } if (pairwise & WPA_CIPHER_TKIP) bss->wpa_group = WPA_CIPHER_TKIP; else bss->wpa_group = WPA_CIPHER_CCMP; if (bss->wpa && bss->ieee802_1x) bss->ssid.security_policy = SECURITY_WPA; else if (bss->wpa) bss->ssid.security_policy = SECURITY_WPA_PSK; else if (bss->ieee802_1x) { bss->ssid.security_policy = SECURITY_IEEE_802_1X; bss->ssid.wep.default_len = bss->default_wep_key_len; } else if (bss->ssid.wep.keys_set) bss->ssid.security_policy = SECURITY_STATIC_WEP; else bss->ssid.security_policy = SECURITY_PLAINTEXT; if(bss->wpa_group == WPA_CIPHER_TKIP && wpa_s->fgHotspot) conf->ieee80211n = 0; else conf->ieee80211n = 1; #ifdef CONFIG_WPS /* * Enable WPS by default, but require user interaction to actually use * it. Only the internal Registrar is supported. */ bss->eap_server = 1; bss->wps_state = 2; bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); os_memcpy(bss->device_type, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); } if (wpa_s->conf->manufacturer) bss->manufacturer = os_strdup(wpa_s->conf->manufacturer); if (wpa_s->conf->model_name) bss->model_name = os_strdup(wpa_s->conf->model_name); if (wpa_s->conf->model_number) bss->model_number = os_strdup(wpa_s->conf->model_number); if (wpa_s->conf->serial_number) bss->serial_number = os_strdup(wpa_s->conf->serial_number); if (is_nil_uuid(wpa_s->conf->uuid)) os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN); else os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); os_memcpy(bss->os_version, wpa_s->conf->os_version, 4); #endif /* CONFIG_WPS */ if (wpa_s->max_stations && wpa_s->max_stations < wpa_s->conf->max_num_sta) bss->max_num_sta = wpa_s->max_stations; else bss->max_num_sta = wpa_s->conf->max_num_sta; bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; return 0; }