OSDN Git Service

AI 146027: Update wpa_supplicant from 0.5.10 to 0.5.11
authorDmitry Shmidt <>
Tue, 14 Apr 2009 01:43:17 +0000 (18:43 -0700)
committerThe Android Open Source Project <initial-contribution@android.com>
Tue, 14 Apr 2009 01:43:17 +0000 (18:43 -0700)
  BUG=1786358

Automated import of CL 146027

37 files changed:
ChangeLog
Makefile
base64.c
ctrl_iface.c
ctrl_iface_dbus.c
ctrl_iface_unix.c
dbus_dict_helpers.c
driver_broadcom.c
driver_hostap.h
driver_ndis.c
driver_wext.c
eap.c
eap_aka.c
eap_gpsk.c
eap_gpsk_common.c
eap_ttls.c
eloop.c
eloop.h
eloop_none.c
eloop_win.c
mlme.c
os_unix.c
preauth_test.c
radius.c
sha1.c
tls_openssl.c
version.h
wpa.c
wpa.h
wpa_gui-qt4/networkconfig.cpp
wpa_gui-qt4/scanresults.cpp
wpa_gui-qt4/wpagui.cpp
wpa_gui/networkconfig.ui.h
wpa_gui/userdatarequest.ui.h
wpa_gui/wpagui.ui.h
wpa_i.h
wpa_supplicant.c

index 1ba2e1c..10b1aca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 ChangeLog for wpa_supplicant
 
+2008-11-28 - v0.5.11
+       * fixed race condition between disassociation event and group key
+         handshake to avoid getting stuck in incorrect state [Bug 261]
+       * updated D-Bus usage to avoid deprecated functions
+       * silence SIOCSIWAUTH ioctl failure message (these can be ignored in
+         most cases and are now only shown in debug output)
+       * increase timeout for IBSS connection
+       * driver_wext: do not overwrite BSS frequency if channel was already
+         received
+       * driver_wext: set interface down for mode switches, if needed (e.g.,
+         for mac80211)
+       * driver_wext: fixed re-initialization of a removed and re-inserted
+         interface (e.g., USB dongle or on resume if driver was unloaded for
+         suspend)
+       * improve per-SSID scanning for drivers that report background scan
+         results frequently
+       * fixed scanning behavior after a failed initial association
+       * driver_wext: fixed processing of invalid event messages from kernel
+         not to crash wpa_supplicant (this could happen when using 64-bit
+         kernel with 32-bit userspace)
+       * fixed EAP-AKA to use RES Length field in AT_RES as length in bits,
+         not bytes
+       * fixed canceling of PMKSA caching when using drivers that generate
+         RSN IE and refuse to drop PMKIDs that wpa_supplicant does not know
+         about
+
 2008-02-19 - v0.5.10
        * added support for Makefile builds to include debug-log-to-a-file
          functionality (CONFIG_DEBUG_FILE=y and -f<path> on command line)
index 51114fa..1e7e383 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,10 @@ endif
 
 ifdef CONFIG_DRIVER_NDIS
 CFLAGS += -DCONFIG_DRIVER_NDIS
-OBJS_d += driver_ndis.o driver_ndis_.o
+OBJS_d += driver_ndis.o
+ifdef CONFIG_NDIS_EVENTS_INTEGRATED
+OBJS_d += driver_ndis_.o
+endif
 ifndef CONFIG_L2_PACKET
 CONFIG_L2_PACKET=pcap
 endif
index 0c33e58..8b1da25 100644 (file)
--- a/base64.c
+++ b/base64.c
@@ -115,7 +115,7 @@ unsigned char * base64_decode(const unsigned char *src, size_t len,
                        count++;
        }
 
-       if (count % 4)
+       if (count == 0 || count % 4)
                return NULL;
 
        olen = count / 4 * 3;
index 653d89b..c774c86 100644 (file)
@@ -76,6 +76,7 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
 }
 
 
+#ifdef IEEE8021X_EAPOL
 static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
                                             char *addr)
 {
@@ -94,6 +95,7 @@ static int wpa_supplicant_ctrl_iface_preauth(struct wpa_supplicant *wpa_s,
 
        return 0;
 }
+#endif /* IEEE8021X_EAPOL */
 
 
 #ifdef CONFIG_PEERKEY
@@ -538,7 +540,7 @@ static int wpa_supplicant_ctrl_iface_scan_results(
                return 0;
        if (wpa_s->scan_results == NULL)
                return 0;
-       
+
        pos = buf;
        end = buf + buflen;
        ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
@@ -1200,9 +1202,11 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
                        wpa_s->reassociate = 1;
                        wpa_supplicant_req_scan(wpa_s, 0, 0);
                }
+#ifdef IEEE8021X_EAPOL
        } else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
                if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
                        reply_len = -1;
