]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Validate WEP key lengths based on driver capabilities
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 10 May 2012 11:34:46 +0000 (14:34 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 10 May 2012 11:34:46 +0000 (14:34 +0300)
The nl80211 driver interface does not allow 128-bit WEP to be used
without a vendor specific cipher suite and no such suite is defined for
this purpose. Do not accept WEP key length 16 for nl80211 driver
interface forn ow. wext-interface can still try to use these for
backwards compatibility.

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

src/drivers/driver.h
src/drivers/driver_wext.c
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/interworking.c
wpa_supplicant/scan.c
wpa_supplicant/scan.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 329f89a25f1eba07a5a4be9fb0530e15396a45df..f7fb2efb2540ca772195b16bc7689ffffdce0a1a 100644 (file)
@@ -740,6 +740,7 @@ struct wpa_driver_capa {
 #define WPA_DRIVER_CAPA_ENC_WEP104     0x00000002
 #define WPA_DRIVER_CAPA_ENC_TKIP       0x00000004
 #define WPA_DRIVER_CAPA_ENC_CCMP       0x00000008
+#define WPA_DRIVER_CAPA_ENC_WEP128     0x00000010
        unsigned int enc;
 
 #define WPA_DRIVER_AUTH_OPEN           0x00000001
index b76ce1d2020e1a180d4422ca6d892c50b978f96b..c688874bc66a80f1441cc7c32b1151e1f70a2051 100644 (file)
@@ -1575,6 +1575,7 @@ static int wpa_driver_wext_get_range(void *priv)
                }
                drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP40 |
                        WPA_DRIVER_CAPA_ENC_WEP104;
+               drv->capa.enc |= WPA_DRIVER_CAPA_ENC_WEP128;
                if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
                        drv->capa.enc |= WPA_DRIVER_CAPA_ENC_TKIP;
                if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
index de8ff1590e4ea9eeb4dde0016a70953712b82069..ce763b3052979fcdaff6b84742f0402bfa0c3fbf 100644 (file)
@@ -2924,23 +2924,3 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line)
 
        return ret;
 }
