]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPS: Allow vendor specific attribute to be added into M1
authorAnirban Sirkhell <anirban@qca.qualcomm.com>
Tue, 3 Apr 2012 21:08:57 +0000 (00:08 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 3 Apr 2012 21:08:57 +0000 (00:08 +0300)
wps_vendor_ext_m1 configuration parameter can now be used to add a
vendor specific attribute into the WPS M1 message, e.g., for
Windows Vertical Pairing.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/wps/wps.h
src/wps/wps_dev_attr.c
src/wps/wps_dev_attr.h
src/wps/wps_enrollee.c
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/wpa_supplicant.conf
wpa_supplicant/wps_supplicant.c

index 435f36a67ce81a021732fe9db0dbc81bd807282b..10a45f204835885384b769f386f3f3145fa5d622 100644 (file)
@@ -94,6 +94,7 @@ struct wps_device_data {
        u32 os_version;
        u8 rf_bands;
        u16 config_methods;
+       struct wpabuf *vendor_ext_m1;
        struct wpabuf *vendor_ext[MAX_WPS_VENDOR_EXTENSIONS];
 
        int p2p;
index 559582dd57999641ba1914e21bde21c764b03292..3c94a43467a1aed1ec8880a2e7ce12a84022ad10 100644 (file)
@@ -203,6 +203,20 @@ int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg)
 }
 
 
+int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg)
+{
+       if (dev->vendor_ext_m1 != NULL) {
+               wpa_hexdump(MSG_DEBUG, "WPS:  * Vendor Extension M1",
+                           wpabuf_head_u8(dev->vendor_ext_m1),
+                           wpabuf_len(dev->vendor_ext_m1));
+               wpabuf_put_be16(msg, ATTR_VENDOR_EXT);
+               wpabuf_put_be16(msg, wpabuf_len(dev->vendor_ext_m1));
+               wpabuf_put_buf(msg, dev->vendor_ext_m1);
+       }
+       return 0;
+}
+
+
 int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * RF Bands (%x)", dev->rf_bands);
index 7ca81ad6c83da353a7097058ab3499cad0635f41..200c9c45adcf566d6729284db51e568ba6a12cc0 100644 (file)
@@ -17,6 +17,7 @@ int wps_build_model_number(struct wps_device_data *dev, struct wpabuf *msg);
 int wps_build_dev_name(struct wps_device_data *dev, struct wpabuf *msg);
 int wps_build_device_attrs(struct wps_device_data *dev, struct wpabuf *msg);
 int wps_build_os_version(struct wps_device_data *dev, struct wpabuf *msg);
+int wps_build_vendor_ext_m1(struct wps_device_data *dev, struct wpabuf *msg);
 int wps_build_rf_bands(struct wps_device_data *dev, struct wpabuf *msg);
 int wps_build_primary_dev_type(struct wps_device_data *dev,
                               struct wpabuf *msg);
index 85d2e9581fc18779f4a522d69bc55193bf2de1e7..da0c101b74825ac7e5eeed2f85e81bb5a0771507 100644 (file)
@@ -163,7 +163,8 @@ static struct wpabuf * wps_build_m1(struct wps_data *wps)
            wps_build_dev_password_id(msg, wps->dev_pw_id) ||
            wps_build_config_error(msg, WPS_CFG_NO_ERROR) ||
            wps_build_os_version(&wps->wps->dev, msg) ||
-           wps_build_wfa_ext(msg, 0, NULL, 0)) {
+           wps_build_wfa_ext(msg, 0, NULL, 0) ||
+           wps_build_vendor_ext_m1(&wps->wps->dev, msg)) {
                wpabuf_free(msg);
                return NULL;
        }
index ea0b6f468a15af7c2af67ffb8b1749104b003ecb..2a166c7dee0e7be90c9875f7b1afb4c306845b33 100644 (file)
@@ -1835,6 +1835,7 @@ void wpa_config_free(struct wpa_config *config)
        }
 #endif /* CONFIG_NO_CONFIG_BLOBS */
 
+       wpabuf_free(config->wps_vendor_ext_m1);
        os_free(config->ctrl_interface);
        os_free(config->ctrl_interface_group);
        os_free(config->opensc_engine_path);
@@ -2673,6 +2674,43 @@ static int wpa_config_process_os_version(const struct global_parse_data *data,
        return 0;
 }
 
+
+static int wpa_config_process_wps_vendor_ext_m1(
+       const struct global_parse_data *data,
+       struct wpa_config *config, int line, const char *pos)
+{
+       struct wpabuf *tmp;
+       int len = os_strlen(pos) / 2;
+       u8 *p;
+
+       if (!len) {
+               wpa_printf(MSG_ERROR, "Line %d: "
+                          "invalid wps_vendor_ext_m1", line);
+               return -1;
+       }
+
+       tmp = wpabuf_alloc(len);
+       if (tmp) {
+               p = wpabuf_put(tmp, len);
+
+               if (hexstr2bin(pos, p, len)) {
+                       wpa_printf(MSG_ERROR, "Line %d: "
+                                  "invalid wps_vendor_ext_m1", line);
+                       wpabuf_free(tmp);
+                       return -1;
+               }
+
+               wpabuf_free(config->wps_vendor_ext_m1);
+               config->wps_vendor_ext_m1 = tmp;
+       } else {
+               wpa_printf(MSG_ERROR, "Can not allocate "
+                          "memory for wps_vendor_ext_m1");
+               return -1;
+       }
+
+       return 0;
+}
+
 #endif /* CONFIG_WPS */
 
 #ifdef CONFIG_P2P
@@ -2809,6 +2847,7 @@ static const struct global_parse_data global_fields[] = {
        { FUNC(os_version), CFG_CHANGED_OS_VERSION },
        { STR(config_methods), CFG_CHANGED_CONFIG_METHODS },
        { INT_RANGE(wps_cred_processing, 0, 2), 0 },
+       { FUNC(wps_vendor_ext_m1), CFG_CHANGED_VENDOR_EXTENSION },
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
        { FUNC(sec_device_type), CFG_CHANGED_SEC_DEVICE_TYPE },
index ac4ecfaf02920025c5af6904e3f90e0457f855c9..9bdc29e22b5f113a22ea0fe3012c509ffb0f37f1 100644 (file)
@@ -507,6 +507,8 @@ struct wpa_config {
        unsigned int num_p2p_pref_chan;
        struct p2p_channel *p2p_pref_chan;
 
+       struct wpabuf *wps_vendor_ext_m1;
+
 #define MAX_WPS_VENDOR_EXT 10
        /**
         * wps_vendor_ext - Vendor extension attributes in WPS
index e7f3a7ccbcf40bdb80d98f8155c42626108587d6..e1e3a310270cb8892fe384cd5095cd6da4f2e555 100644 (file)
@@ -768,6 +768,16 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
        if (config->wps_cred_processing)
                fprintf(f, "wps_cred_processing=%d\n",
                        config->wps_cred_processing);
+       if (config->wps_vendor_ext_m1) {
+               int i, len = wpabuf_len(config->wps_vendor_ext_m1);
+               const u8 *p = wpabuf_head_u8(config->wps_vendor_ext_m1);
+               if (len > 0) {
+                       fprintf(f, "wps_vendor_ext_m1=");
+                       for (i = 0; i < len; i++)
+                               fprintf(f, "%02x", *p++);
+                       fprintf(f, "\n");
+               }
+       }
 #endif /* CONFIG_WPS */
 #ifdef CONFIG_P2P
        if (config->p2p_listen_reg_class)
index fb8ea259adda0ae0050099ec8e27aee844193448..e2269542ba798ded974e6e802c1795f38b8fab67 100644 (file)
@@ -214,6 +214,10 @@ fast_reauth=1
 #      to external program(s)
 #wps_cred_processing=0
 
+# Vendor attribute in WPS M1, e.g., Windows 7 Vertical Pairing
+# The vendor attribute contents to be added in M1 (hex string)
+#wps_vendor_ext_m1=000137100100020001
+
 # Maximum number of BSS entries to keep in memory
 # Default: 200
 # This can be used to limit memory use on the BSS entries (cached scan
index 49654399719e5b8ccd1f90ed9b87920d93898ac1..00ce9beabc4d6dc7b4d6a5707ae340f63f0dd71e 100644 (file)
@@ -1130,6 +1130,23 @@ static void wpas_wps_set_uuid(struct wpa_supplicant *wpa_s,
 }
 
 
+static void wpas_wps_set_vendor_ext_m1(struct wpa_supplicant *wpa_s,
+                                      struct wps_context *wps)
+{
+       wpabuf_free(wps->dev.vendor_ext_m1);
+       wps->dev.vendor_ext_m1 = NULL;
+
+       if (wpa_s->conf->wps_vendor_ext_m1) {
+               wps->dev.vendor_ext_m1 =
+                       wpabuf_dup(wpa_s->conf->wps_vendor_ext_m1);
+               if (!wps->dev.vendor_ext_m1) {
+                       wpa_printf(MSG_ERROR, "WPS: Cannot "
+                                  "allocate memory for vendor_ext_m1");
+               }
+       }
+}
+
+
 int wpas_wps_init(struct wpa_supplicant *wpa_s)
 {
        struct wps_context *wps;
@@ -1168,6 +1185,8 @@ int wpas_wps_init(struct wpa_supplicant *wpa_s)
        os_memcpy(wps->dev.sec_dev_type, wpa_s->conf->sec_device_type,
                  WPS_DEV_TYPE_LEN * wps->dev.num_sec_dev_types);
 
+       wpas_wps_set_vendor_ext_m1(wpa_s, wps);
+
        wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);
        modes = wpa_s->hw.modes;
        if (modes) {
@@ -1228,6 +1247,7 @@ void wpas_wps_deinit(struct wpa_supplicant *wpa_s)
        wpabuf_free(wpa_s->wps->dh_privkey);
        wpabuf_free(wpa_s->wps->oob_conf.pubkey_hash);
        wpabuf_free(wpa_s->wps->oob_conf.dev_password);
+       wpabuf_free(wpa_s->wps->dev.vendor_ext_m1);
        os_free(wpa_s->wps->network_key);
        os_free(wpa_s->wps);
        wpa_s->wps = NULL;
@@ -1717,6 +1737,9 @@ void wpas_wps_update_config(struct wpa_supplicant *wpa_s)
                          wps->dev.num_sec_dev_types * WPS_DEV_TYPE_LEN);
        }
 
+       if (wpa_s->conf->changed_parameters & CFG_CHANGED_VENDOR_EXTENSION)
+               wpas_wps_set_vendor_ext_m1(wpa_s, wps);
+
        if (wpa_s->conf->changed_parameters & CFG_CHANGED_OS_VERSION)
                wps->dev.os_version = WPA_GET_BE32(wpa_s->conf->os_version);