+#endif /* IEEE8021X_EAPOL */
 #ifdef CONFIG_PEERKEY
        } else if (os_strncmp(buf, "STKSTART ", 9) == 0) {
                if (wpa_supplicant_ctrl_iface_stkstart(wpa_s, buf + 9))
index ba78516..7475aa4 100644 (file)
 #include "wpa_ctrl.h"
 #include "eap.h"
 
-#define DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR)
+#define _DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR)
 #define DBUS_VER(major, minor) ((major) << 8 | (minor))
 
-#if DBUS_VERSION < DBUS_VER(1,1)
+#if _DBUS_VERSION < DBUS_VER(1,1)
 #define dbus_watch_get_unix_fd dbus_watch_get_fd
 #endif
 
index 2b9446e..316ea68 100644 (file)
@@ -315,7 +315,7 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
                        /* Group name not found - try to parse this as gid */
                        gid = strtol(gid_str, &endp, 10);
                        if (*gid_str == '\0' || *endp != '\0') {
-                               wpa_printf(MSG_DEBUG, "CTRL: Invalid group "
+                               wpa_printf(MSG_ERROR, "CTRL: Invalid group "
                                           "'%s'", gid_str);
                                goto fail;
                        }
index 2852ed5..b6ea556 100644 (file)
@@ -629,36 +629,56 @@ dbus_bool_t wpa_dbus_dict_open_read(DBusMessageIter *iter,
 }
 
 
+#define BYTE_ARRAY_CHUNK_SIZE 34
+#define BYTE_ARRAY_ITEM_SIZE (sizeof (char))
+
 static dbus_bool_t _wpa_dbus_dict_entry_get_byte_array(
-       DBusMessageIter *iter, int array_len, int array_type,
+       DBusMessageIter *iter, int array_type,
        struct wpa_dbus_dict_entry *entry)
 {
-       dbus_uint32_t i = 0;
+       dbus_uint32_t count = 0;
        dbus_bool_t success = FALSE;
-       char byte;
+       char *buffer;
 
-       /* Zero-length arrays are valid. */
-       if (array_len == 0) {
-               entry->bytearray_value = NULL;
-               entry->array_type = DBUS_TYPE_BYTE;
-               success = TRUE;
-               goto done;
-       }
+       entry->bytearray_value = NULL;
+       entry->array_type = DBUS_TYPE_BYTE;
 
-       entry->bytearray_value = wpa_zalloc(array_len * sizeof(char));
-       if (!entry->bytearray_value) {
+       buffer = wpa_zalloc(BYTE_ARRAY_ITEM_SIZE * BYTE_ARRAY_CHUNK_SIZE);
+       if (!buffer) {
                perror("_wpa_dbus_dict_entry_get_byte_array[dbus]: out of "
                       "memory");
                goto done;
        }
 
-       entry->array_type = DBUS_TYPE_BYTE;
-       entry->array_len = array_len;
+       entry->bytearray_value = buffer;
+       entry->array_len = 0;
        while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_BYTE) {
+               char byte;
+
+               if ((count % BYTE_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
+                       buffer = realloc(buffer, BYTE_ARRAY_ITEM_SIZE *
+                                        (count + BYTE_ARRAY_CHUNK_SIZE));
+                       if (buffer == NULL) {
+                               perror("_wpa_dbus_dict_entry_get_byte_array["
+                                      "dbus] out of memory trying to "
+                                      "retrieve the string array");
+                               goto done;
+                       }
+               }
+               entry->bytearray_value = buffer;
+
                dbus_message_iter_get_basic(iter, &byte);
-               entry->bytearray_value[i++] = byte;
+               entry->bytearray_value[count] = byte;
+               entry->array_len = ++count;
                dbus_message_iter_next(iter);
        }
+
+       /* Zero-length arrays are valid. */
+       if (entry->array_len == 0) {
+               free(entry->bytearray_value);
+               entry->bytearray_value = NULL;
+       }
+
        success = TRUE;
 
 done:
@@ -666,8 +686,11 @@ done:
 }
 
 
+#define STR_ARRAY_CHUNK_SIZE 8
+#define STR_ARRAY_ITEM_SIZE (sizeof (char *))
+
 static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
-       DBusMessageIter *iter, int array_len, int array_type,
+       DBusMessageIter *iter, int array_type,
        struct wpa_dbus_dict_entry *entry)
 {
        dbus_uint32_t count = 0;
@@ -677,13 +700,7 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
        entry->strarray_value = NULL;
        entry->array_type = DBUS_TYPE_STRING;
 
-       /* Zero-length arrays are valid. */
-       if (array_len == 0) {
-               success = TRUE;
-               goto done;
-       }
-
-       buffer = wpa_zalloc(sizeof (char *) * 8);
+       buffer = wpa_zalloc(STR_ARRAY_ITEM_SIZE * STR_ARRAY_CHUNK_SIZE);
        if (buffer == NULL) {
                perror("_wpa_dbus_dict_entry_get_string_array[dbus] out of "
                       "memory trying to retrieve a string array");
@@ -696,18 +713,15 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
                const char *value;
                char *str;
 
-               if ((count % 8) == 0 && count != 0) {
-                       char **tmp;
-                       tmp = realloc(buffer, sizeof(char *) * (count + 8));
-                       if (tmp == NULL) {
+               if ((count % STR_ARRAY_CHUNK_SIZE) == 0 && count != 0) {
+                       buffer = realloc(buffer, STR_ARRAY_ITEM_SIZE *
+                                        (count + STR_ARRAY_CHUNK_SIZE));
+                       if (buffer == NULL) {
                                perror("_wpa_dbus_dict_entry_get_string_array["
                                       "dbus] out of memory trying to "
                                       "retrieve the string array");
-                               free(buffer);
-                               buffer = NULL;
                                goto done;
                        }
-                       buffer = tmp;
                }
                entry->strarray_value = buffer;
 
@@ -723,6 +737,13 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
                entry->array_len = ++count;
                dbus_message_iter_next(iter);
        }
+
+       /* Zero-length arrays are valid. */
+       if (entry->array_len == 0) {
+               free(entry->strarray_value);
+               entry->strarray_value = NULL;
+       }
+
        success = TRUE;
 
 done:
@@ -734,7 +755,6 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_array(
        DBusMessageIter *iter_dict_val, struct wpa_dbus_dict_entry *entry)
 {
        int array_type = dbus_message_iter_get_element_type(iter_dict_val);
-       int array_len;
        dbus_bool_t success = FALSE;
        DBusMessageIter iter_array;
 
@@ -743,20 +763,14 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_array(
 
        dbus_message_iter_recurse(iter_dict_val, &iter_array);
 
-       array_len = dbus_message_iter_get_array_len(&iter_array);
-       if (array_len < 0)
-               return FALSE;
-
        switch (array_type) {
        case DBUS_TYPE_BYTE:
                success = _wpa_dbus_dict_entry_get_byte_array(&iter_array,
-                                                             array_len,
                                                              array_type,
                                                              entry);
                break;
        case DBUS_TYPE_STRING:
                success = _wpa_dbus_dict_entry_get_string_array(&iter_array,
-                                                               array_len,
                                                                array_type,
                                                                entry);
                break;
@@ -946,9 +960,17 @@ void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry)
                break;
        case DBUS_TYPE_ARRAY:
                switch (entry->array_type) {
-               case DBUS_TYPE_BYTE:
-                       free(entry->bytearray_value);
-                       break;
+               case DBUS_TYPE_BYTE: {
+                               free(entry->bytearray_value);
+                               break;
+                       }
+               case DBUS_TYPE_STRING: {
+                               unsigned int i;
+                               for (i = 0; i < entry->array_len; i++)
+                                       free(entry->strarray_value[i]);
+                               free(entry->strarray_value);
+                               break;
+                       }
                }
                break;
        }
index 79b2568..3cb8129 100644 (file)
@@ -487,8 +487,9 @@ wpa_driver_broadcom_get_scan_results(void *priv,
                wbi = (wl_bss_info_t *) ((u8 *) wbi + wbi->length);
        }
 
-       wpa_printf(MSG_MSGDUMP, "Received %d bytes of scan results (%d BSSes)",
-                  wsr->buflen, ap_num);
+       wpa_printf(MSG_MSGDUMP, "Received %d bytes of scan results (%lu "
+                  "BSSes)",
+                  wsr->buflen, (unsigned long) ap_num);
        
        os_free(buf);
        return ap_num;
index a83322f..a2508ed 100644 (file)
@@ -84,9 +84,9 @@ enum {
 
 #define PRISM2_HOSTAPD_MAX_BUF_SIZE 1024
 #define PRISM2_HOSTAPD_RID_HDR_LEN \
-((int) (&((struct prism2_hostapd_param *) 0)->u.rid.data))
+((size_t) (&((struct prism2_hostapd_param *) 0)->u.rid.data))
 #define PRISM2_HOSTAPD_GENERIC_ELEMENT_HDR_LEN \
-((int) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
+((size_t) (&((struct prism2_hostapd_param *) 0)->u.generic_elem.data))
 
 /* Maximum length for algorithm names (-1 for nul termination) used in ioctl()
  */
index 570b4ca..de34306 100644 (file)
@@ -42,7 +42,9 @@ int close(int fd);
 #include "driver_ndis.h"
 
 int wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv);
+#ifdef CONFIG_NDIS_EVENTS_INTEGRATED
 void wpa_driver_ndis_event_pipe_cb(void *eloop_data, void *user_data);
+#endif /* CONFIG_NDIS_EVENTS_INTEGRATED */
 
 static void wpa_driver_ndis_deinit(void *priv);
 static void wpa_driver_ndis_poll(void *drv);
index e1f949a..a2e4578 100644 (file)
@@ -62,6 +62,7 @@ struct wpa_driver_wext_data {
        char ifname[IFNAMSIZ + 1];
        int ifindex;
        int ifindex2;
+       int if_removed;
        u8 *assoc_req_ies;
        size_t assoc_req_ies_len;
        u8 *assoc_resp_ies;
@@ -84,6 +85,8 @@ struct wpa_driver_wext_data {
 
 static int wpa_driver_wext_flush_pmkid(void *priv);
 static int wpa_driver_wext_get_range(void *priv);
+static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
+
 
 static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
                                          int linkmode, int operstate)
@@ -154,9 +157,11 @@ static int wpa_driver_wext_set_auth_param(struct wpa_driver_wext_data *drv,
        iwr.u.param.value = value;
 
        if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
-               perror("ioctl[SIOCSIWAUTH]");
-               fprintf(stderr, "WEXT auth param %d value 0x%x - ",
-                       idx, value);
+               if (errno != EOPNOTSUPP) {
+                       wpa_printf(MSG_DEBUG, "WEXT: SIOCSIWAUTH(param %d "
+                                  "value 0x%x) failed: %s)",
+                                  idx, value, strerror(errno));
+               }
                ret = errno == EOPNOTSUPP ? -2 : -1;
        }
 
@@ -577,12 +582,20 @@ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
                        }
                        break;
                case IWEVMICHAELMICFAILURE:
+                       if (custom + iwe->u.data.length > end) {
+                               wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                                          "IWEVMICHAELMICFAILURE length");
+                               return;
+                       }
                        wpa_driver_wext_event_wireless_michaelmicfailure(
                                ctx, custom, iwe->u.data.length);
                        break;
                case IWEVCUSTOM:
-                       if (custom + iwe->u.data.length > end)
+                       if (custom + iwe->u.data.length > end) {
+                               wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                                          "IWEVCUSTOM length");
                                return;
+                       }
                        buf = os_malloc(iwe->u.data.length + 1);
                        if (buf == NULL)
                                return;
@@ -598,14 +611,29 @@ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
                        wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
                        break;
                case IWEVASSOCREQIE:
+                       if (custom + iwe->u.data.length > end) {
+                               wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                                          "IWEVASSOCREQIE length");
+                               return;
+                       }
                        wpa_driver_wext_event_wireless_assocreqie(
                                drv, custom, iwe->u.data.length);
                        break;
                case IWEVASSOCRESPIE:
+                       if (custom + iwe->u.data.length > end) {
+                               wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                                          "IWEVASSOCRESPIE length");
+                               return;
+                       }
                        wpa_driver_wext_event_wireless_assocrespie(
                                drv, custom, iwe->u.data.length);
                        break;
                case IWEVPMKIDCAND:
+                       if (custom + iwe->u.data.length > end) {
+                               wpa_printf(MSG_DEBUG, "WEXT: Invalid "
+                                          "IWEVPMKIDCAND length");
+                               return;
+                       }
                        wpa_driver_wext_event_wireless_pmkidcand(
                                drv, custom, iwe->u.data.length);
                        break;
@@ -616,7 +644,8 @@ static void wpa_driver_wext_event_wireless(struct wpa_driver_wext_data *drv,
 }
 
 
-static void wpa_driver_wext_event_link(void *ctx, char *buf, size_t len,
+static void wpa_driver_wext_event_link(struct wpa_driver_wext_data *drv,
+                                      void *ctx, char *buf, size_t len,
                                       int del)
 {
        union wpa_event_data event;
@@ -633,10 +662,68 @@ static void wpa_driver_wext_event_link(void *ctx, char *buf, size_t len,
                   event.interface_status.ifname,
                   del ? "removed" : "added");
 
+       if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
+               if (del)
+                       drv->if_removed = 1;
+               else
+                       drv->if_removed = 0;
+       }
+
        wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &event);
 }
 
 
+static int wpa_driver_wext_own_ifname(struct wpa_driver_wext_data *drv,
+                                     struct nlmsghdr *h)
+{
+       struct ifinfomsg *ifi;
+       int attrlen, nlmsg_len, rta_len;
+       struct rtattr *attr;
+
+       ifi = NLMSG_DATA(h);
+
+       nlmsg_len = NLMSG_ALIGN(sizeof(struct ifinfomsg));
+
+       attrlen = h->nlmsg_len - nlmsg_len;
+       if (attrlen < 0)
+               return 0;
+
+       attr = (struct rtattr *) (((char *) ifi) + nlmsg_len);
+
+       rta_len = RTA_ALIGN(sizeof(struct rtattr));
+       while (RTA_OK(attr, attrlen)) {
+               if (attr->rta_type == IFLA_IFNAME) {
+                       if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
+                           == 0)
+                               return 1;
+                       else
+                               break;
+               }
+               attr = RTA_NEXT(attr, attrlen);
+       }
+
+       return 0;
+}
+
+
+static int wpa_driver_wext_own_ifindex(struct wpa_driver_wext_data *drv,
+                                      int ifindex, struct nlmsghdr *h)
+{
+       if (drv->ifindex == ifindex || drv->ifindex2 == ifindex)
+               return 1;
+
+       if (drv->if_removed && wpa_driver_wext_own_ifname(drv, h)) {
+               drv->ifindex = if_nametoindex(drv->ifname);
+               wpa_printf(MSG_DEBUG, "WEXT: Update ifindex for a removed "
+                          "interface");
+               wpa_driver_wext_finish_drv_init(drv);
+               return 1;
+       }
+
+       return 0;
+}
+
+
 static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv,
                                              void *ctx, struct nlmsghdr *h,
                                              size_t len)
