WPS: Determine the OpCode based on message type attribute (UPnP)
[libeap.git] / src / wps / wps_enrollee.c
index 8c8d087..df2c086 100644 (file)
@@ -328,6 +328,16 @@ static struct wpabuf * wps_build_m7(struct wps_data *wps)
        }
        wpabuf_free(plain);
 
+       if (wps->wps->ap && wps->wps->registrar) {
+               /*
+                * If the Registrar is only learning our current configuration,
+                * it may not continue protocol run to successful completion.
+                * Store information here to make sure it remains available.
+                */
+               wps_device_store(wps->wps->registrar, &wps->peer_dev,
+                                wps->uuid_r);
+       }
+
        wps->state = RECV_M8;
        return msg;
 }
@@ -545,10 +555,6 @@ static int wps_process_pubkey(struct wps_data *wps, const u8 *pk,
        if (wps_derive_keys(wps) < 0)
                return -1;
 
-       if (wps->request_type == WPS_REQ_WLAN_MANAGER_REGISTRAR &&
-           wps_derive_mgmt_keys(wps) < 0)
-               return -1;
-
        return 0;
 }
 
@@ -751,7 +757,8 @@ static enum wps_process_res wps_process_m2(struct wps_data *wps,
            wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
            wps_process_uuid_r(wps, attr->uuid_r) ||
            wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
-           wps_process_authenticator(wps, attr->authenticator, msg)) {
+           wps_process_authenticator(wps, attr->authenticator, msg) ||
+           wps_process_device_attrs(&wps->peer_dev, attr)) {
                wps->state = SEND_WSC_NACK;
                return WPS_CONTINUE;
        }
@@ -1183,6 +1190,17 @@ enum wps_process_res wps_enrollee_process_msg(struct wps_data *wps,
                   "op_code=%d)",
                   (unsigned long) wpabuf_len(msg), op_code);
 
+       if (op_code == WSC_UPnP) {
+               /* Determine the OpCode based on message type attribute */
+               struct wps_parse_attr attr;
+               if (wps_parse_msg(msg, &attr) == 0 && attr.msg_type) {
+                       if (*attr.msg_type == WPS_WSC_ACK)
+                               op_code = WSC_ACK;
+                       else if (*attr.msg_type == WPS_WSC_NACK)
+                               op_code = WSC_NACK;
+               }
+       }
+
        switch (op_code) {
        case WSC_MSG:
        case WSC_UPnP: