static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; wpa_printf(MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed " "out"); wpas_clear_wps(wpa_s); }
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid, int p2p_group) { struct wpa_ssid *ssid; wpas_clear_wps(wpa_s); ssid = wpas_wps_add_network(wpa_s, 0, bssid); if (ssid == NULL) return -1; ssid->temporary = 1; ssid->p2p_group = p2p_group; #ifdef CONFIG_P2P if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) { ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1); if (ssid->ssid) { ssid->ssid_len = wpa_s->go_params->ssid_len; os_memcpy(ssid->ssid, wpa_s->go_params->ssid, ssid->ssid_len); wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP " "SSID", ssid->ssid, ssid->ssid_len); } } #endif /* CONFIG_P2P */ wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0); if (wpa_s->wps_fragment_size) ssid->eap.fragment_size = wpa_s->wps_fragment_size; eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); wpas_wps_reassoc(wpa_s, ssid, bssid); return 0; }
static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s, struct wps_event_fail *fail) { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d", fail->msg); wpas_clear_wps(wpa_s); wpas_notify_wps_event_fail(wpa_s, fail); }
static void wpa_supplicant_wps_event_fail(struct wpa_supplicant *wpa_s, struct wps_event_fail *fail) { if (fail->error_indication > 0 && fail->error_indication < NUM_WPS_EI_VALUES) { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)", fail->msg, fail->config_error, fail->error_indication, wps_event_fail_reason[fail->error_indication]); if (wpa_s->parent && wpa_s->parent != wpa_s) wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)", fail->msg, fail->config_error, fail->error_indication, wps_event_fail_reason[fail->error_indication]); } else { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL "msg=%d config_error=%d", fail->msg, fail->config_error); if (wpa_s->parent && wpa_s->parent != wpa_s) wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL "msg=%d config_error=%d", fail->msg, fail->config_error); } wpas_clear_wps(wpa_s); wpas_notify_wps_event_fail(wpa_s, fail); #ifdef CONFIG_P2P wpas_p2p_wps_failed(wpa_s, fail); #endif /* CONFIG_P2P */ }
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) { if (!wpa_s->wps_success && wpa_s->current_ssid && eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) { const u8 *bssid = wpa_s->bssid; if (is_zero_ether_addr(bssid)) bssid = wpa_s->pending_bssid; wpa_printf(MSG_DEBUG, "WPS: PIN registration with " MACSTR " did not succeed - continue trying to find " "suitable AP", MAC2STR(bssid)); wpa_blacklist_add(wpa_s, bssid); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, wpa_s->blacklist_cleared ? 5 : 0, 0); wpa_s->blacklist_cleared = 0; return 1; } eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && !wpa_s->wps_success) wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_FAIL); if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid && !(wpa_s->current_ssid->key_mgmt & WPA_KEY_MGMT_WPS)) { int disabled = wpa_s->current_ssid->disabled; wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - " "try to associate with the received credential"); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); if (disabled) { wpa_printf(MSG_DEBUG, "WPS: Current network is " "disabled - wait for user to enable"); return 1; } wpa_s->after_wps = 5; wpa_s->wps_freq = wpa_s->assoc_freq; wpa_s->normal_scans = 0; wpa_s->reassociate = 1; wpa_supplicant_req_scan(wpa_s, 0, 0); return 1; } if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS && wpa_s->current_ssid) { wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting " "for external credential processing"); wpas_clear_wps(wpa_s); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); return 1; } return 0; }
int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid) { struct wpa_ssid *ssid; wpas_clear_wps(wpa_s); ssid = wpas_wps_add_network(wpa_s, 0, bssid); if (ssid == NULL) return -1; wpa_config_set(ssid, "phase1", "\"pbc=1\"", 0); eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); wpas_wps_reassoc(wpa_s, ssid); return 0; }
/* Cancel the wps pbc/pin requests */ int wpas_wps_cancel(struct wpa_supplicant *wpa_s) { #ifdef CONFIG_AP if (wpa_s->ap_iface) { wpa_printf(MSG_DEBUG, "WPS: Cancelling in AP mode"); return wpa_supplicant_ap_wps_cancel(wpa_s); } #endif /* CONFIG_AP */ if (wpa_s->wpa_state == WPA_SCANNING) { wpa_printf(MSG_DEBUG, "WPS: Cancel operation - cancel scan"); wpa_supplicant_cancel_scan(wpa_s); wpas_clear_wps(wpa_s); } else if (wpa_s->wpa_state >= WPA_ASSOCIATED) { wpa_printf(MSG_DEBUG, "WPS: Cancel operation - " "deauthenticate"); wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); wpas_clear_wps(wpa_s); } return 0; }
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, char *path, char *method, char *name) { struct wps_context *wps = wpa_s->wps; struct oob_device_data *oob_dev; oob_dev = wps_get_oob_device(device_type); if (oob_dev == NULL) return -1; oob_dev->device_path = path; oob_dev->device_name = name; wps->oob_conf.oob_method = wps_get_oob_method(method); if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) { /* * Use pre-configured DH keys in order to be able to write the * key hash into the OOB file. */ wpabuf_free(wps->dh_pubkey); wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; wps->dh_pubkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &wps->dh_pubkey); wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192); if (wps->dh_ctx == NULL || wps->dh_pubkey == NULL) { wpa_printf(MSG_ERROR, "WPS: Failed to initialize " "Diffie-Hellman handshake"); return -1; } } if (wps->oob_conf.oob_method == OOB_METHOD_CRED) wpas_clear_wps(wpa_s); if (wps_process_oob(wps, oob_dev, 0) < 0) return -1; if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E || wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) && wpas_wps_start_pin(wpa_s, NULL, wpabuf_head(wps->oob_conf.dev_password), 0, DEV_PW_DEFAULT) < 0) return -1; return 0; }
int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin) { struct wpa_ssid *ssid; char val[30]; if (!pin) return -1; wpas_clear_wps(wpa_s); ssid = wpas_wps_add_network(wpa_s, 1, bssid); if (ssid == NULL) return -1; os_snprintf(val, sizeof(val), "\"pin=%s\"", pin); wpa_config_set(ssid, "phase1", val, 0); eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); wpas_wps_reassoc(wpa_s, ssid); return 0; }
int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin, struct wps_new_ap_settings *settings) { struct wpa_ssid *ssid; char val[200]; char *pos, *end; int res; if (!pin) return -1; wpas_clear_wps(wpa_s); ssid = wpas_wps_add_network(wpa_s, 1, bssid); if (ssid == NULL) return -1; ssid->temporary = 1; pos = val; end = pos + sizeof(val); res = os_snprintf(pos, end - pos, "\"pin=%s", pin); if (res < 0 || res >= end - pos) return -1; pos += res; if (settings) { res = os_snprintf(pos, end - pos, " new_ssid=%s new_auth=%s " "new_encr=%s new_key=%s", settings->ssid_hex, settings->auth, settings->encr, settings->key_hex); if (res < 0 || res >= end - pos) return -1; pos += res; } res = os_snprintf(pos, end - pos, "\""); if (res < 0 || res >= end - pos) return -1; wpa_config_set(ssid, "phase1", val, 0); if (wpa_s->wps_fragment_size) ssid->eap.fragment_size = wpa_s->wps_fragment_size; eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); wpas_wps_reassoc(wpa_s, ssid, bssid); return 0; }
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin, int p2p_group, u16 dev_pw_id) { struct wpa_ssid *ssid; char val[128]; unsigned int rpin = 0; wpas_clear_wps(wpa_s); ssid = wpas_wps_add_network(wpa_s, 0, bssid); if (ssid == NULL) return -1; ssid->temporary = 1; ssid->p2p_group = p2p_group; #ifdef CONFIG_P2P if (p2p_group && wpa_s->go_params && wpa_s->go_params->ssid_len) { ssid->ssid = os_zalloc(wpa_s->go_params->ssid_len + 1); if (ssid->ssid) { ssid->ssid_len = wpa_s->go_params->ssid_len; os_memcpy(ssid->ssid, wpa_s->go_params->ssid, ssid->ssid_len); wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP " "SSID", ssid->ssid, ssid->ssid_len); } } #endif /* CONFIG_P2P */ if (pin) os_snprintf(val, sizeof(val), "\"pin=%s dev_pw_id=%u\"", pin, dev_pw_id); else { rpin = wps_generate_pin(); os_snprintf(val, sizeof(val), "\"pin=%08d dev_pw_id=%u\"", rpin, dev_pw_id); } wpa_config_set(ssid, "phase1", val, 0); if (wpa_s->wps_fragment_size) ssid->eap.fragment_size = wpa_s->wps_fragment_size; eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); wpas_wps_reassoc(wpa_s, ssid, bssid); return rpin; }
int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin) { struct wpa_ssid *ssid; char val[128]; unsigned int rpin = 0; wpas_clear_wps(wpa_s); ssid = wpas_wps_add_network(wpa_s, 0, bssid); if (ssid == NULL) return -1; if (pin) os_snprintf(val, sizeof(val), "\"pin=%s\"", pin); else { rpin = wps_generate_pin(); os_snprintf(val, sizeof(val), "\"pin=%08d\"", rpin); } wpa_config_set(ssid, "phase1", val, 0); eloop_register_timeout(WPS_PBC_WALK_TIME, 0, wpas_wps_timeout, wpa_s, NULL); wpas_wps_reassoc(wpa_s, ssid); return rpin; }