@@ -650,8 +737,7 @@ static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv,
 
        ifi = NLMSG_DATA(h);
 
-       if (drv->ifindex != ifi->ifi_index && drv->ifindex2 != ifi->ifi_index)
-       {
+       if (!wpa_driver_wext_own_ifindex(drv, ifi->ifi_index, h)) {
                wpa_printf(MSG_DEBUG, "Ignore event for foreign ifindex %d",
                           ifi->ifi_index);
                return;
@@ -663,7 +749,7 @@ static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv,
                   (ifi->ifi_flags & IFF_UP) ? "[UP]" : "",
                   (ifi->ifi_flags & IFF_RUNNING) ? "[RUNNING]" : "",
                   (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
-                  (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT" : "");
+                  (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
        /*
         * Some drivers send the association event before the operup event--in
         * this case, lifting operstate in wpa_driver_wext_set_operstate()
@@ -690,7 +776,7 @@ static void wpa_driver_wext_event_rtm_newlink(struct wpa_driver_wext_data *drv,
                                drv, ctx, ((char *) attr) + rta_len,
                                attr->rta_len - rta_len);
                } else if (attr->rta_type == IFLA_IFNAME) {
-                       wpa_driver_wext_event_link(ctx,
+                       wpa_driver_wext_event_link(drv, ctx,
                                                   ((char *) attr) + rta_len,
                                                   attr->rta_len - rta_len, 0);
                }
@@ -723,7 +809,7 @@ static void wpa_driver_wext_event_rtm_dellink(struct wpa_driver_wext_data *drv,
        rta_len = RTA_ALIGN(sizeof(struct rtattr));
        while (RTA_OK(attr, attrlen)) {
                if (attr->rta_type == IFLA_IFNAME) {
-                       wpa_driver_wext_event_link(ctx,
+                       wpa_driver_wext_event_link(drv,  ctx,
                                                   ((char *) attr) + rta_len,
                                                   attr->rta_len - rta_len, 1);
                }
@@ -864,7 +950,7 @@ int wpa_driver_wext_set_ifflags(struct wpa_driver_wext_data *drv, int flags)
  */
 void * wpa_driver_wext_init(void *ctx, const char *ifname)
 {
-       int s, flags;
+       int s;
        struct sockaddr_nl local;
        struct wpa_driver_wext_data *drv;
 
@@ -905,6 +991,16 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
 
        drv->mlme_sock = -1;
 
+       wpa_driver_wext_finish_drv_init(drv);
+
+       return drv;
+}
+
+
+static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
+{
+       int flags;
+
        /*
         * Make sure that the driver does not have any obsolete PMKID entries.
         */
@@ -923,7 +1019,7 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
 
        drv->ifindex = if_nametoindex(drv->ifname);
 
-       if (os_strncmp(ifname, "wlan", 4) == 0) {
+       if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
                /*
                 * Host AP driver may use both wlan# and wifi# interface in
                 * wireless events. Since some of the versions included WE-18
@@ -933,14 +1029,12 @@ void * wpa_driver_wext_init(void *ctx, const char *ifname)
                 * driver are not in use anymore.
                 */
                char ifname2[IFNAMSIZ + 1];
-               os_strncpy(ifname2, ifname, sizeof(ifname2));
+               os_strncpy(ifname2, drv->ifname, sizeof(ifname2));
                os_memcpy(ifname2, "wifi", 4);
                wpa_driver_wext_alternative_ifindex(drv, ifname2);
        }
 
        wpa_driver_wext_send_oper_ifla(drv, 1, IF_OPER_DORMANT);
-
-       return drv;
 }
 
 
@@ -1232,8 +1326,17 @@ int wpa_driver_wext_get_scan_results(void *priv,
                                         * Some drivers do not report
                                         * frequency, but a channel. Try to map
                                         * this to frequency by assuming they
-                                        * are using IEEE 802.11b/g.
+                                        * are using IEEE 802.11b/g. But don't
+                                        * overwrite a previously parsed
+                                        * frequency if the driver sends both
+                                        * frequency and channel, since the
+                                        * driver may be sending an A-band
+                                        * channel that we don't handle here.
                                         */
+
+                                       if (results[ap_num].freq)
+                                               break;
+
                                        if (iwe->u.freq.m >= 1 &&
                                            iwe->u.freq.m <= 13) {
                                                results[ap_num].freq =
@@ -1920,17 +2023,54 @@ int wpa_driver_wext_set_mode(void *priv, int mode)
 {
        struct wpa_driver_wext_data *drv = priv;
        struct iwreq iwr;
-       int ret = 0;
+       int ret = -1, flags;
+       unsigned int new_mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
 
        os_memset(&iwr, 0, sizeof(iwr));
        os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
-       iwr.u.mode = mode ? IW_MODE_ADHOC : IW_MODE_INFRA;
+       iwr.u.mode = new_mode;
+       if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) == 0) {
+               ret = 0;
+               goto done;
+       }
 
-       if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) {
+       if (errno != EBUSY) {
                perror("ioctl[SIOCSIWMODE]");
-               ret = -1;
+               goto done;
+       }
+
+       /* mac80211 doesn't allow mode changes while the device is up, so if
+        * the device isn't in the mode we're about to change to, take device
+        * down, try to set the mode again, and bring it back up.
+        */
+       if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
+               perror("ioctl[SIOCGIWMODE]");
+               goto done;
+       }
+
+       if (iwr.u.mode == new_mode) {
+               ret = 0;
+               goto done;
+       }
+
+       if (wpa_driver_wext_get_ifflags(drv, &flags) == 0) {
+               (void) wpa_driver_wext_set_ifflags(drv, flags & ~IFF_UP);
+
+               /* Try to set the mode again while the interface is down */
+               iwr.u.mode = new_mode;
+               if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0)
+                       perror("ioctl[SIOCSIWMODE]");
+               else
+                       ret = 0;
+
+               /* Ignore return value of get_ifflags to ensure that the device
+                * is always up like it was before this function was called.
+                */
+               (void) wpa_driver_wext_get_ifflags(drv, &flags);
+               (void) wpa_driver_wext_set_ifflags(drv, flags | IFF_UP);
        }
 
+done:
        return ret;
 }
 
diff --git a/eap.c b/eap.c
index a5cd982..8021e80 100644 (file)
--- a/eap.c
+++ b/eap.c
@@ -892,7 +892,7 @@ static int eap_sm_imsi_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
 #endif /* PCSC_FUNCS */
 
 
-static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
+static int eap_sm_set_scard_pin(struct eap_sm *sm, struct wpa_ssid *ssid)
 {
 #ifdef PCSC_FUNCS
        if (scard_set_pin(sm->scard_ctx, ssid->pin)) {
@@ -907,6 +907,17 @@ static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
                eap_sm_request_pin(sm);
                return -1;
        }
+       return 0;
+#else /* PCSC_FUNCS */
+       return -1;
+#endif /* PCSC_FUNCS */
+}
+
+static int eap_sm_get_scard_identity(struct eap_sm *sm, struct wpa_ssid *ssid)
+{
+#ifdef PCSC_FUNCS
+       if (eap_sm_set_scard_pin(sm, ssid))
+               return -1;
 
        return eap_sm_imsi_identity(sm, ssid);
 #else /* PCSC_FUNCS */
@@ -973,6 +984,9 @@ u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
                        eap_sm_request_identity(sm);
                        return NULL;
                }
+       } else if (config->pcsc) {
+               if (eap_sm_set_scard_pin(sm, config) < 0)
+                       return NULL;
        }
 
        *len = sizeof(struct eap_hdr) + 1 + identity_len;
index a8b56ca..daf7722 100644 (file)
--- a/eap_aka.c
+++ b/eap_aka.c
@@ -292,7 +292,7 @@ static u8 * eap_aka_response_challenge(struct eap_aka_data *data,
        msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
                               EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE);
        wpa_printf(MSG_DEBUG, "   AT_RES");
-       eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len,
+       eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
                        data->res, data->res_len);
        wpa_printf(MSG_DEBUG, "   AT_MAC");
        eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
index 81b03ed..a9af85c 100644 (file)
@@ -240,8 +240,8 @@ const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm,
                return NULL;
        }
        if (*list_len == 0 || (*list_len % sizeof(struct eap_gpsk_csuite))) {
-               wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %d",
-                          *list_len);
+               wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %lu",
+                          (unsigned long) *list_len);
                return NULL;
        }
        *list = pos;
