diff --git a/wpa_supplicant-0.5.10-dbus-service-file.patch b/wpa_supplicant-0.5.10-dbus-service-file.patch index 082a3ec..626cf40 100644 --- a/wpa_supplicant-0.5.10-dbus-service-file.patch +++ b/wpa_supplicant-0.5.10-dbus-service-file.patch @@ -5,5 +5,5 @@ diff -up wpa_supplicant-0.6.3/wpa_supplicant/dbus-wpa_supplicant.service.fedora [D-BUS Service] Name=fi.epitest.hostap.WPASupplicant -Exec=/sbin/wpa_supplicant -u -+Exec=/usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -u -f /var/log/wpa_supplicant.log ++Exec=/usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid User=root diff --git a/wpa_supplicant-0.6.9-eapol-race-fix.patch b/wpa_supplicant-0.6.9-eapol-race-fix.patch new file mode 100644 index 0000000..08984aa --- /dev/null +++ b/wpa_supplicant-0.6.9-eapol-race-fix.patch @@ -0,0 +1,104 @@ +From: Jouni Malinen +Date: Fri, 4 Sep 2009 15:04:41 +0000 (+0300) +Subject: Delay processing of EAPOL frames when not associated +X-Git-Url: http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=commitdiff_plain;h=1ff733383f3d5c73233ef452a738765667021609 + +Delay processing of EAPOL frames when not associated + +If an EAPOL frame is received while wpa_supplicant thinks the driver is +not associated, queue the frame for processing at the moment when the +association event is received. This is a workaround to a race condition +in receiving data frames and management events from the kernel. + +The pending EAPOL frame will not be processed unless an association +event is received within 100 msec for the same BSSID. +--- + +diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c +index e5e799d..2ea9279 100644 +--- a/wpa_supplicant/events.c ++++ b/wpa_supplicant/events.c +@@ -943,6 +943,25 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, + eapol_sm_notify_portValid(wpa_s->eapol, TRUE); + eapol_sm_notify_eap_success(wpa_s->eapol, TRUE); + } ++ ++ if (wpa_s->pending_eapol_rx) { ++ struct os_time now, age; ++ os_get_time(&now); ++ os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age); ++ if (age.sec == 0 && age.usec < 100000 && ++ os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) == ++ 0) { ++ wpa_printf(MSG_DEBUG, "Process pending EAPOL frame " ++ "that was received just before association " ++ "notification"); ++ wpa_supplicant_rx_eapol( ++ wpa_s, wpa_s->pending_eapol_rx_src, ++ wpabuf_head(wpa_s->pending_eapol_rx), ++ wpabuf_len(wpa_s->pending_eapol_rx)); ++ } ++ wpabuf_free(wpa_s->pending_eapol_rx); ++ wpa_s->pending_eapol_rx = NULL; ++ } + } + + +diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c +index d03e9da..c68dd82 100644 +--- a/wpa_supplicant/wpa_supplicant.c ++++ b/wpa_supplicant/wpa_supplicant.c +@@ -405,6 +405,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) + ieee80211_sta_deinit(wpa_s); + + wpas_wps_deinit(wpa_s); ++ ++ wpabuf_free(wpa_s->pending_eapol_rx); ++ wpa_s->pending_eapol_rx = NULL; + } + + +@@ -1574,6 +1577,27 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, + wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr)); + wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len); + ++ if (wpa_s->wpa_state < WPA_ASSOCIATED) { ++ /* ++ * There is possible race condition between receiving the ++ * association event and the EAPOL frame since they are coming ++ * through different paths from the driver. In order to avoid ++ * issues in trying to process the EAPOL frame before receiving ++ * association information, lets queue it for processing until ++ * the association event is received. ++ */ ++ wpa_printf(MSG_DEBUG, "Not associated - Delay processing of " ++ "received EAPOL frame"); ++ wpabuf_free(wpa_s->pending_eapol_rx); ++ wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len); ++ if (wpa_s->pending_eapol_rx) { ++ os_get_time(&wpa_s->pending_eapol_rx_time); ++ os_memcpy(wpa_s->pending_eapol_rx_src, src_addr, ++ ETH_ALEN); ++ } ++ return; ++ } ++ + if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) { + wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since " + "no key management is configured"); +diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h +index 63984d8..e814f86 100644 +--- a/wpa_supplicant/wpa_supplicant_i.h ++++ b/wpa_supplicant/wpa_supplicant_i.h +@@ -364,6 +364,10 @@ struct wpa_supplicant { + int wps_success; /* WPS success event received */ + int blacklist_cleared; + ++ struct wpabuf *pending_eapol_rx; ++ struct os_time pending_eapol_rx_time; ++ u8 pending_eapol_rx_src[ETH_ALEN]; ++ + int disconnect_count; + }; + + diff --git a/wpa_supplicant-0.6.9-scan-faster.patch b/wpa_supplicant-0.6.9-scan-faster.patch new file mode 100644 index 0000000..fb26db9 --- /dev/null +++ b/wpa_supplicant-0.6.9-scan-faster.patch @@ -0,0 +1,264 @@ +diff -up wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface.c.scan-faster wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface.c +--- wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface.c.scan-faster 2009-02-15 10:00:00.000000000 -0800 ++++ wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface.c 2009-11-29 13:35:44.517283679 -0800 +@@ -733,8 +733,9 @@ static int wpa_supplicant_ctrl_iface_sca + static int wpa_supplicant_ctrl_iface_select_network( + struct wpa_supplicant *wpa_s, char *cmd) + { +- int id; ++ int id, timeout, do_scan = 1; + struct wpa_ssid *ssid; ++ struct os_time now; + + /* cmd: "" or "any" */ + if (os_strcmp(cmd, "any") == 0) { +@@ -745,7 +746,22 @@ static int wpa_supplicant_ctrl_iface_sel + ssid = ssid->next; + } + wpa_s->reassociate = 1; +- wpa_supplicant_req_scan(wpa_s, 0, 0); ++ ++ /* Just associate and don't request a scan if the latest ++ * scan results are less than 10 seconds old. ++ */ ++ if (os_get_time(&now) == 0) { ++ now.sec -= 10; ++ if (os_time_before(&now, &(wpa_s->last_scan))) { ++ if (wpa_supplicant_select_bss_and_associate ( ++ wpa_s, &timeout) >= 0) { ++ do_scan = 0; ++ } ++ } ++ } ++ ++ if (do_scan) ++ wpa_supplicant_req_scan(wpa_s, 0, 0); + return 0; + } + +diff -up wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface_dbus_handlers.c.scan-faster wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface_dbus_handlers.c +--- wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface_dbus_handlers.c.scan-faster 2009-11-29 13:35:44.511309733 -0800 ++++ wpa_supplicant-0.6.8/wpa_supplicant/ctrl_iface_dbus_handlers.c 2009-11-29 13:35:44.518283666 -0800 +@@ -1073,7 +1073,8 @@ DBusMessage * wpas_dbus_iface_select_net + wpa_supplicant_req_scan(wpa_s, 0, 0); + } else { + const char *obj_path; +- int nid; ++ int nid, timeout, do_scan = 1; ++ struct os_time now; + + if (!dbus_message_get_args(message, NULL, + DBUS_TYPE_OBJECT_PATH, &op, +@@ -1124,7 +1125,22 @@ DBusMessage * wpas_dbus_iface_select_net + } + wpa_s->disconnected = 0; + wpa_s->reassociate = 1; +- wpa_supplicant_req_scan(wpa_s, 0, 0); ++ ++ /* Just associate and don't request a scan if the latest ++ * scan results are less than 10 seconds old. ++ */ ++ if (os_get_time(&now) == 0) { ++ now.sec -= 10; ++ if (os_time_before(&now, &(wpa_s->last_scan))) { ++ if (wpa_supplicant_select_bss_and_associate ( ++ wpa_s, &timeout) >= 0) { ++ do_scan = 0; ++ } ++ } ++ } ++ ++ if (do_scan) ++ wpa_supplicant_req_scan(wpa_s, 0, 0); + } + + reply = wpas_dbus_new_success_reply(message); +diff -up wpa_supplicant-0.6.8/wpa_supplicant/events.c.scan-faster wpa_supplicant-0.6.8/wpa_supplicant/events.c +--- wpa_supplicant-0.6.8/wpa_supplicant/events.c.scan-faster 2009-11-29 13:35:44.512309091 -0800 ++++ wpa_supplicant-0.6.8/wpa_supplicant/events.c 2009-11-29 13:47:07.789286282 -0800 +@@ -683,43 +683,17 @@ wpa_supplicant_select_bss(struct wpa_sup + } + + +-static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s) +-{ +- int prio, timeout; +- struct wpa_scan_res *selected = NULL; +- struct wpa_ssid *ssid = NULL; ++/* Returns 0 on success; -1 when no BSS has been selected */ ++int ++wpa_supplicant_select_bss_and_associate (struct wpa_supplicant *wpa_s, ++ int *out_timeout) ++ { ++ struct wpa_scan_res *selected = NULL; ++ struct wpa_ssid *ssid = NULL; ++ int prio; + int qual = 0, max_qual = 0, qual_valid = 0, bssid_valid = 0, i; + struct cur_ap cur; + +- wpa_supplicant_notify_scanning(wpa_s, 0); +- +- if (wpa_supplicant_get_scan_results(wpa_s) < 0) { +- if (wpa_s->conf->ap_scan == 2) +- return; +- wpa_printf(MSG_DEBUG, "Failed to get scan results - try " +- "scanning again"); +- timeout = 1; +- goto req_scan; +- } +- +- /* +- * Don't post the results if this was the initial cached +- * and there were no results. +- */ +- if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 && +- wpa_s->scan_res->num == 0) { +- wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are " +- "empty - not posting"); +- } else { +- wpa_msg(wpa_s, MSG_DEBUG, WPA_EVENT_SCAN_RESULTS); +- wpa_supplicant_dbus_notify_scan_results(wpa_s); +- wpas_wps_notify_scan_results(wpa_s); +- } +- +- if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)) || +- wpa_s->disconnected) +- return; +- + /* Get current driver BSSID and signal strength */ + os_memset(&cur, 0, sizeof(cur)); + +@@ -772,40 +746,84 @@ static void wpa_supplicant_event_scan_re + } + } + +- if (selected) { +- if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { +- wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP +- "PBC session overlap"); +- timeout = 10; +- goto req_scan; +- } +- +- /* 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 || +- (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; +- } +- wpa_supplicant_associate(wpa_s, selected, ssid); +- } else { +- wpa_printf(MSG_DEBUG, "Already associated with the " +- "selected AP."); ++ if (!selected) { ++ *out_timeout = 5; ++ return -1; ++ } ++ ++ if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { ++ wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP ++ "PBC session overlap"); ++ *out_timeout = 10; ++ return -1; ++ } ++ ++ /* 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 || ++ (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)) { ++ *out_timeout = 10; ++ return -1; + } +- rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res); ++ wpa_supplicant_associate(wpa_s, selected, ssid); + } else { +- wpa_printf(MSG_DEBUG, "No suitable AP found."); +- timeout = 5; ++ wpa_printf(MSG_DEBUG, "Already associated with the " ++ "selected AP."); ++ } ++ ++ return 0; ++} ++ ++static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s) ++{ ++ int timeout; ++ ++ wpa_supplicant_notify_scanning(wpa_s, 0); ++ ++ if (wpa_supplicant_get_scan_results(wpa_s) < 0) { ++ if (wpa_s->conf->ap_scan == 2) ++ return; ++ wpa_printf(MSG_DEBUG, "Failed to get scan results - try " ++ "scanning again"); ++ timeout = 1; + goto req_scan; + } + +- return; ++ /* ++ * Don't post the results if this was the initial cached ++ * and there were no results. ++ */ ++ if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1 && ++ wpa_s->scan_res->num == 0) { ++ wpa_msg(wpa_s, MSG_DEBUG, "Cached scan results are " ++ "empty - not posting"); ++ } else { ++ wpa_msg(wpa_s, MSG_DEBUG, WPA_EVENT_SCAN_RESULTS); ++ wpa_supplicant_dbus_notify_scan_results(wpa_s); ++ wpas_wps_notify_scan_results(wpa_s); ++ } ++ ++ /* Update scan timestamp if there are any scan results */ ++ if (wpa_s->scan_res->num > 0) ++ os_get_time(&(wpa_s->last_scan)); ++ ++ if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)) || ++ wpa_s->disconnected) ++ return; ++ ++ /* Find a BSS and kick off an association with it */ ++ if (wpa_supplicant_select_bss_and_associate(wpa_s, &timeout) == 0) { ++ rsn_preauth_scan_results(wpa_s->wpa, wpa_s->scan_res); ++ return; ++ } else { ++ wpa_printf(MSG_DEBUG, "No suitable AP found."); ++ } + + req_scan: + if (wpa_s->scan_res_tried == 1 && wpa_s->conf->ap_scan == 1) { +diff -up wpa_supplicant-0.6.8/wpa_supplicant/wpa_supplicant_i.h.scan-faster wpa_supplicant-0.6.8/wpa_supplicant/wpa_supplicant_i.h +--- wpa_supplicant-0.6.8/wpa_supplicant/wpa_supplicant_i.h.scan-faster 2009-11-29 13:35:44.514283924 -0800 ++++ wpa_supplicant-0.6.8/wpa_supplicant/wpa_supplicant_i.h 2009-11-29 13:35:44.520285108 -0800 +@@ -347,6 +347,7 @@ struct wpa_supplicant { + * to speed up the first association if the driver + * has already available scan results. */ + int scan_runs; /* number of scan runs since WPS was started */ ++ struct os_time last_scan; /* timestamp of last scan results */ + + struct wpa_client_mlme mlme; + int use_client_mlme; +@@ -415,6 +416,8 @@ void wpa_supplicant_notify_scanning(stru + + /* events.c */ + void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s); ++int wpa_supplicant_select_bss_and_associate (struct wpa_supplicant *wpa_s, ++ int *out_timeout); + + /* driver_ops */ + static inline void * wpa_drv_init(struct wpa_supplicant *wpa_s, diff --git a/wpa_supplicant.spec b/wpa_supplicant.spec index f579167..0b059f0 100644 --- a/wpa_supplicant.spec +++ b/wpa_supplicant.spec @@ -2,7 +2,7 @@ Summary: WPA/WPA2/IEEE 802.1X Supplicant Name: wpa_supplicant Epoch: 1 Version: 0.6.8 -Release: 6%{?dist} +Release: 7%{?dist} License: BSD Group: System Environment/Base Source0: http://hostap.epitest.fi/releases/%{name}-%{version}.tar.gz @@ -22,6 +22,8 @@ Patch7: wpa_supplicant-0.6.8-disconnect-init-deinit.patch Patch8: wpa_supplicant-0.6.8-handle-driver-disconnect-spam.patch Patch9: wpa_supplicant-0.6.8-ap-stability.patch Patch10: wpa_supplicant-0.6.8-scanning-property.patch +Patch11: wpa_supplicant-0.6.9-scan-faster.patch +Patch12: wpa_supplicant-0.6.9-eapol-race-fix.patch URL: http://w1.fi/wpa_supplicant/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -59,6 +61,8 @@ Graphical User Interface for wpa_supplicant written using QT3 %patch8 -p1 -b .disconnect-spam %patch9 -p1 -b .ap-stability %patch10 -p1 -b .scanning-property +%patch11 -p1 -b .scan-faster +%patch12 -p1 -b .eapol-race-fix %build pushd wpa_supplicant @@ -149,6 +153,11 @@ fi %{_bindir}/wpa_gui %changelog +* Sun Nov 29 2009 Dan Williams - 1:0.6.8-7 +- Fix supplicant initscript return value (rh #521807) +- Fix race when connecting to WPA-Enterprise/802.1x-enabled access points (rh #508509) +- Don't double-scan when attempting to associate + * Fri Aug 21 2009 Tomas Mraz - 1:0.6.8-6 - rebuilt with new openssl diff --git a/wpa_supplicant.sysconfig b/wpa_supplicant.sysconfig index 10820b6..23fc1e7 100644 --- a/wpa_supplicant.sysconfig +++ b/wpa_supplicant.sysconfig @@ -9,4 +9,8 @@ DRIVERS="" # Other arguments # -u Enable the D-Bus interface (required for use with NetworkManager) # -f Log to /var/log/wpa_supplicant.log -OTHER_ARGS="-u -f /var/log/wpa_supplicant.log" +# -P Write pid file to /var/run/wpa_supplicant.pid +# required to return proper codes by init scripts (e.g. double "start" action) +# -B to daemonize that has to be used together with -P is already in wpa_supplicant.init.d +OTHER_ARGS="-u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplicant.pid" +