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)