WPS: Added callback for failure-after-M2/M2D
authorJouni Malinen <j@w1.fi>
Fri, 19 Dec 2008 20:19:41 +0000 (22:19 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 19 Dec 2008 20:19:41 +0000 (22:19 +0200)
This callback is now used to stop wpa_supplicant from trying to continue
using parameters (most likely, device password) that do not work in a
loop. In addition, wpa_gui can now notify user of failed registration.

src/common/wpa_ctrl.h
src/wps/wps.h
src/wps/wps_common.c
src/wps/wps_enrollee.c
src/wps/wps_i.h
src/wps/wps_registrar.c
wpa_supplicant/wpa_gui-qt4/wpagui.cpp
wpa_supplicant/wps_supplicant.c

index 4032db8..b093f28 100644 (file)
@@ -62,6 +62,8 @@ extern "C" {
 #define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
 /** M2D received */
 #define WPS_EVENT_M2D "WPS-M2D "
+/** WPS registration failed after M2/M2D */
+#define WPS_EVENT_FAIL "WPS-FAIL "
 
 /* hostapd control interface - fixed message prefixes */
 #define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
index e1026b6..d61db68 100644 (file)
@@ -96,7 +96,8 @@ struct wps_registrar_config {
 
 
 enum wps_event {
-       WPS_EV_M2D
+       WPS_EV_M2D,
+       WPS_EV_FAIL
 };
 
 union wps_event_data {
@@ -116,6 +117,9 @@ union wps_event_data {
                u16 config_error;
                u16 dev_password_id;
        } m2d;
+       struct wps_event_fail {
+               int msg; /* enum wps_msg_type */
+       } fail;
 };
 
 /**
index 7ac3c03..99f6eb9 100644 (file)
@@ -298,3 +298,16 @@ unsigned int wps_generate_pin(void)
        /* Append checksum digit */
        return val * 10 + wps_pin_checksum(val);
 }
+
+
+void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg)
+{
+       union wps_event_data data;
+
+       if (wps->event_cb == NULL)
+               return;
+
+       os_memset(&data, 0, sizeof(data));
+       data.fail.msg = msg;
+       wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
+}
index 7fd1b35..18967cd 100644 (file)
@@ -947,12 +947,18 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
                break;
        case WPS_M4:
                ret = wps_process_m4(wps, msg, &attr);
+               if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
+                       wps_fail_event(wps->wps, WPS_M4);
                break;
        case WPS_M6:
                ret = wps_process_m6(wps, msg, &attr);
+               if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
+                       wps_fail_event(wps->wps, WPS_M6);
                break;
        case WPS_M8:
                ret = wps_process_m8(wps, msg, &attr);
+               if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
+                       wps_fail_event(wps->wps, WPS_M8);
                break;
        default:
                wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@@ -1079,6 +1085,24 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
        wpa_printf(MSG_DEBUG, "WPS: Registrar terminated negotiation with "
                   "Configuration Error %d", WPA_GET_BE16(attr.config_error));
 
+       switch (wps->state) {
+       case RECV_M4:
+               wps_fail_event(wps->wps, WPS_M3);
+               break;
+       case RECV_M6:
+               wps_fail_event(wps->wps, WPS_M5);
+               break;
+       case RECV_M8:
+               wps_fail_event(wps->wps, WPS_M7);
+               break;
+       default:
+               break;
+       }
+
+       /* Followed by NACK if Enrollee is Supplicant or EAP-Failure if
+        * Enrollee is Authenticator */
+       wps->state = SEND_WSC_NACK;
+
        return WPS_FAILURE;
 }
 
index b661b5d..3ae53b8 100644 (file)
@@ -165,6 +165,7 @@ void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
                    size_t dev_passwd_len);
 struct wpabuf * wps_decrypt_encr_settings(struct wps_data *wps, const u8 *encr,
                                          size_t encr_len);
+void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg);
 
 /* wps_attr_parse.c */
 int wps_parse_msg(const struct wpabuf *msg, struct wps_parse_attr *attr);
