P2P: Allow WPS_PBC command on GO to select on P2P Device Address
[mech_eap.git] / src / eap_server / eap_server_wsc.c
index 0345cdc..e944a4d 100644 (file)
 #include "eloop.h"
 #include "eap_i.h"
 #include "eap_common/eap_wsc_common.h"
+#include "p2p/p2p.h"
 #include "wps/wps.h"
 
 
 struct eap_wsc_data {
-       enum { START, MSG, FRAG_ACK, WAIT_FRAG_ACK, DONE, FAIL } state;
+       enum { START, MESG, FRAG_ACK, WAIT_FRAG_ACK, DONE, FAIL } state;
        int registrar;
        struct wpabuf *in_buf;
        struct wpabuf *out_buf;
@@ -40,8 +41,8 @@ static const char * eap_wsc_state_txt(int state)
        switch (state) {
        case START:
                return "START";
-       case MSG:
-               return "MSG";
+       case MESG:
+               return "MESG";
        case FRAG_ACK:
                return "FRAG_ACK";
        case WAIT_FRAG_ACK:
@@ -104,7 +105,7 @@ static void * eap_wsc_init(struct eap_sm *sm)
        data = os_zalloc(sizeof(*data));
        if (data == NULL)
                return NULL;
-       data->state = registrar ? START : MSG;
+       data->state = registrar ? START : MESG;
        data->registrar = registrar;
 
        os_memset(&cfg, 0, sizeof(cfg));
@@ -119,24 +120,37 @@ static void * eap_wsc_init(struct eap_sm *sm)
                }
        } else {
                if (sm->user == NULL || sm->user->password == NULL) {
-                       wpa_printf(MSG_INFO, "EAP-WSC: No AP PIN (password) "
-                                  "configured for Enrollee functionality");
-                       os_free(data);
-                       return NULL;
+                       /*
+                        * In theory, this should not really be needed, but
+                        * Windows 7 uses Registrar mode to probe AP's WPS
+                        * capabilities before trying to use Enrollee and fails
+                        * if the AP does not allow that probing to happen..
+                        */
+                       wpa_printf(MSG_DEBUG, "EAP-WSC: No AP PIN (password) "
+                                  "configured for Enrollee functionality - "
+                                  "allow for probing capabilities (M1)");
+               } else {
+                       cfg.pin = sm->user->password;
+                       cfg.pin_len = sm->user->password_len;
                }
-               cfg.pin = sm->user->password;
-               cfg.pin_len = sm->user->password_len;
        }
        cfg.assoc_wps_ie = sm->assoc_wps_ie;
        cfg.peer_addr = sm->peer_addr;
-       if (0 /* TODO: could provide option for forcing PSK format */)
-                cfg.use_psk_key = 1;
+#ifdef CONFIG_P2P
+       if (sm->assoc_p2p_ie) {
+               wpa_printf(MSG_DEBUG, "EAP-WSC: Prefer PSK format for P2P "
+                          "client");
+               cfg.use_psk_key = 1;
+               cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie);
+       }
+#endif /* CONFIG_P2P */
        data->wps = wps_init(&cfg);
        if (data->wps == NULL) {
                os_free(data);
                return NULL;
        }
-       data->fragment_size = WSC_FRAGMENT_SIZE;
+       data->fragment_size = sm->fragment_size > 0 ? sm->fragment_size :
+               WSC_FRAGMENT_SIZE;
 
        return data;
 }
@@ -217,7 +231,7 @@ static struct wpabuf * eap_wsc_build_msg(struct eap_wsc_data *data, u8 id)
                wpabuf_free(data->out_buf);
                data->out_buf = NULL;
                data->out_used = 0;
-               eap_wsc_state(data, MSG);
+               eap_wsc_state(data, MESG);
        } else {
                wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %lu bytes "
                           "(%lu more to send)", (unsigned long) send_len,
@@ -237,7 +251,7 @@ static struct wpabuf * eap_wsc_buildReq(struct eap_sm *sm, void *priv, u8 id)
        switch (data->state) {
        case START:
                return eap_wsc_build_start(sm, data, id);
-       case MSG:
+       case MESG:
                if (data->out_buf == NULL) {
                        data->out_buf = wps_get_msg(data->wps,
                                                    &data->out_op_code);
@@ -390,7 +404,7 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
                        return;
                }
                wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment acknowledged");
-               eap_wsc_state(data, MSG);
+               eap_wsc_state(data, MESG);
                return;
        }
 
@@ -432,14 +446,14 @@ static void eap_wsc_process(struct eap_sm *sm, void *priv,
                eap_wsc_state(data, FAIL);
                break;
        case WPS_CONTINUE:
-               eap_wsc_state(data, MSG);
+               eap_wsc_state(data, MESG);
                break;
        case WPS_FAILURE:
                wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing failed");
                eap_wsc_state(data, FAIL);
                break;
        case WPS_PENDING:
-               eap_wsc_state(data, MSG);
+               eap_wsc_state(data, MESG);
                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,