void hostapd_deinit_wps(struct hostapd_data *hapd) { if (hapd->wps == NULL) return; #ifdef CONFIG_WPS_UPNP hostapd_wps_upnp_deinit(hapd); #endif /* CONFIG_WPS_UPNP */ wps_registrar_deinit(hapd->wps->registrar); os_free(hapd->wps->network_key); wps_device_data_free(&hapd->wps->dev); wps_free_pending_msgs(hapd->wps->upnp_msgs); os_free(hapd->wps); hapd->wps = NULL; hostapd_wps_clear_ies(hapd); }
void hostapd_deinit_wps(struct hostapd_data *hapd) { eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL); eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL); if (hapd->wps == NULL) return; #ifdef CONFIG_WPS_UPNP hostapd_wps_upnp_deinit(hapd); #endif /* CONFIG_WPS_UPNP */ wps_registrar_deinit(hapd->wps->registrar); os_free(hapd->wps->network_key); wps_device_data_free(&hapd->wps->dev); wpabuf_free(hapd->wps->dh_pubkey); wpabuf_free(hapd->wps->dh_privkey); wps_free_pending_msgs(hapd->wps->upnp_msgs); hostapd_wps_nfc_clear(hapd->wps); os_free(hapd->wps); hapd->wps = NULL; hostapd_wps_clear_ies(hapd); }
int hostapd_init_wps(struct hostapd_data *hapd, struct hostapd_bss_config *conf) { struct wps_context *wps; struct wps_registrar_config cfg; if (conf->wps_state == 0) { hostapd_wps_clear_ies(hapd); return 0; } wps = os_zalloc(sizeof(*wps)); if (wps == NULL) return -1; wps->cred_cb = hostapd_wps_cred_cb; wps->event_cb = hostapd_wps_event_cb; wps->cb_ctx = hapd; os_memset(&cfg, 0, sizeof(cfg)); wps->wps_state = hapd->conf->wps_state; wps->ap_setup_locked = hapd->conf->ap_setup_locked; if (is_nil_uuid(hapd->conf->uuid)) { const u8 *uuid; uuid = get_own_uuid(hapd->iface); if (uuid) { os_memcpy(wps->uuid, uuid, UUID_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another " "interface", wps->uuid, UUID_LEN); } else { uuid_gen_mac_addr(hapd->own_addr, wps->uuid); wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC " "address", wps->uuid, UUID_LEN); } } else { os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Use configured UUID", wps->uuid, UUID_LEN); } wps->ssid_len = hapd->conf->ssid.ssid_len; os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len); wps->ap = 1; os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN); wps->dev.device_name = hapd->conf->device_name ? os_strdup(hapd->conf->device_name) : NULL; wps->dev.manufacturer = hapd->conf->manufacturer ? os_strdup(hapd->conf->manufacturer) : NULL; wps->dev.model_name = hapd->conf->model_name ? os_strdup(hapd->conf->model_name) : NULL; wps->dev.model_number = hapd->conf->model_number ? os_strdup(hapd->conf->model_number) : NULL; wps->dev.serial_number = hapd->conf->serial_number ? os_strdup(hapd->conf->serial_number) : NULL; wps->config_methods = wps_config_methods_str2bin(hapd->conf->config_methods); #ifdef CONFIG_WPS2 if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY | WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) { wpa_printf(MSG_INFO, "WPS: Converting display to " "virtual_display for WPS 2.0 compliance"); wps->config_methods |= WPS_CONFIG_VIRT_DISPLAY; } if ((wps->config_methods & (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) { wpa_printf(MSG_INFO, "WPS: Converting push_button to " "virtual_push_button for WPS 2.0 compliance"); wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON; } #endif /* CONFIG_WPS2 */ os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type, WPS_DEV_TYPE_LEN); if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) { os_free(wps); return -1; } wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); if (conf->wps_rf_bands) { wps->dev.rf_bands = conf->wps_rf_bands; } else { wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ } if (conf->wpa & WPA_PROTO_RSN) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPA2PSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA2; if (conf->rsn_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->rsn_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->wpa & WPA_PROTO_WPA) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPAPSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA; if (conf->wpa_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->wpa_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->ssid.security_policy == SECURITY_PLAINTEXT) { wps->encr_types |= WPS_ENCR_NONE; wps->auth_types |= WPS_AUTH_OPEN; } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) { wps->encr_types |= WPS_ENCR_WEP; if (conf->auth_algs & WPA_AUTH_ALG_OPEN) wps->auth_types |= WPS_AUTH_OPEN; if (conf->auth_algs & WPA_AUTH_ALG_SHARED) wps->auth_types |= WPS_AUTH_SHARED; } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) { wps->auth_types |= WPS_AUTH_OPEN; if (conf->default_wep_key_len) wps->encr_types |= WPS_ENCR_WEP; else wps->encr_types |= WPS_ENCR_NONE; } if (conf->ssid.wpa_psk_file) { /* Use per-device PSKs */ } else if (conf->ssid.wpa_passphrase) { wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); } else if (conf->ssid.wpa_psk) { wps->network_key = os_malloc(2 * PMK_LEN + 1); if (wps->network_key == NULL) { os_free(wps); return -1; } wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, conf->ssid.wpa_psk->psk, PMK_LEN); wps->network_key_len = 2 * PMK_LEN; } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { wps->network_key = os_malloc(conf->ssid.wep.len[0]); if (wps->network_key == NULL) { os_free(wps); return -1; } os_memcpy(wps->network_key, conf->ssid.wep.key[0], conf->ssid.wep.len[0]); wps->network_key_len = conf->ssid.wep.len[0]; } if (conf->ssid.wpa_psk) { os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN); wps->psk_set = 1; } if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) { /* Override parameters to enable security by default */ wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK; wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP; } wps->ap_settings = conf->ap_settings; wps->ap_settings_len = conf->ap_settings_len; cfg.new_psk_cb = hostapd_wps_new_psk_cb; cfg.set_ie_cb = hostapd_wps_set_ie_cb; cfg.pin_needed_cb = hostapd_wps_pin_needed_cb; cfg.reg_success_cb = hostapd_wps_reg_success_cb; cfg.enrollee_seen_cb = hostapd_wps_enrollee_seen_cb; cfg.cb_ctx = hapd; cfg.skip_cred_build = conf->skip_cred_build; cfg.extra_cred = conf->extra_cred; cfg.extra_cred_len = conf->extra_cred_len; cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) && conf->skip_cred_build; if (conf->ssid.security_policy == SECURITY_STATIC_WEP) cfg.static_wep_only = 1; cfg.dualband = interface_count(hapd->iface) > 1; if (cfg.dualband) wpa_printf(MSG_DEBUG, "WPS: Dualband AP"); wps->registrar = wps_registrar_init(wps, &cfg); if (wps->registrar == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar"); os_free(wps->network_key); os_free(wps); return -1; } #ifdef CONFIG_WPS_UPNP wps->friendly_name = hapd->conf->friendly_name; wps->manufacturer_url = hapd->conf->manufacturer_url; wps->model_description = hapd->conf->model_description; wps->model_url = hapd->conf->model_url; wps->upc = hapd->conf->upc; #endif /* CONFIG_WPS_UPNP */ hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd); hapd->wps = wps; return 0; }
int hostapd_init_wps(struct hostapd_data *hapd, struct hostapd_bss_config *conf) { struct wps_context *wps; struct wps_registrar_config cfg; if (conf->wps_state == 0) { hostapd_wps_clear_ies(hapd); return 0; } wps = os_zalloc(sizeof(*wps)); if (wps == NULL) return -1; wps->cred_cb = hostapd_wps_cred_cb; wps->event_cb = hostapd_wps_event_cb; wps->cb_ctx = hapd; os_memset(&cfg, 0, sizeof(cfg)); wps->wps_state = hapd->conf->wps_state; wps->ap_setup_locked = hapd->conf->ap_setup_locked; if (is_nil_uuid(hapd->conf->uuid)) { uuid_gen_mac_addr(hapd->own_addr, wps->uuid); wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC address", wps->uuid, UUID_LEN); } else os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN); wps->ssid_len = hapd->conf->ssid.ssid_len; os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len); wps->ap = 1; os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN); wps->dev.device_name = hapd->conf->device_name ? os_strdup(hapd->conf->device_name) : NULL; wps->dev.manufacturer = hapd->conf->manufacturer ? os_strdup(hapd->conf->manufacturer) : NULL; wps->dev.model_name = hapd->conf->model_name ? os_strdup(hapd->conf->model_name) : NULL; wps->dev.model_number = hapd->conf->model_number ? os_strdup(hapd->conf->model_number) : NULL; wps->dev.serial_number = hapd->conf->serial_number ? os_strdup(hapd->conf->serial_number) : NULL; if (hapd->conf->config_methods) { char *m = hapd->conf->config_methods; if (os_strstr(m, "label")) wps->config_methods |= WPS_CONFIG_LABEL; if (os_strstr(m, "display")) wps->config_methods |= WPS_CONFIG_DISPLAY; if (os_strstr(m, "push_button")) wps->config_methods |= WPS_CONFIG_PUSHBUTTON; if (os_strstr(m, "keypad")) wps->config_methods |= WPS_CONFIG_KEYPAD; } if (hapd->conf->device_type) { char *pos; u8 oui[4]; /* <categ>-<OUI>-<subcateg> */ wps->dev.categ = atoi(hapd->conf->device_type); pos = os_strchr(hapd->conf->device_type, '-'); if (pos == NULL) { wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); os_free(wps); return -1; } pos++; if (hexstr2bin(pos, oui, 4)) { wpa_printf(MSG_ERROR, "WPS: Invalid device_type OUI"); os_free(wps); return -1; } wps->dev.oui = WPA_GET_BE32(oui); pos = os_strchr(pos, '-'); if (pos == NULL) { wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); os_free(wps); return -1; } pos++; wps->dev.sub_categ = atoi(pos); } wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ if (conf->wpa & WPA_PROTO_RSN) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPA2PSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA2; if (conf->rsn_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->rsn_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->wpa & WPA_PROTO_WPA) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPAPSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA; if (conf->wpa_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->wpa_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->ssid.security_policy == SECURITY_PLAINTEXT) { wps->encr_types |= WPS_ENCR_NONE; wps->auth_types |= WPS_AUTH_OPEN; } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) { wps->encr_types |= WPS_ENCR_WEP; if (conf->auth_algs & WPA_AUTH_ALG_OPEN) wps->auth_types |= WPS_AUTH_OPEN; if (conf->auth_algs & WPA_AUTH_ALG_SHARED) wps->auth_types |= WPS_AUTH_SHARED; } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) { wps->auth_types |= WPS_AUTH_OPEN; if (conf->default_wep_key_len) wps->encr_types |= WPS_ENCR_WEP; else wps->encr_types |= WPS_ENCR_NONE; } if (conf->ssid.wpa_psk_file) { /* Use per-device PSKs */ } else if (conf->ssid.wpa_passphrase) { wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); } else if (conf->ssid.wpa_psk) { wps->network_key = os_malloc(2 * PMK_LEN + 1); if (wps->network_key == NULL) { os_free(wps); return -1; } wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, conf->ssid.wpa_psk->psk, PMK_LEN); wps->network_key_len = 2 * PMK_LEN; } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { wps->network_key = os_malloc(conf->ssid.wep.len[0]); if (wps->network_key == NULL) { os_free(wps); return -1; } os_memcpy(wps->network_key, conf->ssid.wep.key[0], conf->ssid.wep.len[0]); wps->network_key_len = conf->ssid.wep.len[0]; } if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) { /* Override parameters to enable security by default */ wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK; wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP; } wps->ap_settings = conf->ap_settings; wps->ap_settings_len = conf->ap_settings_len; cfg.new_psk_cb = hostapd_wps_new_psk_cb; cfg.set_ie_cb = hostapd_wps_set_ie_cb; cfg.pin_needed_cb = hostapd_wps_pin_needed_cb; cfg.reg_success_cb = hostapd_wps_reg_success_cb; cfg.cb_ctx = hapd; cfg.skip_cred_build = conf->skip_cred_build; cfg.extra_cred = conf->extra_cred; cfg.extra_cred_len = conf->extra_cred_len; cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) && conf->skip_cred_build; if (conf->ssid.security_policy == SECURITY_STATIC_WEP) cfg.static_wep_only = 1; wps->registrar = wps_registrar_init(wps, &cfg); if (wps->registrar == NULL) { printf("Failed to initialize WPS Registrar\n"); os_free(wps->network_key); os_free(wps); return -1; } #ifdef CONFIG_WPS_UPNP wps->friendly_name = hapd->conf->friendly_name; wps->manufacturer_url = hapd->conf->manufacturer_url; wps->model_description = hapd->conf->model_description; wps->model_url = hapd->conf->model_url; wps->upc = hapd->conf->upc; if (hostapd_wps_upnp_init(hapd, wps) < 0) { wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP"); wps_registrar_deinit(wps->registrar); os_free(wps->network_key); os_free(wps); return -1; } #endif /* CONFIG_WPS_UPNP */ hapd->wps = wps; return 0; }