]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Add wps_config ctrl_interface command for configuring AP
authorJouni Malinen <jouni.malinen@atheros.com>
Thu, 21 Oct 2010 13:49:41 +0000 (16:49 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 21 Oct 2010 13:49:41 +0000 (16:49 +0300)
This command can be used to configure the AP using the internal
WPS registrar. It works in the same way as new AP settings received
from an ER.

hostapd/README-WPS
hostapd/ctrl_iface.c
hostapd/hostapd_cli.c
src/ap/wps_hostapd.c
src/ap/wps_hostapd.h
src/wps/wps.h
src/wps/wps_registrar.c

index c052df658888ca13fb3de996277daa3d78cf0344..44e3d9d25da05b325beb7b2b8192425c02b42ae0 100644 (file)
@@ -239,6 +239,14 @@ hostapd_cli wps_ap_pin set <PIN> [timeout]
 hostapd_cli get_config
 - display the current configuration
 
+hostapd_cli wps_config <new SSID> <auth> <encr> <new key>
+examples:
+  hostapd_cli wps_config testing WPA2PSK CCMP 12345678
+  hostapd_cli wps_config "no security" OPEN NONE ""
+
+<auth> must be one of the following: OPEN WPAPSK WPA2PSK
+<encr> must be one of the following: NONE WEP TKIP CCMP
+
 
 Credential generation and configuration changes
 -----------------------------------------------
index 2cdcdc13a3025330b6764a455515405c94726341..d0ed897c86eb6444e6fe264da852f028171dd30f 100644 (file)
@@ -490,6 +490,33 @@ static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
 
        return -1;
 }
+
+
+static int hostapd_ctrl_iface_wps_config(struct hostapd_data *hapd, char *txt)
+{
+       char *pos;
+       char *ssid, *auth, *encr = NULL, *key = NULL;
+
+       ssid = txt;
+       pos = os_strchr(txt, ' ');
+       if (!pos)
+               return -1;
+       *pos++ = '\0';
+
+       auth = pos;
+       pos = os_strchr(pos, ' ');
+       if (pos) {
+               *pos++ = '\0';
+               encr = pos;
+               pos = os_strchr(pos, ' ');
+               if (pos) {
+                       *pos++ = '\0';
+                       key = pos;
+               }
+       }
+
+       return hostapd_wps_config_ap(hapd, ssid, auth, encr, key);
+}
 #endif /* CONFIG_WPS */
 
 
@@ -821,6 +848,9 @@ static void hostapd_ctrl_iface_receive(int sock, void *eloop_ctx,
        } else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
                reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
                                                          reply, reply_size);
+       } else if (os_strncmp(buf, "WPS_CONFIG ", 11) == 0) {
+               if (hostapd_ctrl_iface_wps_config(hapd, buf + 11) < 0)
+                       reply_len = -1;
 #endif /* CONFIG_WPS */
        } else if (os_strcmp(buf, "GET_CONFIG") == 0) {
                reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
index c0d647f5a11da25a383938e980b36c5ae40dc2fd..3fdaa159616de784684a9c8893db0f68c2a83bf7 100644 (file)
@@ -96,6 +96,7 @@ static const char *commands_help =
 "   wps_oob <type> <path> <method>  use WPS with out-of-band (UFD)\n"
 #endif /* CONFIG_WPS_OOB */
 "   wps_ap_pin <cmd> [params..]  enable/disable AP PIN\n"
+"   wps_config <SSID> <auth> <encr> <key>  configure AP\n"
 #endif /* CONFIG_WPS */
 "   get_config           show current configuration\n"
 "   help                 show this usage help\n"
@@ -458,6 +459,50 @@ static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
                snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
        return wpa_ctrl_command(ctrl, buf);
 }
+
+
+static int hostapd_cli_cmd_wps_config(struct wpa_ctrl *ctrl, int argc,
+                                     char *argv[])
+{
+       char buf[256];
+       char ssid_hex[2 * 32 + 1];
+       char key_hex[2 * 64 + 1];
+       int i;
+
+       if (argc < 1) {
+               printf("Invalid 'wps_config' command - at least two arguments "
+                      "are required.\n");
+               return -1;
+       }
+
+       ssid_hex[0] = '\0';
+       for (i = 0; i < 32; i++) {
+               if (argv[0][i] == '\0')
+                       break;
+               os_snprintf(&ssid_hex[i * 2], 3, "%02x", argv[0][i]);
+       }
+
+       key_hex[0] = '\0';
+       if (argc > 3) {
+               for (i = 0; i < 64; i++) {
+                       if (argv[3][i] == '\0')
+                               break;
+                       os_snprintf(&key_hex[i * 2], 3, "%02x",
+                                   argv[3][i]);
+               }
+       }
+
+       if (argc > 3)
+               snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s %s",
+                        ssid_hex, argv[1], argv[2], key_hex);
+       else if (argc > 2)
+               snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s %s",
+                        ssid_hex, argv[1], argv[2]);
+       else
+               snprintf(buf, sizeof(buf), "WPS_CONFIG %s %s",
+                        ssid_hex, argv[1]);
+       return wpa_ctrl_command(ctrl, buf);
+}
 #endif /* CONFIG_WPS */
 
 
