From 9dd7d6b09cd13bf2347306475f3309d8e6b58378 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 17 Nov 2010 16:48:39 +0200 Subject: [PATCH] WPS: Add special AP Setup Locked mode to allow read only ER ap_setup_locked=2 can now be used to enable a special mode where WPS ER can learn the current AP settings, but cannot change then. In other words, the protocol is allowed to continue past M2, but is stopped at M7 when AP is in this mode. WPS IE does not advertise AP Setup Locked in this case to avoid interoperability issues. In wpa_supplicant, use ap_setup_locked=2 by default. Since the AP PIN is disabled by default, this does not enable any new functionality automatically. To allow the read-only ER to go through the protocol, wps_ap_pin command needs to be used to enable the AP PIN. --- src/wps/wps_enrollee.c | 22 +++++++++++++++++++++- src/wps/wps_registrar.c | 2 +- wpa_supplicant/ap.c | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c index 162a35074..bcf94d0e6 100644 --- a/src/wps/wps_enrollee.c +++ b/src/wps/wps_enrollee.c @@ -839,8 +839,15 @@ static enum wps_process_res wps_process_m2(struct wps_data *wps, return WPS_CONTINUE; } + /* + * Stop here on an AP as an Enrollee if AP Setup is locked unless the + * special locked mode is used to allow protocol run up to M7 in order + * to support external Registrars that only learn the current AP + * configuration without changing it. + */ if (wps->wps->ap && - (wps->wps->ap_setup_locked || wps->dev_password == NULL)) { + ((wps->wps->ap_setup_locked && wps->wps->ap_setup_locked != 2) || + wps->dev_password == NULL)) { wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse " "registration of a new Registrar"); wps->config_error = WPS_CFG_SETUP_LOCKED; @@ -1045,6 +1052,19 @@ static enum wps_process_res wps_process_m8(struct wps_data *wps, return WPS_CONTINUE; } + if (wps->wps->ap && wps->wps->ap_setup_locked) { + /* + * Stop here if special ap_setup_locked == 2 mode allowed the + * protocol to continue beyond M2. This allows ER to learn the + * current AP settings without changing them. + */ + wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse " + "registration of a new Registrar"); + wps->config_error = WPS_CFG_SETUP_LOCKED; + wps->state = SEND_WSC_NACK; + return WPS_CONTINUE; + } + decrypted = wps_decrypt_encr_settings(wps, attr->encr_settings, attr->encr_settings_len); if (decrypted == NULL) { diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index d98c6aac8..7a82b92b8 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -392,7 +392,7 @@ static void wps_registrar_free_pending_m2(struct wps_context *wps) static int wps_build_ap_setup_locked(struct wps_context *wps, struct wpabuf *msg) { - if (wps->ap_setup_locked) { + if (wps->ap_setup_locked && wps->ap_setup_locked != 2) { wpa_printf(MSG_DEBUG, "WPS: * AP Setup Locked"); wpabuf_put_be16(msg, ATTR_AP_SETUP_LOCKED); wpabuf_put_be16(msg, 1); diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 1a8d5193f..5c573619e 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -161,7 +161,7 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, */ bss->eap_server = 1; bss->wps_state = 2; - bss->ap_setup_locked = 1; + bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); if (wpa_s->conf->device_type)