summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsam <sam@FreeBSD.org>2007-07-11 15:58:52 +0000
committersam <sam@FreeBSD.org>2007-07-11 15:58:52 +0000
commitf2e5f38ec4b02cb33d67218cb24312f6e522cf58 (patch)
tree2ac7b230023aef064f602608ca239d971e0e4ac3
parent752f54d1e6282a9ab07c3c1b8873e85478e1b5d2 (diff)
downloadFreeBSD-src-f2e5f38ec4b02cb33d67218cb24312f6e522cf58.zip
FreeBSD-src-f2e5f38ec4b02cb33d67218cb24312f6e522cf58.tar.gz
resolve merge conflicts
Reviewed by: thompsa, sephe Approved by: re (hrs)
-rw-r--r--contrib/wpa_supplicant/common.h312
-rw-r--r--contrib/wpa_supplicant/driver_ndis_.c164
-rw-r--r--contrib/wpa_supplicant/events.c257
-rw-r--r--contrib/wpa_supplicant/wpa_ctrl.c295
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/eventhistory.ui.h41
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.ui.h513
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/scanresults.ui.h101
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui.h70
-rw-r--r--contrib/wpa_supplicant/wpa_gui-qt4/wpagui.ui.h651
-rw-r--r--contrib/wpa_supplicant/wpa_supplicant.c939
10 files changed, 1372 insertions, 1971 deletions
diff --git a/contrib/wpa_supplicant/common.h b/contrib/wpa_supplicant/common.h
index eab0410..ae70600 100644
--- a/contrib/wpa_supplicant/common.h
+++ b/contrib/wpa_supplicant/common.h
@@ -1,6 +1,6 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
- * Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,12 +17,14 @@
#ifndef COMMON_H
#define COMMON_H
+#include "os.h"
+
#ifdef __linux__
#include <endian.h>
#include <byteswap.h>
#endif /* __linux__ */
-#if defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
@@ -31,51 +33,22 @@
#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64
-#endif /* defined(__FreeBSD__) || defined(__NetBSD__) */
-
-#ifdef CONFIG_NATIVE_WINDOWS
-#include <winsock2.h>
-
-static inline int daemon(int nochdir, int noclose)
-{
- printf("Windows - daemon() not supported yet\n");
- return -1;
-}
-
-static inline void sleep(int seconds)
-{
- Sleep(seconds * 1000);
-}
-
-static inline void usleep(unsigned long usec)
-{
- Sleep(usec / 1000);
-}
-
-#ifndef timersub
-#define timersub(a, b, res) do { \
- (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
- (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
- if ((res)->tv_usec < 0) { \
- (res)->tv_sec--; \
- (res)->tv_usec += 1000000; \
- } \
-} while (0)
+#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
+ * defined(__DragonFly__) */
+
+#ifdef CONFIG_TI_COMPILER
+#define __BIG_ENDIAN 4321
+#define __LITTLE_ENDIAN 1234
+#ifdef __big_endian__
+#define __BYTE_ORDER __BIG_ENDIAN
+#else
+#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
+#endif /* CONFIG_TI_COMPILER */
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-
-int gettimeofday(struct timeval *tv, struct timezone *tz);
-
-static inline long int random(void)
-{
- return rand();
-}
+#ifdef CONFIG_NATIVE_WINDOWS
+#include <winsock.h>
-typedef int gid_t;
typedef int socklen_t;
#ifndef MSG_DONTWAIT
@@ -86,6 +59,10 @@ typedef int socklen_t;
#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
+#ifdef _MSC_VER
+#define inline __inline
+#endif /* _MSC_VER */
+
static inline unsigned short wpa_swap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
@@ -107,6 +84,18 @@ static inline unsigned int wpa_swap_32(unsigned int v)
#else /* __CYGWIN__ */
+#ifndef __BYTE_ORDER
+#ifndef __LITTLE_ENDIAN
+#ifndef __BIG_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#if defined(sparc)
+#define __BYTE_ORDER __BIG_ENDIAN
+#endif
+#endif /* __BIG_ENDIAN */
+#endif /* __LITTLE_ENDIAN */
+#endif /* __BYTE_ORDER */
+
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
@@ -115,6 +104,10 @@ static inline unsigned int wpa_swap_32(unsigned int v)
#define le_to_host32(n) (n)
#define be_to_host32(n) bswap_32(n)
#define host_to_be32(n) bswap_32(n)
+#define le_to_host64(n) (n)
+#define host_to_le64(n) (n)
+#define be_to_host64(n) bswap_64(n)
+#define host_to_be64(n) bswap_64(n)
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
@@ -123,6 +116,10 @@ static inline unsigned int wpa_swap_32(unsigned int v)
#define le_to_host32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
+#define le_to_host64(n) bswap_64(n)
+#define host_to_le64(n) bswap_64(n)
+#define be_to_host64(n) (n)
+#define host_to_be64(n) (n)
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#endif
@@ -147,12 +144,88 @@ static inline unsigned int wpa_swap_32(unsigned int v)
(a)[0] = ((u16) (val)) & 0xff; \
} while (0)
+#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
+ ((u32) (a)[2]))
+#define WPA_PUT_BE24(a, val) \
+ do { \
+ (a)[0] = (u8) (((u32) (val)) >> 16); \
+ (a)[1] = (u8) (((u32) (val)) >> 8); \
+ (a)[2] = (u8) (((u32) (val)) & 0xff); \
+ } while (0)
+
+#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
+ (((u32) (a)[2]) << 8) | ((u32) (a)[3]))
+#define WPA_PUT_BE32(a, val) \
+ do { \
+ (a)[0] = (u8) (((u32) (val)) >> 24); \
+ (a)[1] = (u8) (((u32) (val)) >> 16); \
+ (a)[2] = (u8) (((u32) (val)) >> 8); \
+ (a)[3] = (u8) (((u32) (val)) & 0xff); \
+ } while (0)
+
+#define WPA_PUT_BE64(a, val) \
+ do { \
+ (a)[0] = (u8) (((u64) (val)) >> 56); \
+ (a)[1] = (u8) (((u64) (val)) >> 48); \
+ (a)[2] = (u8) (((u64) (val)) >> 40); \
+ (a)[3] = (u8) (((u64) (val)) >> 32); \
+ (a)[4] = (u8) (((u64) (val)) >> 24); \
+ (a)[5] = (u8) (((u64) (val)) >> 16); \
+ (a)[6] = (u8) (((u64) (val)) >> 8); \
+ (a)[7] = (u8) (((u64) (val)) & 0xff); \
+ } while (0)
+
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
+#ifdef _MSC_VER
+typedef UINT64 u64;
+typedef UINT32 u32;
+typedef UINT16 u16;
+typedef UINT8 u8;
+typedef INT64 s64;
+typedef INT32 s32;
+typedef INT16 s16;
+typedef INT8 s8;
+#define WPA_TYPES_DEFINED
+#endif /* _MSC_VER */
+
+#ifdef __vxworks
+typedef unsigned long long u64;
+typedef UINT32 u32;
+typedef UINT16 u16;
+typedef UINT8 u8;
+typedef long long s64;
+typedef INT32 s32;
+typedef INT16 s16;
+typedef INT8 s8;
+#define WPA_TYPES_DEFINED
+#endif /* __vxworks */
+
+#ifdef CONFIG_TI_COMPILER
+#ifdef _LLONG_AVAILABLE
+typedef unsigned long long u64;
+#else
+/*
+ * TODO: 64-bit variable not available. Using long as a workaround to test the
+ * build, but this will likely not work for all operations.
+ */
+typedef unsigned long u64;
+#endif
+typedef unsigned int u32;
+typedef unsigned short u16;
+typedef unsigned char u8;
+#define WPA_TYPES_DEFINED
+#endif /* CONFIG_TI_COMPILER */
+
+#ifndef WPA_TYPES_DEFINED
+#ifdef CONFIG_USE_INTTYPES_H
+#include <inttypes.h>
+#else
#include <stdint.h>
+#endif
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
@@ -161,19 +234,27 @@ typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
+#define WPA_TYPES_DEFINED
+#endif /* !WPA_TYPES_DEFINED */
-int hostapd_get_rand(u8 *buf, size_t len);
-void hostapd_hexdump(const char *title, const u8 *buf, size_t len);
+#define hostapd_get_rand os_get_random
int hwaddr_aton(const char *txt, u8 *addr);
int hexstr2bin(const char *hex, u8 *buf, size_t len);
-char * rel2abs_path(const char *rel_path);
void inc_byte_array(u8 *counter, size_t len);
-void print_char(char c);
-void fprint_char(FILE *f, char c);
+void wpa_get_ntp_timestamp(u8 *buf);
+
+
+#ifdef __GNUC__
+#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
+#define STRUCT_PACKED __attribute__ ((packed))
+#else
+#define PRINTF_FORMAT(a,b)
+#define STRUCT_PACKED
+#endif
/* Debugging function - conditional printf and hex dump. Driver wrappers can
- * use these for debugging purposes. */
+ * use these for debugging purposes. */
enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR };
@@ -181,13 +262,18 @@ enum { MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR };
#define wpa_debug_print_timestamp() do { } while (0)
#define wpa_printf(args...) do { } while (0)
-#define wpa_hexdump(args...) do { } while (0)
-#define wpa_hexdump_key(args...) do { } while (0)
-#define wpa_hexdump_ascii(args...) do { } while (0)
-#define wpa_hexdump_ascii_key(args...) do { } while (0)
+#define wpa_hexdump(l,t,b,le) do { } while (0)
+#define wpa_hexdump_key(l,t,b,le) do { } while (0)
+#define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
+#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
+#define wpa_debug_open_file() do { } while (0)
+#define wpa_debug_close_file() do { } while (0)
#else /* CONFIG_NO_STDOUT_DEBUG */
+int wpa_debug_open_file(void);
+void wpa_debug_close_file(void);
+
/**
* wpa_debug_printf_timestamp - Print timestamp for debug output
*
@@ -209,7 +295,7 @@ void wpa_debug_print_timestamp(void);
* Note: New line '\n' is added to the end of the text when printing to stdout.
*/
void wpa_printf(int level, char *fmt, ...)
-__attribute__ ((format (printf, 2, 3)));
+PRINTF_FORMAT(2, 3);
/**
* wpa_hexdump - conditional hex dump
@@ -275,6 +361,42 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
#endif /* CONFIG_NO_STDOUT_DEBUG */
+#ifdef CONFIG_NO_WPA_MSG
+#define wpa_msg(args...) do { } while (0)
+#define wpa_msg_register_cb(f) do { } while (0)
+#else /* CONFIG_NO_WPA_MSG */
+/**
+ * wpa_msg - Conditional printf for default target and ctrl_iface monitors
+ * @ctx: Pointer to context data; this is the ctx variable registered
+ * with struct wpa_driver_ops::init()
+ * @level: priority level (MSG_*) of the message
+ * @fmt: printf format string, followed by optional arguments
+ *
+ * This function is used to print conditional debugging and error messages. The
+ * output may be directed to stdout, stderr, and/or syslog based on
+ * configuration. This function is like wpa_printf(), but it also sends the
+ * same message to all attached ctrl_iface monitors.
+ *
+ * Note: New line '\n' is added to the end of the text when printing to stdout.
+ */
+void wpa_msg(void *ctx, int level, char *fmt, ...) PRINTF_FORMAT(3, 4);
+
+typedef void (*wpa_msg_cb_func)(void *ctx, int level, const char *txt,
+ size_t len);
+
+/**
+ * wpa_msg_register_cb - Register callback function for wpa_msg() messages
+ * @func: Callback function (%NULL to unregister)
+ */
+void wpa_msg_register_cb(wpa_msg_cb_func func);
+#endif /* CONFIG_NO_WPA_MSG */
+
+
+int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
+int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
+ size_t len);
+
+
#ifdef EAPOL_TEST
#define WPA_ASSERT(a) \
do { \
@@ -289,4 +411,84 @@ void wpa_hexdump_ascii_key(int level, const char *title, const u8 *buf,
#define WPA_ASSERT(a) do { } while (0)
#endif
+
+#ifdef _MSC_VER
+#undef vsnprintf
+#define vsnprintf _vsnprintf
+#undef close
+#define close closesocket
+#endif /* _MSC_VER */
+
+
+#ifdef CONFIG_ANSI_C_EXTRA
+
+#if !defined(_MSC_VER) || _MSC_VER < 1400
+/* snprintf - used in number of places; sprintf() is _not_ a good replacement
+ * due to possible buffer overflow; see, e.g.,
+ * http://www.ijs.si/software/snprintf/ for portable implementation of
+ * snprintf. */
+int snprintf(char *str, size_t size, const char *format, ...);
+
+/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */
+int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */
+
+/* getopt - only used in main.c */
+int getopt(int argc, char *const argv[], const char *optstring);
+extern char *optarg;
+extern int optind;
+
+#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF
+#ifndef __socklen_t_defined
+typedef int socklen_t;
+#endif
+#endif
+
+/* inline - define as __inline or just define it to be empty, if needed */
+#ifdef CONFIG_NO_INLINE
+#define inline
+#else
+#define inline __inline
+#endif
+
+#ifndef __func__
+#define __func__ "__func__ not defined"
+#endif
+
+#ifndef bswap_16
+#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
+#endif
+
+#ifndef bswap_32
+#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \
+ (((u32) (a) << 8) & 0xff0000) | \
+ (((u32) (a) >> 8) & 0xff00) | \
+ (((u32) (a) >> 24) & 0xff))
+#endif
+
+#ifndef MSG_DONTWAIT
+#define MSG_DONTWAIT 0
+#endif
+
+#ifdef _WIN32_WCE
+void perror(const char *s);
+#endif /* _WIN32_WCE */
+
+#endif /* CONFIG_ANSI_C_EXTRA */
+
+#define wpa_zalloc(s) os_zalloc((s))
+
+#ifdef CONFIG_NATIVE_WINDOWS
+void wpa_unicode2ascii_inplace(TCHAR *str);
+TCHAR * wpa_strdup_tchar(const char *str);
+#else /* CONFIG_NATIVE_WINDOWS */
+#define wpa_unicode2ascii_inplace(s) do { } while (0)
+#define wpa_strdup_tchar(s) strdup((s))
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len);
+
+typedef u32 __be32;
+typedef u64 __be64;
+
#endif /* COMMON_H */
diff --git a/contrib/wpa_supplicant/driver_ndis_.c b/contrib/wpa_supplicant/driver_ndis_.c
deleted file mode 100644
index e71b13b..0000000
--- a/contrib/wpa_supplicant/driver_ndis_.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * WPA Supplicant - Windows/NDIS driver interface - event processing
- * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/unistd.h>
-#include <sys/types.h>
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
-
-#include "common.h"
-#include "driver.h"
-#include "wpa_supplicant.h"
-#include "l2_packet.h"
-#include "eloop.h"
-#include "wpa.h"
-
-/* Keep this event processing in a separate file and without WinPcap headers to
- * avoid conflicts with some of the header files. */
-struct _ADAPTER;
-typedef struct _ADAPTER * LPADAPTER;
-#include "driver_ndis.h"
-
-
-void wpa_driver_ndis_event_connect(struct wpa_driver_ndis_data *drv);
-void wpa_driver_ndis_event_disconnect(struct wpa_driver_ndis_data *drv);
-void wpa_driver_ndis_event_media_specific(struct wpa_driver_ndis_data *drv,
- const u8 *data, size_t data_len);
-
-
-enum event_types { EVENT_CONNECT, EVENT_DISCONNECT,
- EVENT_MEDIA_SPECIFIC };
-
-/* Event data:
- * enum event_types (as int, i.e., 4 octets)
- * InstanceName length (1 octet)
- * InstanceName (variable len)
- * data length (1 octet, optional)
- * data (variable len, optional)
- */
-
-
-static void wpa_driver_ndis_event_cb(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wpa_driver_ndis_data *drv = eloop_ctx;
- u8 buf[512], *pos, *data = NULL;
- int res, i, desc_len;
- enum event_types type;
- unsigned char instance_len;
- char *instance;
- size_t data_len = 0;
-
- res = recv(sock, buf, sizeof(buf), 0);
- if (res < 0) {
- perror("wpa_driver_ndis_event_cb - recv");
- return;
- }
- wpa_hexdump(MSG_MSGDUMP, "NDIS: received event data", buf, res);
- if (res < sizeof(int) + 1)
- return;
- type = *((int *) buf);
- pos = buf + sizeof(int);
- wpa_printf(MSG_DEBUG, "NDIS: event - type %d", type);
- instance_len = *pos++;
- if (instance_len > buf + res - pos) {
- wpa_printf(MSG_DEBUG, "NDIS: event InstanceName overflow");
- return;
- }
- instance = pos;
- pos += instance_len;
- wpa_hexdump_ascii(MSG_MSGDUMP, "NDIS: event InstanceName",
- instance, instance_len);
-
- if (buf + res - pos > 1) {
- data_len = *pos++;
- if (data_len > buf + res - pos) {
- wpa_printf(MSG_DEBUG, "NDIS: event data overflow");
- return;
- }
- data = pos;
- wpa_hexdump(MSG_MSGDUMP, "NDIS: event data", data, data_len);
- }
-
- if (drv->adapter_desc) {
- desc_len = strlen(drv->adapter_desc);
- if (instance_len < desc_len ||
- strncmp(drv->adapter_desc, instance, desc_len)) {
- wpa_printf(MSG_DEBUG, "NDIS: ignored event for "
- "another adapter");
- return;
- }
-
- /* InstanceName:
- * <driver desc> #<num>
- * <driver desc> #<num> - <intermediate drv name> Miniport
- */
- for (i = desc_len + 1; i < instance_len; i++) {
- if (instance[i] == '-') {
- wpa_printf(MSG_DEBUG, "NDIS: ignored event "
- "for intermediate miniport");
- return;
- }
- }
- }
-
- switch (type) {
- case EVENT_CONNECT:
- wpa_driver_ndis_event_connect(drv);
- break;
- case EVENT_DISCONNECT:
- wpa_driver_ndis_event_disconnect(drv);
- break;
- case EVENT_MEDIA_SPECIFIC:
- wpa_driver_ndis_event_media_specific(drv, data, data_len);
- break;
- }
-}
-
-
-int wpa_driver_register_event_cb(struct wpa_driver_ndis_data *drv)
-{
- struct sockaddr_in addr;
-
- drv->event_sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (drv->event_sock < 0) {
- perror("socket");
- return -1;
- }
-
- /* These events are received from an external program, ndis_events,
- * which is converting WMI events to more "UNIX-like" input for
- * wpa_supplicant, i.e., UDP packets that can be received through the
- * eloop mechanism. */
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl((127 << 24) | 1);
- addr.sin_port = htons(9876);
- if (bind(drv->event_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
- {
- perror("bind");
- close(drv->event_sock);
- drv->event_sock = -1;
- return -1;
- }
-
- eloop_register_read_sock(drv->event_sock, wpa_driver_ndis_event_cb,
- drv, NULL);
-
- return 0;
-}
diff --git a/contrib/wpa_supplicant/events.c b/contrib/wpa_supplicant/events.c
index b1207ba..89bb9b9 100644
--- a/contrib/wpa_supplicant/events.c
+++ b/contrib/wpa_supplicant/events.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant - Driver event processing
- * Copyright (c) 2003-2006, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2003-2006, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,11 +14,7 @@
* $FreeBSD$
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
+#include "includes.h"
#include "common.h"
#include "eapol_sm.h"
@@ -30,8 +26,10 @@
#include "wpa_supplicant_i.h"
#include "pcsc_funcs.h"
#include "preauth.h"
+#include "pmksa_cache.h"
#include "wpa_ctrl.h"
#include "eap.h"
+#include "ctrl_iface_dbus.h"
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
@@ -65,6 +63,8 @@ static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
}
+ if (wpa_s->current_ssid && wpa_s->current_ssid != ssid)
+ eapol_sm_invalidate_cached_session(wpa_s->eapol);
wpa_s->current_ssid = ssid;
wpa_sm_set_config(wpa_s->wpa, wpa_s->current_ssid);
wpa_supplicant_initiate_eapol(wpa_s);
@@ -87,10 +87,11 @@ static void wpa_supplicant_stop_countermeasures(void *eloop_ctx,
}
-static void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
+void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
{
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK)
@@ -147,6 +148,7 @@ static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
return 0;
+#ifdef IEEE8021X_EAPOL
if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
wpa_s->current_ssid &&
!(wpa_s->current_ssid->eapol_flags &
@@ -156,6 +158,7 @@ static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
* plaintext or static WEP keys). */
return 0;
}
+#endif /* IEEE8021X_EAPOL */
return 1;
}
@@ -173,6 +176,7 @@ static int wpa_supplicant_dynamic_keys(struct wpa_supplicant *wpa_s)
int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
+#ifdef IEEE8021X_EAPOL
int aka = 0, sim = 0, type;
if (ssid->pcsc == NULL || wpa_s->scard != NULL)
@@ -182,22 +186,23 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
sim = 1;
aka = 1;
} else {
- u8 *eap = ssid->eap_methods;
- while (*eap != EAP_TYPE_NONE) {
- if (*eap == EAP_TYPE_SIM)
- sim = 1;
- else if (*eap == EAP_TYPE_AKA)
- aka = 1;
+ struct eap_method_type *eap = ssid->eap_methods;
+ while (eap->vendor != EAP_VENDOR_IETF ||
+ eap->method != EAP_TYPE_NONE) {
+ if (eap->vendor == EAP_VENDOR_IETF) {
+ if (eap->method == EAP_TYPE_SIM)
+ sim = 1;
+ else if (eap->method == EAP_TYPE_AKA)
+ aka = 1;
+ }
eap++;
}
}
-#ifndef EAP_SIM
- sim = 0;
-#endif /* EAP_SIM */
-#ifndef EAP_AKA
- aka = 0;
-#endif /* EAP_AKA */
+ if (eap_sm_get_eap_methods(EAP_VENDOR_IETF, EAP_TYPE_SIM) == NULL)
+ sim = 0;
+ if (eap_sm_get_eap_methods(EAP_VENDOR_IETF, EAP_TYPE_AKA) == NULL)
+ aka = 0;
if (!sim && !aka) {
wpa_printf(MSG_DEBUG, "Selected network is configured to use "
@@ -222,6 +227,7 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
}
wpa_sm_set_scard_ctx(wpa_s->wpa, wpa_s->scard);
eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
+#endif /* IEEE8021X_EAPOL */
return 0;
}
@@ -232,16 +238,21 @@ static int wpa_supplicant_match_privacy(struct wpa_scan_result *bss,
{
int i, privacy = 0;
+ if (ssid->mixed_cell)
+ return 1;
+
for (i = 0; i < NUM_WEP_KEYS; i++) {
if (ssid->wep_key_len[i]) {
privacy = 1;
break;
}
}
+#ifdef IEEE8021X_EAPOL
if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
ssid->eapol_flags & (EAPOL_FLAG_REQUIRE_KEY_UNICAST |
EAPOL_FLAG_REQUIRE_KEY_BROADCAST))
privacy = 1;
+#endif /* IEEE8021X_EAPOL */
if (bss->caps & IEEE80211_CAP_PRIVACY)
return privacy;
@@ -286,6 +297,15 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_ssid *ssid,
break;
}
+#ifdef CONFIG_IEEE80211W
+ if (!(ie.capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION)
+ && ssid->ieee80211w == IEEE80211W_REQUIRED) {
+ wpa_printf(MSG_DEBUG, " skip RSN IE - no mgmt frame "
+ "protection");
+ break;
+ }
+#endif /* CONFIG_IEEE80211W */
+
wpa_printf(MSG_DEBUG, " selected based on RSN IE");
return 1;
}
@@ -348,6 +368,7 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
bss = NULL;
ssid = NULL;
/* First, try to find WPA-enabled AP */
+ wpa_printf(MSG_DEBUG, "Try to find WPA-enabled AP");
for (i = 0; i < num && !selected; i++) {
bss = &results[i];
wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
@@ -356,8 +377,8 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
wpa_ssid_txt(bss->ssid, bss->ssid_len),
(unsigned long) bss->wpa_ie_len,
(unsigned long) bss->rsn_ie_len, bss->caps);
- if ((e = wpa_blacklist_get(wpa_s, bss->bssid)) &&
- e->count > 1) {
+ e = wpa_blacklist_get(wpa_s, bss->bssid);
+ if (e && e->count > 1) {
wpa_printf(MSG_DEBUG, " skip - blacklisted");
continue;
}
@@ -368,17 +389,20 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
}
for (ssid = group; ssid; ssid = ssid->pnext) {
- if (ssid->disabled)
+ if (ssid->disabled) {
+ wpa_printf(MSG_DEBUG, " skip - disabled");
continue;
+ }
if (bss->ssid_len != ssid->ssid_len ||
- memcmp(bss->ssid, ssid->ssid,
- bss->ssid_len) != 0) {
+ os_memcmp(bss->ssid, ssid->ssid,
+ bss->ssid_len) != 0) {
wpa_printf(MSG_DEBUG, " skip - "
"SSID mismatch");
continue;
}
if (ssid->bssid_set &&
- memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0) {
+ os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
+ {
wpa_printf(MSG_DEBUG, " skip - "
"BSSID mismatch");
continue;
@@ -386,6 +410,11 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
if (wpa_supplicant_ssid_bss_match(ssid, bss)) {
selected = bss;
*selected_ssid = ssid;
+ wpa_printf(MSG_DEBUG, " selected WPA AP "
+ MACSTR " ssid='%s'",
+ MAC2STR(bss->bssid),
+ wpa_ssid_txt(bss->ssid,
+ bss->ssid_len));
break;
}
}
@@ -393,35 +422,76 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
/* If no WPA-enabled AP found, try to find non-WPA AP, if configuration
* allows this. */
+ wpa_printf(MSG_DEBUG, "Try to find non-WPA AP");
for (i = 0; i < num && !selected; i++) {
bss = &results[i];
- if ((e = wpa_blacklist_get(wpa_s, bss->bssid)) &&
- e->count > 1) {
+ wpa_printf(MSG_DEBUG, "%d: " MACSTR " ssid='%s' "
+ "wpa_ie_len=%lu rsn_ie_len=%lu caps=0x%x",
+ i, MAC2STR(bss->bssid),
+ wpa_ssid_txt(bss->ssid, bss->ssid_len),
+ (unsigned long) bss->wpa_ie_len,
+ (unsigned long) bss->rsn_ie_len, bss->caps);
+ e = wpa_blacklist_get(wpa_s, bss->bssid);
+ if (e && e->count > 1) {
+ wpa_printf(MSG_DEBUG, " skip - blacklisted");
continue;
}
for (ssid = group; ssid; ssid = ssid->pnext) {
- if (!ssid->disabled &&
- (ssid->ssid_len == 0 ||
- (bss->ssid_len == ssid->ssid_len &&
- memcmp(bss->ssid, ssid->ssid, bss->ssid_len) ==
- 0)) &&
- (!ssid->bssid_set ||
- memcmp(bss->bssid, ssid->bssid, ETH_ALEN) == 0) &&
- ((ssid->key_mgmt & WPA_KEY_MGMT_NONE) ||
- (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
- && bss->wpa_ie_len == 0 && bss->rsn_ie_len == 0 &&
- wpa_supplicant_match_privacy(bss, ssid) &&
- !(bss->caps & IEEE80211_CAP_IBSS))
+ if (ssid->disabled) {
+ wpa_printf(MSG_DEBUG, " skip - disabled");
+ continue;
+ }
+ if (bss->ssid_len != ssid->ssid_len ||
+ os_memcmp(bss->ssid, ssid->ssid,
+ bss->ssid_len) != 0) {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "SSID mismatch");
+ continue;
+ }
+
+ if (ssid->bssid_set &&
+ os_memcmp(bss->bssid, ssid->bssid, ETH_ALEN) != 0)
{
- selected = bss;
- *selected_ssid = ssid;
- wpa_printf(MSG_DEBUG, " selected non-WPA AP "
- MACSTR " ssid='%s'",
- MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid,
- bss->ssid_len));
- break;
+ wpa_printf(MSG_DEBUG, " skip - "
+ "BSSID mismatch");
+ continue;
+ }
+
+ if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
+ !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
+ {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "non-WPA network not allowed");
+ continue;
}
+
+ if ((ssid->key_mgmt &
+ (WPA_KEY_MGMT_IEEE8021X | WPA_KEY_MGMT_PSK)) ||
+ bss->wpa_ie_len != 0 || bss->rsn_ie_len != 0) {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "WPA network");
+ continue;
+ }
+
+ if (!wpa_supplicant_match_privacy(bss, ssid)) {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "privacy mismatch");
+ continue;
+ }
+
+ if (bss->caps & IEEE80211_CAP_IBSS) {
+ wpa_printf(MSG_DEBUG, " skip - "
+ "IBSS (adhoc) network");
+ continue;
+ }
+
+ selected = bss;
+ *selected_ssid = ssid;
+ wpa_printf(MSG_DEBUG, " selected non-WPA AP "
+ MACSTR " ssid='%s'",
+ MAC2STR(bss->bssid),
+ wpa_ssid_txt(bss->ssid, bss->ssid_len));
+ break;
}
}
@@ -431,7 +501,7 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
{
- int num, prio;
+ int num, prio, timeout;
struct wpa_scan_result *selected = NULL;
struct wpa_ssid *ssid = NULL;
struct wpa_scan_result *results;
@@ -441,9 +511,12 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
return;
wpa_printf(MSG_DEBUG, "Failed to get scan results - try "
"scanning again");
- wpa_supplicant_req_scan(wpa_s, 1, 0);
- return;
+ timeout = 1;
+ goto req_scan;
}
+
+ wpa_supplicant_dbus_notify_scan_results(wpa_s);
+
if (wpa_s->conf->ap_scan == 2)
return;
results = wpa_s->scan_results;
@@ -468,8 +541,15 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
}
if (selected) {
+ /* Do not trigger new association unless the BSSID has changed
+ * or if reassociation is requested. If we are in process of
+ * associating with the selected BSSID, do not trigger new
+ * attempt. */
if (wpa_s->reassociate ||
- memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0) {
+ (os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
+ (wpa_s->wpa_state != WPA_ASSOCIATING ||
+ os_memcmp(selected->bssid, wpa_s->pending_bssid,
+ ETH_ALEN) != 0))) {
if (wpa_supplicant_scard_init(wpa_s, ssid)) {
wpa_supplicant_req_scan(wpa_s, 10, 0);
return;
@@ -482,8 +562,22 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
rsn_preauth_scan_results(wpa_s->wpa, results, num);
} else {
wpa_printf(MSG_DEBUG, "No suitable AP found.");
- wpa_supplicant_req_scan(wpa_s, 5, 0);
+ timeout = 5;
+ goto req_scan;
}
+
+ return;
+
+req_scan:
+ if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) {
+ /*
+ * Quick recovery if the initial scan results were not
+ * complete when fetched before the first scan request.
+ */
+ wpa_s->scan_res_tried++;
+ timeout = 0;
+ }
+ wpa_supplicant_req_scan(wpa_s, timeout, 0);
}
@@ -517,7 +611,7 @@ static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
break;
}
if ((p[0] == GENERIC_INFO_ELEM && p[1] >= 6 &&
- (memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
+ (os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0)) ||
(p[0] == RSN_INFO_ELEM && p[1] >= 2)) {
if (wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, p, len))
break;
@@ -547,7 +641,7 @@ static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
}
if (!wpa_found &&
p[0] == GENERIC_INFO_ELEM && p[1] >= 6 &&
- memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
+ os_memcmp(&p[2], "\x00\x50\xF2\x01\x01\x00", 6) == 0) {
wpa_found = 1;
wpa_sm_set_ap_wpa_ie(wpa_s->wpa, p, len);
}
@@ -578,11 +672,15 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
wpa_supplicant_event_associnfo(wpa_s, data);
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATED);
- if (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
- memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0) {
+ if (wpa_s->use_client_mlme)
+ os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
+ if (wpa_s->use_client_mlme ||
+ (wpa_drv_get_bssid(wpa_s, bssid) >= 0 &&
+ os_memcmp(bssid, wpa_s->bssid, ETH_ALEN) != 0)) {
wpa_msg(wpa_s, MSG_DEBUG, "Associated to a new BSS: BSSID="
MACSTR, MAC2STR(bssid));
- memcpy(wpa_s->bssid, bssid, ETH_ALEN);
+ os_memcpy(wpa_s->bssid, bssid, ETH_ALEN);
+ os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
if (wpa_supplicant_dynamic_keys(wpa_s)) {
wpa_clear_keys(wpa_s, bssid);
}
@@ -627,11 +725,14 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
/* Timeout for receiving the first EAPOL packet */
wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
}
+ wpa_supplicant_cancel_scan(wpa_s);
}
static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
{
+ const u8 *bssid;
+
if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
/*
* At least Host AP driver and a Prism3 card seemed to be
@@ -650,15 +751,18 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s)
}
if (wpa_s->wpa_state >= WPA_ASSOCIATED)
wpa_supplicant_req_scan(wpa_s, 0, 100000);
- wpa_blacklist_add(wpa_s, wpa_s->bssid);
+ bssid = wpa_s->bssid;
+ if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
+ bssid = wpa_s->pending_bssid;
+ wpa_blacklist_add(wpa_s, bssid);
wpa_sm_notify_disassoc(wpa_s->wpa);
- wpa_supplicant_mark_disassoc(wpa_s);
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "- Disconnect event - "
"remove keys");
if (wpa_supplicant_dynamic_keys(wpa_s)) {
wpa_s->keys_cleared = 0;
wpa_clear_keys(wpa_s, wpa_s->bssid);
}
+ wpa_supplicant_mark_disassoc(wpa_s);
}
@@ -667,14 +771,14 @@ wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
int pairwise;
- time_t now;
+ struct os_time t;
wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
pairwise = (data && data->michael_mic_failure.unicast);
wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
- time(&now);
+ os_get_time(&t);
if (wpa_s->last_michael_mic_error &&
- now - wpa_s->last_michael_mic_error <= 60) {
+ t.sec - wpa_s->last_michael_mic_error <= 60) {
/* initialize countermeasures */
wpa_s->countermeasures = 1;
wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");
@@ -683,7 +787,7 @@ wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
* Need to wait for completion of request frame. We do not get
* any callback for the message completion, so just wait a
* short while and hope for the best. */
- usleep(10000);
+ os_sleep(0, 10000);
wpa_drv_set_countermeasures(wpa_s, 1);
wpa_supplicant_deauthenticate(wpa_s,
@@ -696,10 +800,11 @@ wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
/* TODO: mark the AP rejected for 60 second. STA is
* allowed to associate with another AP.. */
}
- wpa_s->last_michael_mic_error = now;
+ wpa_s->last_michael_mic_error = t.sec;
}
+#ifdef CONFIG_TERMINATE_ONLASTIF
static int any_interfaces(struct wpa_supplicant *head)
{
struct wpa_supplicant *wpa_s;
@@ -709,12 +814,13 @@ static int any_interfaces(struct wpa_supplicant *head)
return 1;
return 0;
}
+#endif /* CONFIG_TERMINATE_ONLASTIF */
static void
wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
union wpa_event_data *data)
{
- if (strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
+ if (os_strcmp(wpa_s->ifname, data->interface_status.ifname) != 0)
return;
switch (data->interface_status.ievent) {
@@ -734,14 +840,28 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
wpa_supplicant_mark_disassoc(wpa_s);
l2_packet_deinit(wpa_s->l2);
wpa_s->l2 = NULL;
+#ifdef CONFIG_TERMINATE_ONLASTIF
/* check if last interface */
if (!any_interfaces(wpa_s->global->ifaces))
eloop_terminate();
+#endif /* CONFIG_TERMINATE_ONLASTIF */
break;
}
}
+#ifdef CONFIG_PEERKEY
+static void
+wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
+ union wpa_event_data *data)
+{
+ if (data == NULL)
+ return;
+ wpa_sm_stkstart(wpa_s->wpa, data->stkstart.peer);
+}
+#endif /* CONFIG_PEERKEY */
+
+
void wpa_supplicant_event(struct wpa_supplicant *wpa_s, wpa_event_type event,
union wpa_event_data *data)
{
@@ -767,6 +887,11 @@ void wpa_supplicant_event(struct wpa_supplicant *wpa_s, wpa_event_type event,
case EVENT_PMKID_CANDIDATE:
wpa_supplicant_event_pmkid_candidate(wpa_s, data);
break;
+#ifdef CONFIG_PEERKEY
+ case EVENT_STKSTART:
+ wpa_supplicant_event_stkstart(wpa_s, data);
+ break;
+#endif /* CONFIG_PEERKEY */
default:
wpa_printf(MSG_INFO, "Unknown event %d", event);
break;
diff --git a/contrib/wpa_supplicant/wpa_ctrl.c b/contrib/wpa_supplicant/wpa_ctrl.c
index e7a9a4f..8e621b0 100644
--- a/contrib/wpa_supplicant/wpa_ctrl.c
+++ b/contrib/wpa_supplicant/wpa_ctrl.c
@@ -1,6 +1,6 @@
/*
* wpa_supplicant/hostapd control interface library
- * Copyright (c) 2004-2005, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,22 +14,21 @@
* $FreeBSD$
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <sys/socket.h>
-#include <netinet/in.h>
+#include "includes.h"
+
+#ifdef CONFIG_CTRL_IFACE
+
+#ifdef CONFIG_CTRL_IFACE_UNIX
#include <sys/un.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
+#endif /* CONFIG_CTRL_IFACE_UNIX */
#include "wpa_ctrl.h"
-#ifdef CONFIG_NATIVE_WINDOWS
#include "common.h"
-#endif /* CONFIG_NATIVE_WINDOWS */
+
+
+#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
+#define CTRL_IFACE_SOCKET
+#endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */
/**
@@ -42,83 +41,121 @@
* the arguments for most of the control interface library functions.
*/
struct wpa_ctrl {
- int s;
#ifdef CONFIG_CTRL_IFACE_UDP
+ int s;
struct sockaddr_in local;
struct sockaddr_in dest;
-#else /* CONFIG_CTRL_IFACE_UDP */
+ char *cookie;
+#endif /* CONFIG_CTRL_IFACE_UDP */
+#ifdef CONFIG_CTRL_IFACE_UNIX
+ int s;
struct sockaddr_un local;
struct sockaddr_un dest;
-#endif /* CONFIG_CTRL_IFACE_UDP */
+#endif /* CONFIG_CTRL_IFACE_UNIX */
+#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
+ HANDLE pipe;
+#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
};
+#ifdef CONFIG_CTRL_IFACE_UNIX
+
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
{
struct wpa_ctrl *ctrl;
-#ifndef CONFIG_CTRL_IFACE_UDP
static int counter = 0;
-#endif /* CONFIG_CTRL_IFACE_UDP */
- ctrl = malloc(sizeof(*ctrl));
+ ctrl = os_malloc(sizeof(*ctrl));
if (ctrl == NULL)
return NULL;
- memset(ctrl, 0, sizeof(*ctrl));
+ os_memset(ctrl, 0, sizeof(*ctrl));
-#ifdef CONFIG_CTRL_IFACE_UDP
- ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
+ ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
if (ctrl->s < 0) {
- perror("socket");
- free(ctrl);
+ os_free(ctrl);
return NULL;
}
- ctrl->local.sin_family = AF_INET;
- ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
+ ctrl->local.sun_family = AF_UNIX;
+ os_snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
+ "/tmp/wpa_ctrl_%d-%d", getpid(), counter++);
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
- sizeof(ctrl->local)) < 0) {
+ sizeof(ctrl->local)) < 0) {
close(ctrl->s);
- free(ctrl);
+ os_free(ctrl);
return NULL;
}
- ctrl->dest.sin_family = AF_INET;
- ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
- ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
+ ctrl->dest.sun_family = AF_UNIX;
+ os_snprintf(ctrl->dest.sun_path, sizeof(ctrl->dest.sun_path), "%s",
+ ctrl_path);
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
sizeof(ctrl->dest)) < 0) {
- perror("connect");
close(ctrl->s);
- free(ctrl);
+ unlink(ctrl->local.sun_path);
+ os_free(ctrl);
return NULL;
}
-#else /* CONFIG_CTRL_IFACE_UDP */
- ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
+
+ return ctrl;
+}
+
+
+void wpa_ctrl_close(struct wpa_ctrl *ctrl)
+{
+ unlink(ctrl->local.sun_path);
+ close(ctrl->s);
+ os_free(ctrl);
+}
+
+#endif /* CONFIG_CTRL_IFACE_UNIX */
+
+
+#ifdef CONFIG_CTRL_IFACE_UDP
+
+struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
+{
+ struct wpa_ctrl *ctrl;
+ char buf[128];
+ size_t len;
+
+ ctrl = os_malloc(sizeof(*ctrl));
+ if (ctrl == NULL)
+ return NULL;
+ os_memset(ctrl, 0, sizeof(*ctrl));
+
+ ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
if (ctrl->s < 0) {
- free(ctrl);
+ perror("socket");
+ os_free(ctrl);
return NULL;
}
- ctrl->local.sun_family = AF_UNIX;
- snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path) - 1,
- "/tmp/wpa_ctrl_%d-%d", getpid(), counter++);
+ ctrl->local.sin_family = AF_INET;
+ ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
- sizeof(ctrl->local)) < 0) {
+ sizeof(ctrl->local)) < 0) {
close(ctrl->s);
- free(ctrl);
+ os_free(ctrl);
return NULL;
}
- ctrl->dest.sun_family = AF_UNIX;
- strncpy(ctrl->dest.sun_path, ctrl_path, sizeof(ctrl->dest.sun_path) - 1);
+ ctrl->dest.sin_family = AF_INET;
+ ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
+ ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
sizeof(ctrl->dest)) < 0) {
+ perror("connect");
close(ctrl->s);
- unlink(ctrl->local.sun_path);
- free(ctrl);
+ os_free(ctrl);
return NULL;
}
-#endif /* CONFIG_CTRL_IFACE_UDP */
+
+ len = sizeof(buf) - 1;
+ if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) {
+ buf[len] = '\0';
+ ctrl->cookie = strdup(buf);
+ }
return ctrl;
}
@@ -126,14 +163,15 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
{
-#ifndef CONFIG_CTRL_IFACE_UDP
- unlink(ctrl->local.sun_path);
-#endif /* CONFIG_CTRL_IFACE_UDP */
close(ctrl->s);
- free(ctrl);
+ os_free(ctrl->cookie);
+ os_free(ctrl);
}
+#endif /* CONFIG_CTRL_IFACE_UDP */
+
+#ifdef CTRL_IFACE_SOCKET
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
char *reply, size_t *reply_len,
void (*msg_cb)(char *msg, size_t len))
@@ -141,9 +179,35 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
struct timeval tv;
int res;
fd_set rfds;
+ const char *_cmd;
+ char *cmd_buf = NULL;
+ size_t _cmd_len;
- if (send(ctrl->s, cmd, cmd_len, 0) < 0)
+#ifdef CONFIG_CTRL_IFACE_UDP
+ if (ctrl->cookie) {
+ char *pos;
+ _cmd_len = strlen(ctrl->cookie) + 1 + cmd_len;
+ cmd_buf = os_malloc(_cmd_len );
+ if (cmd_buf == NULL)
+ return -1;
+ _cmd = cmd_buf;
+ pos = cmd_buf;
+ strcpy(pos, ctrl->cookie);
+ pos += strlen(ctrl->cookie);
+ *pos++ = ' ';
+ memcpy(pos, cmd, cmd_len);
+ } else
+#endif /* CONFIG_CTRL_IFACE_UDP */
+ {
+ _cmd = cmd;
+ _cmd_len = cmd_len;
+ }
+
+ if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
+ os_free(cmd_buf);
return -1;
+ }
+ os_free(cmd_buf);
for (;;) {
tv.tv_sec = 2;
@@ -178,6 +242,7 @@ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
}
return 0;
}
+#endif /* CTRL_IFACE_SOCKET */
static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
@@ -190,7 +255,7 @@ static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
buf, &len, NULL);
if (ret < 0)
return ret;
- if (len == 3 && memcmp(buf, "OK\n", 3) == 0)
+ if (len == 3 && os_memcmp(buf, "OK\n", 3) == 0)
return 0;
return -1;
}
@@ -208,6 +273,8 @@ int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
}
+#ifdef CTRL_IFACE_SOCKET
+
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
{
int res;
@@ -223,13 +290,12 @@ int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
{
struct timeval tv;
- int res;
fd_set rfds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rfds);
FD_SET(ctrl->s, &rfds);
- res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
+ select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
return FD_ISSET(ctrl->s, &rfds);
}
@@ -238,3 +304,124 @@ int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
{
return ctrl->s;
}
+
+#endif /* CTRL_IFACE_SOCKET */
+
+
+#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
+
+#ifndef WPA_SUPPLICANT_NAMED_PIPE
+#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant"
+#endif
+#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE)
+
+struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
+{
+ struct wpa_ctrl *ctrl;
+ DWORD mode;
+ TCHAR name[256];
+ int i;
+
+ ctrl = os_malloc(sizeof(*ctrl));
+ if (ctrl == NULL)
+ return NULL;
+ os_memset(ctrl, 0, sizeof(*ctrl));
+
+#ifdef UNICODE
+ if (ctrl_path == NULL)
+ _snwprintf(name, 256, NAMED_PIPE_PREFIX);
+ else
+ _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
+ ctrl_path);
+#else /* UNICODE */
+ if (ctrl_path == NULL)
+ os_snprintf(name, 256, NAMED_PIPE_PREFIX);
+ else
+ os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
+ ctrl_path);
+#endif /* UNICODE */
+
+ for (i = 0; i < 10; i++) {
+ ctrl->pipe = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0,
+ NULL, OPEN_EXISTING, 0, NULL);
+ /*
+ * Current named pipe server side in wpa_supplicant is
+ * re-opening the pipe for new clients only after the previous
+ * one is taken into use. This leaves a small window for race
+ * conditions when two connections are being opened at almost
+ * the same time. Retry if that was the case.
+ */
+ if (ctrl->pipe != INVALID_HANDLE_VALUE ||
+ GetLastError() != ERROR_PIPE_BUSY)
+ break;
+ WaitNamedPipe(name, 1000);
+ }
+ if (ctrl->pipe == INVALID_HANDLE_VALUE) {
+ os_free(ctrl);
+ return NULL;
+ }
+
+ mode = PIPE_READMODE_MESSAGE;
+ if (!SetNamedPipeHandleState(ctrl->pipe, &mode, NULL, NULL)) {
+ CloseHandle(ctrl->pipe);
+ os_free(ctrl);
+ return NULL;
+ }
+
+ return ctrl;
+}
+
+
+void wpa_ctrl_close(struct wpa_ctrl *ctrl)
+{
+ CloseHandle(ctrl->pipe);
+ os_free(ctrl);
+}
+
+
+int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
+ char *reply, size_t *reply_len,
+ void (*msg_cb)(char *msg, size_t len))
+{
+ DWORD written;
+ DWORD readlen = *reply_len;
+
+ if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL))
+ return -1;
+
+ if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL))
+ return -1;
+ *reply_len = readlen;
+
+ return 0;
+}
+
+
+int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
+{
+ DWORD len = *reply_len;
+ if (!ReadFile(ctrl->pipe, reply, *reply_len, &len, NULL))
+ return -1;
+ *reply_len = len;
+ return 0;
+}
+
+
+int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
+{
+ DWORD left;
+
+ if (!PeekNamedPipe(ctrl->pipe, NULL, 0, NULL, &left, NULL))
+ return -1;
+ return left ? 1 : 0;
+}
+
+
+int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
+{
+ return -1;
+}
+
+#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
+
+#endif /* CONFIG_CTRL_IFACE */
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/eventhistory.ui.h b/contrib/wpa_supplicant/wpa_gui-qt4/eventhistory.ui.h
deleted file mode 100644
index cb2caab..0000000
--- a/contrib/wpa_supplicant/wpa_gui-qt4/eventhistory.ui.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-void EventHistory::init()
-{
-}
-
-
-void EventHistory::destroy()
-{
-}
-
-
-void EventHistory::addEvents(WpaMsgList msgs)
-{
- WpaMsgList::iterator it;
- for (it = msgs.begin(); it != msgs.end(); it++) {
- addEvent(*it);
- }
-}
-
-
-void EventHistory::addEvent(WpaMsg msg)
-{
- Q3ListViewItem *item;
- item = new Q3ListViewItem(eventListView,
- msg.getTimestamp().toString("yyyy-MM-dd hh:mm:ss.zzz"),
- msg.getMsg());
- if (item == NULL)
- return;
- eventListView->setSelected(item, false);
-}
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.ui.h b/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.ui.h
deleted file mode 100644
index 5e87462..0000000
--- a/contrib/wpa_supplicant/wpa_gui-qt4/networkconfig.ui.h
+++ /dev/null
@@ -1,513 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-
-enum {
- AUTH_NONE = 0,
- AUTH_IEEE8021X = 1,
- AUTH_WPA_PSK = 2,
- AUTH_WPA_EAP = 3,
- AUTH_WPA2_PSK = 4,
- AUTH_WPA2_EAP = 5
-};
-
-void NetworkConfig::init()
-{
- wpagui = NULL;
- new_network = false;
-}
-
-void NetworkConfig::paramsFromScanResults(Q3ListViewItem *sel)
-{
- new_network = true;
-
- /* SSID BSSID frequency signal flags */
- setCaption(sel->text(0));
- ssidEdit->setText(sel->text(0));
-
- QString flags = sel->text(4);
- int auth, encr = 0;
- if (flags.find("[WPA2-EAP") >= 0)
- auth = AUTH_WPA2_EAP;
- else if (flags.find("[WPA-EAP") >= 0)
- auth = AUTH_WPA_EAP;
- else if (flags.find("[WPA2-PSK") >= 0)
- auth = AUTH_WPA2_PSK;
- else if (flags.find("[WPA-PSK") >= 0)
- auth = AUTH_WPA_PSK;
- else
- auth = AUTH_NONE;
-
- if (flags.find("-CCMP") >= 0)
- encr = 1;
- else if (flags.find("-TKIP") >= 0)
- encr = 0;
- else if (flags.find("WEP") >= 0)
- encr = 1;
- else
- encr = 0;
-
- authSelect->setCurrentItem(auth);
- authChanged(auth);
- encrSelect->setCurrentItem(encr);
-
- getEapCapa();
-}
-
-
-void NetworkConfig::authChanged(int sel)
-{
- pskEdit->setEnabled(sel == AUTH_WPA_PSK || sel == AUTH_WPA2_PSK);
- bool eap = sel == AUTH_IEEE8021X || sel == AUTH_WPA_EAP ||
- sel == AUTH_WPA2_EAP;
- eapSelect->setEnabled(eap);
- identityEdit->setEnabled(eap);
- passwordEdit->setEnabled(eap);
- cacertEdit->setEnabled(eap);
-
- while (encrSelect->count())
- encrSelect->removeItem(0);
-
- if (sel == AUTH_NONE || sel == AUTH_IEEE8021X) {
- encrSelect->insertItem("None");
- encrSelect->insertItem("WEP");
- encrSelect->setCurrentItem(sel == AUTH_NONE ? 0 : 1);
- } else {
- encrSelect->insertItem("TKIP");
- encrSelect->insertItem("CCMP");
- encrSelect->setCurrentItem((sel == AUTH_WPA2_PSK ||
- sel == AUTH_WPA2_EAP) ? 1 : 0);
- }
-
- wepEnabled(sel == AUTH_IEEE8021X);
-}
-
-
-void NetworkConfig::addNetwork()
-{
- char reply[10], cmd[256];
- size_t reply_len;
- int id;
- int psklen = pskEdit->text().length();
- int auth = authSelect->currentItem();
-
- if (auth == AUTH_WPA_PSK || auth == AUTH_WPA2_PSK) {
- if (psklen < 8 || psklen > 64) {
- QMessageBox::warning(this, "wpa_gui", "WPA-PSK requires a passphrase "
- "of 8 to 63 characters\n"
- "or 64 hex digit PSK");
- return;
- }
- }
-
- if (wpagui == NULL)
- return;
-
- memset(reply, 0, sizeof(reply));
- reply_len = sizeof(reply) - 1;
-
- if (new_network) {
- wpagui->ctrlRequest("ADD_NETWORK", reply, &reply_len);
- if (reply[0] == 'F') {
- QMessageBox::warning(this, "wpa_gui", "Failed to add network to wpa_supplicant\n"
- "configuration.");
- return;
- }
- id = atoi(reply);
- } else {
- id = edit_network_id;
- }
-
- setNetworkParam(id, "ssid", ssidEdit->text().ascii(), true);
-
- char *key_mgmt = NULL, *proto = NULL, *pairwise = NULL;
- switch (auth) {
- case AUTH_NONE:
- key_mgmt = "NONE";
- break;
- case AUTH_IEEE8021X:
- key_mgmt = "IEEE8021X";
- break;
- case AUTH_WPA_PSK:
- key_mgmt = "WPA-PSK";
- proto = "WPA";
- break;
- case AUTH_WPA_EAP:
- key_mgmt = "WPA-EAP";
- proto = "WPA";
- break;
- case AUTH_WPA2_PSK:
- key_mgmt = "WPA-PSK";
- proto = "WPA2";
- break;
- case AUTH_WPA2_EAP:
- key_mgmt = "WPA-EAP";
- proto = "WPA2";
- break;
- }
-
- if (auth == AUTH_WPA_PSK || auth == AUTH_WPA_EAP ||
- auth == AUTH_WPA2_PSK || auth == AUTH_WPA2_EAP) {
- int encr = encrSelect->currentItem();
- if (encr == 0)
- pairwise = "TKIP";
- else
- pairwise = "CCMP";
- }
-
- if (proto)
- setNetworkParam(id, "proto", proto, false);
- if (key_mgmt)
- setNetworkParam(id, "key_mgmt", key_mgmt, false);
- if (pairwise) {
- setNetworkParam(id, "pairwise", pairwise, false);
- setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
- }
- if (pskEdit->isEnabled())
- setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
- if (eapSelect->isEnabled())
- setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);
- if (identityEdit->isEnabled())
- setNetworkParam(id, "identity", identityEdit->text().ascii(), true);
- if (passwordEdit->isEnabled())
- setNetworkParam(id, "password", passwordEdit->text().ascii(), true);
- if (cacertEdit->isEnabled())
- setNetworkParam(id, "ca_cert", cacertEdit->text().ascii(), true);
- writeWepKey(id, wep0Edit, 0);
- writeWepKey(id, wep1Edit, 1);
- writeWepKey(id, wep2Edit, 2);
- writeWepKey(id, wep3Edit, 3);
-
- if (wep0Radio->isEnabled() && wep0Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "0", false);
- else if (wep1Radio->isEnabled() && wep1Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "1", false);
- else if (wep2Radio->isEnabled() && wep2Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "2", false);
- else if (wep3Radio->isEnabled() && wep3Radio->isChecked())
- setNetworkParam(id, "wep_tx_keyidx", "3", false);
-
- snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %d", id);
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (strncmp(reply, "OK", 2) != 0) {
- QMessageBox::warning(this, "wpa_gui", "Failed to enable network in wpa_supplicant\n"
- "configuration.");
- /* Network was added, so continue anyway */
- }
- wpagui->triggerUpdate();
- wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
-
- close();
-}
-
-
-void NetworkConfig::setWpaGui( WpaGui *_wpagui )
-{
- wpagui = _wpagui;
-}
-
-
-int NetworkConfig::setNetworkParam(int id, const char *field, const char *value, bool quote)
-{
- char reply[10], cmd[256];
- size_t reply_len;
- snprintf(cmd, sizeof(cmd), "SET_NETWORK %d %s %s%s%s",
- id, field, quote ? "\"" : "", value, quote ? "\"" : "");
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- return strncmp(reply, "OK", 2) == 0 ? 0 : -1;
-}
-
-
-void NetworkConfig::encrChanged( const QString &sel )
-{
- wepEnabled(sel.find("WEP") == 0);
-}
-
-
-void NetworkConfig::wepEnabled( bool enabled )
-{
- wep0Edit->setEnabled(enabled);
- wep1Edit->setEnabled(enabled);
- wep2Edit->setEnabled(enabled);
- wep3Edit->setEnabled(enabled);
- wep0Radio->setEnabled(enabled);
- wep1Radio->setEnabled(enabled);
- wep2Radio->setEnabled(enabled);
- wep3Radio->setEnabled(enabled);
-}
-
-
-void NetworkConfig::writeWepKey( int network_id, QLineEdit *edit, int id )
-{
- char buf[10];
- bool hex;
- const char *txt, *pos;
- size_t len;
-
- if (!edit->isEnabled() || edit->text().isEmpty())
- return;
-
- /*
- * Assume hex key if only hex characters are present and length matches
- * with 40, 104, or 128-bit key
- */
- txt = edit->text().ascii();
- len = strlen(txt);
- if (len == 0)
- return;
- pos = txt;
- hex = true;
- while (*pos) {
- if (!((*pos >= '0' && *pos <= '9') || (*pos >= 'a' && *pos <= 'f') ||
- (*pos >= 'A' && *pos <= 'F'))) {
- hex = false;
- break;
- }
- pos++;
- }
- if (hex && len != 10 && len != 26 && len != 32)
- hex = false;
- snprintf(buf, sizeof(buf), "wep_key%d", id);
- setNetworkParam(network_id, buf, txt, !hex);
-}
-
-
-void NetworkConfig::paramsFromConfig( int network_id )
-{
- int i;
-
- edit_network_id = network_id;
- getEapCapa();
-
- char reply[1024], cmd[256], *pos;
- size_t reply_len;
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ssid", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- ssidEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d proto", network_id);
- reply_len = sizeof(reply);
- int wpa = 0;
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "RSN") || strstr(reply, "WPA2"))
- wpa = 2;
- else if (strstr(reply, "WPA"))
- wpa = 1;
- }
-
- int auth = AUTH_NONE, encr = 0;
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d key_mgmt", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "WPA-EAP"))
- auth = wpa & 2 ? AUTH_WPA2_EAP : AUTH_WPA_EAP;
- else if (strstr(reply, "WPA-PSK"))
- auth = wpa & 2 ? AUTH_WPA2_PSK : AUTH_WPA_PSK;
- else if (strstr(reply, "IEEE8021X")) {
- auth = AUTH_IEEE8021X;
- encr = 1;
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d pairwise", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0) {
- reply[reply_len] = '\0';
- if (strstr(reply, "CCMP"))
- encr = 1;
- else if (strstr(reply, "TKIP"))
- encr = 0;
- else if (strstr(reply, "WEP"))
- encr = 1;
- else
- encr = 0;
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d psk", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- pskEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d identity", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- identityEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d password", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- passwordEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d ca_cert", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- cacertEdit->setText(reply + 1);
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d eap", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
- reply[reply_len] = '\0';
- for (i = 0; i < eapSelect->count(); i++) {
- if (eapSelect->text(i).compare(reply) == 0) {
- eapSelect->setCurrentItem(i);
- break;
- }
- }
- }
-
- for (i = 0; i < 4; i++) {
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_key%d", network_id, i);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 2 &&
- reply[0] == '"') {
- reply[reply_len] = '\0';
- pos = strchr(reply + 1, '"');
- if (pos)
- *pos = '\0';
- if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
- encr = 1;
-
- switch (i) {
- case 0:
- wep0Edit->setText(reply + 1);
- break;
- case 1:
- wep1Edit->setText(reply + 1);
- break;
- case 2:
- wep2Edit->setText(reply + 1);
- break;
- case 3:
- wep3Edit->setText(reply + 1);
- break;
- }
- }
- }
-
- snprintf(cmd, sizeof(cmd), "GET_NETWORK %d wep_tx_keyidx", network_id);
- reply_len = sizeof(reply);
- if (wpagui->ctrlRequest(cmd, reply, &reply_len) >= 0 && reply_len >= 1) {
- reply[reply_len] = '\0';
- switch (atoi(reply)) {
- case 0:
- wep0Radio->setChecked(true);
- break;
- case 1:
- wep1Radio->setChecked(true);
- break;
- case 2:
- wep2Radio->setChecked(true);
- break;
- case 3:
- wep3Radio->setChecked(true);
- break;
- }
- }
-
- authSelect->setCurrentItem(auth);
- authChanged(auth);
- encrSelect->setCurrentItem(encr);
- if (auth == AUTH_NONE || auth == AUTH_IEEE8021X)
- wepEnabled(encr == 1);
-
- removeButton->setEnabled(true);
- addButton->setText("Save");
-}
-
-
-void NetworkConfig::removeNetwork()
-{
- char reply[10], cmd[256];
- size_t reply_len;
-
- if (QMessageBox::information(this, "wpa_gui",
- "This will permanently remove the network\n"
- "from the configuration. Do you really want\n"
- "to remove this network?", "Yes", "No") != 0)
- return;
-
- snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", edit_network_id);
- reply_len = sizeof(reply);
- wpagui->ctrlRequest(cmd, reply, &reply_len);
- if (strncmp(reply, "OK", 2) != 0) {
- QMessageBox::warning(this, "wpa_gui",
- "Failed to remove network from wpa_supplicant\n"
- "configuration.");
- } else {
- wpagui->triggerUpdate();
- wpagui->ctrlRequest("SAVE_CONFIG", reply, &reply_len);
- }
-
- close();
-}
-
-
-void NetworkConfig::newNetwork()
-{
- new_network = true;
- getEapCapa();
-}
-
-
-void NetworkConfig::getEapCapa()
-{
- char reply[256];
- size_t reply_len;
-
- if (wpagui == NULL)
- return;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("GET_CAPABILITY eap", reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
-
- QString res(reply);
- QStringList types = QStringList::split(QChar(' '), res);
- eapSelect->insertStringList(types);
-}
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.ui.h b/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.ui.h
deleted file mode 100644
index 530d2e6..0000000
--- a/contrib/wpa_supplicant/wpa_gui-qt4/scanresults.ui.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-void ScanResults::init()
-{
- wpagui = NULL;
-}
-
-
-void ScanResults::destroy()
-{
- delete timer;
-}
-
-
-void ScanResults::setWpaGui(WpaGui *_wpagui)
-{
- wpagui = _wpagui;
- updateResults();
-
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), SLOT(getResults()));
- timer->start(10000, FALSE);
-}
-
-
-void ScanResults::updateResults()
-{
- char reply[8192];
- size_t reply_len;
-
- if (wpagui == NULL)
- return;
-
- reply_len = sizeof(reply) - 1;
- if (wpagui->ctrlRequest("SCAN_RESULTS", reply, &reply_len) < 0)
- return;
- reply[reply_len] = '\0';
-
- scanResultsView->clear();
-
- QString res(reply);
- QStringList lines = QStringList::split(QChar('\n'), res);
- bool first = true;
- for (QStringList::Iterator it = lines.begin(); it != lines.end(); it++) {
- if (first) {
- first = false;
- continue;
- }
-
- QStringList cols = QStringList::split(QChar('\t'), *it, true);
- QString ssid, bssid, freq, signal, flags;
- bssid = cols.count() > 0 ? cols[0] : "";
- freq = cols.count() > 1 ? cols[1] : "";
- signal = cols.count() > 2 ? cols[2] : "";
- flags = cols.count() > 3 ? cols[3] : "";
- ssid = cols.count() > 4 ? cols[4] : "";
- new Q3ListViewItem(scanResultsView, ssid, bssid, freq, signal, flags);
- }
-}
-
-
-void ScanResults::scanRequest()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (wpagui == NULL)
- return;
-
- wpagui->ctrlRequest("SCAN", reply, &reply_len);
-}
-
-
-void ScanResults::getResults()
-{
- updateResults();
-}
-
-
-
-
-void ScanResults::bssSelected( Q3ListViewItem * sel )
-{
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(wpagui);
- nc->paramsFromScanResults(sel);
- nc->show();
- nc->exec();
-}
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui.h b/contrib/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui.h
deleted file mode 100644
index 4b47ccd..0000000
--- a/contrib/wpa_supplicant/wpa_gui-qt4/userdatarequest.ui.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-int UserDataRequest::setParams(WpaGui *_wpagui, const char *reqMsg)
-{
- char *tmp, *pos, *pos2;
- wpagui = _wpagui;
- tmp = strdup(reqMsg);
- if (tmp == NULL)
- return -1;
- pos = strchr(tmp, '-');
- if (pos == NULL) {
- free(tmp);
- return -1;
- }
- *pos++ = '\0';
- field = tmp;
- pos2 = strchr(pos, ':');
- if (pos2 == NULL) {
- free(tmp);
- return -1;
- }
- *pos2++ = '\0';
-
- networkid = atoi(pos);
- queryInfo->setText(pos2);
- if (strcmp(tmp, "PASSWORD") == 0) {
- queryField->setText("Password: ");
- queryEdit->setEchoMode(QLineEdit::Password);
- } else if (strcmp(tmp, "NEW_PASSWORD") == 0) {
- queryField->setText("New password: ");
- queryEdit->setEchoMode(QLineEdit::Password);
- } else if (strcmp(tmp, "IDENTITY") == 0)
- queryField->setText("Identity: ");
- else if (strcmp(tmp, "PASSPHRASE") == 0) {
- queryField->setText("Private key passphrase: ");
- queryEdit->setEchoMode(QLineEdit::Password);
- } else
- queryField->setText(field + ":");
- free(tmp);
-
- return 0;
-}
-
-
-void UserDataRequest::sendReply()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- if (wpagui == NULL) {
- reject();
- return;
- }
-
- QString cmd = QString(WPA_CTRL_RSP) + field + '-' +
- QString::number(networkid) + ':' +
- queryEdit->text();
- wpagui->ctrlRequest(cmd.ascii(), reply, &reply_len);
- accept();
-}
diff --git a/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.ui.h b/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.ui.h
deleted file mode 100644
index 58760e7..0000000
--- a/contrib/wpa_supplicant/wpa_gui-qt4/wpagui.ui.h
+++ /dev/null
@@ -1,651 +0,0 @@
-/****************************************************************************
-** ui.h extension file, included from the uic-generated form implementation.
-**
-** If you want to add, delete, or rename functions or slots, use
-** Qt Designer to update this file, preserving your code.
-**
-** You should not define a constructor or destructor in this file.
-** Instead, write your code in functions called init() and destroy().
-** These will automatically be called by the form's constructor and
-** destructor.
-*****************************************************************************/
-
-
-#ifdef __MINGW32__
-/* Need to get getopt() */
-#include <unistd.h>
-#endif
-
-
-void WpaGui::init()
-{
- eh = NULL;
- scanres = NULL;
- udr = NULL;
- ctrl_iface = NULL;
- ctrl_conn = NULL;
- monitor_conn = NULL;
- msgNotifier = NULL;
- ctrl_iface_dir = strdup("/var/run/wpa_supplicant");
-
- parse_argv();
-
- textStatus->setText("connecting to wpa_supplicant");
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), SLOT(ping()));
- timer->start(1000, FALSE);
-
- if (openCtrlConnection(ctrl_iface) < 0) {
- printf("Failed to open control connection to wpa_supplicant.\n");
- }
-
- updateStatus();
- networkMayHaveChanged = true;
- updateNetworks();
-}
-
-
-void WpaGui::destroy()
-{
- delete msgNotifier;
-
- if (monitor_conn) {
- wpa_ctrl_detach(monitor_conn);
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
- if (ctrl_conn) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (eh) {
- eh->close();
- delete eh;
- eh = NULL;
- }
-
- if (scanres) {
- scanres->close();
- delete scanres;
- scanres = NULL;
- }
-
- if (udr) {
- udr->close();
- delete udr;
- udr = NULL;
- }
-
- free(ctrl_iface);
- ctrl_iface = NULL;
-
- free(ctrl_iface_dir);
- ctrl_iface_dir = NULL;
-}
-
-
-void WpaGui::parse_argv()
-{
- int c;
- for (;;) {
- c = getopt(qApp->argc(), qApp->argv(), "i:p:");
- if (c < 0)
- break;
- switch (c) {
- case 'i':
- free(ctrl_iface);
- ctrl_iface = strdup(optarg);
- break;
- case 'p':
- free(ctrl_iface_dir);
- ctrl_iface_dir = strdup(optarg);
- break;
- }
- }
-}
-
-
-int WpaGui::openCtrlConnection(const char *ifname)
-{
- char *cfile;
- int flen;
-
- if (ifname) {
- if (ifname != ctrl_iface) {
- free(ctrl_iface);
- ctrl_iface = strdup(ifname);
- }
- } else {
-#ifdef CONFIG_CTRL_IFACE_UDP
- free(ctrl_iface);
- ctrl_iface = strdup("udp");
-#else /* CONFIG_CTRL_IFACE_UDP */
- struct dirent *dent;
- DIR *dir = opendir(ctrl_iface_dir);
- free(ctrl_iface);
- ctrl_iface = NULL;
- if (dir) {
- while ((dent = readdir(dir))) {
- if (strcmp(dent->d_name, ".") == 0 ||
- strcmp(dent->d_name, "..") == 0)
- continue;
- printf("Selected interface '%s'\n", dent->d_name);
- ctrl_iface = strdup(dent->d_name);
- break;
- }
- closedir(dir);
- }
-#endif /* CONFIG_CTRL_IFACE_UDP */
- }
-
- if (ctrl_iface == NULL)
- return -1;
-
- flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
- cfile = (char *) malloc(flen);
- if (cfile == NULL)
- return -1;
- snprintf(cfile, flen, "%s/%s", ctrl_iface_dir, ctrl_iface);
-
- if (ctrl_conn) {
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- }
-
- if (monitor_conn) {
- delete msgNotifier;
- msgNotifier = NULL;
- wpa_ctrl_detach(monitor_conn);
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- }
-
- printf("Trying to connect to '%s'\n", cfile);
- ctrl_conn = wpa_ctrl_open(cfile);
- if (ctrl_conn == NULL) {
- free(cfile);
- return -1;
- }
- monitor_conn = wpa_ctrl_open(cfile);
- free(cfile);
- if (monitor_conn == NULL) {
- wpa_ctrl_close(ctrl_conn);
- return -1;
- }
- if (wpa_ctrl_attach(monitor_conn)) {
- printf("Failed to attach to wpa_supplicant\n");
- wpa_ctrl_close(monitor_conn);
- monitor_conn = NULL;
- wpa_ctrl_close(ctrl_conn);
- ctrl_conn = NULL;
- return -1;
- }
-
- msgNotifier = new QSocketNotifier(wpa_ctrl_get_fd(monitor_conn),
- QSocketNotifier::Read, this);
- connect(msgNotifier, SIGNAL(activated(int)), SLOT(receiveMsgs()));
-
- adapterSelect->clear();
- adapterSelect->insertItem(ctrl_iface);
- adapterSelect->setCurrentItem(0);
-
- return 0;
-}
-
-
-static void wpa_gui_msg_cb(char *msg, size_t)
-{
- /* This should not happen anymore since two control connections are used. */
- printf("missed message: %s\n", msg);
-}
-
-
-int WpaGui::ctrlRequest(const char *cmd, char *buf, size_t *buflen)
-{
- int ret;
-
- if (ctrl_conn == NULL)
- return -3;
- ret = wpa_ctrl_request(ctrl_conn, cmd, strlen(cmd), buf, buflen,
- wpa_gui_msg_cb);
- if (ret == -2) {
- printf("'%s' command timed out.\n", cmd);
- } else if (ret < 0) {
- printf("'%s' command failed.\n", cmd);
- }
-
- return ret;
-}
-
-
-void WpaGui::updateStatus()
-{
- char buf[2048], *start, *end, *pos;
- size_t len;
-
- pingsToStatusUpdate = 10;
-
- len = sizeof(buf) - 1;
- if (ctrl_conn == NULL || ctrlRequest("STATUS", buf, &len) < 0) {
- textStatus->setText("Could not get status from wpa_supplicant");
- textAuthentication->clear();
- textEncryption->clear();
- textSsid->clear();
- textBssid->clear();
- textIpAddress->clear();
- return;
- }
-
- buf[len] = '\0';
-
- bool auth_updated = false, ssid_updated = false;
- bool bssid_updated = false, ipaddr_updated = false;
- bool status_updated = false;
- char *pairwise_cipher = NULL, *group_cipher = NULL;
-
- start = buf;
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- pos = strchr(start, '=');
- if (pos) {
- *pos++ = '\0';
- if (strcmp(start, "bssid") == 0) {
- bssid_updated = true;
- textBssid->setText(pos);
- } else if (strcmp(start, "ssid") == 0) {
- ssid_updated = true;
- textSsid->setText(pos);
- } else if (strcmp(start, "ip_address") == 0) {
- ipaddr_updated = true;
- textIpAddress->setText(pos);
- } else if (strcmp(start, "wpa_state") == 0) {
- status_updated = true;
- textStatus->setText(pos);
- } else if (strcmp(start, "key_mgmt") == 0) {
- auth_updated = true;
- textAuthentication->setText(pos);
- /* TODO: could add EAP status to this */
- } else if (strcmp(start, "pairwise_cipher") == 0) {
- pairwise_cipher = pos;
- } else if (strcmp(start, "group_cipher") == 0) {
- group_cipher = pos;
- }
- }
-
- if (last)
- break;
- start = end + 1;
- }
-
- if (pairwise_cipher || group_cipher) {
- QString encr;
- if (pairwise_cipher && group_cipher &&
- strcmp(pairwise_cipher, group_cipher) != 0) {
- encr.append(pairwise_cipher);
- encr.append(" + ");
- encr.append(group_cipher);
- } else if (pairwise_cipher) {
- encr.append(pairwise_cipher);
- } else if (group_cipher) {
- encr.append(group_cipher);
- encr.append(" [group key only]");
- } else {
- encr.append("?");
- }
- textEncryption->setText(encr);
- } else
- textEncryption->clear();
-
- if (!status_updated)
- textStatus->clear();
- if (!auth_updated)
- textAuthentication->clear();
- if (!ssid_updated)
- textSsid->clear();
- if (!bssid_updated)
- textBssid->clear();
- if (!ipaddr_updated)
- textIpAddress->clear();
-}
-
-
-void WpaGui::updateNetworks()
-{
- char buf[2048], *start, *end, *id, *ssid, *bssid, *flags;
- size_t len;
- int first_active = -1;
- bool selected = false;
-
- if (!networkMayHaveChanged)
- return;
-
- networkSelect->clear();
-
- if (ctrl_conn == NULL)
- return;
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("LIST_NETWORKS", buf, &len) < 0)
- return;
-
- buf[len] = '\0';
- start = strchr(buf, '\n');
- if (start == NULL)
- return;
- start++;
-
- while (*start) {
- bool last = false;
- end = strchr(start, '\n');
- if (end == NULL) {
- last = true;
- end = start;
- while (end[0] && end[1])
- end++;
- }
- *end = '\0';
-
- id = start;
- ssid = strchr(id, '\t');
- if (ssid == NULL)
- break;
- *ssid++ = '\0';
- bssid = strchr(ssid, '\t');
- if (bssid == NULL)
- break;
- *bssid++ = '\0';
- flags = strchr(bssid, '\t');
- if (flags == NULL)
- break;
- *flags++ = '\0';
-
- QString network(id);
- network.append(": ");
- network.append(ssid);
- networkSelect->insertItem(network);
-
- if (strstr(flags, "[CURRENT]")) {
- networkSelect->setCurrentItem(networkSelect->count() - 1);
- selected = true;
- } else if (first_active < 0 && strstr(flags, "[DISABLED]") == NULL)
- first_active = networkSelect->count() - 1;
-
- if (last)
- break;
- start = end + 1;
- }
-
- if (!selected && first_active >= 0)
- networkSelect->setCurrentItem(first_active);
-
- networkMayHaveChanged = false;
-}
-
-
-void WpaGui::helpIndex()
-{
- printf("helpIndex\n");
-}
-
-
-void WpaGui::helpContents()
-{
- printf("helpContents\n");
-}
-
-
-void WpaGui::helpAbout()
-{
- QMessageBox::about(this, "wpa_gui for wpa_supplicant",
- "Copyright (c) 2003-2005,\n"
- "Jouni Malinen <jkmaline@cc.hut.fi>\n"
- "and contributors.\n"
- "\n"
- "This program is free software. You can\n"
- "distribute it and/or modify it under the terms of\n"
- "the GNU General Public License version 2.\n"
- "\n"
- "Alternatively, this software may be distributed\n"
- "under the terms of the BSD license.\n"
- "\n"
- "This product includes software developed\n"
- "by the OpenSSL Project for use in the\n"
- "OpenSSL Toolkit (http://www.openssl.org/)\n");
-}
-
-
-void WpaGui::disconnect()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
- ctrlRequest("DISCONNECT", reply, &reply_len);
-}
-
-
-void WpaGui::scan()
-{
- if (scanres) {
- scanres->close();
- delete scanres;
- }
-
- scanres = new ScanResults();
- if (scanres == NULL)
- return;
- scanres->setWpaGui(this);
- scanres->show();
- scanres->exec();
-}
-
-
-void WpaGui::eventHistory()
-{
- if (eh) {
- eh->close();
- delete eh;
- }
-
- eh = new EventHistory();
- if (eh == NULL)
- return;
- eh->addEvents(msgs);
- eh->show();
- eh->exec();
-}
-
-
-void WpaGui::ping()
-{
- char buf[10];
- size_t len;
-
- if (scanres && !scanres->isVisible()) {
- delete scanres;
- scanres = NULL;
- }
-
- if (eh && !eh->isVisible()) {
- delete eh;
- eh = NULL;
- }
-
- if (udr && !udr->isVisible()) {
- delete udr;
- udr = NULL;
- }
-
- len = sizeof(buf) - 1;
- if (ctrlRequest("PING", buf, &len) < 0) {
- printf("PING failed - trying to reconnect\n");
- if (openCtrlConnection(ctrl_iface) >= 0) {
- printf("Reconnected successfully\n");
- pingsToStatusUpdate = 0;
- }
- }
-
- pingsToStatusUpdate--;
- if (pingsToStatusUpdate <= 0) {
- updateStatus();
- updateNetworks();
- }
-}
-
-
-static int str_match(const char *a, const char *b)
-{
- return strncmp(a, b, strlen(b)) == 0;
-}
-
-
-void WpaGui::processMsg(char *msg)
-{
- char *pos = msg, *pos2;
- int priority = 2;
-
- if (*pos == '<') {
- /* skip priority */
- pos++;
- priority = atoi(pos);
- pos = strchr(pos, '>');
- if (pos)
- pos++;
- else
- pos = msg;
- }
-
- WpaMsg wm(pos, priority);
- if (eh)
- eh->addEvent(wm);
- msgs.append(wm);
- while (msgs.count() > 100)
- msgs.pop_front();
-
- /* Update last message with truncated version of the event */
- if (strncmp(pos, "CTRL-", 5) == 0) {
- pos2 = strchr(pos, str_match(pos, WPA_CTRL_REQ) ? ':' : ' ');
- if (pos2)
- pos2++;
- else
- pos2 = pos;
- } else
- pos2 = pos;
- QString lastmsg = pos2;
- lastmsg.truncate(40);
- textLastMessage->setText(lastmsg);
-
- pingsToStatusUpdate = 0;
- networkMayHaveChanged = true;
-
- if (str_match(pos, WPA_CTRL_REQ))
- processCtrlReq(pos + strlen(WPA_CTRL_REQ));
-}
-
-
-void WpaGui::processCtrlReq(const char *req)
-{
- if (udr) {
- udr->close();
- delete udr;
- }
- udr = new UserDataRequest();
- if (udr == NULL)
- return;
- if (udr->setParams(this, req) < 0) {
- delete udr;
- udr = NULL;
- return;
- }
- udr->show();
- udr->exec();
-}
-
-
-void WpaGui::receiveMsgs()
-{
- char buf[256];
- size_t len;
-
- while (wpa_ctrl_pending(monitor_conn)) {
- len = sizeof(buf) - 1;
- if (wpa_ctrl_recv(monitor_conn, buf, &len) == 0) {
- buf[len] = '\0';
- processMsg(buf);
- }
- }
-}
-
-
-void WpaGui::connectB()
-{
- char reply[10];
- size_t reply_len = sizeof(reply);
- ctrlRequest("REASSOCIATE", reply, &reply_len);
-}
-
-
-void WpaGui::selectNetwork( const QString &sel )
-{
- QString cmd(sel);
- char reply[10];
- size_t reply_len = sizeof(reply);
-
- int pos = cmd.find(':');
- if (pos < 0) {
- printf("Invalid selectNetwork '%s'\n", cmd.ascii());
- return;
- }
- cmd.truncate(pos);
- cmd.prepend("SELECT_NETWORK ");
- ctrlRequest(cmd.ascii(), reply, &reply_len);
-}
-
-
-void WpaGui::editNetwork()
-{
- QString sel(networkSelect->currentText());
- int pos = sel.find(':');
- if (pos < 0) {
- printf("Invalid selectNetwork '%s'\n", sel.ascii());
- return;
- }
- sel.truncate(pos);
-
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(this);
-
- nc->paramsFromConfig(sel.toInt());
- nc->show();
- nc->exec();
-}
-
-
-void WpaGui::triggerUpdate()
-{
- updateStatus();
- networkMayHaveChanged = true;
- updateNetworks();
-}
-
-
-void WpaGui::addNetwork()
-{
- NetworkConfig *nc = new NetworkConfig();
- if (nc == NULL)
- return;
- nc->setWpaGui(this);
- nc->newNetwork();
- nc->show();
- nc->exec();
-}
diff --git a/contrib/wpa_supplicant/wpa_supplicant.c b/contrib/wpa_supplicant/wpa_supplicant.c
index 2b2d6e0..09ca35a 100644
--- a/contrib/wpa_supplicant/wpa_supplicant.c
+++ b/contrib/wpa_supplicant/wpa_supplicant.c
@@ -1,6 +1,6 @@
/*
* WPA Supplicant
- * Copyright (c) 2003-2006, Jouni Malinen <jkmaline@cc.hut.fi>
+ * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,19 +11,14 @@
*
* See README and COPYING for more details.
*
+ * This file implements functions for registering and unregistering
+ * %wpa_supplicant interfaces. In addition, this file contains number of
+ * functions for managing network connections.
+ *
* $FreeBSD$
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <signal.h>
-#ifndef CONFIG_NATIVE_WINDOWS
-#include <netinet/in.h>
-#endif /* CONFIG_NATIVE_WINDOWS */
+#include "includes.h"
#include "common.h"
#include "eapol_sm.h"
@@ -35,14 +30,17 @@
#include "l2_packet.h"
#include "wpa_supplicant_i.h"
#include "ctrl_iface.h"
+#include "ctrl_iface_dbus.h"
#include "pcsc_funcs.h"
#include "version.h"
#include "preauth.h"
+#include "pmksa_cache.h"
#include "wpa_ctrl.h"
+#include "mlme.h"
const char *wpa_supplicant_version =
"wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2006, Jouni Malinen <jkmaline@cc.hut.fi> and contributors";
+"Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi> and contributors";
const char *wpa_supplicant_license =
"This program is free software. You can distribute it and/or modify it\n"
@@ -50,14 +48,15 @@ const char *wpa_supplicant_license =
"\n"
"Alternatively, this software may be distributed under the terms of the\n"
"BSD license. See README and COPYING for more details.\n"
-#ifdef EAP_TLS_FUNCS
+#ifdef EAP_TLS_OPENSSL
"\nThis product includes software developed by the OpenSSL Project\n"
"for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"
-#endif /* EAP_TLS_FUNCS */
+#endif /* EAP_TLS_OPENSSL */
;
#ifndef CONFIG_NO_STDOUT_DEBUG
-const char *wpa_supplicant_full_license =
+/* Long text divided into parts in order to fit in C89 strings size limits. */
+const char *wpa_supplicant_full_license1 =
"This program is free software; you can redistribute it and/or modify\n"
"it under the terms of the GNU General Public License version 2 as\n"
"published by the Free Software Foundation.\n"
@@ -66,10 +65,11 @@ const char *wpa_supplicant_full_license =
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
"GNU General Public License for more details.\n"
-"\n"
+"\n";
+const char *wpa_supplicant_full_license2 =
"You should have received a copy of the GNU General Public License\n"
"along with this program; if not, write to the Free Software\n"
-"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\n"
+"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
"\n"
"Alternatively, this software may be distributed under the terms of the\n"
"BSD license.\n"
@@ -77,14 +77,16 @@ const char *wpa_supplicant_full_license =
"Redistribution and use in source and binary forms, with or without\n"
"modification, are permitted provided that the following conditions are\n"
"met:\n"
-"\n"
+"\n";
+const char *wpa_supplicant_full_license3 =
"1. Redistributions of source code must retain the above copyright\n"
" notice, this list of conditions and the following disclaimer.\n"
"\n"
"2. Redistributions in binary form must reproduce the above copyright\n"
" notice, this list of conditions and the following disclaimer in the\n"
" documentation and/or other materials provided with the distribution.\n"
-"\n"
+"\n";
+const char *wpa_supplicant_full_license4 =
"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n"
" names of its contributors may be used to endorse or promote products\n"
" derived from this software without specific prior written permission.\n"
@@ -92,7 +94,8 @@ const char *wpa_supplicant_full_license =
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n"
"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n"
"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n"
-"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n"
+"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n";
+const char *wpa_supplicant_full_license5 =
"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n"
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n"
"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n"
@@ -105,37 +108,14 @@ const char *wpa_supplicant_full_license =
extern struct wpa_driver_ops *wpa_supplicant_drivers[];
+extern int wpa_debug_use_file;
extern int wpa_debug_level;
extern int wpa_debug_show_keys;
extern int wpa_debug_timestamp;
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx);
-void wpa_msg(struct wpa_supplicant *wpa_s, int level, char *fmt, ...)
-{
- va_list ap;
- char *buf;
- const int buflen = 2048;
- int len;
-
- buf = malloc(buflen);
- if (buf == NULL) {
- printf("Failed to allocate message buffer for:\n");
- va_start(ap, fmt);
- vprintf(fmt, ap);
- printf("\n");
- va_end(ap);
- return;
- }
- va_start(ap, fmt);
- len = vsnprintf(buf, buflen, fmt, ap);
- va_end(ap);
- wpa_printf(level, "%s", buf);
- wpa_supplicant_ctrl_iface_send(wpa_s, level, buf, len);
- free(buf);
-}
-
-
+#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
const void *data, u16 data_len,
size_t *msg_len, void **data_pos)
@@ -143,18 +123,18 @@ static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
struct ieee802_1x_hdr *hdr;
*msg_len = sizeof(*hdr) + data_len;
- hdr = malloc(*msg_len);
+ hdr = os_malloc(*msg_len);
if (hdr == NULL)
return NULL;
hdr->version = wpa_s->conf->eapol_version;
hdr->type = type;
- hdr->length = htons(data_len);
+ hdr->length = host_to_be16(data_len);
if (data)
- memcpy(hdr + 1, data, data_len);
+ os_memcpy(hdr + 1, data, data_len);
else
- memset(hdr + 1, 0, data_len);
+ os_memset(hdr + 1, 0, data_len);
if (data_pos)
*data_pos = hdr + 1;
@@ -165,14 +145,15 @@ static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
/**
* wpa_ether_send - Send Ethernet frame
- * @wpa_s: pointer to wpa_supplicant data
+ * @wpa_s: Pointer to wpa_supplicant data
* @dest: Destination MAC address
- * @proto: Ethertype
+ * @proto: Ethertype in host byte order
* @buf: Frame payload starting from IEEE 802.1X header
* @len: Frame payload length
+ * Returns: >=0 on success, <0 on failure
*/
-int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest, u16 proto,
- const u8 *buf, size_t len)
+static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
+ u16 proto, const u8 *buf, size_t len)
{
if (wpa_s->l2) {
return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
@@ -180,15 +161,17 @@ int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest, u16 proto,
return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len);
}
+#endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
#ifdef IEEE8021X_EAPOL
/**
* wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
- * @ctx: pointer to wpa_supplicant data
+ * @ctx: Pointer to wpa_supplicant data (wpa_s)
* @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
* @buf: EAPOL payload (after IEEE 802.1X header)
* @len: EAPOL payload length
+ * Returns: >=0 on success, <0 on failure
*
* This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
* to the current Authenticator.
@@ -224,11 +207,13 @@ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
return -1;
}
- if (memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0) {
+ if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
+ {
wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
"EAPOL frame");
if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
- memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
+ os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) !=
+ 0) {
dst = bssid;
wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
" from the driver as the EAPOL destination",
@@ -252,30 +237,45 @@ static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
- free(msg);
+ os_free(msg);
return res;
}
/**
* wpa_eapol_set_wep_key - set WEP key for the driver
- * @ctx: pointer to wpa_supplicant data
+ * @ctx: Pointer to wpa_supplicant data (wpa_s)
* @unicast: 1 = individual unicast key, 0 = broadcast key
* @keyidx: WEP key index (0..3)
- * @key: pointer to key data
- * @keylen: key length in bytes
- *
- * Returns 0 on success or < 0 on error.
+ * @key: Pointer to key data
+ * @keylen: Key length in bytes
+ * Returns: 0 on success or < 0 on error.
*/
static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
const u8 *key, size_t keylen)
{
struct wpa_supplicant *wpa_s = ctx;
+ if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
+ int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
+ WPA_CIPHER_WEP104;
+ if (unicast)
+ wpa_s->pairwise_cipher = cipher;
+ else
+ wpa_s->group_cipher = cipher;
+ }
return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
unicast ? wpa_s->bssid :
(u8 *) "\xff\xff\xff\xff\xff\xff",
keyidx, unicast, (u8 *) "", 0, key, keylen);
}
+
+
+static void wpa_supplicant_aborted_cached(void *ctx)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ wpa_sm_aborted_cached(wpa_s->wpa);
+}
+
#endif /* IEEE8021X_EAPOL */
@@ -332,14 +332,14 @@ static int wpa_supplicant_set_wpa_none_key(struct wpa_supplicant *wpa_s,
switch (wpa_s->group_cipher) {
case WPA_CIPHER_CCMP:
- memcpy(key, ssid->psk, 16);
+ os_memcpy(key, ssid->psk, 16);
keylen = 16;
alg = WPA_ALG_CCMP;
break;
case WPA_CIPHER_TKIP:
/* WPA-None uses the same Michael MIC key for both TX and RX */
- memcpy(key, ssid->psk, 16 + 8);
- memcpy(key + 16 + 8, ssid->psk + 16, 8);
+ os_memcpy(key, ssid->psk, 16 + 8);
+ os_memcpy(key + 16 + 8, ssid->psk + 16, 8);
keylen = 32;
alg = WPA_ALG_TKIP;
break;
@@ -373,6 +373,12 @@ static void wpa_supplicant_notify_eapol_done(void *ctx)
#endif /* IEEE8021X_EAPOL */
+/**
+ * wpa_blacklist_get - Get the blacklist entry for a BSSID
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID
+ * Returns: Matching blacklist entry for the BSSID or %NULL if not found
+ */
struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
const u8 *bssid)
{
@@ -380,7 +386,7 @@ struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
e = wpa_s->blacklist;
while (e) {
- if (memcmp(e->bssid, bssid, ETH_ALEN) == 0)
+ if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
return e;
e = e->next;
}
@@ -389,6 +395,22 @@ struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpa_blacklist_add - Add an BSSID to the blacklist
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID to be added to the blacklist
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function adds the specified BSSID to the blacklist or increases the
+ * blacklist count if the BSSID was already listed. It should be called when
+ * an association attempt fails either due to the selected BSS rejecting
+ * association or due to timeout.
+ *
+ * This blacklist is used to force %wpa_supplicant to go through all available
+ * BSSes before retrying to associate with an BSS that rejected or timed out
+ * association. It does not prevent the listed BSS from being used; it only
+ * changes the order in which they are tried.
+ */
int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_blacklist *e;
@@ -402,11 +424,10 @@ int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
return 0;
}
- e = malloc(sizeof(*e));
+ e = os_zalloc(sizeof(*e));
if (e == NULL)
return -1;
- memset(e, 0, sizeof(*e));
- memcpy(e->bssid, bssid, ETH_ALEN);
+ os_memcpy(e->bssid, bssid, ETH_ALEN);
e->count = 1;
e->next = wpa_s->blacklist;
wpa_s->blacklist = e;
@@ -417,13 +438,13 @@ int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
}
-int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
+static int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
{
struct wpa_blacklist *e, *prev = NULL;
e = wpa_s->blacklist;
while (e) {
- if (memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
+ if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
if (prev == NULL) {
wpa_s->blacklist = e->next;
} else {
@@ -431,7 +452,7 @@ int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
}
wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
"blacklist", MAC2STR(bssid));
- free(e);
+ os_free(e);
return 0;
}
prev = e;
@@ -441,6 +462,10 @@ int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
}
+/**
+ * wpa_blacklist_clear - Clear the blacklist of all entries
+ * @wpa_s: Pointer to wpa_supplicant data
+ */
void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
{
struct wpa_blacklist *e, *prev;
@@ -452,28 +477,20 @@ void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
e = e->next;
wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
"blacklist (clear)", MAC2STR(prev->bssid));
- free(prev);
- }
-}
-
-
-const char * wpa_ssid_txt(u8 *ssid, size_t ssid_len)
-{
- static char ssid_txt[MAX_SSID_LEN + 1];
- char *pos;
-
- if (ssid_len > MAX_SSID_LEN)
- ssid_len = MAX_SSID_LEN;
- memcpy(ssid_txt, ssid, ssid_len);
- ssid_txt[ssid_len] = '\0';
- for (pos = ssid_txt; *pos != '\0'; pos++) {
- if ((u8) *pos < 32 || (u8) *pos >= 127)
- *pos = '_';
+ os_free(prev);
}
- return ssid_txt;
}
+/**
+ * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @sec: Number of seconds after which to scan
+ * @usec: Number of microseconds after which to scan
+ *
+ * This function is used to schedule a scan for neighboring access points after
+ * the specified time.
+ */
void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
{
wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
@@ -483,6 +500,13 @@ void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
}
+/**
+ * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
+ * @wpa_s: Pointer to wpa_supplicant data
+ *
+ * This function is used to cancel a scan request scheduled with
+ * wpa_supplicant_req_scan().
+ */
void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
{
wpa_msg(wpa_s, MSG_DEBUG, "Cancelling scan request");
@@ -493,9 +517,12 @@ void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
+ const u8 *bssid = wpa_s->bssid;
+ if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
+ bssid = wpa_s->pending_bssid;
wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
MAC2STR(wpa_s->bssid));
- wpa_blacklist_add(wpa_s, wpa_s->bssid);
+ wpa_blacklist_add(wpa_s, bssid);
wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
wpa_s->reassociate = 1;
@@ -503,11 +530,20 @@ static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
}
+/**
+ * wpa_supplicant_req_auth_timeout - Schedule a timeout for authentication
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @sec: Number of seconds after which to time out authentication
+ * @usec: Number of microseconds after which to time out authentication
+ *
+ * This function is used to schedule a timeout for the current authentication
+ * attempt.
+ */
void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
int sec, int usec)
{
if (wpa_s->conf && wpa_s->conf->ap_scan == 0 &&
- wpa_s->driver && strcmp(wpa_s->driver->name, "wired") == 0)
+ wpa_s->driver && os_strcmp(wpa_s->driver->name, "wired") == 0)
return;
wpa_msg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec "
@@ -517,6 +553,14 @@ void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout
+ * @wpa_s: Pointer to wpa_supplicant data
+ *
+ * This function is used to cancel authentication timeout scheduled with
+ * wpa_supplicant_req_auth_timeout() and it is called when authentication has
+ * been completed.
+ */
void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
{
wpa_msg(wpa_s, MSG_DEBUG, "Cancelling authentication timeout");
@@ -525,8 +569,16 @@ void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s)
}
+/**
+ * wpa_supplicant_initiate_eapol - Configure EAPOL state machine
+ * @wpa_s: Pointer to wpa_supplicant data
+ *
+ * This function is used to configure EAPOL state machine based on the selected
+ * authentication mode.
+ */
void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
{
+#ifdef IEEE8021X_EAPOL
struct eapol_config eapol_conf;
struct wpa_ssid *ssid = wpa_s->current_ssid;
@@ -540,7 +592,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
else
eapol_sm_notify_portControl(wpa_s->eapol, Auto);
- memset(&eapol_conf, 0, sizeof(eapol_conf));
+ os_memset(&eapol_conf, 0, sizeof(eapol_conf));
if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
eapol_conf.accept_802_1x_keys = 1;
eapol_conf.required_keys = 0;
@@ -553,18 +605,29 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
}
if (wpa_s->conf && wpa_s->driver &&
- strcmp(wpa_s->driver->name, "wired") == 0) {
+ os_strcmp(wpa_s->driver->name, "wired") == 0) {
eapol_conf.required_keys = 0;
}
}
- eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
+ if (wpa_s->conf)
+ eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
eapol_conf.workaround = ssid->eap_workaround;
eapol_conf.eap_disabled = wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA;
eapol_sm_notify_config(wpa_s->eapol, ssid, &eapol_conf);
+#endif /* IEEE8021X_EAPOL */
}
+/**
+ * wpa_supplicant_set_non_wpa_policy - Set WPA parameters to non-WPA mode
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @ssid: Configuration data for the network
+ *
+ * This function is used to configure WPA state machine and related parameters
+ * to a mode where WPA is not enabled. This is called as part of the
+ * authentication configuration when the selected network does not use WPA.
+ */
void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
@@ -579,6 +642,7 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
wpa_s->pairwise_cipher = WPA_CIPHER_NONE;
wpa_s->group_cipher = WPA_CIPHER_NONE;
+ wpa_s->mgmt_group_cipher = 0;
for (i = 0; i < NUM_WEP_KEYS; i++) {
if (ssid->wep_key_len[i] > 5) {
@@ -596,6 +660,10 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PAIRWISE,
wpa_s->pairwise_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
+#ifdef CONFIG_IEEE80211W
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
+ wpa_s->mgmt_group_cipher);
+#endif /* CONFIG_IEEE80211W */
pmksa_cache_clear_current(wpa_s->wpa);
}
@@ -609,14 +677,21 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
eapol_sm_register_scard_ctx(wpa_s->eapol, NULL);
l2_packet_deinit(wpa_s->l2);
wpa_s->l2 = NULL;
+ if (wpa_s->l2_br) {
+ l2_packet_deinit(wpa_s->l2_br);
+ wpa_s->l2_br = NULL;
+ }
- wpa_supplicant_ctrl_iface_deinit(wpa_s);
+ if (wpa_s->ctrl_iface) {
+ wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
+ wpa_s->ctrl_iface = NULL;
+ }
if (wpa_s->conf != NULL) {
wpa_config_free(wpa_s->conf);
wpa_s->conf = NULL;
}
- free(wpa_s->confname);
+ os_free(wpa_s->confname);
wpa_s->confname = NULL;
wpa_sm_set_eapol(wpa_s->wpa, NULL);
@@ -626,19 +701,29 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
rsn_preauth_deinit(wpa_s->wpa);
pmksa_candidate_free(wpa_s->wpa);
- pmksa_cache_free(wpa_s->wpa);
wpa_sm_deinit(wpa_s->wpa);
wpa_s->wpa = NULL;
wpa_blacklist_clear(wpa_s);
- free(wpa_s->scan_results);
+ os_free(wpa_s->scan_results);
wpa_s->scan_results = NULL;
wpa_s->num_scan_results = 0;
wpa_supplicant_cancel_scan(wpa_s);
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+
+ ieee80211_sta_deinit(wpa_s);
}
+/**
+ * wpa_clear_keys - Clear keys configured for the driver
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @addr: Previously used BSSID or %NULL if not available
+ *
+ * This function clears the encryption keys that has been previously configured
+ * for the driver.
+ */
void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
{
u8 *bcast = (u8 *) "\xff\xff\xff\xff\xff\xff";
@@ -656,6 +741,7 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
return;
}
+ /* MLME-DELETEKEYS.request */
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 0, 0, NULL, 0, NULL, 0);
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 1, 0, NULL, 0, NULL, 0);
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, bcast, 2, 0, NULL, 0, NULL, 0);
@@ -663,11 +749,21 @@ void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr)
if (addr) {
wpa_drv_set_key(wpa_s, WPA_ALG_NONE, addr, 0, 0, NULL, 0, NULL,
0);
+ /* MLME-SETPROTECTION.request(None) */
+ wpa_drv_mlme_setprotection(
+ wpa_s, addr,
+ MLME_SETPROTECTION_PROTECT_TYPE_NONE,
+ MLME_SETPROTECTION_KEY_TYPE_PAIRWISE);
}
wpa_s->keys_cleared = 1;
}
+/**
+ * wpa_supplicant_state_txt - Get the connection state name as a text string
+ * @state: State (wpa_state; WPA_*)
+ * Returns: The state name as a printable text string
+ */
const char * wpa_supplicant_state_txt(int state)
{
switch (state) {
@@ -693,26 +789,50 @@ const char * wpa_supplicant_state_txt(int state)
}
+/**
+ * wpa_supplicant_set_state - Set current connection state
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @state: The new connection state
+ *
+ * This function is called whenever the connection state changes, e.g.,
+ * association is completed for WPA/WPA2 4-Way Handshake is started.
+ */
void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state)
{
wpa_printf(MSG_DEBUG, "State: %s -> %s",
wpa_supplicant_state_txt(wpa_s->wpa_state),
wpa_supplicant_state_txt(state));
+
+ wpa_supplicant_dbus_notify_state_change(wpa_s, state,
+ wpa_s->wpa_state);
+
if (state == WPA_COMPLETED && wpa_s->new_connection) {
- wpa_s->new_connection = 0;
+#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_CONNECTED "- Connection to "
- MACSTR " completed %s",
+ MACSTR " completed %s [id=%d id_str=%s]",
MAC2STR(wpa_s->bssid), wpa_s->reassociated_connection ?
- "(reauth)" : "(auth)");
+ "(reauth)" : "(auth)",
+ ssid ? ssid->id : -1,
+ ssid && ssid->id_str ? ssid->id_str : "");
+#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
+ wpa_s->new_connection = 0;
wpa_s->reassociated_connection = 1;
+ wpa_drv_set_operstate(wpa_s, 1);
} else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING ||
state == WPA_ASSOCIATED) {
wpa_s->new_connection = 1;
+ wpa_drv_set_operstate(wpa_s, 0);
}
wpa_s->wpa_state = state;
}
+/**
+ * wpa_supplicant_get_state - Get the connection state
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: The current connection state (WPA_*)
+ */
wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
{
return wpa_s->wpa_state;
@@ -732,6 +852,27 @@ static void wpa_supplicant_terminate(int sig, void *eloop_ctx,
}
+static void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
+{
+ wpa_s->pairwise_cipher = 0;
+ wpa_s->group_cipher = 0;
+ wpa_s->mgmt_group_cipher = 0;
+ wpa_s->key_mgmt = 0;
+ wpa_s->wpa_state = WPA_DISCONNECTED;
+}
+
+
+/**
+ * wpa_supplicant_reload_configuration - Reload configuration data
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: 0 on success or -1 if configuration parsing failed
+ *
+ * This function can be used to request that the configuration data is reloaded
+ * (e.g., after configuration file change). This function is reloading
+ * configuration only for one interface, so this may need to be called multiple
+ * times if %wpa_supplicant is controlling multiple interfaces and all
+ * interfaces need reconfiguration.
+ */
int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
{
struct wpa_config *conf;
@@ -747,26 +888,30 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
reconf_ctrl = !!conf->ctrl_interface != !!wpa_s->conf->ctrl_interface
|| (conf->ctrl_interface && wpa_s->conf->ctrl_interface &&
- strcmp(conf->ctrl_interface, wpa_s->conf->ctrl_interface)
- != 0);
+ os_strcmp(conf->ctrl_interface,
+ wpa_s->conf->ctrl_interface) != 0);
- if (reconf_ctrl)
- wpa_supplicant_ctrl_iface_deinit(wpa_s);
+ if (reconf_ctrl && wpa_s->ctrl_iface) {
+ wpa_supplicant_ctrl_iface_deinit(wpa_s->ctrl_iface);
+ wpa_s->ctrl_iface = NULL;
+ }
+ eapol_sm_invalidate_cached_session(wpa_s->eapol);
wpa_s->current_ssid = NULL;
/*
* TODO: should notify EAPOL SM about changes in opensc_engine_path,
* pkcs11_engine_path, pkcs11_module_path.
- */
+ */
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
wpa_sm_set_config(wpa_s->wpa, NULL);
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
- pmksa_cache_notify_reconfig(wpa_s->wpa);
rsn_preauth_deinit(wpa_s->wpa);
wpa_config_free(wpa_s->conf);
wpa_s->conf = conf;
if (reconf_ctrl)
- wpa_supplicant_ctrl_iface_init(wpa_s);
+ wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
+
+ wpa_supplicant_clear_status(wpa_s);
wpa_s->reassociate = 1;
wpa_supplicant_req_scan(wpa_s, 0, 0);
wpa_msg(wpa_s, MSG_DEBUG, "Reconfiguration completed");
@@ -774,7 +919,6 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s)
}
-#ifndef CONFIG_NATIVE_WINDOWS
static void wpa_supplicant_reconfig(int sig, void *eloop_ctx,
void *signal_ctx)
{
@@ -787,7 +931,6 @@ static void wpa_supplicant_reconfig(int sig, void *eloop_ctx,
}
}
}
-#endif /* CONFIG_NATIVE_WINDOWS */
static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
@@ -804,7 +947,7 @@ static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
wpa_supplicant_initiate_eapol(wpa_s);
wpa_printf(MSG_DEBUG, "Already associated with a configured network - "
"generating associated event");
- memset(&data, 0, sizeof(data));
+ os_memset(&data, 0, sizeof(data));
wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
}
@@ -813,7 +956,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
struct wpa_ssid *ssid;
- int enabled, scan_req = 0;
+ int enabled, scan_req = 0, ret;
if (wpa_s->disconnected)
return;
@@ -835,6 +978,13 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
scan_req = wpa_s->scan_req;
wpa_s->scan_req = 0;
+ if (wpa_s->conf->ap_scan != 0 &&
+ wpa_s->driver && os_strcmp(wpa_s->driver->name, "wired") == 0) {
+ wpa_printf(MSG_DEBUG, "Using wired driver - overriding "
+ "ap_scan configuration");
+ wpa_s->conf->ap_scan = 0;
+ }
+
if (wpa_s->conf->ap_scan == 0) {
wpa_supplicant_gen_assoc_event(wpa_s);
return;
@@ -866,8 +1016,13 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
* ap_scan=2 mode - try to associate with each SSID instead of
* scanning for each scan_ssid=1 network.
*/
- if (ssid == NULL)
+ if (ssid == NULL) {
+ wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached "
+ "end of scan list - go back to beginning");
+ wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
return;
+ }
if (ssid->next) {
/* Continue from the next SSID on the next attempt. */
wpa_s->prev_scan_ssid = ssid;
@@ -888,8 +1043,23 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
} else
wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
- if (wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL,
- ssid ? ssid->ssid_len : 0)) {
+ if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1) {
+ wpa_s->scan_res_tried++;
+ wpa_printf(MSG_DEBUG, "Trying to get current scan results "
+ "first without requesting a new scan to speed up "
+ "initial association");
+ wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL);
+ return;
+ }
+
+ if (wpa_s->use_client_mlme) {
+ ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL,
+ ssid ? ssid->ssid_len : 0);
+ } else {
+ ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL,
+ ssid ? ssid->ssid_len : 0);
+ }
+ if (ret) {
wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
wpa_supplicant_req_scan(wpa_s, 10, 0);
}
@@ -966,10 +1136,34 @@ static int wpa_supplicant_suites_from_ai(struct wpa_supplicant *wpa_s,
return -1;
}
+#ifdef CONFIG_IEEE80211W
+ if (!(ie->capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION) &&
+ ssid->ieee80211w == IEEE80211W_REQUIRED) {
+ wpa_msg(wpa_s, MSG_INFO, "WPA: Driver associated with an AP "
+ "that does not support management frame protection - "
+ "reject");
+ return -1;
+ }
+#endif /* CONFIG_IEEE80211W */
+
return 0;
}
+/**
+ * wpa_supplicant_set_suites - Set authentication and encryption parameters
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bss: Scan results for the selected BSS, or %NULL if not available
+ * @ssid: Configuration data for the selected network
+ * @wpa_ie: Buffer for the WPA/RSN IE
+ * @wpa_ie_len: Maximum wpa_ie buffer size on input. This is changed to be the
+ * used buffer length in case the functions returns success.
+ * Returns: 0 on success or -1 on failure
+ *
+ * This function is used to configure authentication and encryption parameters
+ * based on the network configuration and scan result for the selected BSS (if
+ * available).
+ */
int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
struct wpa_scan_result *bss,
struct wpa_ssid *ssid,
@@ -1001,18 +1195,30 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
else
proto = WPA_PROTO_WPA;
if (wpa_supplicant_suites_from_ai(wpa_s, ssid, &ie) < 0) {
- memset(&ie, 0, sizeof(ie));
+ os_memset(&ie, 0, sizeof(ie));
ie.group_cipher = ssid->group_cipher;
ie.pairwise_cipher = ssid->pairwise_cipher;
ie.key_mgmt = ssid->key_mgmt;
+#ifdef CONFIG_IEEE80211W
+ ie.mgmt_group_cipher =
+ ssid->ieee80211w != NO_IEEE80211W ?
+ WPA_CIPHER_AES_128_CMAC : 0;
+#endif /* CONFIG_IEEE80211W */
wpa_printf(MSG_DEBUG, "WPA: Set cipher suites based "
"on configuration");
- }
+ } else
+ proto = ie.proto;
}
wpa_printf(MSG_DEBUG, "WPA: Selected cipher suites: group %d "
- "pairwise %d key_mgmt %d",
- ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt);
+ "pairwise %d key_mgmt %d proto %d",
+ ie.group_cipher, ie.pairwise_cipher, ie.key_mgmt, proto);
+#ifdef CONFIG_IEEE80211W
+ if (ssid->ieee80211w) {
+ wpa_printf(MSG_DEBUG, "WPA: Selected mgmt group cipher %d",
+ ie.mgmt_group_cipher);
+ }
+#endif /* CONFIG_IEEE80211W */
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_PROTO, proto);
@@ -1077,6 +1283,23 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
wpa_s->pairwise_cipher);
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_GROUP, wpa_s->group_cipher);
+#ifdef CONFIG_IEEE80211W
+ sel = ie.mgmt_group_cipher;
+ if (ssid->ieee80211w == NO_IEEE80211W ||
+ !(ie.capabilities & WPA_CAPABILITY_MGMT_FRAME_PROTECTION))
+ sel = 0;
+ if (sel & WPA_CIPHER_AES_128_CMAC) {
+ wpa_s->mgmt_group_cipher = WPA_CIPHER_AES_128_CMAC;
+ wpa_msg(wpa_s, MSG_DEBUG, "WPA: using MGMT group cipher "
+ "AES-128-CMAC");
+ } else {
+ wpa_s->mgmt_group_cipher = 0;
+ wpa_msg(wpa_s, MSG_DEBUG, "WPA: not using MGMT group cipher");
+ }
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MGMT_GROUP,
+ wpa_s->mgmt_group_cipher);
+#endif /* CONFIG_IEEE80211W */
+
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
wpa_printf(MSG_WARNING, "WPA: Failed to generate WPA IE.");
return -1;
@@ -1091,15 +1314,23 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpa_supplicant_associate - Request association
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bss: Scan results for the selected BSS, or %NULL if not available
+ * @ssid: Configuration data for the selected network
+ *
+ * This function is used to request %wpa_supplicant to associate with a BSS.
+ */
void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
struct wpa_scan_result *bss,
struct wpa_ssid *ssid)
{
u8 wpa_ie[80];
size_t wpa_ie_len;
- int use_crypt;
+ int use_crypt, ret, i;
int algs = AUTH_ALG_OPEN_SYSTEM;
- int cipher_pairwise, cipher_group;
+ wpa_cipher cipher_pairwise, cipher_group;
struct wpa_driver_associate_params params;
int wep_keys_set = 0;
struct wpa_driver_capa capa;
@@ -1110,10 +1341,12 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
" (SSID='%s' freq=%d MHz)", MAC2STR(bss->bssid),
wpa_ssid_txt(bss->ssid, bss->ssid_len), bss->freq);
- memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
} else {
wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+ os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
}
wpa_supplicant_cancel_scan(wpa_s);
@@ -1121,6 +1354,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
* previous association. */
wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
+#ifdef IEEE8021X_EAPOL
if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
if (ssid->leap) {
if (ssid->non_leap == 0)
@@ -1129,6 +1363,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
algs |= AUTH_ALG_LEAP;
}
}
+#endif /* IEEE8021X_EAPOL */
wpa_printf(MSG_DEBUG, "Automatic auth_alg selection: 0x%x", algs);
if (ssid->auth_alg) {
algs = 0;
@@ -1181,7 +1416,6 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
cipher_group = cipher_suite2driver(wpa_s->group_cipher);
if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
- int i;
if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
use_crypt = 0;
for (i = 0; i < NUM_WEP_KEYS; i++) {
@@ -1196,6 +1430,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
}
}
+#ifdef IEEE8021X_EAPOL
if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
if ((ssid->eapol_flags &
(EAPOL_FLAG_REQUIRE_KEY_UNICAST |
@@ -1209,6 +1444,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
cipher_pairwise = cipher_group = CIPHER_WEP104;
}
}
+#endif /* IEEE8021X_EAPOL */
if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE) {
/* Set the key before (and later after) association */
@@ -1217,7 +1453,7 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
wpa_drv_set_drop_unencrypted(wpa_s, use_crypt);
wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
- memset(&params, 0, sizeof(params));
+ os_memset(&params, 0, sizeof(params));
if (bss) {
params.bssid = bss->bssid;
params.ssid = bss->ssid;
@@ -1234,7 +1470,32 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt);
params.auth_alg = algs;
params.mode = ssid->mode;
- if (wpa_drv_associate(wpa_s, &params) < 0) {
+ for (i = 0; i < NUM_WEP_KEYS; i++) {
+ if (ssid->wep_key_len[i])
+ params.wep_key[i] = ssid->wep_key[i];
+ params.wep_key_len[i] = ssid->wep_key_len[i];
+ }
+ params.wep_tx_keyidx = ssid->wep_tx_keyidx;
+
+#ifdef CONFIG_IEEE80211W
+ switch (ssid->ieee80211w) {
+ case NO_IEEE80211W:
+ params.mgmt_frame_protection = NO_MGMT_FRAME_PROTECTION;
+ break;
+ case IEEE80211W_OPTIONAL:
+ params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_OPTIONAL;
+ break;
+ case IEEE80211W_REQUIRED:
+ params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_REQUIRED;
+ break;
+ }
+#endif /* CONFIG_IEEE80211W */
+
+ if (wpa_s->use_client_mlme)
+ ret = ieee80211_sta_associate(wpa_s, &params);
+ else
+ ret = wpa_drv_associate(wpa_s, &params);
+ if (ret < 0) {
wpa_msg(wpa_s, MSG_INFO, "Association request to the driver "
"failed");
/* try to continue anyway; new association will be tried again
@@ -1265,48 +1526,78 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
/* Set static WEP keys again */
- int i;
- for (i = 0; i < NUM_WEP_KEYS; i++) {
- if (ssid->wep_key_len[i]) {
+ int j;
+ for (j = 0; j < NUM_WEP_KEYS; j++) {
+ if (ssid->wep_key_len[j]) {
wpa_set_wep_key(wpa_s,
- i == ssid->wep_tx_keyidx,
- i, ssid->wep_key[i],
- ssid->wep_key_len[i]);
+ j == ssid->wep_tx_keyidx,
+ j, ssid->wep_key[j],
+ ssid->wep_key_len[j]);
}
}
}
+ if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
+ /*
+ * Do not allow EAP session resumption between different
+ * network configurations.
+ */
+ eapol_sm_invalidate_cached_session(wpa_s->eapol);
+ }
wpa_s->current_ssid = ssid;
wpa_sm_set_config(wpa_s->wpa, wpa_s->current_ssid);
wpa_supplicant_initiate_eapol(wpa_s);
}
+/**
+ * wpa_supplicant_disassociate - Disassociate the current connection
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @reason_code: IEEE 802.11 reason code for the disassociate frame
+ *
+ * This function is used to request %wpa_supplicant to disassociate with the
+ * current AP.
+ */
void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
int reason_code)
{
u8 *addr = NULL;
- wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- if (memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
- wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
+ if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0)
+ {
+ if (wpa_s->use_client_mlme)
+ ieee80211_sta_disassociate(wpa_s, reason_code);
+ else
+ wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
addr = wpa_s->bssid;
}
wpa_clear_keys(wpa_s, addr);
+ wpa_supplicant_mark_disassoc(wpa_s);
wpa_s->current_ssid = NULL;
wpa_sm_set_config(wpa_s->wpa, NULL);
eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
- eapol_sm_notify_portEnabled(wpa_s->eapol, FALSE);
- eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
}
+/**
+ * wpa_supplicant_deauthenticate - Deauthenticate the current connection
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @reason_code: IEEE 802.11 reason code for the deauthenticate frame
+ *
+ * This function is used to request %wpa_supplicant to disassociate with the
+ * current AP.
+ */
void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
int reason_code)
{
u8 *addr = NULL;
wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
- if (memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
- wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code);
+ if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0)
+ {
+ if (wpa_s->use_client_mlme)
+ ieee80211_sta_deauthenticate(wpa_s, reason_code);
+ else
+ wpa_drv_deauthenticate(wpa_s, wpa_s->bssid,
+ reason_code);
addr = wpa_s->bssid;
}
wpa_clear_keys(wpa_s, addr);
@@ -1318,24 +1609,36 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
}
+/**
+ * wpa_supplicant_get_scan_results - Get scan results
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is request the current scan results from the driver and stores
+ * a local copy of the results in wpa_s->scan_results.
+ */
int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s)
{
#define SCAN_AP_LIMIT 128
struct wpa_scan_result *results, *tmp;
int num;
- results = malloc(SCAN_AP_LIMIT * sizeof(struct wpa_scan_result));
+ results = os_malloc(SCAN_AP_LIMIT * sizeof(struct wpa_scan_result));
if (results == NULL) {
wpa_printf(MSG_WARNING, "Failed to allocate memory for scan "
"results");
return -1;
}
- num = wpa_drv_get_scan_results(wpa_s, results, SCAN_AP_LIMIT);
+ if (wpa_s->use_client_mlme) {
+ num = ieee80211_sta_get_scan_results(wpa_s, results,
+ SCAN_AP_LIMIT);
+ } else
+ num = wpa_drv_get_scan_results(wpa_s, results, SCAN_AP_LIMIT);
wpa_printf(MSG_DEBUG, "Scan results: %d", num);
if (num < 0) {
wpa_printf(MSG_DEBUG, "Failed to get scan results");
- free(results);
+ os_free(results);
return -1;
}
if (num > SCAN_AP_LIMIT) {
@@ -1345,12 +1648,12 @@ int wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s)
}
/* Free unneeded memory for unused scan result entries */
- tmp = realloc(results, num * sizeof(struct wpa_scan_result));
+ tmp = os_realloc(results, num * sizeof(struct wpa_scan_result));
if (tmp || num == 0) {
results = tmp;
}
- free(wpa_s->scan_results);
+ os_free(wpa_s->scan_results);
wpa_s->scan_results = results;
wpa_s->num_scan_results = num;
@@ -1370,7 +1673,14 @@ static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
}
for (i = 0; i < wpa_s->num_scan_results; i++) {
- if (memcmp(results[i].bssid, wpa_s->bssid, ETH_ALEN) == 0) {
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+ if (os_memcmp(results[i].bssid, wpa_s->bssid, ETH_ALEN) != 0)
+ continue;
+ if (ssid == NULL ||
+ ((results[i].ssid_len == ssid->ssid_len &&
+ os_memcmp(results[i].ssid, ssid->ssid, ssid->ssid_len)
+ == 0) ||
+ ssid->ssid_len == 0)) {
curr = &results[i];
break;
}
@@ -1409,36 +1719,52 @@ static int wpa_supplicant_get_beacon_ie(void *ctx)
/**
- * wpa_supplicant_get_ssid - get a pointer to the current network structure
- * @wpa_s: pointer to wpa_supplicant data
- *
- * Returns: a pointer to the current network structure or %NULL on failure
+ * wpa_supplicant_get_ssid - Get a pointer to the current network structure
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: A pointer to the current network structure or %NULL on failure
*/
struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s)
{
struct wpa_ssid *entry;
u8 ssid[MAX_SSID_LEN];
- int ssid_len;
+ int res;
+ size_t ssid_len;
u8 bssid[ETH_ALEN];
+ int wired;
- ssid_len = wpa_drv_get_ssid(wpa_s, ssid);
- if (ssid_len < 0) {
- wpa_printf(MSG_WARNING, "Could not read SSID from driver.");
- return NULL;
+ if (wpa_s->use_client_mlme) {
+ if (ieee80211_sta_get_ssid(wpa_s, ssid, &ssid_len)) {
+ wpa_printf(MSG_WARNING, "Could not read SSID from "
+ "MLME.");
+ return NULL;
+ }
+ } else {
+ res = wpa_drv_get_ssid(wpa_s, ssid);
+ if (res < 0) {
+ wpa_printf(MSG_WARNING, "Could not read SSID from "
+ "driver.");
+ return NULL;
+ }
+ ssid_len = res;
}
- if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
+ if (wpa_s->use_client_mlme)
+ os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
+ else if (wpa_drv_get_bssid(wpa_s, bssid) < 0) {
wpa_printf(MSG_WARNING, "Could not read BSSID from driver.");
return NULL;
}
+ wired = wpa_s->conf->ap_scan == 0 && wpa_s->driver &&
+ os_strcmp(wpa_s->driver->name, "wired") == 0;
+
entry = wpa_s->conf->ssid;
while (entry) {
if (!entry->disabled &&
- ssid_len == entry->ssid_len &&
- memcmp(ssid, entry->ssid, ssid_len) == 0 &&
+ ((ssid_len == entry->ssid_len &&
+ os_memcmp(ssid, entry->ssid, ssid_len) == 0) || wired) &&
(!entry->bssid_set ||
- memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
+ os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
return entry;
entry = entry->next;
}
@@ -1505,8 +1831,13 @@ static struct wpa_ssid * _wpa_supplicant_get_ssid(void *wpa_s)
}
-static int wpa_supplicant_get_bssid(void *wpa_s, u8 *bssid)
+static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
{
+ struct wpa_supplicant *wpa_s = ctx;
+ if (wpa_s->use_client_mlme) {
+ os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
+ return 0;
+ }
return wpa_drv_get_bssid(wpa_s, bssid);
}
@@ -1521,6 +1852,15 @@ static int wpa_supplicant_set_key(void *wpa_s, wpa_alg alg,
}
+static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
+ int protection_type,
+ int key_type)
+{
+ return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
+ key_type);
+}
+
+
static int wpa_supplicant_add_pmkid(void *wpa_s,
const u8 *bssid, const u8 *pmkid)
{
@@ -1557,13 +1897,13 @@ static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
}
for (i = 0; wpa_supplicant_drivers[i]; i++) {
- if (strcmp(name, wpa_supplicant_drivers[i]->name) == 0) {
+ if (os_strcmp(name, wpa_supplicant_drivers[i]->name) == 0) {
wpa_s->driver = wpa_supplicant_drivers[i];
return 0;
}
}
- printf("Unsupported driver '%s'.\n", name);
+ wpa_printf(MSG_ERROR, "Unsupported driver '%s'.\n", name);
return -1;
}
@@ -1604,7 +1944,7 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
* an AP, so just allow any address to be used for now. The replies are
* still sent to the current BSSID (if available), though. */
- memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
+ os_memcpy(wpa_s->last_eapol_src, src_addr, ETH_ALEN);
if (wpa_s->key_mgmt != WPA_KEY_MGMT_PSK &&
eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
return;
@@ -1613,6 +1953,17 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
}
+/**
+ * wpa_supplicant_driver_init - Initialize driver interface parameters
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @wait_for_interface: 0 = do not wait for the interface (reports a failure if
+ * the interface is not present), 1 = wait until the interface is available
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is called to initialize driver interface parameters.
+ * wpa_drv_init() must have been called before this function to initialize the
+ * driver interface.
+ */
int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
int wait_for_interface)
{
@@ -1622,7 +1973,7 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
if (wpa_s->driver->send_eapol) {
const u8 *addr = wpa_drv_get_mac_addr(wpa_s);
if (addr)
- memcpy(wpa_s->own_addr, addr, ETH_ALEN);
+ os_memcpy(wpa_s->own_addr, addr, ETH_ALEN);
break;
}
wpa_s->l2 = l2_packet_init(wpa_s->ifname,
@@ -1633,18 +1984,34 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
break;
else if (!wait_for_interface)
return -1;
- printf("Waiting for interface..\n");
- sleep(5);
+ wpa_printf(MSG_DEBUG, "Waiting for interface..");
+ os_sleep(5, 0);
}
if (wpa_s->l2 && l2_packet_get_own_addr(wpa_s->l2, wpa_s->own_addr)) {
- fprintf(stderr, "Failed to get own L2 address\n");
+ wpa_printf(MSG_ERROR, "Failed to get own L2 address");
return -1;
}
wpa_printf(MSG_DEBUG, "Own MAC address: " MACSTR,
MAC2STR(wpa_s->own_addr));
+ if (wpa_s->bridge_ifname[0]) {
+ wpa_printf(MSG_DEBUG, "Receiving packets from bridge interface"
+ " '%s'", wpa_s->bridge_ifname);
+ wpa_s->l2_br = l2_packet_init(wpa_s->bridge_ifname,
+ wpa_s->own_addr,
+ ETH_P_EAPOL,
+ wpa_supplicant_rx_eapol, wpa_s,
+ 0);
+ if (wpa_s->l2_br == NULL) {
+ wpa_printf(MSG_ERROR, "Failed to open l2_packet "
+ "connection for the bridge interface '%s'",
+ wpa_s->bridge_ifname);
+ return -1;
+ }
+ }
+
/* Backwards compatibility call to set_wpa() handler. This is called
* only just after init and just before deinit, so these handler can be
* used to implement same functionality. */
@@ -1656,8 +2023,8 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "Driver does not support WPA.");
/* Continue to allow non-WPA modes to be used. */
} else {
- fprintf(stderr, "Failed to enable WPA in the "
- "driver.\n");
+ wpa_printf(MSG_ERROR, "Failed to enable WPA in the "
+ "driver.");
return -1;
}
}
@@ -1681,20 +2048,7 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
static int wpa_supplicant_daemon(const char *pid_file)
{
wpa_printf(MSG_DEBUG, "Daemonize..");
- if (daemon(0, 0)) {
- perror("daemon");
- return -1;
- }
-
- if (pid_file) {
- FILE *f = fopen(pid_file, "w");
- if (f) {
- fprintf(f, "%u\n", getpid());
- fclose(f);
- }
- }
-
- return 0;
+ return os_daemonize(pid_file);
}
@@ -1702,11 +2056,9 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void)
{
struct wpa_supplicant *wpa_s;
- wpa_s = malloc(sizeof(*wpa_s));
+ wpa_s = os_zalloc(sizeof(*wpa_s));
if (wpa_s == NULL)
return NULL;
- memset(wpa_s, 0, sizeof(*wpa_s));
- wpa_s->ctrl_sock = -1;
wpa_s->scan_req = 1;
return wpa_s;
@@ -1717,10 +2069,11 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
struct wpa_interface *iface)
{
wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
- "'%s' ctrl_interface '%s'", iface->ifname,
+ "'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
iface->confname ? iface->confname : "N/A",
iface->driver ? iface->driver : "default",
- iface->ctrl_interface ? iface->ctrl_interface : "N/A");
+ iface->ctrl_interface ? iface->ctrl_interface : "N/A",
+ iface->bridge_ifname ? iface->bridge_ifname : "N/A");
if (wpa_supplicant_set_driver(wpa_s, iface->driver) < 0) {
return -1;
@@ -1728,7 +2081,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
if (iface->confname) {
#ifdef CONFIG_BACKEND_FILE
- wpa_s->confname = rel2abs_path(iface->confname);
+ wpa_s->confname = os_rel2abs_path(iface->confname);
if (wpa_s->confname == NULL) {
wpa_printf(MSG_ERROR, "Failed to get absolute path "
"for configuration file '%s'.",
@@ -1738,12 +2091,12 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG, "Configuration file '%s' -> '%s'",
iface->confname, wpa_s->confname);
#else /* CONFIG_BACKEND_FILE */
- wpa_s->confname = strdup(iface->confname);
+ wpa_s->confname = os_strdup(iface->confname);
#endif /* CONFIG_BACKEND_FILE */
wpa_s->conf = wpa_config_read(wpa_s->confname);
if (wpa_s->conf == NULL) {
- printf("Failed to read read or parse configuration "
- "'%s'.\n", wpa_s->confname);
+ wpa_printf(MSG_ERROR, "Failed to read or parse "
+ "configuration '%s'.", wpa_s->confname);
return -1;
}
@@ -1752,34 +2105,46 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
* line.
*/
if (iface->ctrl_interface) {
- free(wpa_s->conf->ctrl_interface);
+ os_free(wpa_s->conf->ctrl_interface);
wpa_s->conf->ctrl_interface =
- strdup(iface->ctrl_interface);
+ os_strdup(iface->ctrl_interface);
}
if (iface->driver_param) {
- free(wpa_s->conf->driver_param);
+ os_free(wpa_s->conf->driver_param);
wpa_s->conf->driver_param =
- strdup(iface->driver_param);
+ os_strdup(iface->driver_param);
}
} else
wpa_s->conf = wpa_config_alloc_empty(iface->ctrl_interface,
iface->driver_param);
if (wpa_s->conf == NULL) {
- printf("\nNo configuration found.\n");
+ wpa_printf(MSG_ERROR, "\nNo configuration found.");
return -1;
}
if (iface->ifname == NULL) {
- printf("\nInterface name is required.\n");
+ wpa_printf(MSG_ERROR, "\nInterface name is required.");
return -1;
}
- if (strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
- printf("Too long interface name '%s'.\n", iface->ifname);
+ if (os_strlen(iface->ifname) >= sizeof(wpa_s->ifname)) {
+ wpa_printf(MSG_ERROR, "\nToo long interface name '%s'.",
+ iface->ifname);
return -1;
}
- strncpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
+ os_strncpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
+
+ if (iface->bridge_ifname) {
+ if (os_strlen(iface->bridge_ifname) >=
+ sizeof(wpa_s->bridge_ifname)) {
+ wpa_printf(MSG_ERROR, "\nToo long bridge interface "
+ "name '%s'.", iface->bridge_ifname);
+ return -1;
+ }
+ os_strncpy(wpa_s->bridge_ifname, iface->bridge_ifname,
+ sizeof(wpa_s->bridge_ifname));
+ }
return 0;
}
@@ -1789,13 +2154,12 @@ static int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
{
#ifdef IEEE8021X_EAPOL
struct eapol_ctx *ctx;
- ctx = malloc(sizeof(*ctx));
+ ctx = os_zalloc(sizeof(*ctx));
if (ctx == NULL) {
- printf("Failed to allocate EAPOL context.\n");
+ wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
return -1;
}
- memset(ctx, 0, sizeof(*ctx));
ctx->ctx = wpa_s;
ctx->msg_ctx = wpa_s;
ctx->eapol_send_ctx = wpa_s;
@@ -1805,13 +2169,15 @@ static int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
ctx->set_wep_key = wpa_eapol_set_wep_key;
ctx->set_config_blob = wpa_supplicant_set_config_blob;
ctx->get_config_blob = wpa_supplicant_get_config_blob;
+ ctx->aborted_cached = wpa_supplicant_aborted_cached;
ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
wpa_s->eapol = eapol_sm_init(ctx);
if (wpa_s->eapol == NULL) {
- free(ctx);
- printf("Failed to initialize EAPOL state machines.\n");
+ os_free(ctx);
+ wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
+ "machines.");
return -1;
}
#endif /* IEEE8021X_EAPOL */
@@ -1824,13 +2190,12 @@ static int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
{
#ifndef CONFIG_NO_WPA
struct wpa_sm_ctx *ctx;
- ctx = malloc(sizeof(*ctx));
+ ctx = os_zalloc(sizeof(*ctx));
if (ctx == NULL) {
- printf("Failed to allocate WPA context.\n");
+ wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
return -1;
}
- memset(ctx, 0, sizeof(*ctx));
ctx->ctx = wpa_s;
ctx->set_state = _wpa_supplicant_set_state;
ctx->get_state = _wpa_supplicant_get_state;
@@ -1849,10 +2214,12 @@ static int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
ctx->set_config_blob = wpa_supplicant_set_config_blob;
ctx->get_config_blob = wpa_supplicant_get_config_blob;
+ ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
wpa_s->wpa = wpa_sm_init(ctx);
if (wpa_s->wpa == NULL) {
- fprintf(stderr, "Failed to initialize WPA state machine\n");
+ wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
+ "machine");
return -1;
}
#endif /* CONFIG_NO_WPA */
@@ -1865,6 +2232,7 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s,
int wait_for_interface)
{
const char *ifname;
+ struct wpa_driver_capa capa;
wpa_printf(MSG_DEBUG, "Initializing interface (2) '%s'",
wpa_s->ifname);
@@ -1882,50 +2250,52 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s,
* call. */
wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
if (wpa_s->drv_priv == NULL) {
- fprintf(stderr, "Failed to initialize driver interface\n");
+ wpa_printf(MSG_ERROR, "Failed to initialize driver interface");
return -1;
}
if (wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param) < 0) {
- fprintf(stderr, "Driver interface rejected driver_param "
- "'%s'\n", wpa_s->conf->driver_param);
+ wpa_printf(MSG_ERROR, "Driver interface rejected "
+ "driver_param '%s'", wpa_s->conf->driver_param);
return -1;
}
ifname = wpa_drv_get_ifname(wpa_s);
- if (ifname && strcmp(ifname, wpa_s->ifname) != 0) {
+ if (ifname && os_strcmp(ifname, wpa_s->ifname) != 0) {
wpa_printf(MSG_DEBUG, "Driver interface replaced interface "
"name with '%s'", ifname);
- strncpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
+ os_strncpy(wpa_s->ifname, ifname, sizeof(wpa_s->ifname));
}
if (wpa_supplicant_init_wpa(wpa_s) < 0)
return -1;
- wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname);
+ wpa_sm_set_ifname(wpa_s->wpa, wpa_s->ifname,
+ wpa_s->bridge_ifname[0] ? wpa_s->bridge_ifname :
+ NULL);
wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
if (wpa_s->conf->dot11RSNAConfigPMKLifetime &&
wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_LIFETIME,
wpa_s->conf->dot11RSNAConfigPMKLifetime)) {
- fprintf(stderr, "Invalid WPA parameter value for "
- "dot11RSNAConfigPMKLifetime\n");
+ wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
+ "dot11RSNAConfigPMKLifetime");
return -1;
}
if (wpa_s->conf->dot11RSNAConfigPMKReauthThreshold &&
wpa_sm_set_param(wpa_s->wpa, RSNA_PMK_REAUTH_THRESHOLD,
wpa_s->conf->dot11RSNAConfigPMKReauthThreshold)) {
- fprintf(stderr, "Invalid WPA parameter value for "
- "dot11RSNAConfigPMKReauthThreshold\n");
+ wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
+ "dot11RSNAConfigPMKReauthThreshold");
return -1;
}
if (wpa_s->conf->dot11RSNAConfigSATimeout &&
wpa_sm_set_param(wpa_s->wpa, RSNA_SA_TIMEOUT,
wpa_s->conf->dot11RSNAConfigSATimeout)) {
- fprintf(stderr, "Invalid WPA parameter value for "
- "dot11RSNAConfigSATimeout\n");
+ wpa_printf(MSG_ERROR, "Invalid WPA parameter value for "
+ "dot11RSNAConfigSATimeout");
return -1;
}
@@ -1934,18 +2304,27 @@ static int wpa_supplicant_init_iface2(struct wpa_supplicant *wpa_s,
}
wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
- if (wpa_supplicant_ctrl_iface_init(wpa_s)) {
- printf("Failed to initialize control interface '%s'.\n"
- "You may have another wpa_supplicant process already "
- "running or the file was\n"
- "left by an unclean termination of wpa_supplicant in "
- "which case you will need\n"
- "to manually remove this file before starting "
- "wpa_supplicant again.\n",
- wpa_s->conf->ctrl_interface);
+ wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
+ if (wpa_s->ctrl_iface == NULL) {
+ wpa_printf(MSG_ERROR,
+ "Failed to initialize control interface '%s'.\n"
+ "You may have another wpa_supplicant process "
+ "already running or the file was\n"
+ "left by an unclean termination of wpa_supplicant "
+ "in which case you will need\n"
+ "to manually remove this file before starting "
+ "wpa_supplicant again.\n",
+ wpa_s->conf->ctrl_interface);
return -1;
}
+ if (wpa_drv_get_capa(wpa_s, &capa) == 0 &&
+ capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
+ wpa_s->use_client_mlme = 1;
+ if (ieee80211_sta_init(wpa_s))
+ return -1;
+ }
+
return 0;
}
@@ -1959,17 +2338,21 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s)
* called only just after init and just before deinit, so these
* handler can be used to implement same functionality. */
if (wpa_drv_set_wpa(wpa_s, 0) < 0) {
- fprintf(stderr, "Failed to disable WPA in the "
- "driver.\n");
+ wpa_printf(MSG_ERROR, "Failed to disable WPA in the "
+ "driver.");
}
wpa_drv_set_drop_unencrypted(wpa_s, 0);
wpa_drv_set_countermeasures(wpa_s, 0);
wpa_clear_keys(wpa_s, NULL);
-
- wpa_drv_deinit(wpa_s);
}
+
+ wpas_dbus_unregister_iface(wpa_s);
+
wpa_supplicant_cleanup(wpa_s);
+
+ if (wpa_s->drv_priv)
+ wpa_drv_deinit(wpa_s);
}
@@ -2003,11 +2386,19 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
wpa_printf(MSG_DEBUG, "Failed to add interface %s",
iface->ifname);
wpa_supplicant_deinit_iface(wpa_s);
- free(wpa_s);
+ os_free(wpa_s);
return NULL;
}
wpa_s->global = global;
+
+ /* Register the interface with the dbus control interface */
+ if (wpas_dbus_register_iface(wpa_s)) {
+ wpa_supplicant_deinit_iface(wpa_s);
+ os_free(wpa_s);
+ return NULL;
+ }
+
wpa_s->next = global->ifaces;
global->ifaces = wpa_s;
@@ -2048,7 +2439,7 @@ int wpa_supplicant_remove_iface(struct wpa_global *global,
wpa_printf(MSG_DEBUG, "Removing interface %s", wpa_s->ifname);
wpa_supplicant_deinit_iface(wpa_s);
- free(wpa_s);
+ os_free(wpa_s);
return 0;
}
@@ -2066,7 +2457,7 @@ struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
struct wpa_supplicant *wpa_s;
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
- if (strcmp(wpa_s->ifname, ifname) == 0)
+ if (os_strcmp(wpa_s->ifname, ifname) == 0)
return wpa_s;
}
return NULL;
@@ -2085,37 +2476,68 @@ struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
{
struct wpa_global *global;
+ int ret;
if (params == NULL)
return NULL;
- global = malloc(sizeof(*global));
+
+ wpa_debug_use_file = params->wpa_debug_use_file;
+ wpa_debug_open_file();
+
+ ret = eap_peer_register_methods();
+ if (ret) {
+ wpa_printf(MSG_ERROR, "Failed to register EAP methods");
+ if (ret == -2)
+ wpa_printf(MSG_ERROR, "Two or more EAP methods used "
+ "the same EAP type.");
+ return NULL;
+ }
+
+ global = os_zalloc(sizeof(*global));
if (global == NULL)
return NULL;
- memset(global, 0, sizeof(*global));
global->params.daemonize = params->daemonize;
global->params.wait_for_interface = params->wait_for_interface;
global->params.wait_for_monitor = params->wait_for_monitor;
+ global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
if (params->pid_file)
- global->params.pid_file = strdup(params->pid_file);
+ global->params.pid_file = os_strdup(params->pid_file);
if (params->ctrl_interface)
- global->params.ctrl_interface = strdup(params->ctrl_interface);
+ global->params.ctrl_interface =
+ os_strdup(params->ctrl_interface);
wpa_debug_level = global->params.wpa_debug_level =
params->wpa_debug_level;
wpa_debug_show_keys = global->params.wpa_debug_show_keys =
params->wpa_debug_show_keys;
wpa_debug_timestamp = global->params.wpa_debug_timestamp =
params->wpa_debug_timestamp;
+ wpa_debug_use_file = global->params.wpa_debug_use_file =
+ params->wpa_debug_use_file;
- eloop_init(global);
+ if (eloop_init(global)) {
+ wpa_printf(MSG_ERROR, "Failed to initialize event loop");
+ wpa_supplicant_deinit(global);
+ return NULL;
+ }
- if (wpa_supplicant_global_ctrl_iface_init(global)) {
- eloop_destroy();
+ global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
+ if (global->ctrl_iface == NULL) {
+ wpa_supplicant_deinit(global);
return NULL;
}
+ if (global->params.dbus_ctrl_interface) {
+ global->dbus_ctrl_iface =
+ wpa_supplicant_dbus_ctrl_iface_init(global);
+ if (global->dbus_ctrl_iface == NULL) {
+ wpa_supplicant_deinit(global);
+ return NULL;
+ }
+ }
+
if (global->params.wait_for_interface && global->params.daemonize &&
wpa_supplicant_daemon(global->params.pid_file)) {
- eloop_destroy();
+ wpa_supplicant_deinit(global);
return NULL;
}
@@ -2142,14 +2564,13 @@ int wpa_supplicant_run(struct wpa_global *global)
if (global->params.wait_for_monitor) {
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
- wpa_supplicant_ctrl_iface_wait(wpa_s);
+ if (wpa_s->ctrl_iface)
+ wpa_supplicant_ctrl_iface_wait(
+ wpa_s->ctrl_iface);
}
- eloop_register_signal(SIGINT, wpa_supplicant_terminate, NULL);
- eloop_register_signal(SIGTERM, wpa_supplicant_terminate, NULL);
-#ifndef CONFIG_NATIVE_WINDOWS
- eloop_register_signal(SIGHUP, wpa_supplicant_reconfig, NULL);
-#endif /* CONFIG_NATIVE_WINDOWS */
+ eloop_register_signal_terminate(wpa_supplicant_terminate, NULL);
+ eloop_register_signal_reconfig(wpa_supplicant_reconfig, NULL);
eloop_run();
@@ -2172,15 +2593,21 @@ void wpa_supplicant_deinit(struct wpa_global *global)
while (global->ifaces)
wpa_supplicant_remove_iface(global, global->ifaces);
- wpa_supplicant_global_ctrl_iface_deinit(global);
+ if (global->ctrl_iface)
+ wpa_supplicant_global_ctrl_iface_deinit(global->ctrl_iface);
+ if (global->dbus_ctrl_iface)
+ wpa_supplicant_dbus_ctrl_iface_deinit(global->dbus_ctrl_iface);
+
+ eap_peer_unregister_methods();
eloop_destroy();
if (global->params.pid_file) {
- unlink(global->params.pid_file);
- free(global->params.pid_file);
+ os_daemonize_terminate(global->params.pid_file);
+ os_free(global->params.pid_file);
}
- free(global->params.ctrl_interface);
+ os_free(global->params.ctrl_interface);
- free(global);
+ os_free(global);
+ wpa_debug_close_file();
}
OpenPOWER on IntegriCloud