From 3c5126a41f9de5ae6d5666328b5046efc824d03a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 26 Jun 2010 22:49:41 -0700 Subject: [PATCH] P2P: Set Device Password ID in WPS M1/M2 per new rules If the P2P client (WPS Enrollee) uses a PIN from the GO (Registrar), Device Password ID in M1 & M2 is set to Registrar-specified. --- src/eap_peer/eap_wsc.c | 4 ++++ src/wps/wps.c | 2 +- src/wps/wps.h | 5 +++++ wpa_supplicant/ctrl_iface.c | 5 +++-- wpa_supplicant/dbus/dbus_new_handlers_wps.c | 3 ++- wpa_supplicant/dbus/dbus_old_handlers_wps.c | 6 ++++-- wpa_supplicant/p2p_supplicant.c | 18 ++++++++++++++---- wpa_supplicant/wpa_supplicant_i.h | 1 + wpa_supplicant/wps_supplicant.c | 8 +++++--- wpa_supplicant/wps_supplicant.h | 2 +- 10 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/eap_peer/eap_wsc.c b/src/eap_peer/eap_wsc.c index 00eab6354..09d8a1c8a 100644 --- a/src/eap_peer/eap_wsc.c +++ b/src/eap_peer/eap_wsc.c @@ -203,6 +203,10 @@ static void * eap_wsc_init(struct eap_sm *sm) return NULL; } + pos = os_strstr(phase1, "dev_pw_id="); + if (pos && cfg.pin) + cfg.dev_pw_id = atoi(pos + 10); + res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); diff --git a/src/wps/wps.c b/src/wps/wps.c index 3b6bf193e..2a25c6a50 100644 --- a/src/wps/wps.c +++ b/src/wps/wps.c @@ -46,7 +46,7 @@ struct wps_data * wps_init(const struct wps_config *cfg) } if (cfg->pin) { data->dev_pw_id = data->wps->oob_dev_pw_id == 0 ? - DEV_PW_DEFAULT : data->wps->oob_dev_pw_id; + cfg->dev_pw_id : data->wps->oob_dev_pw_id; data->dev_password = os_malloc(cfg->pin_len); if (data->dev_password == NULL) { os_free(data); diff --git a/src/wps/wps.h b/src/wps/wps.h index 3f61189b4..6667b02b5 100644 --- a/src/wps/wps.h +++ b/src/wps/wps.h @@ -159,6 +159,11 @@ struct wps_config { * struct wpa_context::psk. */ int use_psk_key; + + /** + * dev_pw_id - Device Password ID for Enrollee when PIN is used + */ + u16 dev_pw_id; }; struct wps_data * wps_init(const struct wps_config *cfg); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 7c096b3f7..c4169f2b5 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -216,7 +216,8 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, #endif /* CONFIG_AP */ if (pin) { - ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0); + ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, + DEV_PW_DEFAULT); if (ret < 0) return -1; ret = os_snprintf(buf, buflen, "%s", pin); @@ -225,7 +226,7 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, return ret; } - ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0); + ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT); if (ret < 0) return -1; diff --git a/wpa_supplicant/dbus/dbus_new_handlers_wps.c b/wpa_supplicant/dbus/dbus_new_handlers_wps.c index a4715cbb1..05aed5ec0 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_wps.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_wps.c @@ -231,7 +231,8 @@ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin, NULL); else if (params.type == 1) { - ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0); + ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0, + DEV_PW_DEFAULT); if (ret > 0) os_snprintf(npin, sizeof(npin), "%08d", ret); } else diff --git a/wpa_supplicant/dbus/dbus_old_handlers_wps.c b/wpa_supplicant/dbus/dbus_old_handlers_wps.c index 4c748bf36..c04b8446c 100644 --- a/wpa_supplicant/dbus/dbus_old_handlers_wps.c +++ b/wpa_supplicant/dbus/dbus_old_handlers_wps.c @@ -94,9 +94,11 @@ DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message, } if (os_strlen(pin) > 0) - ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0); + ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, + DEV_PW_DEFAULT); else - ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0); + ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, + DEV_PW_DEFAULT); if (ret < 0) { return dbus_message_new_error(message, diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 037f1ac37..ccb2e0d19 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -683,9 +683,13 @@ static void wpas_start_wps_enrollee(struct wpa_supplicant *wpa_s, if (res->wps_method == WPS_PBC) wpas_wps_start_pbc(wpa_s, NULL /* res->peer_interface_addr */, 1); - else + else { + u16 dev_pw_id = DEV_PW_DEFAULT; + if (wpa_s->p2p_wps_method == WPS_PIN_KEYPAD) + dev_pw_id = DEV_PW_REGISTRAR_SPECIFIED; wpas_wps_start_pin(wpa_s, res->peer_interface_addr, - wpa_s->p2p_pin, 1); + wpa_s->p2p_pin, 1, dev_pw_id); + } } @@ -928,9 +932,11 @@ void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) wpas_p2p_remove_pending_group_interface(wpa_s); return; } - if (group_wpa_s != wpa_s) + if (group_wpa_s != wpa_s) { os_memcpy(group_wpa_s->p2p_pin, wpa_s->p2p_pin, sizeof(group_wpa_s->p2p_pin)); + group_wpa_s->p2p_wps_method = wpa_s->p2p_wps_method; + } os_memset(wpa_s->pending_interface_addr, 0, ETH_ALEN); wpa_s->pending_interface_name[0] = '\0'; group_wpa_s->p2p_in_provisioning = 1; @@ -2384,9 +2390,11 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s) group = wpas_p2p_get_group_iface(wpa_s, 0, 0); if (group == NULL) return -1; - if (group != wpa_s) + if (group != wpa_s) { os_memcpy(group->p2p_pin, wpa_s->p2p_pin, sizeof(group->p2p_pin)); + group->p2p_wps_method = wpa_s->p2p_wps_method; + } group->p2p_in_provisioning = 1; @@ -2430,6 +2438,8 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, if (!auth) wpa_s->p2p_long_listen = 0; + wpa_s->p2p_wps_method = wps_method; + if (pin) os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin)); else if (wps_method == WPS_PIN_DISPLAY) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 8a2e69057..f76ea57d7 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -473,6 +473,7 @@ struct wpa_supplicant { struct p2p_group *p2p_group; int p2p_long_listen; char p2p_pin[10]; + int p2p_wps_method; int p2p_sd_over_ctrl_iface; int p2p_in_provisioning; int pending_invite_ssid_id; diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 6d95921ee..8f5329ad3 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -702,7 +702,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, int p2p_group) + const char *pin, int p2p_group, u16 dev_pw_id) { struct wpa_ssid *ssid; char val[128]; @@ -715,10 +715,12 @@ int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, ssid->temporary = 1; ssid->p2p_group = p2p_group; 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) diff --git a/wpa_supplicant/wps_supplicant.h b/wpa_supplicant/wps_supplicant.h index 3d1994b28..59d37b4cc 100644 --- a/wpa_supplicant/wps_supplicant.h +++ b/wpa_supplicant/wps_supplicant.h @@ -38,7 +38,7 @@ enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid); int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid, int p2p_group); int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, - const char *pin, int p2p_group); + const char *pin, int p2p_group, u16 dev_pw_id); int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, char *path, char *method, char *name); int wpas_wps_start_reg(struct wpa_supplicant *wpa_s, const u8 *bssid,