Fix WPS UPnP SSDP on 32-bit targets
[wpasupplicant] / src / eap_server / eap_wsc.c
index 262503a..3c17577 100644 (file)
@@ -15,6 +15,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "eloop.h"
 #include "eap_i.h"
 #include "eap_common/eap_wsc_common.h"
 #include "wps/wps.h"
@@ -29,6 +30,7 @@ struct eap_wsc_data {
        size_t out_used;
        size_t fragment_size;
        struct wps_data *wps;
+       int ext_reg_timeout;
 };
 
 
@@ -62,6 +64,21 @@ static void eap_wsc_state(struct eap_wsc_data *data, int state)
 }
 
 
+static void eap_wsc_ext_reg_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+       struct eap_sm *sm = eloop_ctx;
+       struct eap_wsc_data *data = timeout_ctx;
+
+       if (sm->method_pending != METHOD_PENDING_WAIT)
+               return;
+
+       wpa_printf(MSG_DEBUG, "EAP-WSC: Timeout while waiting for an External "
+                  "Registrar");
+       data->ext_reg_timeout = 1;
+       eap_sm_pending_cb(sm);
+}
+
+
 static void * eap_wsc_init(struct eap_sm *sm)
 {
        struct eap_wsc_data *data;
@@ -89,8 +106,8 @@ static void * eap_wsc_init(struct eap_sm *sm)
        data->registrar = registrar;
 
        os_memset(&cfg, 0, sizeof(cfg));
-       cfg.authenticator = 1;
        cfg.wps = sm->wps;
+       cfg.registrar = registrar;
        if (registrar) {
                if (sm->wps == NULL || sm->wps->registrar == NULL) {
                        wpa_printf(MSG_INFO, "EAP-WSC: WPS Registrar not "
@@ -98,7 +115,6 @@ static void * eap_wsc_init(struct eap_sm *sm)
                        os_free(data);
                        return NULL;
                }
-               cfg.registrar = sm->wps->registrar;
        } else {
                if (sm->user == NULL || sm->user->password == NULL) {
                        wpa_printf(MSG_INFO, "EAP-WSC: No AP PIN (password) "
@@ -124,6 +140,7 @@ static void * eap_wsc_init(struct eap_sm *sm)
 static void eap_wsc_reset(struct eap_sm *sm, void *priv)
 {
        struct eap_wsc_data *data = priv;
+       eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
        wpabuf_free(data->in_buf);
        wpabuf_free(data->out_buf);
        wps_deinit(data->wps);
@@ -325,6 +342,12 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
        enum wps_process_res res;
        struct wpabuf tmpbuf;
 
+       eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
+       if (data->ext_reg_timeout) {
+               eap_wsc_state(data, FAIL);
+               return;
+       }
+
        pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
                               respData, &len);
        if (pos == NULL || len < 2)
@@ -411,8 +434,11 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
                eap_wsc_state(data, FAIL);
                break;
        case WPS_PENDING:
-               wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing pending");
+               eap_wsc_state(data, MSG);
                sm->method_pending = METHOD_PENDING_WAIT;
+               eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
+               eloop_register_timeout(5, 0, eap_wsc_ext_reg_timeout,
+                                      sm, data);
                break;
        }