X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=wpa_supplicant%2Fwps_supplicant.c;h=b9c22f9f58c9fff88fa225329430e94f3155e942;hb=545cc6af2593b3174ae7813d2fd658074ff44e23;hp=bb46adb17093c52dc0913ec107d2a6b51f1ae3ff;hpb=ad4741183f6f0d3c3ebdd979c3c5924561aa6e68;p=libeap.git diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index bb46adb..b9c22f9 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -32,6 +32,9 @@ #include "blacklist.h" #include "bss.h" #include "scan.h" +#include "ap.h" +#include "p2p/p2p.h" +#include "p2p_supplicant.h" #include "wps_supplicant.h" @@ -240,6 +243,8 @@ static int wpa_supplicant_wps_cred(void *ctx, ssid->eap.phase1 = NULL; os_free(ssid->eap.eap_methods); ssid->eap.eap_methods = NULL; + if (!ssid->p2p_group) + ssid->temporary = 0; } else { wpa_printf(MSG_DEBUG, "WPS: Create a new network based on the " "received credential"); @@ -386,7 +391,12 @@ static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s, 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); + 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); } @@ -397,6 +407,9 @@ static void wpa_supplicant_wps_event_success(struct wpa_supplicant *wpa_s) wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_SUCCESS); wpa_s->wps_success = 1; wpas_notify_wps_event_success(wpa_s); +#ifdef CONFIG_P2P + wpas_p2p_wps_success(wpa_s, wpa_s->bssid, 0); +#endif /* CONFIG_P2P */ } @@ -580,8 +593,8 @@ static void wpas_clear_wps(struct wpa_supplicant *wpa_s) 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"); + wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_TIMEOUT "Requested operation timed " + "out"); wpas_clear_wps(wpa_s); } @@ -596,6 +609,7 @@ static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s, return NULL; wpas_notify_network_added(wpa_s, ssid); wpa_config_set_network_defaults(ssid); + ssid->temporary = 1; if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 || wpa_config_set(ssid, "eap", "WSC", 0) < 0 || wpa_config_set(ssid, "identity", registrar ? @@ -607,12 +621,20 @@ static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s, } if (bssid) { +#ifndef CONFIG_P2P struct wpa_bss *bss; int count = 0; +#endif /* CONFIG_P2P */ os_memcpy(ssid->bssid, bssid, ETH_ALEN); ssid->bssid_set = 1; + /* + * Note: With P2P, the SSID may change at the time the WPS + * provisioning is started, so better not filter the AP based + * on the current SSID in the scan results. + */ +#ifndef CONFIG_P2P dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0) continue; @@ -636,6 +658,7 @@ static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s, ssid->ssid = NULL; ssid->ssid_len = 0; } +#endif /* CONFIG_P2P */ } return ssid; @@ -665,14 +688,31 @@ static void wpas_wps_reassoc(struct wpa_supplicant *wpa_s, } -int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid) +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); @@ -681,7 +721,7 @@ int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid) int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, - const char *pin) + const char *pin, int p2p_group, u16 dev_pw_id) { struct wpa_ssid *ssid; char val[128]; @@ -691,13 +731,31 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, 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\"", 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\"", rpin); + 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); @@ -705,6 +763,32 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, } +/* 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; +} + + #ifdef CONFIG_WPS_OOB int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, char *path, char *method, char *name) @@ -747,7 +831,8 @@ int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, 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) + wpabuf_head(wps->oob_conf.dev_password), 0, + DEV_PW_DEFAULT) < 0) return -1; return 0; @@ -769,6 +854,7 @@ int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, 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); @@ -788,6 +874,8 @@ int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid, 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); @@ -1035,7 +1123,7 @@ int wpas_wps_ssid_wildcard_ok(struct wpa_supplicant *wpa_s, #ifdef CONFIG_WPS_STRICT if (wps_ie) { if (wps_validate_beacon_probe_resp(wps_ie, bss->beacon_ie_len > - 0) < 0) + 0, bss->bssid) < 0) ret = 0; if (bss->beacon_ie_len) { struct wpabuf *bcn_wps; @@ -1071,12 +1159,21 @@ int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, if (!eap_is_wps_pbc_enrollee(&ssid->eap)) return 0; + wpa_printf(MSG_DEBUG, "WPS: Check whether PBC session overlap is " + "present in scan results; selected BSSID " MACSTR, + MAC2STR(selected->bssid)); + /* Make sure that only one AP is in active PBC mode */ wps_ie = wpa_bss_get_vendor_ie_multi(selected, WPS_IE_VENDOR_TYPE); - if (wps_ie) + if (wps_ie) { sel_uuid = wps_get_uuid_e(wps_ie); - else + wpa_hexdump(MSG_DEBUG, "WPS: UUID of the selected BSS", + sel_uuid, UUID_LEN); + } else { + wpa_printf(MSG_DEBUG, "WPS: Selected BSS does not include " + "WPS IE?!"); sel_uuid = NULL; + } dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { struct wpabuf *ie; @@ -1089,10 +1186,18 @@ int wpas_wps_scan_pbc_overlap(struct wpa_supplicant *wpa_s, wpabuf_free(ie); continue; } + wpa_printf(MSG_DEBUG, "WPS: Another BSS in active PBC mode: " + MACSTR, MAC2STR(bss->bssid)); uuid = wps_get_uuid_e(ie); + wpa_hexdump(MSG_DEBUG, "WPS: UUID of the other BSS", + uuid, UUID_LEN); if (sel_uuid == NULL || uuid == NULL || - os_memcmp(sel_uuid, uuid, 16) != 0) { + os_memcmp(sel_uuid, uuid, UUID_LEN) != 0) { ret = 1; /* PBC overlap */ + wpa_msg(wpa_s, MSG_INFO, "WPS: PBC overlap detected: " + MACSTR " and " MACSTR, + MAC2STR(selected->bssid), + MAC2STR(bss->bssid)); wpabuf_free(ie); break; } @@ -1316,3 +1421,54 @@ int wpas_wps_in_progress(struct wpa_supplicant *wpa_s) return 0; } + + +void wpas_wps_update_config(struct wpa_supplicant *wpa_s) +{ + struct wps_context *wps = wpa_s->wps; + + if (wps == NULL) + return; + + if (wpa_s->conf->changed_parameters & CFG_CHANGED_CONFIG_METHODS) { + wps->config_methods = wps_config_methods_str2bin( + wpa_s->conf->config_methods); + if ((wps->config_methods & + (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) == + (WPS_CONFIG_DISPLAY | WPS_CONFIG_LABEL)) { + wpa_printf(MSG_ERROR, "WPS: Both Label and Display " + "config methods are not allowed at the " + "same time"); + wps->config_methods &= ~WPS_CONFIG_LABEL; + } + } + + if (wpa_s->conf->changed_parameters & CFG_CHANGED_DEVICE_TYPE) { + if (wpa_s->conf->device_type && + wps_dev_type_str2bin(wpa_s->conf->device_type, + wps->dev.pri_dev_type) < 0) + wpa_printf(MSG_ERROR, "WPS: Invalid device_type"); + } + + if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION) + wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version); + + if (wpa_s->conf->changed_parameters & CFG_CHANGED_UUID) { + if (is_nil_uuid(wpa_s->conf->uuid)) { + uuid_gen_mac_addr(wpa_s->own_addr, wps->uuid); + wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC " + "address", wps->uuid, WPS_UUID_LEN); + } else + os_memcpy(wps->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); + } + + if (wpa_s->conf->changed_parameters & + (CFG_CHANGED_DEVICE_NAME | CFG_CHANGED_WPS_STRING)) { + /* Update pointers to make sure they refer current values */ + wps->dev.device_name = wpa_s->conf->device_name; + wps->dev.manufacturer = wpa_s->conf->manufacturer; + wps->dev.model_name = wpa_s->conf->model_name; + wps->dev.model_number = wpa_s->conf->model_number; + wps->dev.serial_number = wpa_s->conf->serial_number; + } +}