Signed-off-by: Shivani Baranwal <quic_shivbara@xxxxxxxxxxx> --- src/p2p/p2p.c | 15 ++- src/p2p/p2p.h | 4 + src/p2p/p2p_i.h | 5 + wpa_supplicant/ctrl_iface.c | 5 +- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 2 +- wpa_supplicant/p2p_supplicant.c | 178 ++++++++++++++++++++++++---- wpa_supplicant/p2p_supplicant.h | 3 +- wpa_supplicant/wpa_supplicant_i.h | 3 + 8 files changed, 184 insertions(+), 31 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 702c90a..216abf4 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1881,6 +1881,12 @@ int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params) } +void p2p_set_auto_go(struct p2p_data *p2p) +{ + p2p->auto_go = 1; +} + + void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) { struct p2p_go_neg_results res; @@ -1987,8 +1993,13 @@ void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer) } #endif /* CONFIG_PASN */ - p2p_set_state(p2p, P2P_PROVISIONING); - p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); + if (p2p->auto_go && peer->p2p2) { + p2p->cfg->set_auto_go_pmk(p2p->cfg->cb_ctx, &res); + p2p->auto_go = 0; + } else { + p2p_set_state(p2p, P2P_PROVISIONING); + p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res); + } } diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 4759947..9962b69 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -973,6 +973,8 @@ struct p2p_config { */ void (*go_neg_completed)(void *ctx, struct p2p_go_neg_results *res); + void (*set_auto_go_pmk)(void *ctx, struct p2p_go_neg_results *res); + /** * sd_request - Callback on Service Discovery Request * @ctx: Callback context from cb_ctx @@ -2189,6 +2191,8 @@ size_t p2p_scan_ie_buf_len(struct p2p_data *p2p); */ int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params); +void p2p_set_auto_go(struct p2p_data *p2p); + /** * p2p_get_group_capab - Get Group Capability from P2P IE data * @p2p_ie: P2P IE(s) contents diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 7ff2c97..3e9119b 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -676,6 +676,11 @@ struct p2p_data { * invitation_resp - Invitation Response frame */ struct wpabuf *invitation_resp; + + /** + * Indicate that auto go is enabled for this device + */ + u8 auto_go; }; /** diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index daa8bef..d00cfda 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -7215,6 +7215,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) { int freq = 0, persistent = 0, group_id = -1; + bool p2p2 = false; bool allow_6ghz = false; int vht = wpa_s->conf->p2p_go_vht; int ht40 = wpa_s->conf->p2p_go_ht40 || vht; @@ -7251,6 +7252,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) persistent = 1; } else if (os_strcmp(token, "allow_6ghz") == 0) { allow_6ghz = true; + } else if (os_strcmp(token, "p2p2") == 0) { + p2p2 = true; } else if (os_strncmp(token, "go_bssid=", 9) == 0) { if (hwaddr_aton(token + 9, go_bssid_buf)) return -1; @@ -7302,7 +7305,7 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) go_bssid); return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht, - max_oper_chwidth, he, edmg, allow_6ghz); + max_oper_chwidth, he, edmg, allow_6ghz, p2p2); } diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index aad4c5b..1814b1d 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -489,7 +489,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, } } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, freq2, ht40, vht, max_oper_chwidth, he, edmg, - allow_6ghz)) + allow_6ghz, wpa_s->p2p2)) goto inv_args; out: diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 0befcdd..0aeb9c6 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -2623,6 +2623,63 @@ bool wpas_p2p_retry_limit_exceeded(struct wpa_supplicant *wpa_s) } +static void wpas_set_auto_go_pmk(void *ctx, struct p2p_go_neg_results *params) +{ + struct wpa_supplicant *wpa_s = ctx; + struct wpa_supplicant *ifs; + struct sta_info sta; + struct sae_data *sae; + struct hostapd_data *hapd; + struct hostapd_ssid *ssid = NULL; + + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { + if (ifs->current_ssid && + ifs->current_ssid->mode == WPAS_MODE_P2P_GO) + break; + } + + if (ifs && ifs->ap_iface && params->p2p2) { + + hapd = ifs->ap_iface->bss[0]; + hapd->conf->wps_state = 0; + ssid = &hapd->conf->ssid; + + if (params->akmp == WPA_KEY_MGMT_SAE) { + memset(&sta, 0, sizeof(struct sta_info)); + memcpy(sta.addr, params->peer_device_addr, ETH_ALEN); + sae = os_zalloc(sizeof(struct sae_data)); + if (!sae) { + wpa_printf(MSG_ERROR, "P2P: Mem alloc failed"); + return; + } + sta.sae = sae; + memcpy(sta.sae->pmkid, params->pmkid, PMKID_LEN); + wpa_printf(MSG_DEBUG, "P2P: Adding PMK for peer: " MACSTR + " by autonomous go", + MAC2STR(params->peer_device_addr)); + wpa_auth_pmksa_add_sae(hapd->wpa_auth, + params->peer_device_addr, + params->pmk, params->pmk_len, + params->pmkid, WPA_KEY_MGMT_SAE); + hostapd_add_pmkid(hapd, params->peer_device_addr, + params->pmk, params->pmk_len, + params->pmkid, WPA_KEY_MGMT_SAE); + memset(&sta, 0, sizeof(struct sta_info)); + os_free(sae); + } else if (params->akmp == WPA_KEY_MGMT_PASN) { + ssid->wpa_passphrase = os_strdup(params->password); + hapd->conf->sae_pwe = SAE_PWE_HASH_TO_ELEMENT; + hapd->conf->wpa_key_mgmt = WPA_KEY_MGMT_SAE; + ssid->pt = sae_derive_pt(hapd->conf->sae_groups, ssid->ssid, + ssid->ssid_len, + (const u8 *) ssid->wpa_passphrase, + os_strlen(ssid->wpa_passphrase), + NULL); + } + } +} + static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) { struct wpa_supplicant *wpa_s = ctx; @@ -4882,7 +4939,8 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, 0); } else if (response_done) { wpas_p2p_group_add(wpa_s, 1, freq, - 0, 0, 0, 0, 0, 0, false); + 0, 0, 0, 0, 0, 0, false, + wpa_s->p2p2); } if (passwd_id == DEV_PW_P2PS_DEFAULT) { @@ -5006,7 +5064,8 @@ static int wpas_prov_disc_resp_cb(void *ctx) NULL, NULL, 0); } else { wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0, - is_p2p_allow_6ghz(wpa_s->global->p2p)); + is_p2p_allow_6ghz(wpa_s->global->p2p), + wpa_s->p2p2); } return 1; @@ -5358,6 +5417,7 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s) p2p.send_action = wpas_send_action; p2p.send_action_done = wpas_send_action_done; p2p.go_neg_completed = wpas_go_neg_completed; + p2p.set_auto_go_pmk = wpas_set_auto_go_pmk; p2p.go_neg_req_rx = wpas_go_neg_req_rx; p2p.dev_found = wpas_dev_found; p2p.dev_lost = wpas_dev_lost; @@ -5831,7 +5891,7 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, if (scan_res) wpas_p2p_scan_res_handler(wpa_s, scan_res); - if (wpa_s->p2p_auto_pd) { + if (!wpa_s->p2p2 && wpa_s->p2p_auto_pd) { int join = wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr); if (join == 0 && @@ -5872,15 +5932,22 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, return; } - if (wpa_s->p2p_auto_join) { + if (wpa_s->p2p2 || wpa_s->p2p_auto_join) { int join = wpas_p2p_peer_go(wpa_s, wpa_s->pending_join_dev_addr); - if (join < 0) { - wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be " - "running a GO -> use GO Negotiation"); - wpa_msg_global(wpa_s->p2pdev, MSG_INFO, - P2P_EVENT_FALLBACK_TO_GO_NEG - "reason=peer-not-running-GO"); + if (wpa_s->p2p2 || join < 0) { + if (join < 0) { + wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be " + "running a GO -> use GO Negotiation"); + wpa_msg_global(wpa_s->p2pdev, MSG_INFO, + P2P_EVENT_FALLBACK_TO_GO_NEG + "reason=peer-not-running-GO"); + } + + if (wpa_s->p2p2) + wpa_printf(MSG_DEBUG, + "P2P2: Initiate Go Neg and provisioning " + "using PASN Authentication"); wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin, wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0, 0, 0, @@ -5897,7 +5964,8 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, NULL, 0, is_p2p_allow_6ghz(wpa_s->global->p2p), wpa_s->p2p2, wpa_s->p2p_bootstrap, - NULL); + wpa_s->pending_join_password_len ? + wpa_s->pending_join_password : NULL); return; } @@ -6051,7 +6119,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, { int ret; struct wpa_driver_scan_params params; - struct wpabuf *wps_ie, *ies; + struct wpabuf *wps_ie = NULL, *ies; size_t ielen; int freqs[2] = { 0, 0 }; unsigned int bands; @@ -6071,13 +6139,16 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, wpa_s->p2p_join_ssid_len = 0; } - wpa_s->wps->dev.p2p = 1; - wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev, - wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0, - NULL); - if (wps_ie == NULL) { - wpas_p2p_scan_res_join(wpa_s, NULL); - return; + if (!wpa_s->p2p2) { + wpa_s->wps->dev.p2p = 1; + wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, + &wpa_s->wps->dev, + wpa_s->wps->uuid, + WPS_REQ_ENROLLEE, 0, NULL); + if (!wps_ie) { + wpas_p2p_scan_res_join(wpa_s, NULL); + return; + } } if (!freq) { @@ -6099,14 +6170,21 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, } ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); - ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen); - if (ies == NULL) { + + if (wps_ie) + ielen += wpabuf_len(wps_ie); + + ies = wpabuf_alloc(ielen); + if (!ies) { wpabuf_free(wps_ie); wpas_p2p_scan_res_join(wpa_s, NULL); return; } - wpabuf_put_buf(ies, wps_ie); - wpabuf_free(wps_ie); + + if (wps_ie) { + wpabuf_put_buf(ies, wps_ie); + wpabuf_free(wps_ie); + } bands = wpas_get_bands(wpa_s, freqs); p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands); @@ -6216,7 +6294,16 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq, os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN); os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr, ETH_ALEN); + if (wpa_s->pending_join_password_len) { + res.akmp = WPA_KEY_MGMT_SAE; + res.password_len = wpa_s->pending_join_password_len; + os_memcpy(res.password, wpa_s->pending_join_password, + res.password_len); + } res.wps_method = wpa_s->pending_join_wps_method; + res.p2p2 = wpa_s->p2p2; + res.cipher = WPA_CIPHER_CCMP; + if (freq && ssid && ssid_len) { res.freq = freq; res.ssid_len = ssid_len; @@ -6251,7 +6338,10 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq, wpa_s->off_channel_freq = 0; wpa_s->roc_waiting_drv_freq = 0; } - wpas_start_wps_enrollee(group, &res); + if (res.p2p2) + wpas_start_gc(group, &res); + else + wpas_start_wps_enrollee(group, &res); /* * Allow a longer timeout for join-a-running-group than normal 15 @@ -6534,12 +6624,41 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, if (join || auto_join) { u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN]; + struct wpa_supplicant *ifs; if (auth) { wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to " "connect a running group from " MACSTR, MAC2STR(peer_addr)); os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); - return ret; + + if (!wpa_s->p2p2) + return ret; + + if (is_zero_ether_addr(wpa_s->pending_interface_addr)) { + wpa_printf(MSG_DEBUG, "P2P: Interface address Invalid"); + return -1; + } + + wpa_printf(MSG_DEBUG, "P2P: own interface address for " + "authorizing join " MACSTR, + MAC2STR(wpa_s->pending_interface_addr)); + + dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant, + radio_list) { + if (ifs->current_ssid == NULL || + ifs->current_ssid->mode != WPAS_MODE_P2P_GO) + continue; + + ssid = ifs->current_ssid; + } + p2p_set_auto_go(wpa_s->global->p2p); + return wpas_p2p_auth_go_neg(wpa_s, peer_addr, + wps_method, 15, + wpa_s->pending_interface_addr, + force_freq, + persistent_group, ssid, + pref_freq, bootstrap, + password); } os_memcpy(dev_addr, peer_addr, ETH_ALEN); if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr, @@ -6556,6 +6675,12 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->p2p_auto_started.usec); } wpa_s->user_initiated_pd = 1; + if (password) { + wpa_s->pending_join_password_len = os_strlen(password); + os_memcpy(wpa_s->pending_join_password, password, + os_strlen(password)); + wpa_s->pending_join_password[wpa_s->pending_join_password_len] = '\0'; + } if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method, auto_join, freq, group_ssid, group_ssid_len) < 0) @@ -7390,7 +7515,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, int freq, int vht_center_freq2, int ht40, int vht, int max_oper_chwidth, int he, int edmg, - bool allow_6ghz) + bool allow_6ghz, bool p2p2) { struct p2p_go_neg_results params; int selected_freq = 0; @@ -7402,6 +7527,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, os_free(wpa_s->global->add_psk); wpa_s->global->add_psk = NULL; + wpa_s->p2p2 = p2p2; /* Make sure we are not running find during connection establishment */ wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND"); diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 61d4281..1e5f77a 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -45,7 +45,8 @@ int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq, struct wpa_ssid *ssid); int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, int freq, int vht_center_freq2, int ht40, int vht, - int max_oper_chwidth, int he, int edmg, bool allow_6ghz); + int max_oper_chwidth, int he, int edmg, bool allow_6ghz, + bool p2p2); int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int addr_allocated, int force_freq, int neg_freq, diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 51da6ff..610072e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1115,6 +1115,9 @@ struct wpa_supplicant { u8 pending_join_dev_addr[ETH_ALEN]; u8 p2p_bootstrap_dev_addr[ETH_ALEN]; int pending_join_wps_method; + u16 pending_join_bootstrap; + char pending_join_password[100]; + size_t pending_join_password_len; u8 p2p_join_ssid[SSID_MAX_LEN]; size_t p2p_join_ssid_len; int p2p_join_scan_count; -- 2.7.4 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap