]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Add mechanism for indicating non-standard WPS errors
authorChao-Wen Yang <Chao-Wen.Yang@Atheros.com>
Thu, 13 Jan 2011 15:50:59 +0000 (17:50 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 13 Jan 2011 15:50:59 +0000 (17:50 +0200)
Previously, only the Configuration Error values were indicated in
WPS-FAIL events. Since those values are defined in the specification
it is not feasible to extend them for indicating other errors. Add
a new error indication value that is internal to wpa_supplicant and
hostapd to allow other errors to be indicated.

Use the new mechanism to indicate if negotiation fails because of
WEP or TKIP-only configurations being disallows by WPS 2.0.

src/ap/wps_hostapd.c
src/wps/wps.h
src/wps/wps_common.c
src/wps/wps_defs.h
src/wps/wps_enrollee.c
src/wps/wps_i.h
src/wps/wps_registrar.c
wpa_supplicant/wps_supplicant.c

index b5cd5a847c15a44724433e5a3140d799a89a2350..cfff55cdf142bb6bceabf656a9b7a86577ffde38 100644 (file)
@@ -535,12 +535,26 @@ static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
 }
 
 
+static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
+       "No Error", /* WPS_EI_NO_ERROR */
+       "TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
+       "WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
+};
+
 static void hostapd_wps_event_fail(struct hostapd_data *hapd,
                                   struct wps_event_fail *fail)
 {
-       wpa_msg(hapd->msg_ctx, MSG_INFO,
-               WPS_EVENT_FAIL "msg=%d config_error=%d",
-               fail->msg, fail->config_error);
+       if (fail->error_indication > 0 &&
+           fail->error_indication < NUM_WPS_EI_VALUES) {
+               wpa_msg(hapd->msg_ctx, MSG_INFO,
+                       WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
+                       fail->msg, fail->config_error, fail->error_indication,
+                       wps_event_fail_reason[fail->error_indication]);
+       } else {
+               wpa_msg(hapd->msg_ctx, MSG_INFO,
+                       WPS_EVENT_FAIL "msg=%d config_error=%d",
+                       fail->msg, fail->config_error);
+       }
 }
 
 
index ce0a22634ab28348bb8f3eeb737e6155a9c47e36..771551a85ad64868f85ae59ad231ea1698c38a57 100644 (file)
@@ -456,6 +456,7 @@ union wps_event_data {
        struct wps_event_fail {
                int msg;
                u16 config_error;
+               u16 error_indication;
        } fail;
 
        struct wps_event_pwd_auth_fail {
index 59fbca7c46eb2413b91809a98eb4b69eceb09f7a..5d0508cf13ab8079411370ad9ab9a826bac10f9b 100644 (file)
@@ -257,7 +257,7 @@ unsigned int wps_generate_pin(void)
 
 
 void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
-                   u16 config_error)
+                   u16 config_error, u16 error_indication)
 {
        union wps_event_data data;
 
@@ -267,6 +267,7 @@ void wps_fail_event(struct wps_context *wps, enum wps_msg_type msg,
        os_memset(&data, 0, sizeof(data));
        data.fail.msg = msg;
        data.fail.config_error = config_error;
+       data.fail.error_indication = error_indication;
        wps->event_cb(wps->cb_ctx, WPS_EV_FAIL, &data);
 }
 
index 868f8ad7e466a48a5b44db2ea7afa86f7291c9dc..43311f30d9da06b1e101c92cf6a9eb01872a68cc 100644 (file)
@@ -224,6 +224,14 @@ enum wps_config_error {
        WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18
 };
 
+/* Vendor specific Error Indication for WPS event messages */
+enum wps_error_indication {
+       WPS_EI_NO_ERROR,
+       WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED,
+       WPS_EI_SECURITY_WEP_PROHIBITED,
+       NUM_WPS_EI_VALUES
+};
+
 /* RF Bands */
 #define WPS_RF_24GHZ 0x01
 #define WPS_RF_50GHZ 0x02
index fcd6197576e770a157e566dddbe27dad143a6098..390254e438296549b8a78adad8a9ad0cacaf0f2b 100644 (file)
@@ -672,6 +672,7 @@ static int wps_process_cred_e(struct wps_data *wps, const u8 *cred,
                if (wps->cred.encr_type & WPS_ENCR_WEP) {
                        wpa_printf(MSG_INFO, "WPS: Reject Credential "
                                   "due to WEP configuration");
+                       wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
                        return -2;
                }
 
@@ -772,6 +773,7 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
                if (cred.encr_type & WPS_ENCR_WEP) {
                        wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
                                   "due to WEP configuration");
+                       wps->error_indication = WPS_EI_SECURITY_WEP_PROHIBITED;
                        return -1;
                }
 
@@ -789,6 +791,8 @@ static int wps_process_ap_settings_e(struct wps_data *wps,
                    WPS_AUTH_WPAPSK) {
                        wpa_printf(MSG_INFO, "WPS-STRICT: Invalid WSC 2.0 "
                                   "AP Settings: WPA-Personal/TKIP only");
+                       wps->error_indication =
+                               WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED;
                        return -1;
                }
        }