@@ -460,6 +460,7 @@ const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data,
                                  data->id_server, data->id_server_len);
                wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3",
                                  pos, len);
+               return NULL;
        }
 
        pos += len;
@@ -537,7 +538,9 @@ const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data,
        miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
        if (end - pos < (int) miclen) {
                wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
-                          "(left=%d miclen=%d)", end - pos, miclen);
+                          "(left=%lu miclen=%lu)",
+                          (unsigned long) (end - pos),
+                          (unsigned long) miclen);
                return NULL;
        }
        if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
@@ -589,8 +592,9 @@ static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
                return NULL;
        }
        if (pos != end) {
-               wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %d bytes of extra "
-                          "data in the end of GPSK-2", end - pos);
+               wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
+                          "data in the end of GPSK-2",
+                          (unsigned long) (end - pos));
        }
 
        req = (const struct eap_hdr *) reqData;
index 7422fa6..ec97a56 100644 (file)
@@ -376,8 +376,8 @@ static int eap_gpsk_compute_mic_aes(const u8 *sk, size_t sk_len,
                                    const u8 *data, size_t len, u8 *mic)
 {
        if (sk_len != 16) {
-               wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid SK length %d for "
-                          "AES-CMAC MIC", sk_len);
+               wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid SK length %lu for "
+                          "AES-CMAC MIC", (unsigned long) sk_len);
                return -1;
        }
 