index b7a38c2..cd53c74 100644 (file)
@@ -1824,12 +1824,18 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
                break;
        case WPS_M3:
                ret = wps_process_m3(wps, msg, &attr);
+               if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
+                       wps_fail_event(wps->wps, WPS_M3);
                break;
        case WPS_M5:
                ret = wps_process_m5(wps, msg, &attr);
+               if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
+                       wps_fail_event(wps->wps, WPS_M5);
                break;
        case WPS_M7:
                ret = wps_process_m7(wps, msg, &attr);
+               if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
+                       wps_fail_event(wps->wps, WPS_M7);
                break;
        default:
                wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@@ -1904,9 +1910,11 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
                                                 const struct wpabuf *msg)
 {
        struct wps_parse_attr attr;
+       int old_state;
 
        wpa_printf(MSG_DEBUG, "WPS: Received WSC_NACK");
 
+       old_state = wps->state;
        wps->state = SEND_WSC_NACK;
 
        if (wps_parse_msg(msg, &attr) < 0)
@@ -1951,6 +1959,23 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
        wpa_printf(MSG_DEBUG, "WPS: Enrollee terminated negotiation with "
                   "Configuration Error %d", WPA_GET_BE16(attr.config_error));
 
+       switch (old_state) {
+       case RECV_M3:
+               wps_fail_event(wps->wps, WPS_M2);
+               break;
+       case RECV_M5:
+               wps_fail_event(wps->wps, WPS_M4);
+               break;
+       case RECV_M7:
+               wps_fail_event(wps->wps, WPS_M6);
+               break;
+       case RECV_DONE:
+               wps_fail_event(wps->wps, WPS_M8);
+               break;
+       default:
+               break;
+       }
+
        return WPS_FAILURE;
 }
 
@@ -2060,6 +2085,7 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
                                               u8 op_code,
                                               const struct wpabuf *msg)
 {
+       enum wps_process_res ret;
 
        wpa_printf(MSG_DEBUG, "WPS: Processing received message (len=%lu "
                   "op_code=%d)",
@@ -2073,7 +2099,12 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
        case WSC_NACK:
                return wps_process_wsc_nack(wps, msg);
        case WSC_Done:
-               return wps_process_wsc_done(wps, msg);
+               ret = wps_process_wsc_done(wps, msg);
+               if (ret == WPS_FAILURE) {
+                       wps->state = SEND_WSC_NACK;
+                       wps_fail_event(wps->wps, WPS_WSC_DONE);
+               }
+               return ret;
        default:
                wpa_printf(MSG_DEBUG, "WPS: Unsupported op_code %d", op_code);
                return WPS_FAILURE;
index edf88ea..dc555ab 100644 (file)
@@ -804,6 +804,8 @@ void WpaGui::processMsg(char *msg)
                        wpsStatusText->setText("Registration started");
        } else if (str_match(pos, WPS_EVENT_M2D)) {
                wpsStatusText->setText("Registrar does not yet know PIN");
+       } else if (str_match(pos, WPS_EVENT_FAIL)) {
+               wpsStatusText->setText("Registration failed");
        }
 }
 
index 5f3b29d..1babe86 100644 (file)
@@ -29,6 +29,7 @@
 
 
 static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx);
+static void wpas_clear_wps(struct wpa_supplicant *wpa_s);
 
 
 int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
@@ -189,6 +190,14 @@ 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);
+       wpas_clear_wps(wpa_s);
+}
+
+
 static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
                                     union wps_event_data *data)
 {
@@ -197,6 +206,9 @@ static void wpa_supplicant_wps_event(void *ctx, enum wps_event event,
        case WPS_EV_M2D:
                wpa_supplicant_wps_event_m2d(wpa_s, &data->m2d);
                break;
+       case WPS_EV_FAIL:
+               wpa_supplicant_wps_event_fail(wpa_s, &data->fail);
+               break;
        }
 }