@@ -1140,21 +1144,24 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
                        return WPS_FAILURE;
                ret = wps_process_m4(wps, msg, &attr);
                if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
-                       wps_fail_event(wps->wps, WPS_M4, wps->config_error);
+                       wps_fail_event(wps->wps, WPS_M4, wps->config_error,
+                                      wps->error_indication);
                break;
        case WPS_M6:
                if (wps_validate_m6(msg) < 0)
                        return WPS_FAILURE;
                ret = wps_process_m6(wps, msg, &attr);
                if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
-                       wps_fail_event(wps->wps, WPS_M6, wps->config_error);
+                       wps_fail_event(wps->wps, WPS_M6, wps->config_error,
+                                      wps->error_indication);
                break;
        case WPS_M8:
                if (wps_validate_m8(msg) < 0)
                        return WPS_FAILURE;
                ret = wps_process_m8(wps, msg, &attr);
                if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
-                       wps_fail_event(wps->wps, WPS_M8, wps->config_error);
+                       wps_fail_event(wps->wps, WPS_M8, wps->config_error,
+                                      wps->error_indication);
                break;
        default:
                wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@@ -1281,13 +1288,16 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
 
        switch (wps->state) {
        case RECV_M4:
-               wps_fail_event(wps->wps, WPS_M3, config_error);
+               wps_fail_event(wps->wps, WPS_M3, config_error,
+                              wps->error_indication);
                break;
        case RECV_M6:
-               wps_fail_event(wps->wps, WPS_M5, config_error);
+               wps_fail_event(wps->wps, WPS_M5, config_error,
+                              wps->error_indication);
                break;
        case RECV_M8:
-               wps_fail_event(wps->wps, WPS_M7, config_error);
+               wps_fail_event(wps->wps, WPS_M7, config_error,
+                              wps->error_indication);
                break;
        default:
                break;
index 9953efbca997dccbf1e6cde9b997e4feab124e62..316e1f69fdc012857a64e17ff4cdfd3fd588c12f 100644 (file)
@@ -102,6 +102,7 @@ struct wps_data {
         * config_error - Configuration Error value to be used in NACK
         */
        u16 config_error;
+       u16 error_indication;
 
        int ext_reg;
        int int_reg;
@@ -213,7 +214,7 @@ void wps_derive_psk(struct wps_data *wps, const u8 *dev_passwd,
 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,
-                   u16 config_error);
+                   u16 config_error, u16 error_indication);
 void wps_success_event(struct wps_context *wps);
 void wps_pwd_auth_fail_event(struct wps_context *wps, int enrollee, int part);
 void wps_pbc_overlap_event(struct wps_context *wps);
index e2681f70b197ee686240ca47ff674c514b84a39c..ec429f831dcfc64e871e8f5668867d57a94dd5a8 100644 (file)
@@ -2597,21 +2597,24 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
                        return WPS_FAILURE;
                ret = wps_process_m3(wps, msg, &attr);
                if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
-                       wps_fail_event(wps->wps, WPS_M3, wps->config_error);
+                       wps_fail_event(wps->wps, WPS_M3, wps->config_error,
+                                      wps->error_indication);
                break;
        case WPS_M5:
                if (wps_validate_m5(msg) < 0)
                        return WPS_FAILURE;
                ret = wps_process_m5(wps, msg, &attr);
                if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
-                       wps_fail_event(wps->wps, WPS_M5, wps->config_error);
+                       wps_fail_event(wps->wps, WPS_M5, wps->config_error,
+                                      wps->error_indication);
                break;
        case WPS_M7:
                if (wps_validate_m7(msg) < 0)
                        return WPS_FAILURE;
                ret = wps_process_m7(wps, msg, &attr);
                if (ret == WPS_FAILURE || wps->state == SEND_WSC_NACK)
-                       wps_fail_event(wps->wps, WPS_M7, wps->config_error);
+                       wps_fail_event(wps->wps, WPS_M7, wps->config_error,
+                                      wps->error_indication);
                break;
        default:
                wpa_printf(MSG_DEBUG, "WPS: Unsupported Message Type %d",
@@ -2756,16 +2759,20 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
 
        switch (old_state) {
        case RECV_M3:
-               wps_fail_event(wps->wps, WPS_M2, config_error);
+               wps_fail_event(wps->wps, WPS_M2, config_error,
+                              wps->error_indication);
                break;
        case RECV_M5:
-               wps_fail_event(wps->wps, WPS_M4, config_error);
+               wps_fail_event(wps->wps, WPS_M4, config_error,
+                              wps->error_indication);
                break;
        case RECV_M7:
-               wps_fail_event(wps->wps, WPS_M6, config_error);
+               wps_fail_event(wps->wps, WPS_M6, config_error,
+                              wps->error_indication);
                break;
        case RECV_DONE:
-               wps_fail_event(wps->wps, WPS_M8, config_error);
+               wps_fail_event(wps->wps, WPS_M8, config_error,
+                              wps->error_indication);
                break;
        default:
                break;
@@ -2949,7 +2956,8 @@ enum wps_process_res wps_registrar_process_msg(struct wps_data *wps,
                if (ret == WPS_FAILURE) {
                        wps->state = SEND_WSC_NACK;
                        wps_fail_event(wps->wps, WPS_WSC_DONE,
-                                      wps->config_error);
+                                      wps->config_error,
+                                      wps->error_indication);
                }
                return ret;
        default:
index 6dfea2f4455089ce08c2c523a11eb71b4ce541e8..04761b41db6da267bff0f734f85c2a0597ebe85d 100644 (file)
@@ -410,15 +410,36 @@ static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
 }
 
 
+static const char * wps_event_fail_reason[NUM_WPS_EI_VALUES] = {
+       "No Error", /* WPS_EI_NO_ERROR */
+       "TKIP Only Prohibited", /* WPS_EI_SECURITY_TKIP_ONLY_PROHIBITED */
+       "WEP Prohibited" /* WPS_EI_SECURITY_WEP_PROHIBITED */
+};
+
 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 config_error=%d",
-               fail->msg, fail->config_error);
-       if (wpa_s->parent && wpa_s->parent != wpa_s)
-               wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
-                       "msg=%d config_error=%d",
+       if (fail->error_indication > 0 &&
+           fail->error_indication < NUM_WPS_EI_VALUES) {
+               wpa_msg(wpa_s, MSG_INFO,
+                       WPS_EVENT_FAIL "msg=%d config_error=%d reason=%d (%s)",
+                       fail->msg, fail->config_error, fail->error_indication,
+                       wps_event_fail_reason[fail->error_indication]);
+               if (wpa_s->parent && wpa_s->parent != wpa_s)
+                       wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
+                               "msg=%d config_error=%d reason=%d (%s)",
+                               fail->msg, fail->config_error,
+                               fail->error_indication,
+                               wps_event_fail_reason[fail->error_indication]);
+       } else {
+               wpa_msg(wpa_s, MSG_INFO,
+                       WPS_EVENT_FAIL "msg=%d config_error=%d",
                        fail->msg, fail->config_error);
+               if (wpa_s->parent && wpa_s->parent != wpa_s)
+                       wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
+                               "msg=%d config_error=%d",
+                               fail->msg, fail->config_error);
+       }
        wpas_clear_wps(wpa_s);
        wpas_notify_wps_event_fail(wpa_s, fail);
 }