-
-
-int wpas_network_disabled(struct wpa_ssid *ssid)
-{
-       int i;
-
-       if (ssid == NULL)
-               return 1;
-
-       if (ssid->disabled)
-               return 1;
-
-       for (i = 0; i < NUM_WEP_KEYS; i++) {
-               size_t len = ssid->wep_key_len[i];
-               if (len && len != 5 && len != 13 && len != 16)
-                       return 1; /* invalid WEP key */
-       }
-
-       return 0;
-}
index 119252e701ac232af22594b9850a0b026aedbb4c..3e4f229425868ac7ecfc3838a0da5443f8c64018 100644 (file)
@@ -653,7 +653,6 @@ int wpa_config_set_quoted(struct wpa_ssid *ssid, const char *var,
 char ** wpa_config_get_all(struct wpa_ssid *ssid, int get_keys);
 char * wpa_config_get(struct wpa_ssid *ssid, const char *var);
 char * wpa_config_get_no_key(struct wpa_ssid *ssid, const char *var);
-int wpas_network_disabled(struct wpa_ssid *ssid);
 void wpa_config_update_psk(struct wpa_ssid *ssid);
 int wpa_config_add_prio_network(struct wpa_config *config,
                                struct wpa_ssid *ssid);
index bdc01b9b80b765b0df7be5e8a6c81cf11c1cba0d..4361f796156a8760bf984f560021a232f06c550f 100644 (file)
@@ -60,7 +60,7 @@ static int pno_start(struct wpa_supplicant *wpa_s)
        num_ssid = 0;
        ssid = wpa_s->conf->ssid;
        while (ssid) {
-               if (!wpas_network_disabled(ssid))
+               if (!wpas_network_disabled(wpa_s, ssid))
                        num_ssid++;
                ssid = ssid->next;
        }
@@ -82,7 +82,7 @@ static int pno_start(struct wpa_supplicant *wpa_s)
        i = 0;
        ssid = wpa_s->conf->ssid;
        while (ssid) {
-               if (!wpas_network_disabled(ssid)) {
+               if (!wpas_network_disabled(wpa_s, ssid)) {
                        params.ssids[i].ssid = ssid->ssid;
                        params.ssids[i].ssid_len = ssid->ssid_len;
                        params.num_ssids++;
index e8cf326953943402f943e27497ff9bfdb10ba588..407407ad3526236a12d5bf739fe8f337529068e4 100644 (file)
@@ -57,7 +57,7 @@ static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
                return -1;
        }
 
-       if (wpas_network_disabled(ssid)) {
+       if (wpas_network_disabled(wpa_s, ssid)) {
                wpa_dbg(wpa_s, MSG_DEBUG, "Selected network is disabled");
                return -1;
        }
@@ -612,7 +612,7 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
        e = wpa_blacklist_get(wpa_s, bss->bssid);
        if (e) {
                int limit = 1;
-               if (wpa_supplicant_enabled_networks(wpa_s->conf) == 1) {
+               if (wpa_supplicant_enabled_networks(wpa_s) == 1) {
                        /*
                         * When only a single network is enabled, we can
                         * trigger blacklisting on the first failure. This
@@ -640,7 +640,7 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
        for (ssid = group; ssid; ssid = ssid->pnext) {
                int check_ssid = wpa ? 1 : (ssid->ssid_len != 0);
 
-               if (wpas_network_disabled(ssid)) {
+               if (wpas_network_disabled(wpa_s, ssid)) {
                        wpa_dbg(wpa_s, MSG_DEBUG, "   skip - disabled");
                        continue;
                }
@@ -805,7 +805,7 @@ wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s,
 static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s,
                                        int timeout_sec, int timeout_usec)
 {
-       if (!wpa_supplicant_enabled_networks(wpa_s->conf)) {
+       if (!wpa_supplicant_enabled_networks(wpa_s)) {
                /*
                 * No networks are enabled; short-circuit request so
                 * we don't wait timeout seconds before transitioning
@@ -876,7 +876,7 @@ wpa_supplicant_pick_new_network(struct wpa_supplicant *wpa_s)
        for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
                for (ssid = wpa_s->conf->pssid[prio]; ssid; ssid = ssid->pnext)
                {
-                       if (wpas_network_disabled(ssid))
+                       if (wpas_network_disabled(wpa_s, ssid))
                                continue;
                        if (ssid->mode == IEEE80211_MODE_IBSS ||
                            ssid->mode == IEEE80211_MODE_AP)
index a260556ee42af19f004578e8b2121f550ed11a5b..515d94bbe591743e6cea74245b28b83d7b08ea07 100644 (file)
@@ -1104,7 +1104,7 @@ static int interworking_find_network_match(struct wpa_supplicant *wpa_s)
 
        dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
                for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
-                       if (wpas_network_disabled(ssid) ||
+                       if (wpas_network_disabled(wpa_s, ssid) ||
                            ssid->mode != WPAS_MODE_INFRA)
                                continue;
                        if (ssid->ssid_len != bss->ssid_len ||
index 277b34f11c74169d32bbf54ebfd47153a94426d8..923717f296a4c307798910b7c9f318d86c056527 100644 (file)
@@ -80,12 +80,12 @@ static int wpas_wps_in_use(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_WPS */
 
 
-int wpa_supplicant_enabled_networks(struct wpa_config *conf)
+int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s)
 {
-       struct wpa_ssid *ssid = conf->ssid;
+       struct wpa_ssid *ssid = wpa_s->conf->ssid;
        int count = 0;
        while (ssid) {
-               if (!wpas_network_disabled(ssid))
+               if (!wpas_network_disabled(wpa_s, ssid))
                        count++;
                ssid = ssid->next;
        }
@@ -97,7 +97,7 @@ static void wpa_supplicant_assoc_try(struct wpa_supplicant *wpa_s,
                                     struct wpa_ssid *ssid)
 {
        while (ssid) {
-               if (!wpas_network_disabled(ssid))
+               if (!wpas_network_disabled(wpa_s, ssid))
                        break;
                ssid = ssid->next;
        }
@@ -447,7 +447,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                return;
        }
 
-       if (!wpa_supplicant_enabled_networks(wpa_s->conf) &&
+       if (!wpa_supplicant_enabled_networks(wpa_s) &&
            !wpa_s->scan_req) {
                wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
                wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
@@ -554,7 +554,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                if (ssid == NULL && max_ssids > 1)
                        ssid = wpa_s->conf->ssid;
                while (ssid) {
-                       if (!wpas_network_disabled(ssid) && ssid->scan_ssid) {
+                       if (!wpas_network_disabled(wpa_s, ssid) &&
+                           ssid->scan_ssid) {
                                wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
                                                  ssid->ssid, ssid->ssid_len);
                                params.ssids[params.num_ssids].ssid =
@@ -574,7 +575,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
                }
 
                for (tssid = wpa_s->conf->ssid; tssid; tssid = tssid->next) {
-                       if (wpas_network_disabled(tssid))
+                       if (wpas_network_disabled(wpa_s, tssid))
                                continue;
                        if ((params.freqs || !freqs_set) && tssid->scan_freq) {
                                int_array_concat(&params.freqs,
@@ -695,7 +696,8 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
                struct wpa_ssid *ssid = wpa_s->conf->ssid;
 
                while (ssid) {
-                       if (!wpas_network_disabled(ssid) && ssid->scan_ssid)
+                       if (!wpas_network_disabled(wpa_s, ssid) &&
+                           ssid->scan_ssid)
                                break;
                        ssid = ssid->next;
                }
@@ -771,14 +773,15 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
 
        need_ssids = 0;
        for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
-               if (!wpas_network_disabled(ssid) && !ssid->scan_ssid) {
+               if (!wpas_network_disabled(wpa_s, ssid) && !ssid->scan_ssid) {
                        /* Use wildcard SSID to find this network */
                        wildcard = 1;
-               } else if (!wpas_network_disabled(ssid) && ssid->ssid_len)
+               } else if (!wpas_network_disabled(wpa_s, ssid) &&
+                          ssid->ssid_len)
                        need_ssids++;
 
 #ifdef CONFIG_WPS
-               if (!wpas_network_disabled(ssid) &&
+               if (!wpas_network_disabled(wpa_s, ssid) &&
                    ssid->key_mgmt == WPA_KEY_MGMT_WPS) {
                        /*
                         * Normal scan is more reliable and faster for WPS
@@ -850,7 +853,7 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
        }
 
        while (ssid) {
-               if (wpas_network_disabled(ssid))
+               if (wpas_network_disabled(wpa_s, ssid))
                        goto next;
 
                if (params.num_filter_ssids < wpa_s->max_match_sets &&
@@ -887,7 +890,7 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
                                do {
                                        ssid = ssid->next;
                                } while (ssid &&
-                                        (wpas_network_disabled(ssid) ||
+                                        (wpas_network_disabled(wpa_s, ssid) ||
                                          !ssid->scan_ssid));
                                break;
                        }
index 8c83a423046d59a0fd42a31b470089280e828fc0..b0ddf97e9d3514aa4e059c237771f92e63e1d6c1 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef SCAN_H
 #define SCAN_H
 
-int wpa_supplicant_enabled_networks(struct wpa_config *conf);
+int wpa_supplicant_enabled_networks(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
 int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s,
                                      int sec, int usec);
index 6e881cf02aa8b8269273c54e7598425597ff4e8a..5b9b55674f9b0962a80fb251278a8744058f131c 100644 (file)
@@ -750,7 +750,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
        wpa_supplicant_update_config(wpa_s);
 
        wpa_supplicant_clear_status(wpa_s);
-       if (wpa_supplicant_enabled_networks(wpa_s->conf)) {
+       if (wpa_supplicant_enabled_networks(wpa_s)) {
                wpa_s->reassociate = 1;
                wpa_supplicant_req_scan(wpa_s, 0, 0);
        }
@@ -1898,14 +1898,14 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
 
        entry = wpa_s->conf->ssid;
        while (entry) {
-               if (!wpas_network_disabled(entry) &&
+               if (!wpas_network_disabled(wpa_s, entry) &&
                    ((ssid_len == entry->ssid_len &&
                      os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
                    (!entry->bssid_set ||
                     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
                        return entry;
 #ifdef CONFIG_WPS
-               if (!wpas_network_disabled(entry) &&
+               if (!wpas_network_disabled(wpa_s, entry) &&
                    (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
                    (entry->ssid == NULL || entry->ssid_len == 0) &&
                    (!entry->bssid_set ||
@@ -1913,7 +1913,7 @@ struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
                        return entry;
 #endif /* CONFIG_WPS */
 
-               if (!wpas_network_disabled(entry) && entry->bssid_set &&
+               if (!wpas_network_disabled(wpa_s, entry) && entry->bssid_set &&
                    entry->ssid_len == 0 &&
                    os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0)
                        return entry;
@@ -2205,7 +2205,7 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s)
        wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
        wpa_s->prev_scan_wildcard = 0;
 
-       if (wpa_supplicant_enabled_networks(wpa_s->conf)) {
+       if (wpa_supplicant_enabled_networks(wpa_s)) {
                if (wpa_supplicant_delayed_sched_scan(wpa_s, interface_count,
                                                      100000))
                        wpa_supplicant_req_scan(wpa_s, interface_count,
@@ -2620,6 +2620,7 @@ next_driver:
        if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
                wpa_s->drv_capa_known = 1;
                wpa_s->drv_flags = capa.flags;
+               wpa_s->drv_enc = capa.enc;
                wpa_s->probe_resp_offloads = capa.probe_resp_offloads;
                wpa_s->max_scan_ssids = capa.max_scan_ssids;
                wpa_s->max_sched_scan_ssids = capa.max_sched_scan_ssids;
@@ -3316,3 +3317,36 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
 #endif /* IEEE8021X_EAPOL */
 }
 #endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
+
+
+int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+       int i;
+       unsigned int drv_enc;
+
+       if (ssid == NULL)
+               return 1;
+
+       if (ssid->disabled)
+               return 1;
+
+       if (wpa_s && wpa_s->drv_capa_known)
+               drv_enc = wpa_s->drv_enc;
+       else
+               drv_enc = (unsigned int) -1;
+
+       for (i = 0; i < NUM_WEP_KEYS; i++) {
+               size_t len = ssid->wep_key_len[i];
+               if (len == 0)
+                       continue;
+               if (len == 5 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP40))
+                       continue;
+               if (len == 13 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP104))
+                       continue;
+               if (len == 16 && (drv_enc & WPA_DRIVER_CAPA_ENC_WEP128))
+                       continue;
+               return 1; /* invalid WEP key */
+       }
+
+       return 0;
+}
index f36d117eb6279963bf2fe4618bfbea9a1b343da0..012732bb791b317bdad03853b8941132161ac055 100644 (file)
@@ -362,6 +362,7 @@ struct wpa_supplicant {
        int normal_scans; /* normal scans run before sched_scan */
 
        unsigned int drv_flags;
+       unsigned int drv_enc;
 
        /*
         * A bitmap of supported protocols for probe response offload. See
@@ -676,4 +677,6 @@ static inline int network_is_persistent_group(struct wpa_ssid *ssid)
        return ((ssid->disabled == 2) || ssid->p2p_persistent_group);
 }
 
+int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+
 #endif /* WPA_SUPPLICANT_I_H */