index ca00694..bdffed4 100644 (file)
@@ -673,7 +673,7 @@ static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
 
        /* MS-CHAP-Challenge */
        challenge = eap_ttls_implicit_challenge(
-               sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN * 2 + 1);
+               sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
        if (challenge == NULL) {
                os_free(buf);
                wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
@@ -777,7 +777,8 @@ static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
                               config->identity, config->identity_len);
 
        /* MS-CHAP-Challenge */
-       challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
+       challenge = eap_ttls_implicit_challenge(
+               sm, data, EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
        if (challenge == NULL) {
                os_free(buf);
                wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
@@ -907,7 +908,8 @@ static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
                               config->identity, config->identity_len);
 
        /* CHAP-Challenge */
-       challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
+       challenge = eap_ttls_implicit_challenge(
+               sm, data, EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
        if (challenge == NULL) {
                os_free(buf);
                wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
diff --git a/eloop.c b/eloop.c
index 232e753..9cac792 100644 (file)
--- a/eloop.c
+++ b/eloop.c
@@ -232,7 +232,10 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
        timeout = os_malloc(sizeof(*timeout));
        if (timeout == NULL)
                return -1;
-       os_get_time(&timeout->time);
+       if (os_get_time(&timeout->time) < 0) {
+               os_free(timeout);
+               return -1;
+       }
        timeout->time.sec += secs;
        timeout->time.usec += usecs;
        while (timeout->time.usec >= 1000000) {
@@ -302,6 +305,25 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
 }
 
 
+int eloop_is_timeout_registered(eloop_timeout_handler handler,
+                               void *eloop_data, void *user_data)
+{
+       struct eloop_timeout *tmp;
+
+       tmp = eloop.timeout;
+       while (tmp != NULL) {
+               if (tmp->handler == handler &&
+                   tmp->eloop_data == eloop_data &&
+                   tmp->user_data == user_data)
+                       return 1;
+
+               tmp = tmp->next;
+       }
+
+       return 0;
+}
+
+
 #ifndef CONFIG_NATIVE_WINDOWS
 static void eloop_handle_alarm(int sig)
 {
diff --git a/eloop.h b/eloop.h
index 4dd2871..cf83f38 100644 (file)
--- a/eloop.h
+++ b/eloop.h
@@ -207,6 +207,19 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
                         void *eloop_data, void *user_data);
 
 /**
+ * eloop_is_timeout_registered - Check if a timeout is already registered
+ * @handler: Matching callback function
+ * @eloop_data: Matching eloop_data
+ * @user_data: Matching user_data
+ * Returns: 1 if the timeout is registered, 0 if the timeout is not registered
+ *
+ * Determine if a matching <handler,eloop_data,user_data> timeout is registered
+ * with eloop_register_timeout().
+ */
+int eloop_is_timeout_registered(eloop_timeout_handler handler,
+                               void *eloop_data, void *user_data);
+
+/**
  * eloop_register_signal - Register handler for signals
  * @sig: Signal number (e.g., SIGHUP)
  * @handler: Callback function to be called when the signal is received
index 6943109..215030b 100644 (file)
@@ -197,6 +197,26 @@ int eloop_cancel_timeout(void (*handler)(void *eloop_ctx, void *sock_ctx),
 }
 
 
+int eloop_is_timeout_registered(void (*handler)(void *eloop_ctx,
+                                               void *timeout_ctx),
+                               void *eloop_data, void *user_data)
+{
+       struct eloop_timeout *tmp;
+
+       tmp = eloop.timeout;
+       while (tmp != NULL) {
+               if (tmp->handler == handler &&
+                   tmp->eloop_data == eloop_data &&
+                   tmp->user_data == user_data)
+                       return 1;
+
+               tmp = tmp->next;
+       }
+
+       return 0;
+}
+
+
 /* TODO: replace with suitable signal handler */
 #if 0
 static void eloop_handle_signal(int sig)
index 73f0eaf..a1ccd94 100644 (file)
@@ -320,6 +320,25 @@ int eloop_cancel_timeout(eloop_timeout_handler handler,
 }
 
 
+int eloop_is_timeout_registered(eloop_timeout_handler handler,
+                               void *eloop_data, void *user_data)
+{
+       struct eloop_timeout *tmp;
+
+       tmp = eloop.timeout;
+       while (tmp != NULL) {
+               if (tmp->handler == handler &&
+                   tmp->eloop_data == eloop_data &&
+                   tmp->user_data == user_data)
+                       return 1;
+
+               tmp = tmp->next;
+       }
+
+       return 0;
+}
+
+
 /* TODO: replace with suitable signal handler */
 #if 0
 static void eloop_handle_signal(int sig)
diff --git a/mlme.c b/mlme.c
index 92b5959..e618e2a 100644 (file)
--- a/mlme.c
+++ b/mlme.c
@@ -985,8 +985,6 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
        supp_rates[1] = 0;
        for (i = 0; i < wpa_s->mlme.num_curr_rates; i++) {
                struct wpa_rate_data *rate = &wpa_s->mlme.curr_rates[i];
-               if (!(rate->flags & WPA_RATE_SUPPORTED))
-                       continue;
                if (esupp_rates) {
                        pos = buf + len;
                        len++;
@@ -996,6 +994,7 @@ static void ieee80211_send_probe_req(struct wpa_supplicant *wpa_s,
                        esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
                        esupp_rates[1] = 1;
                        pos = &esupp_rates[2];
+                       len += 3;
                } else {
                        pos = buf + len;
                        len++;
index 69ba25a..7e3ab4a 100644 (file)
--- a/os_unix.c
+++ b/os_unix.c
@@ -216,7 +216,12 @@ char * os_readfile(const char *name, size_t *len)
                return NULL;
        }
 
-       fread(buf, 1, *len, f);
+       if (fread(buf, 1, *len, f) != *len) {
+               fclose(f);
+               free(buf);
+               return NULL;
+       }
+
        fclose(f);
 
        return buf;
index bd31d8b..6758d9e 100644 (file)
@@ -44,12 +44,6 @@ struct preauth_test_data {
 };
 
 
-static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
-{
-       wpa_supplicant_req_scan(wpa_s, sec, usec);
-}
-
-
 static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
 {
        wpa_supplicant_disassociate(wpa_s, reason_code);
@@ -254,7 +248,6 @@ static void wpa_init_conf(struct wpa_supplicant *wpa_s, const char *ifname)
        ctx->ctx = wpa_s;
        ctx->set_state = _wpa_supplicant_set_state;
        ctx->get_state = _wpa_supplicant_get_state;
-       ctx->req_scan = _wpa_supplicant_req_scan;
        ctx->deauthenticate = _wpa_supplicant_deauthenticate;
        ctx->disassociate = _wpa_supplicant_disassociate;
        ctx->set_key = wpa_supplicant_set_key;
index 743f340..afa4f93 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -801,6 +801,7 @@ static u8 * decrypt_ms_key(const u8 *key, size_t len,
        ppos = plain = os_malloc(plen);
        if (plain == NULL)
                return NULL;
+       plain[0] = 0;
 
        while (left > 0) {
                /* b(1) = MD5(Secret + Request-Authenticator + Salt)
@@ -825,7 +826,7 @@ static u8 * decrypt_ms_key(const u8 *key, size_t len,
                left -= MD5_MAC_LEN;
        }
 
-       if (plain[0] > plen - 1) {
+       if (plain[0] == 0 || plain[0] > plen - 1) {
                printf("Failed to decrypt MPPE key\n");
                os_free(plain);
                return NULL;
diff --git a/sha1.c b/sha1.c
index 194db16..e53c845 100644 (file)
--- a/sha1.c
+++ b/sha1.c
@@ -265,6 +265,10 @@ int tls_prf(const u8 *secret, size_t secret_len, const char *label,
        L_S1 = L_S2 = (secret_len + 1) / 2;
        S1 = secret;
        S2 = secret + L_S1;
+       if (secret_len & 1) {
+               /* The last byte of S1 will be shared with S2 */
+               S2--;
+       }
 
        hmac_md5_vector(S1, L_S1, 2, &MD5_addr[1], &MD5_len[1], A_MD5);
        hmac_sha1_vector(S2, L_S2, 2, &SHA1_addr[1], &SHA1_len[1], A_SHA1);
index d5aafaa..cb6b974 100644 (file)
@@ -871,6 +871,7 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
 {
        SSL_CTX *ssl = ssl_ctx;
        struct tls_connection *conn;
+       long options;
 
        conn = os_zalloc(sizeof(*conn));
        if (conn == NULL)
@@ -884,9 +885,12 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
        }
 
        SSL_set_app_data(conn->ssl, conn);
-       SSL_set_options(conn->ssl,
-                       SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
-                       SSL_OP_SINGLE_DH_USE);
+       options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
+               SSL_OP_SINGLE_DH_USE;
+#ifdef SSL_OP_NO_COMPRESSION
+       options |= SSL_OP_NO_COMPRESSION;
+#endif /* SSL_OP_NO_COMPRESSION */
+       SSL_set_options(conn->ssl, options);
 
        conn->ssl_in = BIO_new(BIO_s_mem());
        if (!conn->ssl_in) {
index 364d8ae..fa00fcc 100644 (file)
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define VERSION_STR "0.5.10"
+#define VERSION_STR "0.5.11"
 
 #endif /* VERSION_H */
diff --git a/wpa.c b/wpa.c
index 5669e6a..7ef746a 100644 (file)
--- a/wpa.c
+++ b/wpa.c
@@ -65,8 +65,7 @@ static const u8 WPA_CIPHER_SUITE_WEP104[] = { 0x00, 0x50, 0xf2, 5 };
 struct wpa_ie_hdr {
        u8 elem_id;
        u8 len;
-       u8 oui[3];
-       u8 oui_type;
+       u8 oui[4]; /* 24-bit OUI followed by 8-bit OUI type */
        u8 version[2];
 } STRUCT_PACKED;
 
@@ -1406,7 +1405,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
                                           "caching attempt");
                                sm->cur_pmksa = NULL;
                                abort_cached = 1;
-                       } else {
+                       } else if (!abort_cached) {
                                return -1;
                        }
                }
@@ -1567,7 +1566,6 @@ static void wpa_supplicant_key_neg_complete(struct wpa_sm *sm,
                MACSTR " [PTK=%s GTK=%s]", MAC2STR(addr),
                wpa_cipher_txt(sm->pairwise_cipher),
                wpa_cipher_txt(sm->group_cipher));
-       eloop_cancel_timeout(sm->ctx->scan, sm->ctx->ctx, NULL);
        wpa_sm_cancel_auth_timeout(sm);
        wpa_sm_set_state(sm, WPA_COMPLETED);
 
@@ -1904,7 +1902,6 @@ static void wpa_report_ie_mismatch(struct wpa_sm *sm,
        }
 
        wpa_sm_disassociate(sm, REASON_IE_IN_4WAY_DIFFERS);
-       wpa_sm_req_scan(sm, 0, 0);
 }
 
 
@@ -3798,7 +3795,6 @@ static void wpa_sm_pmksa_free_cb(struct rsn_pmksa_cache_entry *entry,
 
                os_memset(sm->pmk, 0, sizeof(sm->pmk));
                wpa_sm_deauthenticate(sm, REASON_UNSPECIFIED);
-               wpa_sm_req_scan(sm, 0, 0);
        }
 }
 
diff --git a/wpa.h b/wpa.h
index df075c3..8a9ae76 100644 (file)
--- a/wpa.h
+++ b/wpa.h
@@ -59,7 +59,6 @@ struct wpa_sm_ctx {
 
        void (*set_state)(void *ctx, wpa_states state);
        wpa_states (*get_state)(void *ctx);
-       void (*req_scan)(void *ctx, int sec, int usec);
        void (*deauthenticate)(void * ctx, int reason_code); 
        void (*disassociate)(void *ctx, int reason_code);
        int (*set_key)(void *ctx, wpa_alg alg,
index 6ea35e0..b8e17ac 100644 (file)
@@ -12,6 +12,7 @@
  * See README and COPYING for more details.
  */
 
+#include <cstdio>
 #include <QMessageBox>
 
 #include "networkconfig.h"
index 57cf716..75d1c51 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <QTimer>
 
+#include <cstdio>
+
 #include "scanresults.h"
 #include "wpagui.h"
 #include "networkconfig.h"
index 31cb38c..798786b 100644 (file)
@@ -17,6 +17,7 @@
 #include <unistd.h>
 #endif
 
+#include <cstdio>
 #include <QMessageBox>
 
 #include "wpagui.h"
index a3cd733..22afed9 100644 (file)
@@ -10,6 +10,7 @@
 ** destructor.
 *****************************************************************************/
 
+#include <stdlib.h>
 
 enum {
     AUTH_NONE = 0,
index 4b47ccd..66d4478 100644 (file)
@@ -10,6 +10,8 @@
 ** destructor.
 *****************************************************************************/
 
+#include <stdlib.h>
+
 int UserDataRequest::setParams(WpaGui *_wpagui, const char *reqMsg)
 {
     char *tmp, *pos, *pos2;
index 6db8862..3f86c16 100644 (file)
@@ -16,6 +16,7 @@
 #include <unistd.h>
 #endif
 
+#include <stdlib.h>
 
 void WpaGui::init()
 {
diff --git a/wpa_i.h b/wpa_i.h
index b5adb5e..d1cab4b 100644 (file)
--- a/wpa_i.h
+++ b/wpa_i.h
@@ -146,11 +146,6 @@ static inline wpa_states wpa_sm_get_state(struct wpa_sm *sm)
        return sm->ctx->get_state(sm->ctx->ctx);
 }
 
-static inline void wpa_sm_req_scan(struct wpa_sm *sm, int sec, int usec)
-{
-       sm->ctx->req_scan(sm->ctx->ctx, sec, usec);
-}
-
 static inline void wpa_sm_deauthenticate(struct wpa_sm *sm, int reason_code)
 {
        sm->ctx->deauthenticate(sm->ctx->ctx, reason_code);
index 15188fe..706a010 100644 (file)
@@ -365,7 +365,6 @@ static void wpa_supplicant_notify_eapol_done(void *ctx)
        if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X) {
                wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
        } else {
-               eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
                wpa_supplicant_cancel_auth_timeout(wpa_s);
                wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
        }
@@ -493,6 +492,28 @@ void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
  */
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
 {
+       /* If there's at least one network that should be specifically scanned
+        * then don't cancel the scan and reschedule.  Some drivers do
+        * background scanning which generates frequent scan results, and that
+        * causes the specific SSID scan to get continually pushed back and
+        * never happen, which causes hidden APs to never get probe-scanned.
+        */
+       if (eloop_is_timeout_registered(wpa_supplicant_scan, wpa_s, NULL) &&
+           wpa_s->conf->ap_scan == 1) {
+               struct wpa_ssid *ssid = wpa_s->conf->ssid;
+
+               while (ssid) {
+                       if (!ssid->disabled && ssid->scan_ssid)
+                               break;
+                       ssid = ssid->next;
+               }
+               if (ssid) {
+                       wpa_msg(wpa_s, MSG_DEBUG, "Not rescheduling scan to "
+                               "ensure that specific SSID scans occur");
+                       return;
+               }
+       }
+
        wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
                sec, usec);
        eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
@@ -800,10 +821,10 @@ const char * wpa_supplicant_state_txt(int state)
 void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state)
 {
 #ifdef ANDROID
-        int network_id = -1;
-        if (wpa_s && wpa_s->current_ssid) {
-            network_id = wpa_s->current_ssid->id;
-        }
+       int network_id = -1;
+       if (wpa_s && wpa_s->current_ssid) {
+               network_id = wpa_s->current_ssid->id;
+       }
        wpa_states reported_state = state;
        if (state == WPA_DISCONNECTED && wpa_s->disconnected) {
                reported_state = WPA_IDLE;
@@ -1065,6 +1086,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 
        if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1) {
                wpa_s->scan_res_tried++;
+               wpa_s->scan_req = scan_req;
                wpa_printf(MSG_DEBUG, "Trying to get current scan results "
                           "first without requesting a new scan to speed up "
                           "initial association");
@@ -1535,13 +1557,15 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
                wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
        } else {
                /* Timeout for IEEE 802.11 authentication and association */
-               int timeout;
-               if (assoc_failed)
-                       timeout = 5;
-               else if (wpa_s->conf->ap_scan == 1)
-                       timeout = 10;
-               else
-                       timeout = 60;
+               int timeout = 60;
+
+               if (assoc_failed) {
+                       /* give IBSS a bit more time */
+                       timeout = ssid->mode ? 10 : 5;
+               } else if (wpa_s->conf->ap_scan == 1) {
+                       /* give IBSS a bit more time */
+                       timeout = ssid->mode ? 20 : 10;
+               }
                wpa_supplicant_req_auth_timeout(wpa_s, timeout, 0);
        }
 
@@ -1811,12 +1835,6 @@ static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
 }
 
 
-static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
-{
-       wpa_supplicant_req_scan(wpa_s, sec, usec);
-}
-
-
 static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
 {
        wpa_supplicant_cancel_auth_timeout(wpa_s);
@@ -1838,12 +1856,16 @@ static wpa_states _wpa_supplicant_get_state(void *wpa_s)
 static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
 {
        wpa_supplicant_disassociate(wpa_s, reason_code);
+       /* Schedule a scan to make sure we continue looking for networks */
+       wpa_supplicant_req_scan(wpa_s, 0, 0);
 }
 
 
 static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
 {
        wpa_supplicant_deauthenticate(wpa_s, reason_code);
+       /* Schedule a scan to make sure we continue looking for networks */
+       wpa_supplicant_req_scan(wpa_s, 0, 0);
 }
 
 
@@ -2221,7 +2243,6 @@ static int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
        ctx->ctx = wpa_s;
        ctx->set_state = _wpa_supplicant_set_state;
        ctx->get_state = _wpa_supplicant_get_state;
-       ctx->req_scan = _wpa_supplicant_req_scan;
        ctx->deauthenticate = _wpa_supplicant_deauthenticate;
        ctx->disassociate = _wpa_supplicant_disassociate;
        ctx->set_key = wpa_supplicant_set_key;
@@ -2425,10 +2446,10 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
        char scan_prop[PROPERTY_VALUE_MAX];
        char *endp;
        if (property_get("wifi.supplicant_scan_interval", scan_prop, "5") != 0) {
-           wpa_s->scan_interval = (int)strtol(scan_prop, &endp, 0);
-           if (endp == scan_prop) {
-               wpa_s->scan_interval = 5;
-           }
+               wpa_s->scan_interval = (int)strtol(scan_prop, &endp, 0);
+               if (endp == scan_prop) {
+                       wpa_s->scan_interval = 5;
+               }
        }
 #endif
        wpa_s->next = global->ifaces;