From 41f893d820695e606ff3370f1dfca47022ab7c64 Mon Sep 17 00:00:00 2001 From: Andrew Shadura Date: Thu, 20 Oct 2016 18:32:36 +0200 Subject: Apply patches for dgit. --- wpa_supplicant/Makefile | 2 +- wpa_supplicant/dbus/dbus-wpa_supplicant.conf | 8 ++++++++ .../dbus/fi.epitest.hostap.WPASupplicant.service.in | 2 +- wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in | 2 +- wpa_supplicant/systemd/wpa_supplicant.service.arg.in | 2 +- wpa_supplicant/systemd/wpa_supplicant.service.in | 3 ++- wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop | 2 +- wpa_supplicant/wpa_gui-qt4/wpagui.cpp | 18 ++++++++++++++++-- 8 files changed, 31 insertions(+), 8 deletions(-) diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index f3e86c1..fa3673a 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -934,7 +934,7 @@ else ifdef CONFIG_OSX LIBS += -framework PCSC else -LIBS += -lpcsclite -lpthread +LIBS += $(shell $(PKG_CONFIG) --libs libpcsclite) endif endif endif diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf index 382dcb3..e375cdc 100644 --- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf +++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf @@ -14,6 +14,14 @@ + + + + + + + + diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in index a75918f..714ef9e 100644 --- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in +++ b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=fi.epitest.hostap.WPASupplicant -Exec=@BINDIR@/wpa_supplicant -u +Exec=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant User=root SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in index d97ff39..3b0af67 100644 --- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in +++ b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=fi.w1.wpa_supplicant1 -Exec=@BINDIR@/wpa_supplicant -u +Exec=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant User=root SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in index 7788b38..cff0b6d 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in @@ -9,7 +9,7 @@ Wants=network.target [Service] Type=simple -ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I +ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I [Install] Alias=multi-user.target.wants/wpa_supplicant@%i.service diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in index bc5d49a..0314038 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.in @@ -1,12 +1,13 @@ [Unit] Description=WPA supplicant Before=network.target +After=dbus.service Wants=network.target [Service] Type=dbus BusName=@DBUS_INTERFACE@ -ExecStart=@BINDIR@/wpa_supplicant -u +ExecStart=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant [Install] WantedBy=multi-user.target diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop index ccc7d87..e560f3d 100644 --- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop +++ b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop @@ -2,7 +2,7 @@ Version=1.0 Name=wpa_gui Comment=Graphical user interface for wpa_supplicant -Exec=wpa_gui +Exec=/usr/sbin/wpa_gui Icon=wpa_gui GenericName=wpa_supplicant user interface Terminal=false diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp index a0aa05e..396b121 100644 --- a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp +++ b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp @@ -11,11 +11,14 @@ #endif /* CONFIG_NATIVE_WINDOWS */ #include +#include #include #include #include #include +#include #include +#include #include "wpagui.h" #include "dirent.h" @@ -1415,10 +1418,21 @@ void WpaGui::createTrayIcon(bool trayOnly) void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec, const QString & msg) { - if (!QSystemTrayIcon::supportsMessages()) + if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode) return; - if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode) + /* first try to use KDE's notifications system if running under + * a KDE session */ + if (getenv("KDE_FULL_SESSION") != NULL) { + QStringList args; + args << "--passivepopup" << msg << QString::number(sec); + args << "--title" << "wpa_gui"; + + if (QProcess::execute("/usr/bin/kdialog", args) == 0) + return; + } + + if (!QSystemTrayIcon::supportsMessages()) return; tray_icon->showMessage(qAppName(), msg, type, sec * 1000); -- cgit v1.2.3 From cc0a5d022d499fa74704498477add3c94922d904 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: Use pkg-config for libpcsclite linkage flags At least in debian, we can rely on pkg-config being available and returning more accurate ldflags. Gbp-Pq: Name 01_use_pkg-config_for_pcsc-lite_module.patch --- wpa_supplicant/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index f3e86c1..fa3673a 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -934,7 +934,7 @@ else ifdef CONFIG_OSX LIBS += -framework PCSC else -LIBS += -lpcsclite -lpthread +LIBS += $(shell $(PKG_CONFIG) --libs libpcsclite) endif endif endif -- cgit v1.2.3 From 66fdcca340d577a76699674604039de3d77608ca Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: Add D-Bus group policy Debian does not use pam_console but uses group membership to control access to D-Bus. Activating both options in the conf file makes it work on Debian and Ubuntu. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=15;bug=412179 Gbp-Pq: Name 02_dbus_group_policy.patch --- wpa_supplicant/dbus/dbus-wpa_supplicant.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf index 382dcb3..e375cdc 100644 --- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf +++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf @@ -14,6 +14,14 @@ + + + + + + + + -- cgit v1.2.3 From 85acf75e1ff7a7799172525f9c381354044a530b Mon Sep 17 00:00:00 2001 From: Kel Modderman Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: Use full executable path into wpa_gui.desktop Debian specific patch to desktop meny entry, so that we may exec wpa_gui which being in /usr/sbin may not be in the PATH Gbp-Pq: Name 06_wpa_gui_menu_exec_path.patch --- wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop index ccc7d87..e560f3d 100644 --- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop +++ b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop @@ -2,7 +2,7 @@ Version=1.0 Name=wpa_gui Comment=Graphical user interface for wpa_supplicant -Exec=wpa_gui +Exec=/usr/sbin/wpa_gui Icon=wpa_gui GenericName=wpa_supplicant user interface Terminal=false -- cgit v1.2.3 From ba264e45b5419cab18328fcb6464c28b61e31da6 Mon Sep 17 00:00:00 2001 From: Kel Modderman Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: Tweak D-Bus/systemd service activation configuration files: * log wpa_supplicant messages to syslog * activate control socket interface so that wpa_cli can be used by D-Bus activated wpa_supplicant daemon Gbp-Pq: Name 07_dbus_service_syslog.patch --- wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in | 2 +- wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in | 2 +- wpa_supplicant/systemd/wpa_supplicant.service.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in index a75918f..714ef9e 100644 --- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in +++ b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=fi.epitest.hostap.WPASupplicant -Exec=@BINDIR@/wpa_supplicant -u +Exec=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant User=root SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in index d97ff39..3b0af67 100644 --- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in +++ b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=fi.w1.wpa_supplicant1 -Exec=@BINDIR@/wpa_supplicant -u +Exec=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant User=root SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in index bc5d49a..29c949b 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.in @@ -6,7 +6,7 @@ Wants=network.target [Service] Type=dbus BusName=@DBUS_INTERFACE@ -ExecStart=@BINDIR@/wpa_supplicant -u +ExecStart=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant [Install] WantedBy=multi-user.target -- cgit v1.2.3 From 829e7c162d5b982ad13cace02433250967a0be49 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: Use KDE's KNotify when running under KDE Bug-Debian: http://bugs.debian.org/582793 Gbp-Pq: Name 12_wpa_gui_knotify_support.patch --- wpa_supplicant/wpa_gui-qt4/wpagui.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp index a0aa05e..396b121 100644 --- a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp +++ b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp @@ -11,11 +11,14 @@ #endif /* CONFIG_NATIVE_WINDOWS */ #include +#include #include #include #include #include +#include #include +#include #include "wpagui.h" #include "dirent.h" @@ -1415,10 +1418,21 @@ void WpaGui::createTrayIcon(bool trayOnly) void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec, const QString & msg) { - if (!QSystemTrayIcon::supportsMessages()) + if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode) return; - if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode) + /* first try to use KDE's notifications system if running under + * a KDE session */ + if (getenv("KDE_FULL_SESSION") != NULL) { + QStringList args; + args << "--passivepopup" << msg << QString::number(sec); + args << "--title" << "wpa_gui"; + + if (QProcess::execute("/usr/bin/kdialog", args) == 0) + return; + } + + if (!QSystemTrayIcon::supportsMessages()) return; tray_icon->showMessage(qAppName(), msg, type, sec * 1000); -- cgit v1.2.3 From e65988084b863f31f849eafca46359c8ccbba381 Mon Sep 17 00:00:00 2001 From: Stefan Lippers-Hollmann Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: wpasupplicant: configure driver fallback for networkd Signed-off-by: Stefan Lippers-Hollmann Gbp-Pq: Name networkd-driver-fallback.patch --- wpa_supplicant/systemd/wpa_supplicant.service.arg.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in index 7788b38..cff0b6d 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in @@ -9,7 +9,7 @@ Wants=network.target [Service] Type=simple -ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I +ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I [Install] Alias=multi-user.target.wants/wpa_supplicant@%i.service -- cgit v1.2.3 From 9ee65fafe0b5735334c8cf477e00cb371d29183b Mon Sep 17 00:00:00 2001 From: Stefan Lippers-Hollmann Date: Fri, 24 Feb 2017 16:45:48 +0100 Subject: wpa_supplicant: Fix dependency odering when invoked with DBus Make sure that DBus isn't shut down before wpa_supplicant, as that would also bring down wireless links which are still holding open NFS shares. Debian bug: https://bugs.debian.org/785579 systemd upstream bug: https://bugs.freedesktop.org/show_bug.cgi?id=89847 Signed-off-by: Stefan Lippers-Hollmann Gbp-Pq: Name wpa_supplicant_fix-dependency-odering-when-invoked-with-dbus.patch --- wpa_supplicant/systemd/wpa_supplicant.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in index 29c949b..0314038 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.in @@ -1,6 +1,7 @@ [Unit] Description=WPA supplicant Before=network.target +After=dbus.service Wants=network.target [Service] -- cgit v1.2.3 From 56cf50e1179944732f6e4e46267975c5d6fc7243 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 11 Oct 2016 00:25:20 +0300 Subject: WPS: Force BSSID for WPS provisioning step connection This was already done for most driver cases, but it is possible that the BSSID/frequency is not forced if the driver reports BSS selection capability (e.g., NL80211_ATTR_ROAM_SUPPORT). That could potentially result in the driver ignoring the BSSID/frequency hint and associating with another (incorrect) AP for the WPS provisioning step if that another AP in the same ESS is more preferred (e.g., better signal strength) by the driver and only one of the APs (the not preferred one) is in active WPS registrar state. While most drivers follow the BSSID hint for the initial connection to an ESS, not doing it here for the WPS provisioning would break the protocol. Fix this by enforcing a single BSSID/frequency to disallow the driver from selecting an incorrect AP for the WPS provisioning association. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0001-WPS-Force-BSSID-for-WPS-provisioning-step-connection.patch --- wpa_supplicant/wpa_supplicant.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 7361ee9..e35c276 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2443,12 +2443,14 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) if (bss) { params.ssid = bss->ssid; params.ssid_len = bss->ssid_len; - if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) { + if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set || + wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) { wpa_printf(MSG_DEBUG, "Limit connection to BSSID " MACSTR " freq=%u MHz based on scan results " - "(bssid_set=%d)", + "(bssid_set=%d wps=%d)", MAC2STR(bss->bssid), bss->freq, - ssid->bssid_set); + ssid->bssid_set, + wpa_s->key_mgmt == WPA_KEY_MGMT_WPS); params.bssid = bss->bssid; params.freq.freq = bss->freq; } -- cgit v1.2.3 From a2228b05a64a9e8781e8a6b6ce5577478af70105 Mon Sep 17 00:00:00 2001 From: Joel Cunningham Date: Sat, 8 Oct 2016 12:04:15 -0500 Subject: Check for NULL qsort() base pointers There are a couple of places in wpa_supplicant/hostapd where qsort() can be called with a NULL base pointer. This results in undefined behavior according to the C standard and with some standard C libraries (ARM RVCT 2.2) results in a data abort/memory exception. Fix this by skipping such calls since there is nothing needing to be sorted. Signed-off-by: Joel Cunningham Gbp-Pq: Name 0002-Check-for-NULL-qsort-base-pointers.patch --- hostapd/config_file.c | 3 ++- wpa_supplicant/scan.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 5079f69..2ebf649 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -208,7 +208,8 @@ static int hostapd_config_read_maclist(const char *fname, fclose(f); - qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); + if (*acl) + qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); return 0; } diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index fb8ebdf..bfde0af 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -2177,8 +2177,10 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_WPS */ - qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), - compar); + if (scan_res->res) { + qsort(scan_res->res, scan_res->num, + sizeof(struct wpa_scan_res *), compar); + } dump_scan_res(scan_res); wpa_bss_update_start(wpa_s); -- cgit v1.2.3 From 7a31aaf9f232f46f5eedc2d8dc37fd7bd0187e0f Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Mon, 10 Oct 2016 18:22:09 +0300 Subject: Always propagate scan results to all interfaces Scan results were not propagated to all interfaces if scan results started a new operation, in order to prevent concurrent operations. But this can cause other interfaces to trigger a new scan when scan results are already available. Instead, always notify other interfaces of the scan results, but note that new operations are not allowed. Signed-off-by: Avraham Stern Signed-off-by: Andrei Otcheretianski Gbp-Pq: Name 0003-Always-propagate-scan-results-to-all-interfaces.patch --- wpa_supplicant/events.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index abe3b47..e15109c 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1474,11 +1474,18 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, } -/* Return != 0 if no scan results could be fetched or if scan results should not - * be shared with other virtual interfaces. */ +/* + * Return a negative value if no scan results could be fetched or if scan + * results should not be shared with other virtual interfaces. + * Return 0 if scan results were fetched and may be shared with other + * interfaces. + * Return 1 if scan results may be shared with other virtual interfaces but may + * not trigger any operations. + * Return 2 if the interface was removed and cannot be used. + */ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, union wpa_event_data *data, - int own_request) + int own_request, int update_only) { struct wpa_scan_results *scan_res = NULL; int ret = 0; @@ -1528,6 +1535,11 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_NO_RANDOM_POOL */ + if (update_only) { + ret = 1; + goto scan_work_done; + } + if (own_request && wpa_s->scan_res_handler && !(data && data->scan_info.external_scan)) { void (*scan_res_handler)(struct wpa_supplicant *wpa_s, @@ -1536,7 +1548,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, scan_res_handler = wpa_s->scan_res_handler; wpa_s->scan_res_handler = NULL; scan_res_handler(wpa_s, scan_res); - ret = -2; + ret = 1; goto scan_work_done; } @@ -1672,8 +1684,9 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, if (new_scan) wpa_supplicant_rsn_preauth_scan_results(wpa_s); /* - * Do not notify other virtual radios of scan results since we do not - * want them to start other associations at the same time. + * Do not allow other virtual radios to trigger operations based + * on these scan results since we do not want them to start + * other associations at the same time. */ return 1; } else { @@ -1757,7 +1770,7 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, struct wpa_supplicant *ifs; int res; - res = _wpa_supplicant_event_scan_results(wpa_s, data, 1); + res = _wpa_supplicant_event_scan_results(wpa_s, data, 1, 0); if (res == 2) { /* * Interface may have been removed, so must not dereference @@ -1765,7 +1778,8 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, */ return 1; } - if (res != 0) { + + if (res < 0) { /* * If no scan results could be fetched, then no need to * notify those interfaces that did not actually request @@ -1785,7 +1799,10 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, if (ifs != wpa_s) { wpa_printf(MSG_DEBUG, "%s: Updating scan results from " "sibling", ifs->ifname); - _wpa_supplicant_event_scan_results(ifs, data, 0); + res = _wpa_supplicant_event_scan_results(ifs, data, 0, + res > 0); + if (res < 0) + return 0; } } -- cgit v1.2.3 From 6d8eada693a242f43c363bfa39b076cad9d63189 Mon Sep 17 00:00:00 2001 From: Benjamin Richter Date: Tue, 11 Oct 2016 05:57:38 +0200 Subject: wpa_supplicant: Restore permanent MAC address on reassociation With mac_addr=0 and preassoc_mac_addr=1, the permanent MAC address should be restored for association. Previously this did not happen when reassociating to the same ESS. Signed-off-by: Benjamin Richter Gbp-Pq: Name 0004-wpa_supplicant-Restore-permanent-MAC-address-on-reas.patch --- wpa_supplicant/wpa_supplicant.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e35c276..8d83994 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1673,11 +1673,13 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wmm_ac_save_tspecs(wpa_s); wpa_s->reassoc_same_bss = 1; } - } else if (rand_style > 0) { + } + + if (rand_style > 0 && !wpa_s->reassoc_same_ess) { if (wpas_update_random_addr(wpa_s, rand_style) < 0) return; wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); - } else if (wpa_s->mac_addr_changed) { + } else if (rand_style == 0 && wpa_s->mac_addr_changed) { if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) { wpa_msg(wpa_s, MSG_INFO, "Could not restore permanent MAC address"); -- cgit v1.2.3 From e4c7cc5efc3f8f1c7ecdf489b389d756721413c9 Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Mon, 24 Oct 2016 16:54:36 -0700 Subject: nl80211: Update channel information after channel switch notification When channel switch happens, driver wrapper's internal channel information needs to be updated so that the new frequency will be used in operations using drv->assoc_freq. Previously, only bss->freq was updated and the new frequency was also indicated in the EVENT_CH_SWITCH event. This could potentially leave out couple of cases that use drv->assoc_freq at least as a fallback mechanism for getting the current operating frequency. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0005-nl80211-Update-channel-information-after-channel-swi.patch --- src/drivers/driver_nl80211_event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 762e3ac..0f54574 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -516,6 +516,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, data.ch_switch.cf2 = nla_get_u32(cf2); bss->freq = data.ch_switch.freq; + drv->assoc_freq = data.ch_switch.freq; wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data); } -- cgit v1.2.3 From f3dad383f3a48dad6c0c1fd2ace3d53873ba1d3f Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Thu, 27 Oct 2016 15:18:29 +0300 Subject: Extend ieee80211_freq_to_channel_ext() to cover channels 52-64 Add frequency to channel conversion for the 5 GHz channels 52-64. Signed-off-by: Avraham Stern Gbp-Pq: Name 0006-Extend-ieee80211_freq_to_channel_ext-to-cover-channe.patch --- src/common/ieee802_11_common.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index b6bc449..cc2f5cc 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -681,6 +681,25 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, return HOSTAPD_MODE_IEEE80211A; } + /* 5 GHz, channels 52..64 */ + if (freq >= 5260 && freq <= 5320) { + if ((freq - 5000) % 5) + return NUM_HOSTAPD_MODES; + + if (vht_opclass) + *op_class = vht_opclass; + else if (sec_channel == 1) + *op_class = 119; + else if (sec_channel == -1) + *op_class = 120; + else + *op_class = 118; + + *channel = (freq - 5000) / 5; + + return HOSTAPD_MODE_IEEE80211A; + } + /* 5 GHz, channels 149..169 */ if (freq >= 5745 && freq <= 5845) { if ((freq - 5000) % 5) -- cgit v1.2.3 From 2240973d6cf590f142370ff069e70a9a78c7acf2 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 13 Nov 2016 17:46:00 +0200 Subject: Use estimated throughput to avoid signal based roaming decision Previously, the estimated throughput was used to enable roaming to a better AP. However, this information was not used when considering a roam to an AP that has better signal strength, but smaller estimated throughput. This could result in allowing roaming from 5 GHz band to 2.4 GHz band in cases where 2.4 GHz band has significantly higher signal strength, but still a lower throughput estimate. Make this less likely to happen by increasing/reducing the minimum required signal strength difference based on the estimated throughputs of the current and selected AP. In addition, add more details about the selection process to the debug log to make it easier to determine whaty happened and why. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0007-Use-estimated-throughput-to-avoid-signal-based-roami.patch --- wpa_supplicant/events.c | 52 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index e15109c..7ca3d8e 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1375,8 +1375,9 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, { struct wpa_bss *current_bss = NULL; #ifndef CONFIG_NO_ROAMING - int min_diff; + int min_diff, diff; int to_5ghz; + int cur_est, sel_est; #endif /* CONFIG_NO_ROAMING */ if (wpa_s->reassociate) @@ -1410,12 +1411,13 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, #ifndef CONFIG_NO_ROAMING wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation"); wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR - " level=%d snr=%d est_throughput=%u", - MAC2STR(current_bss->bssid), current_bss->level, + " freq=%d level=%d snr=%d est_throughput=%u", + MAC2STR(current_bss->bssid), + current_bss->freq, current_bss->level, current_bss->snr, current_bss->est_throughput); wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR - " level=%d snr=%d est_throughput=%u", - MAC2STR(selected->bssid), selected->level, + " freq=%d level=%d snr=%d est_throughput=%u", + MAC2STR(selected->bssid), selected->freq, selected->level, selected->snr, selected->est_throughput); if (wpa_s->current_ssid->bssid_set && @@ -1441,6 +1443,14 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, return 0; } + if (current_bss->est_throughput > selected->est_throughput + 5000) { + wpa_dbg(wpa_s, MSG_DEBUG, + "Skip roam - Current BSS has better estimated throughput"); + return 1; + } + + cur_est = current_bss->est_throughput; + sel_est = selected->est_throughput; min_diff = 2; if (current_bss->level < 0) { if (current_bss->level < -85) @@ -1453,20 +1463,42 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, min_diff = 4; else min_diff = 5; + if (cur_est > sel_est * 1.5) + min_diff += 10; + else if (cur_est > sel_est * 1.2) + min_diff += 5; + else if (cur_est > sel_est * 1.1) + min_diff += 2; + else if (cur_est > sel_est) + min_diff++; } if (to_5ghz) { + int reduce = 2; + /* Make it easier to move to 5 GHz band */ - if (min_diff > 2) - min_diff -= 2; + if (sel_est > cur_est * 1.5) + reduce = 5; + else if (sel_est > cur_est * 1.2) + reduce = 4; + else if (sel_est > cur_est * 1.1) + reduce = 3; + + if (min_diff > reduce) + min_diff -= reduce; else min_diff = 0; } - if (abs(current_bss->level - selected->level) < min_diff) { - wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference " - "in signal level"); + diff = abs(current_bss->level - selected->level); + if (diff < min_diff) { + wpa_dbg(wpa_s, MSG_DEBUG, + "Skip roam - too small difference in signal level (%d < %d)", + diff, min_diff); return 0; } + wpa_dbg(wpa_s, MSG_DEBUG, + "Allow reassociation due to difference in signal level (%d >= %d)", + diff, min_diff); return 1; #else /* CONFIG_NO_ROAMING */ return 0; -- cgit v1.2.3 From 5872ef650d3802df8a9aa91fa8eb0b8fb0798244 Mon Sep 17 00:00:00 2001 From: Srinivas Dasari Date: Mon, 21 Nov 2016 17:40:36 +0530 Subject: Use random MAC address for scanning only in non-connected state cfg80211 rejects the scans issued with random MAC address if the STA is in connected state. This resulted in failures when using MAC_RAND_SCAN while connected (CTRL-EVENT-SCAN-FAILED ret=-95). Enable random MAC address functionality only if the STA is not in connected state to avoid this. The real MAC address of the STA is already revealed in the association, so this is an acceptable fallback mechanism for now. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0008-Use-random-MAC-address-for-scanning-only-in-non-conn.patch --- wpa_supplicant/scan.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index bfde0af..d1148a4 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -1047,7 +1047,8 @@ ssid_list_set: } #endif /* CONFIG_P2P */ - if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) { + if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) && + wpa_s->wpa_state <= WPA_SCANNING) { params.mac_addr_rand = 1; if (wpa_s->mac_addr_scan) { params.mac_addr = wpa_s->mac_addr_scan; @@ -1469,7 +1470,8 @@ scan: wpa_setband_scan_freqs(wpa_s, scan_params); - if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) { + if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) && + wpa_s->wpa_state <= WPA_SCANNING) { params.mac_addr_rand = 1; if (wpa_s->mac_addr_sched_scan) { params.mac_addr = wpa_s->mac_addr_sched_scan; @@ -2518,7 +2520,8 @@ int wpas_start_pno(struct wpa_supplicant *wpa_s) params.freqs = wpa_s->manual_sched_scan_freqs; } - if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) { + if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) && + wpa_s->wpa_state <= WPA_SCANNING) { params.mac_addr_rand = 1; if (wpa_s->mac_addr_pno) { params.mac_addr = wpa_s->mac_addr_pno; -- cgit v1.2.3 From ed70cd9065494ce7c67eb5303e5fafc7025cc01a Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: Use pkg-config for libpcsclite linkage flags At least in debian, we can rely on pkg-config being available and returning more accurate ldflags. Gbp-Pq: Name 01_use_pkg-config_for_pcsc-lite_module.patch --- wpa_supplicant/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index f3e86c1..fa3673a 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -934,7 +934,7 @@ else ifdef CONFIG_OSX LIBS += -framework PCSC else -LIBS += -lpcsclite -lpthread +LIBS += $(shell $(PKG_CONFIG) --libs libpcsclite) endif endif endif -- cgit v1.2.3 From f8c87086d4bdc48931daf384c286599eb054aca6 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: Add D-Bus group policy Debian does not use pam_console but uses group membership to control access to D-Bus. Activating both options in the conf file makes it work on Debian and Ubuntu. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=15;bug=412179 Gbp-Pq: Name 02_dbus_group_policy.patch --- wpa_supplicant/dbus/dbus-wpa_supplicant.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf index 382dcb3..e375cdc 100644 --- a/wpa_supplicant/dbus/dbus-wpa_supplicant.conf +++ b/wpa_supplicant/dbus/dbus-wpa_supplicant.conf @@ -14,6 +14,14 @@ + + + + + + + + -- cgit v1.2.3 From 4a9d0965d737442429c2b033ab155a279e453bfe Mon Sep 17 00:00:00 2001 From: Kel Modderman Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: Use full executable path into wpa_gui.desktop Debian specific patch to desktop meny entry, so that we may exec wpa_gui which being in /usr/sbin may not be in the PATH Gbp-Pq: Name 06_wpa_gui_menu_exec_path.patch --- wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop index ccc7d87..e560f3d 100644 --- a/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop +++ b/wpa_supplicant/wpa_gui-qt4/wpa_gui.desktop @@ -2,7 +2,7 @@ Version=1.0 Name=wpa_gui Comment=Graphical user interface for wpa_supplicant -Exec=wpa_gui +Exec=/usr/sbin/wpa_gui Icon=wpa_gui GenericName=wpa_supplicant user interface Terminal=false -- cgit v1.2.3 From eccfa9253fdcf37dd3d443e88a356c7377cc1e92 Mon Sep 17 00:00:00 2001 From: Kel Modderman Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: Tweak D-Bus/systemd service activation configuration files: * log wpa_supplicant messages to syslog * activate control socket interface so that wpa_cli can be used by D-Bus activated wpa_supplicant daemon Gbp-Pq: Name 07_dbus_service_syslog.patch --- wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in | 2 +- wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in | 2 +- wpa_supplicant/systemd/wpa_supplicant.service.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in index a75918f..714ef9e 100644 --- a/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in +++ b/wpa_supplicant/dbus/fi.epitest.hostap.WPASupplicant.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=fi.epitest.hostap.WPASupplicant -Exec=@BINDIR@/wpa_supplicant -u +Exec=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant User=root SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in index d97ff39..3b0af67 100644 --- a/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in +++ b/wpa_supplicant/dbus/fi.w1.wpa_supplicant1.service.in @@ -1,5 +1,5 @@ [D-BUS Service] Name=fi.w1.wpa_supplicant1 -Exec=@BINDIR@/wpa_supplicant -u +Exec=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant User=root SystemdService=wpa_supplicant.service diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in index bc5d49a..29c949b 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.in @@ -6,7 +6,7 @@ Wants=network.target [Service] Type=dbus BusName=@DBUS_INTERFACE@ -ExecStart=@BINDIR@/wpa_supplicant -u +ExecStart=@BINDIR@/wpa_supplicant -u -s -O /run/wpa_supplicant [Install] WantedBy=multi-user.target -- cgit v1.2.3 From acb87d7a7eae4f498e5bb1c4cf12dcf9057b56c4 Mon Sep 17 00:00:00 2001 From: Raphael Geissert Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: Use KDE's KNotify when running under KDE Bug-Debian: http://bugs.debian.org/582793 Gbp-Pq: Name 12_wpa_gui_knotify_support.patch --- wpa_supplicant/wpa_gui-qt4/wpagui.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp index a0aa05e..396b121 100644 --- a/wpa_supplicant/wpa_gui-qt4/wpagui.cpp +++ b/wpa_supplicant/wpa_gui-qt4/wpagui.cpp @@ -11,11 +11,14 @@ #endif /* CONFIG_NATIVE_WINDOWS */ #include +#include #include #include #include #include +#include #include +#include #include "wpagui.h" #include "dirent.h" @@ -1415,10 +1418,21 @@ void WpaGui::createTrayIcon(bool trayOnly) void WpaGui::showTrayMessage(QSystemTrayIcon::MessageIcon type, int sec, const QString & msg) { - if (!QSystemTrayIcon::supportsMessages()) + if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode) return; - if (isVisible() || !tray_icon || !tray_icon->isVisible() || quietMode) + /* first try to use KDE's notifications system if running under + * a KDE session */ + if (getenv("KDE_FULL_SESSION") != NULL) { + QStringList args; + args << "--passivepopup" << msg << QString::number(sec); + args << "--title" << "wpa_gui"; + + if (QProcess::execute("/usr/bin/kdialog", args) == 0) + return; + } + + if (!QSystemTrayIcon::supportsMessages()) return; tray_icon->showMessage(qAppName(), msg, type, sec * 1000); -- cgit v1.2.3 From 36b5e0c237c4db2aa9c0bd3539a280d4ee272405 Mon Sep 17 00:00:00 2001 From: Stefan Lippers-Hollmann Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: wpasupplicant: configure driver fallback for networkd Signed-off-by: Stefan Lippers-Hollmann Gbp-Pq: Name networkd-driver-fallback.patch --- wpa_supplicant/systemd/wpa_supplicant.service.arg.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in index 7788b38..cff0b6d 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.arg.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.arg.in @@ -9,7 +9,7 @@ Wants=network.target [Service] Type=simple -ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -i%I +ExecStart=@BINDIR@/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I [Install] Alias=multi-user.target.wants/wpa_supplicant@%i.service -- cgit v1.2.3 From e95dde3d8b4545ad203feb7004a83d6062261824 Mon Sep 17 00:00:00 2001 From: Stefan Lippers-Hollmann Date: Fri, 20 Oct 2017 15:34:09 +0100 Subject: wpa_supplicant: Fix dependency odering when invoked with DBus Make sure that DBus isn't shut down before wpa_supplicant, as that would also bring down wireless links which are still holding open NFS shares. Debian bug: https://bugs.debian.org/785579 systemd upstream bug: https://bugs.freedesktop.org/show_bug.cgi?id=89847 Signed-off-by: Stefan Lippers-Hollmann Gbp-Pq: Name wpa_supplicant_fix-dependency-odering-when-invoked-with-dbus.patch --- wpa_supplicant/systemd/wpa_supplicant.service.in | 1 + 1 file changed, 1 insertion(+) diff --git a/wpa_supplicant/systemd/wpa_supplicant.service.in b/wpa_supplicant/systemd/wpa_supplicant.service.in index 29c949b..0314038 100644 --- a/wpa_supplicant/systemd/wpa_supplicant.service.in +++ b/wpa_supplicant/systemd/wpa_supplicant.service.in @@ -1,6 +1,7 @@ [Unit] Description=WPA supplicant Before=network.target +After=dbus.service Wants=network.target [Service] -- cgit v1.2.3 From b3185a09f2079d51ded94353450c14716c133e27 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 11 Oct 2016 00:25:20 +0300 Subject: WPS: Force BSSID for WPS provisioning step connection This was already done for most driver cases, but it is possible that the BSSID/frequency is not forced if the driver reports BSS selection capability (e.g., NL80211_ATTR_ROAM_SUPPORT). That could potentially result in the driver ignoring the BSSID/frequency hint and associating with another (incorrect) AP for the WPS provisioning step if that another AP in the same ESS is more preferred (e.g., better signal strength) by the driver and only one of the APs (the not preferred one) is in active WPS registrar state. While most drivers follow the BSSID hint for the initial connection to an ESS, not doing it here for the WPS provisioning would break the protocol. Fix this by enforcing a single BSSID/frequency to disallow the driver from selecting an incorrect AP for the WPS provisioning association. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0001-WPS-Force-BSSID-for-WPS-provisioning-step-connection.patch --- wpa_supplicant/wpa_supplicant.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 7361ee9..e35c276 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2443,12 +2443,14 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) if (bss) { params.ssid = bss->ssid; params.ssid_len = bss->ssid_len; - if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set) { + if (!wpas_driver_bss_selection(wpa_s) || ssid->bssid_set || + wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) { wpa_printf(MSG_DEBUG, "Limit connection to BSSID " MACSTR " freq=%u MHz based on scan results " - "(bssid_set=%d)", + "(bssid_set=%d wps=%d)", MAC2STR(bss->bssid), bss->freq, - ssid->bssid_set); + ssid->bssid_set, + wpa_s->key_mgmt == WPA_KEY_MGMT_WPS); params.bssid = bss->bssid; params.freq.freq = bss->freq; } -- cgit v1.2.3 From f50fc1f98579a48296d21350e70799e9e096dd0f Mon Sep 17 00:00:00 2001 From: Joel Cunningham Date: Sat, 8 Oct 2016 12:04:15 -0500 Subject: Check for NULL qsort() base pointers There are a couple of places in wpa_supplicant/hostapd where qsort() can be called with a NULL base pointer. This results in undefined behavior according to the C standard and with some standard C libraries (ARM RVCT 2.2) results in a data abort/memory exception. Fix this by skipping such calls since there is nothing needing to be sorted. Signed-off-by: Joel Cunningham Gbp-Pq: Name 0002-Check-for-NULL-qsort-base-pointers.patch --- hostapd/config_file.c | 3 ++- wpa_supplicant/scan.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 5079f69..2ebf649 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -208,7 +208,8 @@ static int hostapd_config_read_maclist(const char *fname, fclose(f); - qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); + if (*acl) + qsort(*acl, *num, sizeof(**acl), hostapd_acl_comp); return 0; } diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index fb8ebdf..bfde0af 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -2177,8 +2177,10 @@ wpa_supplicant_get_scan_results(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_WPS */ - qsort(scan_res->res, scan_res->num, sizeof(struct wpa_scan_res *), - compar); + if (scan_res->res) { + qsort(scan_res->res, scan_res->num, + sizeof(struct wpa_scan_res *), compar); + } dump_scan_res(scan_res); wpa_bss_update_start(wpa_s); -- cgit v1.2.3 From 4fd57773bcc67166c15c17bf2a2f98c0e8c58b65 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Mon, 10 Oct 2016 18:22:09 +0300 Subject: Always propagate scan results to all interfaces Scan results were not propagated to all interfaces if scan results started a new operation, in order to prevent concurrent operations. But this can cause other interfaces to trigger a new scan when scan results are already available. Instead, always notify other interfaces of the scan results, but note that new operations are not allowed. Signed-off-by: Avraham Stern Signed-off-by: Andrei Otcheretianski Gbp-Pq: Name 0003-Always-propagate-scan-results-to-all-interfaces.patch --- wpa_supplicant/events.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index abe3b47..e15109c 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1474,11 +1474,18 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, } -/* Return != 0 if no scan results could be fetched or if scan results should not - * be shared with other virtual interfaces. */ +/* + * Return a negative value if no scan results could be fetched or if scan + * results should not be shared with other virtual interfaces. + * Return 0 if scan results were fetched and may be shared with other + * interfaces. + * Return 1 if scan results may be shared with other virtual interfaces but may + * not trigger any operations. + * Return 2 if the interface was removed and cannot be used. + */ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, union wpa_event_data *data, - int own_request) + int own_request, int update_only) { struct wpa_scan_results *scan_res = NULL; int ret = 0; @@ -1528,6 +1535,11 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, } #endif /* CONFIG_NO_RANDOM_POOL */ + if (update_only) { + ret = 1; + goto scan_work_done; + } + if (own_request && wpa_s->scan_res_handler && !(data && data->scan_info.external_scan)) { void (*scan_res_handler)(struct wpa_supplicant *wpa_s, @@ -1536,7 +1548,7 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, scan_res_handler = wpa_s->scan_res_handler; wpa_s->scan_res_handler = NULL; scan_res_handler(wpa_s, scan_res); - ret = -2; + ret = 1; goto scan_work_done; } @@ -1672,8 +1684,9 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, if (new_scan) wpa_supplicant_rsn_preauth_scan_results(wpa_s); /* - * Do not notify other virtual radios of scan results since we do not - * want them to start other associations at the same time. + * Do not allow other virtual radios to trigger operations based + * on these scan results since we do not want them to start + * other associations at the same time. */ return 1; } else { @@ -1757,7 +1770,7 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, struct wpa_supplicant *ifs; int res; - res = _wpa_supplicant_event_scan_results(wpa_s, data, 1); + res = _wpa_supplicant_event_scan_results(wpa_s, data, 1, 0); if (res == 2) { /* * Interface may have been removed, so must not dereference @@ -1765,7 +1778,8 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, */ return 1; } - if (res != 0) { + + if (res < 0) { /* * If no scan results could be fetched, then no need to * notify those interfaces that did not actually request @@ -1785,7 +1799,10 @@ static int wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, if (ifs != wpa_s) { wpa_printf(MSG_DEBUG, "%s: Updating scan results from " "sibling", ifs->ifname); - _wpa_supplicant_event_scan_results(ifs, data, 0); + res = _wpa_supplicant_event_scan_results(ifs, data, 0, + res > 0); + if (res < 0) + return 0; } } -- cgit v1.2.3 From 792cf6b3d66547547884cd5d0418115bb4ea415e Mon Sep 17 00:00:00 2001 From: Benjamin Richter Date: Tue, 11 Oct 2016 05:57:38 +0200 Subject: wpa_supplicant: Restore permanent MAC address on reassociation With mac_addr=0 and preassoc_mac_addr=1, the permanent MAC address should be restored for association. Previously this did not happen when reassociating to the same ESS. Signed-off-by: Benjamin Richter Gbp-Pq: Name 0004-wpa_supplicant-Restore-permanent-MAC-address-on-reas.patch --- wpa_supplicant/wpa_supplicant.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e35c276..8d83994 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1673,11 +1673,13 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, wmm_ac_save_tspecs(wpa_s); wpa_s->reassoc_same_bss = 1; } - } else if (rand_style > 0) { + } + + if (rand_style > 0 && !wpa_s->reassoc_same_ess) { if (wpas_update_random_addr(wpa_s, rand_style) < 0) return; wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); - } else if (wpa_s->mac_addr_changed) { + } else if (rand_style == 0 && wpa_s->mac_addr_changed) { if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) { wpa_msg(wpa_s, MSG_INFO, "Could not restore permanent MAC address"); -- cgit v1.2.3 From 4de05f0a8aff62630556cbddd3e8673b29cd356b Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Mon, 24 Oct 2016 16:54:36 -0700 Subject: nl80211: Update channel information after channel switch notification When channel switch happens, driver wrapper's internal channel information needs to be updated so that the new frequency will be used in operations using drv->assoc_freq. Previously, only bss->freq was updated and the new frequency was also indicated in the EVENT_CH_SWITCH event. This could potentially leave out couple of cases that use drv->assoc_freq at least as a fallback mechanism for getting the current operating frequency. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0005-nl80211-Update-channel-information-after-channel-swi.patch --- src/drivers/driver_nl80211_event.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 762e3ac..0f54574 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -516,6 +516,7 @@ static void mlme_event_ch_switch(struct wpa_driver_nl80211_data *drv, data.ch_switch.cf2 = nla_get_u32(cf2); bss->freq = data.ch_switch.freq; + drv->assoc_freq = data.ch_switch.freq; wpa_supplicant_event(bss->ctx, EVENT_CH_SWITCH, &data); } -- cgit v1.2.3 From 567b2bbb14cfc7465c594ea79b3d1a38d1d57bd9 Mon Sep 17 00:00:00 2001 From: Avraham Stern Date: Thu, 27 Oct 2016 15:18:29 +0300 Subject: Extend ieee80211_freq_to_channel_ext() to cover channels 52-64 Add frequency to channel conversion for the 5 GHz channels 52-64. Signed-off-by: Avraham Stern Gbp-Pq: Name 0006-Extend-ieee80211_freq_to_channel_ext-to-cover-channe.patch --- src/common/ieee802_11_common.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index b6bc449..cc2f5cc 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -681,6 +681,25 @@ enum hostapd_hw_mode ieee80211_freq_to_channel_ext(unsigned int freq, return HOSTAPD_MODE_IEEE80211A; } + /* 5 GHz, channels 52..64 */ + if (freq >= 5260 && freq <= 5320) { + if ((freq - 5000) % 5) + return NUM_HOSTAPD_MODES; + + if (vht_opclass) + *op_class = vht_opclass; + else if (sec_channel == 1) + *op_class = 119; + else if (sec_channel == -1) + *op_class = 120; + else + *op_class = 118; + + *channel = (freq - 5000) / 5; + + return HOSTAPD_MODE_IEEE80211A; + } + /* 5 GHz, channels 149..169 */ if (freq >= 5745 && freq <= 5845) { if ((freq - 5000) % 5) -- cgit v1.2.3 From 3ec73f277418267b8bfba2845e3a37ed3f7a63e3 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 13 Nov 2016 17:46:00 +0200 Subject: Use estimated throughput to avoid signal based roaming decision Previously, the estimated throughput was used to enable roaming to a better AP. However, this information was not used when considering a roam to an AP that has better signal strength, but smaller estimated throughput. This could result in allowing roaming from 5 GHz band to 2.4 GHz band in cases where 2.4 GHz band has significantly higher signal strength, but still a lower throughput estimate. Make this less likely to happen by increasing/reducing the minimum required signal strength difference based on the estimated throughputs of the current and selected AP. In addition, add more details about the selection process to the debug log to make it easier to determine whaty happened and why. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0007-Use-estimated-throughput-to-avoid-signal-based-roami.patch --- wpa_supplicant/events.c | 52 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index e15109c..7ca3d8e 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1375,8 +1375,9 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, { struct wpa_bss *current_bss = NULL; #ifndef CONFIG_NO_ROAMING - int min_diff; + int min_diff, diff; int to_5ghz; + int cur_est, sel_est; #endif /* CONFIG_NO_ROAMING */ if (wpa_s->reassociate) @@ -1410,12 +1411,13 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, #ifndef CONFIG_NO_ROAMING wpa_dbg(wpa_s, MSG_DEBUG, "Considering within-ESS reassociation"); wpa_dbg(wpa_s, MSG_DEBUG, "Current BSS: " MACSTR - " level=%d snr=%d est_throughput=%u", - MAC2STR(current_bss->bssid), current_bss->level, + " freq=%d level=%d snr=%d est_throughput=%u", + MAC2STR(current_bss->bssid), + current_bss->freq, current_bss->level, current_bss->snr, current_bss->est_throughput); wpa_dbg(wpa_s, MSG_DEBUG, "Selected BSS: " MACSTR - " level=%d snr=%d est_throughput=%u", - MAC2STR(selected->bssid), selected->level, + " freq=%d level=%d snr=%d est_throughput=%u", + MAC2STR(selected->bssid), selected->freq, selected->level, selected->snr, selected->est_throughput); if (wpa_s->current_ssid->bssid_set && @@ -1441,6 +1443,14 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, return 0; } + if (current_bss->est_throughput > selected->est_throughput + 5000) { + wpa_dbg(wpa_s, MSG_DEBUG, + "Skip roam - Current BSS has better estimated throughput"); + return 1; + } + + cur_est = current_bss->est_throughput; + sel_est = selected->est_throughput; min_diff = 2; if (current_bss->level < 0) { if (current_bss->level < -85) @@ -1453,20 +1463,42 @@ static int wpa_supplicant_need_to_roam(struct wpa_supplicant *wpa_s, min_diff = 4; else min_diff = 5; + if (cur_est > sel_est * 1.5) + min_diff += 10; + else if (cur_est > sel_est * 1.2) + min_diff += 5; + else if (cur_est > sel_est * 1.1) + min_diff += 2; + else if (cur_est > sel_est) + min_diff++; } if (to_5ghz) { + int reduce = 2; + /* Make it easier to move to 5 GHz band */ - if (min_diff > 2) - min_diff -= 2; + if (sel_est > cur_est * 1.5) + reduce = 5; + else if (sel_est > cur_est * 1.2) + reduce = 4; + else if (sel_est > cur_est * 1.1) + reduce = 3; + + if (min_diff > reduce) + min_diff -= reduce; else min_diff = 0; } - if (abs(current_bss->level - selected->level) < min_diff) { - wpa_dbg(wpa_s, MSG_DEBUG, "Skip roam - too small difference " - "in signal level"); + diff = abs(current_bss->level - selected->level); + if (diff < min_diff) { + wpa_dbg(wpa_s, MSG_DEBUG, + "Skip roam - too small difference in signal level (%d < %d)", + diff, min_diff); return 0; } + wpa_dbg(wpa_s, MSG_DEBUG, + "Allow reassociation due to difference in signal level (%d >= %d)", + diff, min_diff); return 1; #else /* CONFIG_NO_ROAMING */ return 0; -- cgit v1.2.3 From 40500cb18b962297463b73a7ecaf08b72ef75125 Mon Sep 17 00:00:00 2001 From: Srinivas Dasari Date: Mon, 21 Nov 2016 17:40:36 +0530 Subject: Use random MAC address for scanning only in non-connected state cfg80211 rejects the scans issued with random MAC address if the STA is in connected state. This resulted in failures when using MAC_RAND_SCAN while connected (CTRL-EVENT-SCAN-FAILED ret=-95). Enable random MAC address functionality only if the STA is not in connected state to avoid this. The real MAC address of the STA is already revealed in the association, so this is an acceptable fallback mechanism for now. Signed-off-by: Jouni Malinen Gbp-Pq: Name 0008-Use-random-MAC-address-for-scanning-only-in-non-conn.patch --- wpa_supplicant/scan.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index bfde0af..d1148a4 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -1047,7 +1047,8 @@ ssid_list_set: } #endif /* CONFIG_P2P */ - if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) { + if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCAN) && + wpa_s->wpa_state <= WPA_SCANNING) { params.mac_addr_rand = 1; if (wpa_s->mac_addr_scan) { params.mac_addr = wpa_s->mac_addr_scan; @@ -1469,7 +1470,8 @@ scan: wpa_setband_scan_freqs(wpa_s, scan_params); - if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) { + if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_SCHED_SCAN) && + wpa_s->wpa_state <= WPA_SCANNING) { params.mac_addr_rand = 1; if (wpa_s->mac_addr_sched_scan) { params.mac_addr = wpa_s->mac_addr_sched_scan; @@ -2518,7 +2520,8 @@ int wpas_start_pno(struct wpa_supplicant *wpa_s) params.freqs = wpa_s->manual_sched_scan_freqs; } - if (wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) { + if ((wpa_s->mac_addr_rand_enable & MAC_ADDR_RAND_PNO) && + wpa_s->wpa_state <= WPA_SCANNING) { params.mac_addr_rand = 1; if (wpa_s->mac_addr_pno) { params.mac_addr = wpa_s->mac_addr_pno; -- cgit v1.2.3 From 0be93e6b475a081a97201b1f8ecf5ddd73849ed4 Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Fri, 14 Jul 2017 15:15:35 +0200 Subject: hostapd: Avoid key reinstallation in FT handshake Do not reinstall TK to the driver during Reassociation Response frame processing if the first attempt of setting the TK succeeded. This avoids issues related to clearing the TX/RX PN that could result in reusing same PN values for transmitted frames (e.g., due to CCM nonce reuse and also hitting replay protection on the receiver) and accepting replayed frames on RX side. This issue was introduced by the commit 0e84c25434e6a1f283c7b4e62e483729085b78d2 ('FT: Fix PTK configuration in authenticator') which allowed wpa_ft_install_ptk() to be called multiple times with the same PTK. While the second configuration attempt is needed with some drivers, it must be done only if the first attempt failed. Signed-off-by: Mathy Vanhoef Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0001-hostapd-Avoid-key-reinstallation-in-FT-handshake.patch --- src/ap/ieee802_11.c | 16 +++++++++++++--- src/ap/wpa_auth.c | 11 +++++++++++ src/ap/wpa_auth.h | 3 ++- src/ap/wpa_auth_ft.c | 10 ++++++++++ src/ap/wpa_auth_i.h | 1 + 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 4e04169..333035f 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -1841,6 +1841,7 @@ static int add_associated_sta(struct hostapd_data *hapd, { struct ieee80211_ht_capabilities ht_cap; struct ieee80211_vht_capabilities vht_cap; + int set = 1; /* * Remove the STA entry to ensure the STA PS state gets cleared and @@ -1848,9 +1849,18 @@ static int add_associated_sta(struct hostapd_data *hapd, * FT-over-the-DS, where a station re-associates back to the same AP but * skips the authentication flow, or if working with a driver that * does not support full AP client state. + * + * Skip this if the STA has already completed FT reassociation and the + * TK has been configured since the TX/RX PN must not be reset to 0 for + * the same key. */ - if (!sta->added_unassoc) + if (!sta->added_unassoc && + (!(sta->flags & WLAN_STA_AUTHORIZED) || + !wpa_auth_sta_ft_tk_already_set(sta->wpa_sm))) { hostapd_drv_sta_remove(hapd, sta->addr); + wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED); + set = 0; + } #ifdef CONFIG_IEEE80211N if (sta->flags & WLAN_STA_HT) @@ -1873,11 +1883,11 @@ static int add_associated_sta(struct hostapd_data *hapd, sta->flags & WLAN_STA_VHT ? &vht_cap : NULL, sta->flags | WLAN_STA_ASSOC, sta->qosinfo, sta->vht_opmode, sta->p2p_ie ? 1 : 0, - sta->added_unassoc)) { + set)) { hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE, "Could not %s STA to kernel driver", - sta->added_unassoc ? "set" : "add"); + set ? "set" : "add"); if (sta->added_unassoc) { hostapd_drv_sta_remove(hapd, sta->addr); diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 3587086..707971d 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -1745,6 +1745,9 @@ int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event) #else /* CONFIG_IEEE80211R */ break; #endif /* CONFIG_IEEE80211R */ + case WPA_DRV_STA_REMOVED: + sm->tk_already_set = FALSE; + return 0; } #ifdef CONFIG_IEEE80211R @@ -3250,6 +3253,14 @@ int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm) } +int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm) +{ + if (!sm || !wpa_key_mgmt_ft(sm->wpa_key_mgmt)) + return 0; + return sm->tk_already_set; +} + + int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, struct rsn_pmksa_cache_entry *entry) { diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 0de8d97..97461b0 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -267,7 +267,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth, u8 *data, size_t data_len); enum wpa_event { WPA_AUTH, WPA_ASSOC, WPA_DISASSOC, WPA_DEAUTH, WPA_REAUTH, - WPA_REAUTH_EAPOL, WPA_ASSOC_FT + WPA_REAUTH_EAPOL, WPA_ASSOC_FT, WPA_DRV_STA_REMOVED }; void wpa_remove_ptk(struct wpa_state_machine *sm); int wpa_auth_sm_event(struct wpa_state_machine *sm, enum wpa_event event); @@ -280,6 +280,7 @@ int wpa_auth_pairwise_set(struct wpa_state_machine *sm); int wpa_auth_get_pairwise(struct wpa_state_machine *sm); int wpa_auth_sta_key_mgmt(struct wpa_state_machine *sm); int wpa_auth_sta_wpa_version(struct wpa_state_machine *sm); +int wpa_auth_sta_ft_tk_already_set(struct wpa_state_machine *sm); int wpa_auth_sta_clear_pmksa(struct wpa_state_machine *sm, struct rsn_pmksa_cache_entry *entry); struct rsn_pmksa_cache_entry * diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 42242a5..e63b99a 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -780,6 +780,14 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) return; } + if (sm->tk_already_set) { + /* Must avoid TK reconfiguration to prevent clearing of TX/RX + * PN in the driver */ + wpa_printf(MSG_DEBUG, + "FT: Do not re-install same PTK to the driver"); + return; + } + /* FIX: add STA entry to kernel/driver here? The set_key will fail * most likely without this.. At the moment, STA entry is added only * after association has been completed. This function will be called @@ -792,6 +800,7 @@ void wpa_ft_install_ptk(struct wpa_state_machine *sm) /* FIX: MLME-SetProtection.Request(TA, Tx_Rx) */ sm->pairwise_set = TRUE; + sm->tk_already_set = TRUE; } @@ -898,6 +907,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, sm->pairwise = pairwise; sm->PTK_valid = TRUE; + sm->tk_already_set = FALSE; wpa_ft_install_ptk(sm); buflen = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index 72b7eb3..7fd8f05 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -65,6 +65,7 @@ struct wpa_state_machine { struct wpa_ptk PTK; Boolean PTK_valid; Boolean pairwise_set; + Boolean tk_already_set; int keycount; Boolean Pair; struct wpa_key_replay_counter { -- cgit v1.2.3 From 36bd2ec4866c2b72248b3ed6a438a3852200beb5 Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Wed, 12 Jul 2017 16:03:24 +0200 Subject: Prevent reinstallation of an already in-use group key Track the current GTK and IGTK that is in use and when receiving a (possibly retransmitted) Group Message 1 or WNM-Sleep Mode Response, do not install the given key if it is already in use. This prevents an attacker from trying to trick the client into resetting or lowering the sequence counter associated to the group key. Signed-off-by: Mathy Vanhoef Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0002-Prevent-reinstallation-of-an-already-in-use-group-ke.patch --- src/common/wpa_common.h | 11 +++++ src/rsn_supp/wpa.c | 116 ++++++++++++++++++++++++++++++------------------ src/rsn_supp/wpa_i.h | 4 ++ 3 files changed, 87 insertions(+), 44 deletions(-) diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index af1d0f0..d200285 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -217,6 +217,17 @@ struct wpa_ptk { size_t tk_len; }; +struct wpa_gtk { + u8 gtk[WPA_GTK_MAX_LEN]; + size_t gtk_len; +}; + +#ifdef CONFIG_IEEE80211W +struct wpa_igtk { + u8 igtk[WPA_IGTK_MAX_LEN]; + size_t igtk_len; +}; +#endif /* CONFIG_IEEE80211W */ /* WPA IE version 1 * 00-50-f2:1 (OUI:OUI type) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 3c47879..95bd7be 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -714,6 +714,15 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, const u8 *_gtk = gd->gtk; u8 gtk_buf[32]; + /* Detect possible key reinstallation */ + if (sm->gtk.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", + gd->keyidx, gd->tx, gd->gtk_len); + return 0; + } + wpa_hexdump_key(MSG_DEBUG, "WPA: Group Key", gd->gtk, gd->gtk_len); wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Installing GTK to the driver (keyidx=%d tx=%d len=%d)", @@ -748,6 +757,9 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, } os_memset(gtk_buf, 0, sizeof(gtk_buf)); + sm->gtk.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); + return 0; } @@ -854,6 +866,48 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, } +#ifdef CONFIG_IEEE80211W +static int wpa_supplicant_install_igtk(struct wpa_sm *sm, + const struct wpa_igtk_kde *igtk) +{ + size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); + u16 keyidx = WPA_GET_LE16(igtk->keyid); + + /* Detect possible key reinstallation */ + if (sm->igtk.igtk_len == len && + os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", + keyidx); + return 0; + } + + wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, + "WPA: IGTK keyid %d pn %02x%02x%02x%02x%02x%02x", + keyidx, MAC2STR(igtk->pn)); + wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", igtk->igtk, len); + if (keyidx > 4095) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: Invalid IGTK KeyID %d", keyidx); + return -1; + } + if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), + broadcast_ether_addr, + keyidx, 0, igtk->pn, sizeof(igtk->pn), + igtk->igtk, len) < 0) { + wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, + "WPA: Failed to configure IGTK to the driver"); + return -1; + } + + sm->igtk.igtk_len = len; + os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); + + return 0; +} +#endif /* CONFIG_IEEE80211W */ + + static int ieee80211w_set_keys(struct wpa_sm *sm, struct wpa_eapol_ie_parse *ie) { @@ -864,30 +918,14 @@ static int ieee80211w_set_keys(struct wpa_sm *sm, if (ie->igtk) { size_t len; const struct wpa_igtk_kde *igtk; - u16 keyidx; + len = wpa_cipher_key_len(sm->mgmt_group_cipher); if (ie->igtk_len != WPA_IGTK_KDE_PREFIX_LEN + len) return -1; + igtk = (const struct wpa_igtk_kde *) ie->igtk; - keyidx = WPA_GET_LE16(igtk->keyid); - wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: IGTK keyid %d " - "pn %02x%02x%02x%02x%02x%02x", - keyidx, MAC2STR(igtk->pn)); - wpa_hexdump_key(MSG_DEBUG, "WPA: IGTK", - igtk->igtk, len); - if (keyidx > 4095) { - wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, - "WPA: Invalid IGTK KeyID %d", keyidx); - return -1; - } - if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), - broadcast_ether_addr, - keyidx, 0, igtk->pn, sizeof(igtk->pn), - igtk->igtk, len) < 0) { - wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, - "WPA: Failed to configure IGTK to the driver"); + if (wpa_supplicant_install_igtk(sm, igtk) < 0) return -1; - } } return 0; @@ -2307,7 +2345,7 @@ void wpa_sm_deinit(struct wpa_sm *sm) */ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) { - int clear_ptk = 1; + int clear_keys = 1; if (sm == NULL) return; @@ -2333,11 +2371,11 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) /* Prepare for the next transition */ wpa_ft_prepare_auth_request(sm, NULL); - clear_ptk = 0; + clear_keys = 0; } #endif /* CONFIG_IEEE80211R */ - if (clear_ptk) { + if (clear_keys) { /* * IEEE 802.11, 8.4.10: Delete PTK SA on (re)association if * this is not part of a Fast BSS Transition. @@ -2347,6 +2385,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) os_memset(&sm->ptk, 0, sizeof(sm->ptk)); sm->tptk_set = 0; os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); +#ifdef CONFIG_IEEE80211W + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); +#endif /* CONFIG_IEEE80211W */ } #ifdef CONFIG_TDLS @@ -2877,6 +2919,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm) os_memset(sm->pmk, 0, sizeof(sm->pmk)); os_memset(&sm->ptk, 0, sizeof(sm->ptk)); os_memset(&sm->tptk, 0, sizeof(sm->tptk)); + os_memset(&sm->gtk, 0, sizeof(sm->gtk)); +#ifdef CONFIG_IEEE80211W + os_memset(&sm->igtk, 0, sizeof(sm->igtk)); +#endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0)); @@ -2949,29 +2995,11 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) os_memset(&gd, 0, sizeof(gd)); #ifdef CONFIG_IEEE80211W } else if (subelem_id == WNM_SLEEP_SUBELEM_IGTK) { - struct wpa_igtk_kde igd; - u16 keyidx; - - os_memset(&igd, 0, sizeof(igd)); - keylen = wpa_cipher_key_len(sm->mgmt_group_cipher); - os_memcpy(igd.keyid, buf + 2, 2); - os_memcpy(igd.pn, buf + 4, 6); - - keyidx = WPA_GET_LE16(igd.keyid); - os_memcpy(igd.igtk, buf + 10, keylen); - - wpa_hexdump_key(MSG_DEBUG, "Install IGTK (WNM SLEEP)", - igd.igtk, keylen); - if (wpa_sm_set_key(sm, wpa_cipher_to_alg(sm->mgmt_group_cipher), - broadcast_ether_addr, - keyidx, 0, igd.pn, sizeof(igd.pn), - igd.igtk, keylen) < 0) { - wpa_printf(MSG_DEBUG, "Failed to install the IGTK in " - "WNM mode"); - os_memset(&igd, 0, sizeof(igd)); + const struct wpa_igtk_kde *igtk; + + igtk = (const struct wpa_igtk_kde *) (buf + 2); + if (wpa_supplicant_install_igtk(sm, igtk) < 0) return -1; - } - os_memset(&igd, 0, sizeof(igd)); #endif /* CONFIG_IEEE80211W */ } else { wpa_printf(MSG_DEBUG, "Unknown element id"); diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index f653ba6..afc9e37 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -31,6 +31,10 @@ struct wpa_sm { u8 rx_replay_counter[WPA_REPLAY_COUNTER_LEN]; int rx_replay_counter_set; u8 request_counter[WPA_REPLAY_COUNTER_LEN]; + struct wpa_gtk gtk; +#ifdef CONFIG_IEEE80211W + struct wpa_igtk igtk; +#endif /* CONFIG_IEEE80211W */ struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ -- cgit v1.2.3 From 13b3c9a7c6012126b62e309ce7887376396a81be Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 1 Oct 2017 12:12:24 +0300 Subject: Extend protection of GTK/IGTK reinstallation of WNM-Sleep Mode cases This extends the protection to track last configured GTK/IGTK value separately from EAPOL-Key frames and WNM-Sleep Mode frames to cover a corner case where these two different mechanisms may get used when the GTK/IGTK has changed and tracking a single value is not sufficient to detect a possible key reconfiguration. Signed-off-by: Jouni Malinen Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0003-Extend-protection-of-GTK-IGTK-reinstallation-of-WNM-.patch --- src/rsn_supp/wpa.c | 53 +++++++++++++++++++++++++++++++++++++--------------- src/rsn_supp/wpa_i.h | 2 ++ 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 95bd7be..7a2c68d 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -709,14 +709,17 @@ struct wpa_gtk_data { static int wpa_supplicant_install_gtk(struct wpa_sm *sm, const struct wpa_gtk_data *gd, - const u8 *key_rsc) + const u8 *key_rsc, int wnm_sleep) { const u8 *_gtk = gd->gtk; u8 gtk_buf[32]; /* Detect possible key reinstallation */ - if (sm->gtk.gtk_len == (size_t) gd->gtk_len && - os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) { + if ((sm->gtk.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len) == 0) || + (sm->gtk_wnm_sleep.gtk_len == (size_t) gd->gtk_len && + os_memcmp(sm->gtk_wnm_sleep.gtk, gd->gtk, + sm->gtk_wnm_sleep.gtk_len) == 0)) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Not reinstalling already in-use GTK to the driver (keyidx=%d tx=%d len=%d)", gd->keyidx, gd->tx, gd->gtk_len); @@ -757,8 +760,14 @@ static int wpa_supplicant_install_gtk(struct wpa_sm *sm, } os_memset(gtk_buf, 0, sizeof(gtk_buf)); - sm->gtk.gtk_len = gd->gtk_len; - os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); + if (wnm_sleep) { + sm->gtk_wnm_sleep.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk_wnm_sleep.gtk, gd->gtk, + sm->gtk_wnm_sleep.gtk_len); + } else { + sm->gtk.gtk_len = gd->gtk_len; + os_memcpy(sm->gtk.gtk, gd->gtk, sm->gtk.gtk_len); + } return 0; } @@ -852,7 +861,7 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, (wpa_supplicant_check_group_cipher(sm, sm->group_cipher, gtk_len, gtk_len, &gd.key_rsc_len, &gd.alg) || - wpa_supplicant_install_gtk(sm, &gd, key_rsc))) { + wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0))) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: Failed to install GTK"); os_memset(&gd, 0, sizeof(gd)); @@ -868,14 +877,18 @@ static int wpa_supplicant_pairwise_gtk(struct wpa_sm *sm, #ifdef CONFIG_IEEE80211W static int wpa_supplicant_install_igtk(struct wpa_sm *sm, - const struct wpa_igtk_kde *igtk) + const struct wpa_igtk_kde *igtk, + int wnm_sleep) { size_t len = wpa_cipher_key_len(sm->mgmt_group_cipher); u16 keyidx = WPA_GET_LE16(igtk->keyid); /* Detect possible key reinstallation */ - if (sm->igtk.igtk_len == len && - os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) { + if ((sm->igtk.igtk_len == len && + os_memcmp(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len) == 0) || + (sm->igtk_wnm_sleep.igtk_len == len && + os_memcmp(sm->igtk_wnm_sleep.igtk, igtk->igtk, + sm->igtk_wnm_sleep.igtk_len) == 0)) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Not reinstalling already in-use IGTK to the driver (keyidx=%d)", keyidx); @@ -900,8 +913,14 @@ static int wpa_supplicant_install_igtk(struct wpa_sm *sm, return -1; } - sm->igtk.igtk_len = len; - os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); + if (wnm_sleep) { + sm->igtk_wnm_sleep.igtk_len = len; + os_memcpy(sm->igtk_wnm_sleep.igtk, igtk->igtk, + sm->igtk_wnm_sleep.igtk_len); + } else { + sm->igtk.igtk_len = len; + os_memcpy(sm->igtk.igtk, igtk->igtk, sm->igtk.igtk_len); + } return 0; } @@ -924,7 +943,7 @@ static int ieee80211w_set_keys(struct wpa_sm *sm, return -1; igtk = (const struct wpa_igtk_kde *) ie->igtk; - if (wpa_supplicant_install_igtk(sm, igtk) < 0) + if (wpa_supplicant_install_igtk(sm, igtk, 0) < 0) return -1; } @@ -1574,7 +1593,7 @@ static void wpa_supplicant_process_1_of_2(struct wpa_sm *sm, if (wpa_supplicant_rsc_relaxation(sm, key->key_rsc)) key_rsc = null_rsc; - if (wpa_supplicant_install_gtk(sm, &gd, key_rsc) || + if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 0) || wpa_supplicant_send_2_of_2(sm, key, ver, key_info) < 0) goto failed; os_memset(&gd, 0, sizeof(gd)); @@ -2386,8 +2405,10 @@ void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid) sm->tptk_set = 0; os_memset(&sm->tptk, 0, sizeof(sm->tptk)); os_memset(&sm->gtk, 0, sizeof(sm->gtk)); + os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); #ifdef CONFIG_IEEE80211W os_memset(&sm->igtk, 0, sizeof(sm->igtk)); + os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); #endif /* CONFIG_IEEE80211W */ } @@ -2920,8 +2941,10 @@ void wpa_sm_drop_sa(struct wpa_sm *sm) os_memset(&sm->ptk, 0, sizeof(sm->ptk)); os_memset(&sm->tptk, 0, sizeof(sm->tptk)); os_memset(&sm->gtk, 0, sizeof(sm->gtk)); + os_memset(&sm->gtk_wnm_sleep, 0, sizeof(sm->gtk_wnm_sleep)); #ifdef CONFIG_IEEE80211W os_memset(&sm->igtk, 0, sizeof(sm->igtk)); + os_memset(&sm->igtk_wnm_sleep, 0, sizeof(sm->igtk_wnm_sleep)); #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); @@ -2986,7 +3009,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) wpa_hexdump_key(MSG_DEBUG, "Install GTK (WNM SLEEP)", gd.gtk, gd.gtk_len); - if (wpa_supplicant_install_gtk(sm, &gd, key_rsc)) { + if (wpa_supplicant_install_gtk(sm, &gd, key_rsc, 1)) { os_memset(&gd, 0, sizeof(gd)); wpa_printf(MSG_DEBUG, "Failed to install the GTK in " "WNM mode"); @@ -2998,7 +3021,7 @@ int wpa_wnmsleep_install_key(struct wpa_sm *sm, u8 subelem_id, u8 *buf) const struct wpa_igtk_kde *igtk; igtk = (const struct wpa_igtk_kde *) (buf + 2); - if (wpa_supplicant_install_igtk(sm, igtk) < 0) + if (wpa_supplicant_install_igtk(sm, igtk, 1) < 0) return -1; #endif /* CONFIG_IEEE80211W */ } else { diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index afc9e37..9a54631 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -32,8 +32,10 @@ struct wpa_sm { int rx_replay_counter_set; u8 request_counter[WPA_REPLAY_COUNTER_LEN]; struct wpa_gtk gtk; + struct wpa_gtk gtk_wnm_sleep; #ifdef CONFIG_IEEE80211W struct wpa_igtk igtk; + struct wpa_igtk igtk_wnm_sleep; #endif /* CONFIG_IEEE80211W */ struct eapol_sm *eapol; /* EAPOL state machine from upper level code */ -- cgit v1.2.3 From a9763dd4e6030521339ecdc287ffd2b05535f980 Mon Sep 17 00:00:00 2001 From: Mathy Vanhoef Date: Fri, 29 Sep 2017 04:22:51 +0200 Subject: Prevent installation of an all-zero TK Properly track whether a PTK has already been installed to the driver and the TK part cleared from memory. This prevents an attacker from trying to trick the client into installing an all-zero TK. This fixes the earlier fix in commit ad00d64e7d8827b3cebd665a0ceb08adabf15e1e ('Fix TK configuration to the driver in EAPOL-Key 3/4 retry case') which did not take into account possibility of an extra message 1/4 showing up between retries of message 3/4. Signed-off-by: Mathy Vanhoef Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0004-Prevent-installation-of-an-all-zero-TK.patch --- src/common/wpa_common.h | 1 + src/rsn_supp/wpa.c | 5 ++--- src/rsn_supp/wpa_i.h | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index d200285..1021ccb 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -215,6 +215,7 @@ struct wpa_ptk { size_t kck_len; size_t kek_len; size_t tk_len; + int installed; /* 1 if key has already been installed to driver */ }; struct wpa_gtk { diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 7a2c68d..0550a41 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -510,7 +510,6 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm, os_memset(buf, 0, sizeof(buf)); } sm->tptk_set = 1; - sm->tk_to_set = 1; kde = sm->assoc_wpa_ie; kde_len = sm->assoc_wpa_ie_len; @@ -615,7 +614,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, enum wpa_alg alg; const u8 *key_rsc; - if (!sm->tk_to_set) { + if (sm->ptk.installed) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "WPA: Do not re-install same PTK to the driver"); return 0; @@ -659,7 +658,7 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, /* TK is not needed anymore in supplicant */ os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN); - sm->tk_to_set = 0; + sm->ptk.installed = 1; if (sm->wpa_ptk_rekey) { eloop_cancel_timeout(wpa_sm_rekey_ptk, sm, NULL); diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 9a54631..41f371f 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -24,7 +24,6 @@ struct wpa_sm { struct wpa_ptk ptk, tptk; int ptk_set, tptk_set; unsigned int msg_3_of_4_ok:1; - unsigned int tk_to_set:1; u8 snonce[WPA_NONCE_LEN]; u8 anonce[WPA_NONCE_LEN]; /* ANonce from the last 1/4 msg */ int renew_snonce; -- cgit v1.2.3 From 43d1e1f2db0444cb86a5473e0778502a09a05377 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 1 Oct 2017 12:32:57 +0300 Subject: Fix PTK rekeying to generate a new ANonce The Authenticator state machine path for PTK rekeying ended up bypassing the AUTHENTICATION2 state where a new ANonce is generated when going directly to the PTKSTART state since there is no need to try to determine the PMK again in such a case. This is far from ideal since the new PTK would depend on a new nonce only from the supplicant. Fix this by generating a new ANonce when moving to the PTKSTART state for the purpose of starting new 4-way handshake to rekey PTK. Signed-off-by: Jouni Malinen Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0005-Fix-PTK-rekeying-to-generate-a-new-ANonce.patch --- src/ap/wpa_auth.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 707971d..bf10cc1 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -1901,6 +1901,21 @@ SM_STATE(WPA_PTK, AUTHENTICATION2) } +static int wpa_auth_sm_ptk_update(struct wpa_state_machine *sm) +{ + if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { + wpa_printf(MSG_ERROR, + "WPA: Failed to get random data for ANonce"); + sm->Disconnect = TRUE; + return -1; + } + wpa_hexdump(MSG_DEBUG, "WPA: Assign new ANonce", sm->ANonce, + WPA_NONCE_LEN); + sm->TimeoutCtr = 0; + return 0; +} + + SM_STATE(WPA_PTK, INITPMK) { u8 msk[2 * PMK_LEN]; @@ -2458,9 +2473,12 @@ SM_STEP(WPA_PTK) SM_ENTER(WPA_PTK, AUTHENTICATION); else if (sm->ReAuthenticationRequest) SM_ENTER(WPA_PTK, AUTHENTICATION2); - else if (sm->PTKRequest) - SM_ENTER(WPA_PTK, PTKSTART); - else switch (sm->wpa_ptk_state) { + else if (sm->PTKRequest) { + if (wpa_auth_sm_ptk_update(sm) < 0) + SM_ENTER(WPA_PTK, DISCONNECTED); + else + SM_ENTER(WPA_PTK, PTKSTART); + } else switch (sm->wpa_ptk_state) { case WPA_PTK_INITIALIZE: break; case WPA_PTK_DISCONNECT: -- cgit v1.2.3 From dc5dce5fc42853293cce4cc1a9d1440a43381cda Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 22 Sep 2017 11:03:15 +0300 Subject: TDLS: Reject TPK-TK reconfiguration Do not try to reconfigure the same TPK-TK to the driver after it has been successfully configured. This is an explicit check to avoid issues related to resetting the TX/RX packet number. There was already a check for this for TPK M2 (retries of that message are ignored completely), so that behavior does not get modified. For TPK M3, the TPK-TK could have been reconfigured, but that was followed by immediate teardown of the link due to an issue in updating the STA entry. Furthermore, for TDLS with any real security (i.e., ignoring open/WEP), the TPK message exchange is protected on the AP path and simple replay attacks are not feasible. As an additional corner case, make sure the local nonce gets updated if the peer uses a very unlikely "random nonce" of all zeros. Signed-off-by: Jouni Malinen Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0006-TDLS-Reject-TPK-TK-reconfiguration.patch --- src/rsn_supp/tdls.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index e424168..9eb9738 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -112,6 +112,7 @@ struct wpa_tdls_peer { u8 tk[16]; /* TPK-TK; assuming only CCMP will be used */ } tpk; int tpk_set; + int tk_set; /* TPK-TK configured to the driver */ int tpk_success; int tpk_in_progress; @@ -192,6 +193,20 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) u8 rsc[6]; enum wpa_alg alg; + if (peer->tk_set) { + /* + * This same TPK-TK has already been configured to the driver + * and this new configuration attempt (likely due to an + * unexpected retransmitted frame) would result in clearing + * the TX/RX sequence number which can break security, so must + * not allow that to happen. + */ + wpa_printf(MSG_INFO, "TDLS: TPK-TK for the peer " MACSTR + " has already been configured to the driver - do not reconfigure", + MAC2STR(peer->addr)); + return -1; + } + os_memset(rsc, 0, 6); switch (peer->cipher) { @@ -209,12 +224,15 @@ static int wpa_tdls_set_key(struct wpa_sm *sm, struct wpa_tdls_peer *peer) return -1; } + wpa_printf(MSG_DEBUG, "TDLS: Configure pairwise key for peer " MACSTR, + MAC2STR(peer->addr)); if (wpa_sm_set_key(sm, alg, peer->addr, -1, 1, rsc, sizeof(rsc), peer->tpk.tk, key_len) < 0) { wpa_printf(MSG_WARNING, "TDLS: Failed to set TPK to the " "driver"); return -1; } + peer->tk_set = 1; return 0; } @@ -696,7 +714,7 @@ static void wpa_tdls_peer_clear(struct wpa_sm *sm, struct wpa_tdls_peer *peer) peer->cipher = 0; peer->qos_info = 0; peer->wmm_capable = 0; - peer->tpk_set = peer->tpk_success = 0; + peer->tk_set = peer->tpk_set = peer->tpk_success = 0; peer->chan_switch_enabled = 0; os_memset(&peer->tpk, 0, sizeof(peer->tpk)); os_memset(peer->inonce, 0, WPA_NONCE_LEN); @@ -1159,6 +1177,7 @@ skip_rsnie: wpa_tdls_peer_free(sm, peer); return -1; } + peer->tk_set = 0; /* A new nonce results in a new TK */ wpa_hexdump(MSG_DEBUG, "TDLS: Initiator Nonce for TPK handshake", peer->inonce, WPA_NONCE_LEN); os_memcpy(ftie->Snonce, peer->inonce, WPA_NONCE_LEN); @@ -1751,6 +1770,19 @@ static int wpa_tdls_addset_peer(struct wpa_sm *sm, struct wpa_tdls_peer *peer, } +static int tdls_nonce_set(const u8 *nonce) +{ + int i; + + for (i = 0; i < WPA_NONCE_LEN; i++) { + if (nonce[i]) + return 1; + } + + return 0; +} + + static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr, const u8 *buf, size_t len) { @@ -2004,7 +2036,8 @@ skip_rsn: peer->rsnie_i_len = kde.rsn_ie_len; peer->cipher = cipher; - if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0) { + if (os_memcmp(peer->inonce, ftie->Snonce, WPA_NONCE_LEN) != 0 || + !tdls_nonce_set(peer->inonce)) { /* * There is no point in updating the RNonce for every obtained * TPK M1 frame (e.g., retransmission due to timeout) with the @@ -2020,6 +2053,7 @@ skip_rsn: "TDLS: Failed to get random data for responder nonce"); goto error; } + peer->tk_set = 0; /* A new nonce results in a new TK */ } #if 0 -- cgit v1.2.3 From 0345367edcd4c1437a81ab7174bd3883a1530288 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 22 Sep 2017 11:25:02 +0300 Subject: WNM: Ignore WNM-Sleep Mode Response without pending request Commit 03ed0a52393710be6bdae657d1b36efa146520e5 ('WNM: Ignore WNM-Sleep Mode Response if WNM-Sleep Mode has not been used') started ignoring the response when no WNM-Sleep Mode Request had been used during the association. This can be made tighter by clearing the used flag when successfully processing a response. This adds an additional layer of protection against unexpected retransmissions of the response frame. Signed-off-by: Jouni Malinen Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0007-WNM-Ignore-WNM-Sleep-Mode-Response-without-pending-r.patch --- wpa_supplicant/wnm_sta.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 1b3409c..67a07ff 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -260,7 +260,7 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, if (!wpa_s->wnmsleep_used) { wpa_printf(MSG_DEBUG, - "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode has not been used in this association"); + "WNM: Ignore WNM-Sleep Mode Response frame since WNM-Sleep Mode operation has not been requested"); return; } @@ -299,6 +299,8 @@ static void ieee802_11_rx_wnmsleep_resp(struct wpa_supplicant *wpa_s, return; } + wpa_s->wnmsleep_used = 0; + if (wnmsleep_ie->status == WNM_STATUS_SLEEP_ACCEPT || wnmsleep_ie->status == WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE) { wpa_printf(MSG_DEBUG, "Successfully recv WNM-Sleep Response " -- cgit v1.2.3 From 178896b965058d7b5c02a7d6a605d647ac8b6098 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 22 Sep 2017 12:06:37 +0300 Subject: FT: Do not allow multiple Reassociation Response frames The driver is expected to not report a second association event without the station having explicitly request a new association. As such, this case should not be reachable. However, since reconfiguring the same pairwise or group keys to the driver could result in nonce reuse issues, be extra careful here and do an additional state check to avoid this even if the local driver ends up somehow accepting an unexpected Reassociation Response frame. Signed-off-by: Jouni Malinen Gbp-Pq: Topic VU-228519 Gbp-Pq: Name rebased-v2.6-0008-FT-Do-not-allow-multiple-Reassociation-Response-fram.patch --- src/rsn_supp/wpa.c | 3 +++ src/rsn_supp/wpa_ft.c | 8 ++++++++ src/rsn_supp/wpa_i.h | 1 + 3 files changed, 12 insertions(+) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 0550a41..2a53c6f 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -2440,6 +2440,9 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm) #ifdef CONFIG_TDLS wpa_tdls_disassoc(sm); #endif /* CONFIG_TDLS */ +#ifdef CONFIG_IEEE80211R + sm->ft_reassoc_completed = 0; +#endif /* CONFIG_IEEE80211R */ /* Keys are not needed in the WPA state machine anymore */ wpa_sm_drop_sa(sm); diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 205793e..d45bb45 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -153,6 +153,7 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, u16 capab; sm->ft_completed = 0; + sm->ft_reassoc_completed = 0; buf_len = 2 + sizeof(struct rsn_mdie) + 2 + sizeof(struct rsn_ftie) + 2 + sm->r0kh_id_len + ric_ies_len + 100; @@ -681,6 +682,11 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, return -1; } + if (sm->ft_reassoc_completed) { + wpa_printf(MSG_DEBUG, "FT: Reassociation has already been completed for this FT protocol instance - ignore unexpected retransmission"); + return 0; + } + if (wpa_ft_parse_ies(ies, ies_len, &parse) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs"); return -1; @@ -781,6 +787,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, return -1; } + sm->ft_reassoc_completed = 1; + if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0) return -1; diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 41f371f..56f88dc 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -128,6 +128,7 @@ struct wpa_sm { size_t r0kh_id_len; u8 r1kh_id[FT_R1KH_ID_LEN]; int ft_completed; + int ft_reassoc_completed; int over_the_ds_in_progress; u8 target_ap[ETH_ALEN]; /* over-the-DS target AP */ int set_ptk_after_assoc; -- cgit v1.2.3