Merge branch 'moonshot' of ssh://moonshot.suchdamage.org:822/srv/git/libeap into...
[libeap.git] / wpa_supplicant / ctrl_iface.c
index 8c5dcdf..6c7b561 100644 (file)
@@ -261,6 +261,51 @@ static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
 }
 
 
+static int wpa_supplicant_ctrl_iface_wps_check_pin(
+       struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen)
+{
+       char pin[9];
+       size_t len;
+       char *pos;
+       int ret;
+
+       wpa_hexdump_ascii_key(MSG_DEBUG, "WPS_CHECK_PIN",
+                             (u8 *) cmd, os_strlen(cmd));
+       for (pos = cmd, len = 0; *pos != '\0'; pos++) {
+               if (*pos < '0' || *pos > '9')
+                       continue;
+               pin[len++] = *pos;
+               if (len == 9) {
+                       wpa_printf(MSG_DEBUG, "WPS: Too long PIN");
+                       return -1;
+               }
+       }
+       if (len != 4 && len != 8) {
+               wpa_printf(MSG_DEBUG, "WPS: Invalid PIN length %d", (int) len);
+               return -1;
+       }
+       pin[len] = '\0';
+
+       if (len == 8) {
+               unsigned int pin_val;
+               pin_val = atoi(pin);
+               if (!wps_pin_valid(pin_val)) {
+                       wpa_printf(MSG_DEBUG, "WPS: Invalid checksum digit");
+                       ret = os_snprintf(buf, buflen, "FAIL-CHECKSUM\n");
+                       if (ret < 0 || (size_t) ret >= buflen)
+                               return -1;
+                       return ret;
+               }
+       }
+
+       ret = os_snprintf(buf, buflen, "%s", pin);
+       if (ret < 0 || (size_t) ret >= buflen)
+               return -1;
+
+       return ret;
+}
+
+
 #ifdef CONFIG_WPS_OOB
 static int wpa_supplicant_ctrl_iface_wps_oob(struct wpa_supplicant *wpa_s,
                                             char *cmd)
@@ -1930,6 +1975,14 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
                                   persistent_group, join, auth, go_intent,
                                   freq);
+       if (new_pin == -2) {
+               os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
+               return 25;
+       }
+       if (new_pin == -3) {
+               os_memcpy(buf, "FAIL-CHANNEL-UNSUPPORTED\n", 25);
+               return 25;
+       }
        if (new_pin < 0)
                return -1;
        if (wps_method == WPS_PIN_DISPLAY && pin == NULL) {
@@ -2631,7 +2684,10 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                wpa_hexdump_ascii_key(MSG_DEBUG, "RX ctrl_iface",
                                      (const u8 *) buf, os_strlen(buf));
        } else {
-               wpa_hexdump_ascii(MSG_DEBUG, "RX ctrl_iface",
+               int level = MSG_DEBUG;
+               if (os_strcmp(buf, "PING") == 0)
+                       level = MSG_EXCESSIVE;
+               wpa_hexdump_ascii(level, "RX ctrl_iface",
                                  (const u8 *) buf, os_strlen(buf));
        }
 
@@ -2715,6 +2771,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
                                                              reply,
                                                              reply_size);
+       } else if (os_strncmp(buf, "WPS_CHECK_PIN ", 14) == 0) {
+               reply_len = wpa_supplicant_ctrl_iface_wps_check_pin(
+                       wpa_s, buf + 14, reply, reply_size);
        } else if (os_strcmp(buf, "WPS_CANCEL") == 0) {
                if (wpas_wps_cancel(wpa_s))
                        reply_len = -1;