@@ -649,6 +694,7 @@ static struct hostapd_cli_cmd hostapd_cli_commands[] = {
        { "wps_oob", hostapd_cli_cmd_wps_oob },
 #endif /* CONFIG_WPS_OOB */
        { "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
+       { "wps_config", hostapd_cli_cmd_wps_config },
 #endif /* CONFIG_WPS */
        { "get_config", hostapd_cli_cmd_get_config },
        { "help", hostapd_cli_cmd_help },
index f4cbd5e61400f3949e9a9d7c04b0132e7f44740b..75a058657bdbee1b2783e6cdb57cc96287814c91 100644 (file)
@@ -1286,3 +1286,52 @@ void hostapd_wps_update_ie(struct hostapd_data *hapd)
 {
        hostapd_wps_for_each(hapd, wps_update_ie, NULL);
 }
+
+
+int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
+                         const char *auth, const char *encr, const char *key)
+{
+       struct wps_credential cred;
+       size_t len;
+
+       os_memset(&cred, 0, sizeof(cred));
+
+       len = os_strlen(ssid);
+       if ((len & 1) || len > 2 * sizeof(cred.ssid) ||
+           hexstr2bin(ssid, cred.ssid, len / 2))
+               return -1;
+       cred.ssid_len = len / 2;
+
+       if (os_strncmp(auth, "OPEN", 4) == 0)
+               cred.auth_type = WPS_AUTH_OPEN;
+       else if (os_strncmp(auth, "WPAPSK", 6) == 0)
+               cred.auth_type = WPS_AUTH_WPAPSK;
+       else if (os_strncmp(auth, "WPA2PSK", 7) == 0)
+               cred.auth_type = WPS_AUTH_WPA2PSK;
+       else
+               return -1;
+
+       if (encr) {
+               if (os_strncmp(encr, "NONE", 4) == 0)
+                       cred.encr_type = WPS_ENCR_NONE;
+               else if (os_strncmp(encr, "WEP", 3) == 0)
+                       cred.encr_type = WPS_ENCR_WEP;
+               else if (os_strncmp(encr, "TKIP", 4) == 0)
+                       cred.encr_type = WPS_ENCR_TKIP;
+               else if (os_strncmp(encr, "CCMP", 4) == 0)
+                       cred.encr_type = WPS_ENCR_AES;
+               else
+                       return -1;
+       } else
+               cred.encr_type = WPS_ENCR_NONE;
+
+       if (key) {
+               len = os_strlen(key);
+               if ((len & 1) || len > 2 * sizeof(cred.key) ||
+                   hexstr2bin(key, cred.key, len / 2))
+                       return -1;
+               cred.key_len = len / 2;
+       }
+
+       return wps_registrar_config_ap(hapd->wps->registrar, &cred);
+}
index fac736bf4cd4168ae6f7f892bf14f146288572a0..36401be3863e7c8ba8506ab1bcffd42351c263d6 100644 (file)
@@ -34,6 +34,8 @@ const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd);
 int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin,
                           int timeout);
 void hostapd_wps_update_ie(struct hostapd_data *hapd);
+int hostapd_wps_config_ap(struct hostapd_data *hapd, const char *ssid,
+                         const char *auth, const char *encr, const char *key);
 
 #else /* CONFIG_WPS */
 
index beb21b64a1de690c333676b86b617c90cdd168dd..bf8bddc44def6c6b4b93b640ccb6d8ce085cf9fb 100644 (file)
@@ -736,6 +736,8 @@ void wps_registrar_probe_req_rx(struct wps_registrar *reg, const u8 *addr,
 int wps_registrar_update_ie(struct wps_registrar *reg);
 int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
                           char *buf, size_t buflen);
+int wps_registrar_config_ap(struct wps_registrar *reg,
+                           struct wps_credential *cred);
 
 unsigned int wps_pin_checksum(unsigned int pin);
 unsigned int wps_pin_valid(unsigned int pin);
index 7da374a450fc8f37498534342ad2828522328c69..b2c76de98b58d8aa1e29fcdbb4dd00f767b7f735 100644 (file)
@@ -3161,3 +3161,43 @@ int wps_registrar_get_info(struct wps_registrar *reg, const u8 *addr,
 
        return len;
 }
+
+
+int wps_registrar_config_ap(struct wps_registrar *reg,
+                           struct wps_credential *cred)
+{
+#ifdef CONFIG_WPS2
+       printf("encr_type=0x%x\n", cred->encr_type);
+       if (!(cred->encr_type & (WPS_ENCR_NONE | WPS_ENCR_TKIP |
+                                WPS_ENCR_AES))) {
+               if (cred->encr_type & WPS_ENCR_WEP) {
+                       wpa_printf(MSG_INFO, "WPS: Reject new AP settings "
+                                  "due to WEP configuration");
+                       return -1;
+               }
+
+               wpa_printf(MSG_INFO, "WPS: Reject new AP settings due to "
+                          "invalid encr_type 0x%x", cred->encr_type);
+               return -1;
+       }
+
+       if ((cred->encr_type & (WPS_ENCR_TKIP | WPS_ENCR_AES)) ==
+           WPS_ENCR_TKIP) {
+               wpa_printf(MSG_DEBUG, "WPS: Upgrade encr_type TKIP -> "
+                          "TKIP+AES");
+               cred->encr_type |= WPS_ENCR_AES;
+       }
+
+       if ((cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) ==
+           WPS_AUTH_WPAPSK) {
+               wpa_printf(MSG_DEBUG, "WPS: Upgrade auth_type WPAPSK -> "
+                          "WPAPSK+WPA2PSK");
+               cred->auth_type |= WPS_AUTH_WPA2PSK;
+       }
+#endif /* CONFIG_WPS2 */
+
+       if (reg->wps->cred_cb)
+               return reg->wps->cred_cb(reg->wps->cb_ctx, cred);
+
+       return -1;
+}