[pkg-wpa-devel] r1547 - in /hostapd/trunk: debian/ hostapd/ src/ap/ src/common/ src/crypto/ src/drivers/ src/eap_peer/ src/eap_server/ src/l2_packet/ src/rsn_supp/ src/tls/ src/utils/ src/wps/

jandd at users.alioth.debian.org jandd at users.alioth.debian.org
Tue Sep 7 17:48:55 UTC 2010


Author: jandd
Date: Tue Sep  7 17:48:37 2010
New Revision: 1547

URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=1547
Log:
New upstream release, upstream declares this as the new stable release.

Modified:
    hostapd/trunk/debian/changelog
    hostapd/trunk/hostapd/ChangeLog
    hostapd/trunk/hostapd/Makefile
    hostapd/trunk/hostapd/README-WPS
    hostapd/trunk/hostapd/ctrl_iface.c
    hostapd/trunk/hostapd/hostapd.conf
    hostapd/trunk/hostapd/hostapd_cli.c
    hostapd/trunk/src/ap/ap_config.c
    hostapd/trunk/src/ap/beacon.c
    hostapd/trunk/src/ap/hostapd.c
    hostapd/trunk/src/ap/hostapd.h
    hostapd/trunk/src/ap/ieee802_11.c
    hostapd/trunk/src/ap/ieee802_11.h
    hostapd/trunk/src/ap/ieee802_11_ht.c
    hostapd/trunk/src/ap/ieee802_1x.c
    hostapd/trunk/src/ap/wpa_auth.c
    hostapd/trunk/src/ap/wpa_auth_ft.c
    hostapd/trunk/src/ap/wpa_auth_glue.c
    hostapd/trunk/src/ap/wps_hostapd.c
    hostapd/trunk/src/ap/wps_hostapd.h
    hostapd/trunk/src/common/version.h
    hostapd/trunk/src/common/wpa_ctrl.h
    hostapd/trunk/src/crypto/crypto_openssl.c
    hostapd/trunk/src/drivers/driver_atheros.c
    hostapd/trunk/src/drivers/driver_nl80211.c
    hostapd/trunk/src/eap_peer/eap_wsc.c
    hostapd/trunk/src/eap_server/eap_server_fast.c
    hostapd/trunk/src/eap_server/eap_server_wsc.c
    hostapd/trunk/src/l2_packet/l2_packet_ndis.c
    hostapd/trunk/src/rsn_supp/preauth.c
    hostapd/trunk/src/rsn_supp/wpa.c
    hostapd/trunk/src/tls/x509v3.c
    hostapd/trunk/src/tls/x509v3.h
    hostapd/trunk/src/utils/eloop.c
    hostapd/trunk/src/utils/os_unix.c
    hostapd/trunk/src/wps/wps.c
    hostapd/trunk/src/wps/wps.h
    hostapd/trunk/src/wps/wps_attr_build.c
    hostapd/trunk/src/wps/wps_attr_parse.c
    hostapd/trunk/src/wps/wps_attr_process.c
    hostapd/trunk/src/wps/wps_defs.h
    hostapd/trunk/src/wps/wps_enrollee.c
    hostapd/trunk/src/wps/wps_er.c
    hostapd/trunk/src/wps/wps_er.h
    hostapd/trunk/src/wps/wps_i.h
    hostapd/trunk/src/wps/wps_registrar.c
    hostapd/trunk/src/wps/wps_upnp.c
    hostapd/trunk/src/wps/wps_upnp.h
    hostapd/trunk/src/wps/wps_upnp_web.c

Modified: hostapd/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/debian/changelog?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/debian/changelog (original)
+++ hostapd/trunk/debian/changelog Tue Sep  7 17:48:37 2010
@@ -1,3 +1,9 @@
+hostapd (1:0.7.3-1) experimental; urgency=low
+
+  * New upstream release, upstream declares this as the new stable release.
+
+ -- Jan Dittberner <jandd at debian.org>  Tue, 07 Sep 2010 19:46:52 +0200
+
 hostapd (1:0.7.2-2) experimental; urgency=low
 
   * disable madwifi driver

Modified: hostapd/trunk/hostapd/ChangeLog
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ChangeLog?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ChangeLog (original)
+++ hostapd/trunk/hostapd/ChangeLog Tue Sep  7 17:48:37 2010
@@ -1,4 +1,20 @@
 ChangeLog for hostapd
+
+2010-09-07 - v0.7.3
+	* fixed re-association after WPS not initializing WPA state machine in
+	  some cases
+	* fixed WPS IE update on reconfiguration
+	* fixed WPS code not to proxy Probe Request frames for foreign SSIDs
+	* added WPS workaround for open networks and some known interop issues
+	* fixed WPS Diffie-Hellman derivation to use correct public key length
+	* fixed FT RRB messages on big endian CPUs
+	* changed WPS protection for brute force AP PIN attacks to disable AP
+	  PIN only temporarily (but with increasing time) to avoid usability
+	  issues on Label-only devices
+	* added wps_ap_pin command for more secure handling of AP PIN
+	  operations (e.g., to generate a random AP PIN and only use it for
+	  short amount of time)
+	* fixed HT STBC negotiation
 
 2010-04-18 - v0.7.2
 	* fix WPS internal Registrar use when an external Registrar is also

Modified: hostapd/trunk/hostapd/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/Makefile?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/hostapd/Makefile (original)
+++ hostapd/trunk/hostapd/Makefile Tue Sep  7 17:48:37 2010
@@ -694,10 +694,10 @@
 OBJS += ../src/ap/ap_list.o
 OBJS += ../src/ap/ieee802_11.o
 OBJS += ../src/ap/hw_features.o
+CFLAGS += -DNEED_AP_MLME
+endif
 ifdef CONFIG_IEEE80211N
 OBJS += ../src/ap/ieee802_11_ht.o
-endif
-CFLAGS += -DNEED_AP_MLME
 endif
 
 ifdef CONFIG_NO_STDOUT_DEBUG

Modified: hostapd/trunk/hostapd/README-WPS
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/README-WPS?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/hostapd/README-WPS (original)
+++ hostapd/trunk/hostapd/README-WPS Tue Sep  7 17:48:37 2010
@@ -195,6 +195,33 @@
 described above.
 
 
+When an external Registrar is used, the AP can act as an Enrollee and
+use its AP PIN. A static AP PIN (e.g., one one a label in the AP
+device) can be configured in hostapd.conf (ap_pin parameter). A more
+secure option is to use hostapd_cli wps_ap_pin command to enable the
+AP PIN only based on user action (and even better security by using a
+random AP PIN for each session, i.e., by using "wps_ap_pin random"
+command with a timeout value). Following commands are available for
+managing the dynamic AP PIN operations:
+
+hostapd_cli wps_ap_pin disable
+- disable AP PIN (i.e., do not allow external Registrars to use it to
+  learn the current AP settings or to reconfigure the AP)
+
+hostapd_cli wps_ap_pin random [timeout]
+- generate a random AP PIN and enable it
+- if the optional timeout parameter is given, the AP PIN will be enabled
+  for the specified number of seconds
+
+hostapd_cli wps_ap_pin get
+- fetch the current AP PIN
+
+hostapd_cli wps_ap_pin set <PIN> [timeout]
+- set the AP PIN and enable it
+- if the optional timeout parameter is given, the AP PIN will be enabled
+  for the specified number of seconds
+
+
 Credential generation and configuration changes
 -----------------------------------------------
 

Modified: hostapd/trunk/hostapd/ctrl_iface.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/ctrl_iface.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/hostapd/ctrl_iface.c (original)
+++ hostapd/trunk/hostapd/ctrl_iface.c Tue Sep  7 17:48:37 2010
@@ -227,7 +227,7 @@
 		os_memcpy(mgmt.da, addr, ETH_ALEN);
 		os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
 		os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
-		mgmt.u.deauth.reason_code =
+		mgmt.u.disassoc.reason_code =
 			host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
 		if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt,
 					     IEEE80211_HDRLEN +
@@ -313,6 +313,59 @@
 	return hostapd_wps_start_oob(hapd, txt, path, method, name);
 }
 #endif /* CONFIG_WPS_OOB */
+
+
+static int hostapd_ctrl_iface_wps_ap_pin(struct hostapd_data *hapd, char *txt,
+					 char *buf, size_t buflen)
+{
+	int timeout = 300;
+	char *pos;
+	const char *pin_txt;
+
+	pos = os_strchr(txt, ' ');
+	if (pos)
+		*pos++ = '\0';
+
+	if (os_strcmp(txt, "disable") == 0) {
+		hostapd_wps_ap_pin_disable(hapd);
+		return os_snprintf(buf, buflen, "OK\n");
+	}
+
+	if (os_strcmp(txt, "random") == 0) {
+		if (pos)
+			timeout = atoi(pos);
+		pin_txt = hostapd_wps_ap_pin_random(hapd, timeout);
+		if (pin_txt == NULL)
+			return -1;
+		return os_snprintf(buf, buflen, "%s", pin_txt);
+	}
+
+	if (os_strcmp(txt, "get") == 0) {
+		pin_txt = hostapd_wps_ap_pin_get(hapd);
+		if (pin_txt == NULL)
+			return -1;
+		return os_snprintf(buf, buflen, "%s", pin_txt);
+	}
+
+	if (os_strcmp(txt, "set") == 0) {
+		char *pin;
+		if (pos == NULL)
+			return -1;
+		pin = pos;
+		pos = os_strchr(pos, ' ');
+		if (pos) {
+			*pos++ = '\0';
+			timeout = atoi(pos);
+		}
+		if (os_strlen(pin) > buflen)
+			return -1;
+		if (hostapd_wps_ap_pin_set(hapd, pin, timeout) < 0)
+			return -1;
+		return os_snprintf(buf, buflen, "%s", pin);
+	}
+
+	return -1;
+}
 #endif /* CONFIG_WPS */
 
 
@@ -426,6 +479,9 @@
 		if (hostapd_ctrl_iface_wps_oob(hapd, buf + 8))
 			reply_len = -1;
 #endif /* CONFIG_WPS_OOB */
+	} else if (os_strncmp(buf, "WPS_AP_PIN ", 11) == 0) {
+		reply_len = hostapd_ctrl_iface_wps_ap_pin(hapd, buf + 11,
+							  reply, reply_size);
 #endif /* CONFIG_WPS */
 	} else {
 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);

Modified: hostapd/trunk/hostapd/hostapd.conf
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/hostapd.conf?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/hostapd/hostapd.conf (original)
+++ hostapd/trunk/hostapd/hostapd.conf Tue Sep  7 17:48:37 2010
@@ -913,9 +913,13 @@
 #	nfc_interface push_button keypad
 #config_methods=label display push_button keypad
 
-# Access point PIN for initial configuration and adding Registrars
+# Static access point PIN for initial configuration and adding Registrars
 # If not set, hostapd will not allow external WPS Registrars to control the
-# access point.
+# access point. The AP PIN can also be set at runtime with hostapd_cli
+# wps_ap_pin command. Use of temporary (enabled by user action) and random
+# AP PIN is much more secure than configuring a static AP PIN here. As such,
+# use of the ap_pin parameter is not recommended if the AP device has means for
+# displaying a random PIN.
 #ap_pin=12345670
 
 # Skip building of automatic WPS credential

Modified: hostapd/trunk/hostapd/hostapd_cli.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/hostapd/hostapd_cli.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/hostapd/hostapd_cli.c (original)
+++ hostapd/trunk/hostapd/hostapd_cli.c Tue Sep  7 17:48:37 2010
@@ -94,6 +94,7 @@
 #ifdef CONFIG_WPS_OOB
 "   wps_oob <type> <path> <method>  use WPS with out-of-band (UFD)\n"
 #endif /* CONFIG_WPS_OOB */
+"   wps_ap_pin <cmd> [params..]  enable/disable AP PIN\n"
 #endif /* CONFIG_WPS */
 "   help                 show this usage help\n"
 "   interface [ifname]   show interfaces/select interface\n"
@@ -405,6 +406,27 @@
 	return wpa_ctrl_command(ctrl, cmd);
 }
 #endif /* CONFIG_WPS_OOB */
+
+
+static int hostapd_cli_cmd_wps_ap_pin(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	char buf[64];
+	if (argc < 1) {
+		printf("Invalid 'wps_ap_pin' command - at least one argument "
+		       "is required.\n");
+		return -1;
+	}
+	if (argc > 2)
+		snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s %s",
+			 argv[0], argv[1], argv[2]);
+	else if (argc > 1)
+		snprintf(buf, sizeof(buf), "WPS_AP_PIN %s %s",
+			 argv[0], argv[1]);
+	else
+		snprintf(buf, sizeof(buf), "WPS_AP_PIN %s", argv[0]);
+	return wpa_ctrl_command(ctrl, buf);
+}
 #endif /* CONFIG_WPS */
 
 
@@ -567,6 +589,7 @@
 #ifdef CONFIG_WPS_OOB
 	{ "wps_oob", hostapd_cli_cmd_wps_oob },
 #endif /* CONFIG_WPS_OOB */
+	{ "wps_ap_pin", hostapd_cli_cmd_wps_ap_pin },
 #endif /* CONFIG_WPS */
 	{ "help", hostapd_cli_cmd_help },
 	{ "interface", hostapd_cli_cmd_interface },

Modified: hostapd/trunk/src/ap/ap_config.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/ap_config.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/ap_config.c (original)
+++ hostapd/trunk/src/ap/ap_config.c Tue Sep  7 17:48:37 2010
@@ -354,6 +354,7 @@
 
 	os_free(conf->ssid.wpa_passphrase);
 	os_free(conf->ssid.wpa_psk_file);
+	hostapd_config_free_wep(&conf->ssid.wep);
 #ifdef CONFIG_FULL_DYNAMIC_VLAN
 	os_free(conf->ssid.vlan_tagged_interface);
 #endif /* CONFIG_FULL_DYNAMIC_VLAN */
@@ -566,15 +567,15 @@
 		return &wsc_enrollee;
 	}
 
-	if (conf->wps_state && conf->ap_pin &&
-	    identity_len == WSC_ID_REGISTRAR_LEN &&
+	if (conf->wps_state && identity_len == WSC_ID_REGISTRAR_LEN &&
 	    os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) {
 		static struct hostapd_eap_user wsc_registrar;
 		os_memset(&wsc_registrar, 0, sizeof(wsc_registrar));
 		wsc_registrar.methods[0].method = eap_server_get_type(
 			"WSC", &wsc_registrar.methods[0].vendor);
 		wsc_registrar.password = (u8 *) conf->ap_pin;
-		wsc_registrar.password_len = os_strlen(conf->ap_pin);
+		wsc_registrar.password_len = conf->ap_pin ?
+			os_strlen(conf->ap_pin) : 0;
 		return &wsc_registrar;
 	}
 #endif /* CONFIG_WPS */

Modified: hostapd/trunk/src/ap/beacon.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/beacon.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/beacon.c (original)
+++ hostapd/trunk/src/ap/beacon.c Tue Sep  7 17:48:37 2010
@@ -57,7 +57,8 @@
 		}
 		break;
 	}
-	if (hapd->iface->num_sta_no_short_preamble > 0)
+	if (hapd->iface->num_sta_no_short_preamble > 0 ||
+	    hapd->iconf->preamble == LONG_PREAMBLE)
 		erp |= ERP_INFO_BARKER_PREAMBLE_MODE;
 
 	return erp;
@@ -308,15 +309,16 @@
 	/* Extended supported rates */
 	pos = hostapd_eid_ext_supp_rates(hapd, pos);
 
+	/* RSN, MDIE, WPA */
 	pos = hostapd_eid_wpa(hapd, pos, epos - pos, sta);
-
-	/* Wi-Fi Alliance WMM */
-	pos = hostapd_eid_wmm(hapd, pos);
 
 #ifdef CONFIG_IEEE80211N
 	pos = hostapd_eid_ht_capabilities(hapd, pos);
 	pos = hostapd_eid_ht_operation(hapd, pos);
 #endif /* CONFIG_IEEE80211N */
+
+	/* Wi-Fi Alliance WMM */
+	pos = hostapd_eid_wmm(hapd, pos);
 
 #ifdef CONFIG_WPS
 	if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) {
@@ -408,16 +410,17 @@
 	/* Extended supported rates */
 	tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos);
 
+	/* RSN, MDIE, WPA */
 	tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE -
 				  tailpos, NULL);
-
-	/* Wi-Fi Alliance WMM */
-	tailpos = hostapd_eid_wmm(hapd, tailpos);
 
 #ifdef CONFIG_IEEE80211N
 	tailpos = hostapd_eid_ht_capabilities(hapd, tailpos);
 	tailpos = hostapd_eid_ht_operation(hapd, tailpos);
 #endif /* CONFIG_IEEE80211N */
+
+	/* Wi-Fi Alliance WMM */
+	tailpos = hostapd_eid_wmm(hapd, tailpos);
 
 #ifdef CONFIG_WPS
 	if (hapd->conf->wps_state && hapd->wps_beacon_ie) {

Modified: hostapd/trunk/src/ap/hostapd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/hostapd.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/hostapd.c (original)
+++ hostapd/trunk/src/ap/hostapd.c Tue Sep  7 17:48:37 2010
@@ -78,6 +78,11 @@
 			   "after reloading configuration");
 	}
 
+	if (hapd->conf->ieee802_1x || hapd->conf->wpa)
+		hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
+	else
+		hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
+
 	if (hapd->conf->wpa && hapd->wpa_auth == NULL)
 		hostapd_setup_wpa(hapd);
 	else if (hapd->conf->wpa) {
@@ -97,6 +102,7 @@
 	}
 
 	ieee802_11_set_beacon(hapd);
+	hostapd_update_wps(hapd);
 
 	if (hapd->conf->ssid.ssid_set &&
 	    hostapd_set_ssid(hapd, (u8 *) hapd->conf->ssid.ssid,
@@ -104,11 +110,6 @@
 		wpa_printf(MSG_ERROR, "Could not set SSID for kernel driver");
 		/* try to continue */
 	}
-
-	if (hapd->conf->ieee802_1x || hapd->conf->wpa)
-		hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 1);
-	else
-		hapd->drv.set_drv_ieee8021x(hapd, hapd->conf->iface, 0);
 
 	hostapd_config_free(oldconf);
 

Modified: hostapd/trunk/src/ap/hostapd.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/hostapd.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/hostapd.h (original)
+++ hostapd/trunk/src/ap/hostapd.h Tue Sep  7 17:48:37 2010
@@ -167,6 +167,7 @@
 #ifdef CONFIG_WPS
 	unsigned int ap_pin_failures;
 	struct upnp_wps_device_sm *wps_upnp;
+	unsigned int ap_pin_lockout_time;
 #endif /* CONFIG_WPS */
 
 	struct hostapd_probereq_cb *probereq_cb;

Modified: hostapd/trunk/src/ap/ieee802_11.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/ieee802_11.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/ieee802_11.c (original)
+++ hostapd/trunk/src/ap/ieee802_11.c Tue Sep  7 17:48:37 2010
@@ -25,6 +25,7 @@
 #include "common/wpa_ctrl.h"
 #include "radius/radius.h"
 #include "radius/radius_client.h"
+#include "wps/wps.h"
 #include "hostapd.h"
 #include "beacon.h"
 #include "ieee802_11_auth.h"
@@ -187,33 +188,6 @@
 			buf[i] = '.';
 	}
 	buf[len] = '\0';
-}
-
-
-/**
- * ieee802_11_send_deauth - Send Deauthentication frame
- * @hapd: hostapd BSS data
- * @addr: Address of the destination STA
- * @reason: Reason code for Deauthentication
- */
-void ieee802_11_send_deauth(struct hostapd_data *hapd, const u8 *addr,
-			    u16 reason)
-{
-	struct ieee80211_mgmt mgmt;
-
-	hostapd_logger(hapd, addr, HOSTAPD_MODULE_IEEE80211,
-		       HOSTAPD_LEVEL_DEBUG,
-		       "deauthenticate - reason %d", reason);
-	os_memset(&mgmt, 0, sizeof(mgmt));
-	mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
-					  WLAN_FC_STYPE_DEAUTH);
-	os_memcpy(mgmt.da, addr, ETH_ALEN);
-	os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN);
-	os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN);
-	mgmt.u.deauth.reason_code = host_to_le16(reason);
-	if (hapd->drv.send_mgmt_frame(hapd, &mgmt, IEEE80211_HDRLEN +
-				       sizeof(mgmt.u.deauth)) < 0)
-		perror("ieee802_11_send_deauth: send");
 }
 
 
@@ -686,8 +660,8 @@
 			   "Request - assume WPS is used");
 		sta->flags |= WLAN_STA_WPS;
 		wpabuf_free(sta->wps_ie);
-		sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4,
-						elems.wps_ie_len - 4);
+		sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
+							  WPS_IE_VENDOR_TYPE);
 		wpa_ie = NULL;
 		wpa_ie_len = 0;
 	} else if (hapd->conf->wps_state && wpa_ie == NULL) {
@@ -850,13 +824,6 @@
 	p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
 	/* Extended supported rates */
 	p = hostapd_eid_ext_supp_rates(hapd, p);
-	if (sta->flags & WLAN_STA_WMM)
-		p = hostapd_eid_wmm(hapd, p);
-
-#ifdef CONFIG_IEEE80211N
-	p = hostapd_eid_ht_capabilities(hapd, p);
-	p = hostapd_eid_ht_operation(hapd, p);
-#endif /* CONFIG_IEEE80211N */
 
 #ifdef CONFIG_IEEE80211R
 	if (status_code == WLAN_STATUS_SUCCESS) {
@@ -872,6 +839,25 @@
 	if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
 		p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
 #endif /* CONFIG_IEEE80211W */
+
+#ifdef CONFIG_IEEE80211N
+	p = hostapd_eid_ht_capabilities(hapd, p);
+	p = hostapd_eid_ht_operation(hapd, p);
+#endif /* CONFIG_IEEE80211N */
+
+	if (sta->flags & WLAN_STA_WMM)
+		p = hostapd_eid_wmm(hapd, p);
+
+#ifdef CONFIG_WPS
+	if (sta->flags & WLAN_STA_WPS) {
+		struct wpabuf *wps = wps_build_assoc_resp_ie();
+		if (wps) {
+			os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
+			p += wpabuf_len(wps);
+			wpabuf_free(wps);
+		}
+	}
+#endif /* CONFIG_WPS */
 
 	send_len += p - reply->u.assoc_resp.variable;
 

Modified: hostapd/trunk/src/ap/ieee802_11.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/ieee802_11.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/ieee802_11.h (original)
+++ hostapd/trunk/src/ap/ieee802_11.h Tue Sep  7 17:48:37 2010
@@ -21,8 +21,6 @@
 struct hostapd_frame_info;
 struct ieee80211_ht_capabilities;
 
-void ieee802_11_send_deauth(struct hostapd_data *hapd, const u8 *addr,
-			    u16 reason);
 void ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
 		     struct hostapd_frame_info *fi);
 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,

Modified: hostapd/trunk/src/ap/ieee802_11_ht.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/ieee802_11_ht.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/ieee802_11_ht.c (original)
+++ hostapd/trunk/src/ap/ieee802_11_ht.c Tue Sep  7 17:48:37 2010
@@ -30,7 +30,7 @@
 	struct ieee80211_ht_capabilities *cap;
 	u8 *pos = eid;
 
-	if (!hapd->iconf->ieee80211n)
+	if (!hapd->iconf->ieee80211n || !hapd->iface->current_mode)
 		return eid;
 
 	*pos++ = WLAN_EID_HT_CAP;
@@ -256,7 +256,15 @@
 	cap &= hapd->iconf->ht_capab;
 	cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_DISABLED);
 
-	/* FIXME: Rx STBC needs to be handled specially */
-	cap |= (hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK);
+	/*
+	 * STBC needs to be handled specially
+	 * if we don't support RX STBC, mask out TX STBC in the STA's HT caps
+	 * if we don't support TX STBC, mask out RX STBC in the STA's HT caps
+	 */
+	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_RX_STBC_MASK))
+		cap &= ~HT_CAP_INFO_TX_STBC;
+	if (!(hapd->iconf->ht_capab & HT_CAP_INFO_TX_STBC))
+		cap &= ~HT_CAP_INFO_RX_STBC_MASK;
+
 	neg_ht_cap->ht_capabilities_info = host_to_le16(cap);
 }

Modified: hostapd/trunk/src/ap/ieee802_1x.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/ieee802_1x.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/ieee802_1x.c (original)
+++ hostapd/trunk/src/ap/ieee802_1x.c Tue Sep  7 17:48:37 2010
@@ -23,6 +23,7 @@
 #include "radius/radius.h"
 #include "radius/radius_client.h"
 #include "eap_server/eap.h"
+#include "eap_common/eap_wsc_common.h"
 #include "eapol_auth/eapol_auth_sm.h"
 #include "eapol_auth/eapol_auth_sm_i.h"
 #include "hostapd.h"
@@ -646,8 +647,7 @@
 	if (sta->flags & WLAN_STA_PREAUTH)
 		flags |= EAPOL_SM_PREAUTH;
 	if (sta->wpa_sm) {
-		if (wpa_auth_sta_get_pmksa(sta->wpa_sm))
-			flags |= EAPOL_SM_USES_WPA;
+		flags |= EAPOL_SM_USES_WPA;
 		if (wpa_auth_sta_get_pmksa(sta->wpa_sm))
 			flags |= EAPOL_SM_FROM_PMKSA_CACHE;
 	}
@@ -1456,6 +1456,30 @@
 static void ieee802_1x_eapol_send(void *ctx, void *sta_ctx, u8 type,
 				  const u8 *data, size_t datalen)
 {
+#ifdef CONFIG_WPS
+	struct sta_info *sta = sta_ctx;
+
+	if ((sta->flags & (WLAN_STA_WPS | WLAN_STA_MAYBE_WPS)) ==
+	    WLAN_STA_MAYBE_WPS) {
+		const u8 *identity;
+		size_t identity_len;
+		struct eapol_state_machine *sm = sta->eapol_sm;
+
+		identity = eap_get_identity(sm->eap, &identity_len);
+		if (identity &&
+		    ((identity_len == WSC_ID_ENROLLEE_LEN &&
+		      os_memcmp(identity, WSC_ID_ENROLLEE,
+				WSC_ID_ENROLLEE_LEN) == 0) ||
+		     (identity_len == WSC_ID_REGISTRAR_LEN &&
+		      os_memcmp(identity, WSC_ID_REGISTRAR,
+				WSC_ID_REGISTRAR_LEN) == 0))) {
+			wpa_printf(MSG_DEBUG, "WPS: WLAN_STA_MAYBE_WPS -> "
+				   "WLAN_STA_WPS");
+			sta->flags |= WLAN_STA_WPS;
+		}
+	}
+#endif /* CONFIG_WPS */
+
 	ieee802_1x_send(ctx, sta_ctx, type, data, datalen);
 }
 
@@ -1979,4 +2003,23 @@
 			       HOSTAPD_LEVEL_DEBUG,
 			       "Added PMKSA cache entry (IEEE 802.1X)");
 	}
-}
+
+#ifdef CONFIG_WPS
+	if (!success && (sta->flags & WLAN_STA_WPS)) {
+		/*
+		 * Many devices require deauthentication after WPS provisioning
+		 * and some may not be be able to do that themselves, so
+		 * disconnect the client here.
+		 */
+		wpa_printf(MSG_DEBUG, "WPS: Force disconnection after "
+			   "EAP-Failure");
+		/* Add a small sleep to increase likelihood of previously
+		 * requested EAP-Failure TX getting out before this should the
+		 * driver reorder operations.
+		 */
+		os_sleep(0, 10000);
+		ap_sta_disconnect(hapd, sta, sta->addr,
+				  WLAN_REASON_PREV_AUTH_NOT_VALID);
+	}
+#endif /* CONFIG_WPS */
+}

Modified: hostapd/trunk/src/ap/wpa_auth.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/wpa_auth.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/wpa_auth.c (original)
+++ hostapd/trunk/src/ap/wpa_auth.c Tue Sep  7 17:48:37 2010
@@ -1274,6 +1274,24 @@
 		break;
 	case WPA_REAUTH:
 	case WPA_REAUTH_EAPOL:
+		if (!sm->started) {
+			/*
+			 * When using WPS, we may end up here if the STA
+			 * manages to re-associate without the previous STA
+			 * entry getting removed. Consequently, we need to make
+			 * sure that the WPA state machines gets initialized
+			 * properly at this point.
+			 */
+			wpa_printf(MSG_DEBUG, "WPA state machine had not been "
+				   "started - initialize now");
+			sm->started = 1;
+			sm->Init = TRUE;
+			if (wpa_sm_step(sm) == 1)
+				return 1; /* should not really happen */
+			sm->Init = FALSE;
+			sm->AuthenticationRequest = TRUE;
+			break;
+		}
 		if (sm->GUpdateStationKeys) {
 			/*
 			 * Reauthentication cancels the pending group key

Modified: hostapd/trunk/src/ap/wpa_auth_ft.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/wpa_auth_ft.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/wpa_auth_ft.c (original)
+++ hostapd/trunk/src/ap/wpa_auth_ft.c Tue Sep  7 17:48:37 2010
@@ -55,6 +55,7 @@
 {
 	if (wpa_auth->cb.send_ether == NULL)
 		return -1;
+	wpa_printf(MSG_DEBUG, "FT: RRB send to " MACSTR, MAC2STR(dst));
 	return wpa_auth->cb.send_ether(wpa_auth->cb.ctx, dst, ETH_P_RRB,
 				       data, data_len);
 }
@@ -1431,7 +1432,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", r.pmk_r1, PMK_LEN);
 	wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", r.pmk_r1_name,
 		    WPA_PMK_NAME_LEN);
-	r.pairwise = pairwise;
+	r.pairwise = host_to_le16(pairwise);
 
 	if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_RESP_DATA_LEN + 7) / 8,
 		     r.nonce, resp.nonce) < 0) {
@@ -1734,7 +1735,7 @@
 		    WPA_PMK_NAME_LEN);
 	os_get_time(&now);
 	WPA_PUT_LE32(f.timestamp, now.sec);
-	f.pairwise = pairwise;
+	f.pairwise = host_to_le16(pairwise);
 	if (aes_wrap(r1kh->key, (FT_R0KH_R1KH_PUSH_DATA_LEN + 7) / 8,
 		     f.timestamp, frame.timestamp) < 0)
 		return;

Modified: hostapd/trunk/src/ap/wpa_auth_glue.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/wpa_auth_glue.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/wpa_auth_glue.c (original)
+++ hostapd/trunk/src/ap/wpa_auth_glue.c Tue Sep  7 17:48:37 2010
@@ -29,6 +29,12 @@
 #include "ap_drv_ops.h"
 #include "ap_config.h"
 #include "wpa_auth.h"
+
+
+#ifdef CONFIG_IEEE80211R
+static void hostapd_rrb_receive(void *ctx, const u8 *src_addr, const u8 *buf,
+				size_t len);
+#endif /* CONFIG_IEEE80211R */
 
 
 static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
@@ -294,10 +300,65 @@
 }
 
 
+#ifdef CONFIG_IEEE80211R
+
+struct wpa_auth_ft_iface_iter_data {
+	struct hostapd_data *src_hapd;
+	const u8 *dst;
+	const u8 *data;
+	size_t data_len;
+};
+
+
+static int hostapd_wpa_auth_ft_iter(struct hostapd_iface *iface, void *ctx)
+{
+	struct wpa_auth_ft_iface_iter_data *idata = ctx;
+	struct hostapd_data *hapd;
+	size_t j;
+
+	for (j = 0; j < iface->num_bss; j++) {
+		hapd = iface->bss[j];
+		if (hapd == idata->src_hapd)
+			continue;
+		if (os_memcmp(hapd->own_addr, idata->dst, ETH_ALEN) == 0) {
+			wpa_printf(MSG_DEBUG, "FT: Send RRB data directly to "
+				   "locally managed BSS " MACSTR "@%s -> "
+				   MACSTR "@%s",
+				   MAC2STR(idata->src_hapd->own_addr),
+				   idata->src_hapd->conf->iface,
+				   MAC2STR(hapd->own_addr), hapd->conf->iface);
+			hostapd_rrb_receive(hapd, idata->src_hapd->own_addr,
+					    idata->data, idata->data_len);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_IEEE80211R */
+
+
 static int hostapd_wpa_auth_send_ether(void *ctx, const u8 *dst, u16 proto,
 				       const u8 *data, size_t data_len)
 {
 	struct hostapd_data *hapd = ctx;
+
+#ifdef CONFIG_IEEE80211R
+	if (proto == ETH_P_RRB && hapd->iface->for_each_interface) {
+		int res;
+		struct wpa_auth_ft_iface_iter_data idata;
+		idata.src_hapd = hapd;
+		idata.dst = dst;
+		idata.data = data;
+		idata.data_len = data_len;
+		res = hapd->iface->for_each_interface(hapd->iface->interfaces,
+						      hostapd_wpa_auth_ft_iter,
+						      &idata);
+		if (res == 1)
+			return data_len;
+	}
+#endif /* CONFIG_IEEE80211R */
 
 	if (hapd->driver && hapd->driver->send_ether)
 		return hapd->driver->send_ether(hapd->drv_priv, dst,

Modified: hostapd/trunk/src/ap/wps_hostapd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/wps_hostapd.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/wps_hostapd.c (original)
+++ hostapd/trunk/src/ap/wps_hostapd.c Tue Sep  7 17:48:37 2010
@@ -1,6 +1,6 @@
 /*
  * hostapd / WPS integration
- * Copyright (c) 2008-2009, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2008-2010, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -42,6 +42,7 @@
 
 static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr,
 				    const u8 *ie, size_t ie_len);
+static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
 
 
 static int hostapd_wps_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *psk,
@@ -421,20 +422,35 @@
 }
 
 
+static void hostapd_wps_reenable_ap_pin(void *eloop_data, void *user_ctx)
+{
+	struct hostapd_data *hapd = eloop_data;
+
+	if (hapd->conf->ap_setup_locked)
+		return;
+
+	wpa_printf(MSG_DEBUG, "WPS: Re-enable AP PIN");
+	wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
+	hapd->wps->ap_setup_locked = 0;
+	wps_registrar_update_ie(hapd->wps->registrar);
+}
+
+
 static void hostapd_pwd_auth_fail(struct hostapd_data *hapd,
 				  struct wps_event_pwd_auth_fail *data)
 {
-	FILE *f;
-
-	if (!data->enrollee)
+	if (!data->enrollee || hapd->conf->ap_pin == NULL)
 		return;
 
 	/*
 	 * Registrar failed to prove its knowledge of the AP PIN. Lock AP setup
-	 * if this happens multiple times.
+	 * for some time if this happens multiple times to slow down brute
+	 * force attacks.
 	 */
 	hapd->ap_pin_failures++;
-	if (hapd->ap_pin_failures < 4)
+	wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
+		   hapd->ap_pin_failures);
+	if (hapd->ap_pin_failures < 3)
 		return;
 
 	wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_LOCKED);
@@ -442,23 +458,22 @@
 
 	wps_registrar_update_ie(hapd->wps->registrar);
 
-	if (hapd->conf->wps_cred_processing == 1)
-		return;
-
-	f = fopen(hapd->iface->config_fname, "a");
-	if (f == NULL) {
-		wpa_printf(MSG_WARNING, "WPS: Could not append to the current "
-			   "configuration file");
-		return;
-	}
-
-	fprintf(f, "# WPS AP Setup Locked based on possible attack\n");
-	fprintf(f, "ap_setup_locked=1\n");
-	fclose(f);
-
-	/* TODO: dualband AP may need to update multiple configuration files */
-
-	wpa_printf(MSG_DEBUG, "WPS: AP configuration updated");
+	if (!hapd->conf->ap_setup_locked) {
+		if (hapd->ap_pin_lockout_time == 0)
+			hapd->ap_pin_lockout_time = 60;
+		else if (hapd->ap_pin_lockout_time < 365 * 24 * 60 * 60 &&
+			 (hapd->ap_pin_failures % 3) == 0)
+			hapd->ap_pin_lockout_time *= 2;
+
+		wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN for %u seconds",
+			   hapd->ap_pin_lockout_time);
+		eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+		eloop_register_timeout(hapd->ap_pin_lockout_time, 0,
+				       hostapd_wps_reenable_ap_pin, hapd,
+				       NULL);
+	}
+
+	/* TODO: dualband AP may need to update other interfaces */
 }
 
 
@@ -667,6 +682,8 @@
 
 void hostapd_deinit_wps(struct hostapd_data *hapd)
 {
+	eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
+	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
 	if (hapd->wps == NULL)
 		return;
 #ifdef CONFIG_WPS_UPNP
@@ -686,6 +703,17 @@
 }
 
 
+void hostapd_update_wps(struct hostapd_data *hapd)
+{
+	if (hapd->wps == NULL)
+		return;
+	if (hapd->conf->wps_state)
+		wps_registrar_update_ie(hapd->wps->registrar);
+	else
+		hostapd_deinit_wps(hapd);
+}
+
+
 int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
 			const char *pin, int timeout)
 {
@@ -771,9 +799,22 @@
 {
 	struct hostapd_data *hapd = ctx;
 	struct wpabuf *wps_ie;
+	struct ieee802_11_elems elems;
 
 	if (hapd->wps == NULL)
 		return 0;
+
+	if (ieee802_11_parse_elems(ie, ie_len, &elems, 0) == ParseFailed) {
+		wpa_printf(MSG_DEBUG, "WPS: Could not parse ProbeReq from "
+			   MACSTR, MAC2STR(addr));
+		return 0;
+	}
+
+	if (elems.ssid && elems.ssid_len > 0 &&
+	    (elems.ssid_len != hapd->conf->ssid.ssid_len ||
+	     os_memcmp(elems.ssid, hapd->conf->ssid.ssid, elems.ssid_len) !=
+	     0))
+		return 0; /* Not for us */
 
 	wps_ie = ieee802_11_vendor_ie_concat(ie, ie_len, WPS_DEV_OUI_WFA);
 	if (wps_ie == NULL)
@@ -902,3 +943,78 @@
 		return 0;
 	return wps_registrar_get_info(hapd->wps->registrar, addr, buf, buflen);
 }
+
+
+static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
+{
+	struct hostapd_data *hapd = eloop_data;
+	wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
+	hostapd_wps_ap_pin_disable(hapd);
+}
+
+
+static void hostapd_wps_ap_pin_enable(struct hostapd_data *hapd, int timeout)
+{
+	wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
+	hapd->ap_pin_failures = 0;
+	hapd->conf->ap_setup_locked = 0;
+	if (hapd->wps->ap_setup_locked) {
+		wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_AP_SETUP_UNLOCKED);
+		hapd->wps->ap_setup_locked = 0;
+		wps_registrar_update_ie(hapd->wps->registrar);
+	}
+	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
+	if (timeout > 0)
+		eloop_register_timeout(timeout, 0,
+				       hostapd_wps_ap_pin_timeout, hapd, NULL);
+}
+
+
+void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd)
+{
+	wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
+	os_free(hapd->conf->ap_pin);
+	hapd->conf->ap_pin = NULL;
+#ifdef CONFIG_WPS_UPNP
+	upnp_wps_set_ap_pin(hapd->wps_upnp, NULL);
+#endif /* CONFIG_WPS_UPNP */
+	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
+}
+
+
+const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout)
+{
+	unsigned int pin;
+	char pin_txt[9];
+
+	pin = wps_generate_pin();
+	os_snprintf(pin_txt, sizeof(pin_txt), "%u", pin);
+	os_free(hapd->conf->ap_pin);
+	hapd->conf->ap_pin = os_strdup(pin_txt);
+#ifdef CONFIG_WPS_UPNP
+	upnp_wps_set_ap_pin(hapd->wps_upnp, pin_txt);
+#endif /* CONFIG_WPS_UPNP */
+	hostapd_wps_ap_pin_enable(hapd, timeout);
+	return hapd->conf->ap_pin;
+}
+
+
+const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd)
+{
+	return hapd->conf->ap_pin;
+}
+
+
+int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin,
+			   int timeout)
+{
+	os_free(hapd->conf->ap_pin);
+	hapd->conf->ap_pin = os_strdup(pin);
+	if (hapd->conf->ap_pin == NULL)
+		return -1;
+#ifdef CONFIG_WPS_UPNP
+	upnp_wps_set_ap_pin(hapd->wps_upnp, hapd->conf->ap_pin);
+#endif /* CONFIG_WPS_UPNP */
+	hostapd_wps_ap_pin_enable(hapd, timeout);
+	return 0;
+}

Modified: hostapd/trunk/src/ap/wps_hostapd.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/ap/wps_hostapd.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/ap/wps_hostapd.h (original)
+++ hostapd/trunk/src/ap/wps_hostapd.h Tue Sep  7 17:48:37 2010
@@ -1,6 +1,6 @@
 /*
  * hostapd / WPS integration
- * Copyright (c) 2008, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2008-2010, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -20,6 +20,7 @@
 int hostapd_init_wps(struct hostapd_data *hapd,
 		     struct hostapd_bss_config *conf);
 void hostapd_deinit_wps(struct hostapd_data *hapd);
+void hostapd_update_wps(struct hostapd_data *hapd);
 int hostapd_wps_add_pin(struct hostapd_data *hapd, const char *uuid,
 			const char *pin, int timeout);
 int hostapd_wps_button_pushed(struct hostapd_data *hapd);
@@ -27,6 +28,11 @@
 			  char *path, char *method, char *name);
 int hostapd_wps_get_mib_sta(struct hostapd_data *hapd, const u8 *addr,
 			    char *buf, size_t buflen);
+void hostapd_wps_ap_pin_disable(struct hostapd_data *hapd);
+const char * hostapd_wps_ap_pin_random(struct hostapd_data *hapd, int timeout);
+const char * hostapd_wps_ap_pin_get(struct hostapd_data *hapd);
+int hostapd_wps_ap_pin_set(struct hostapd_data *hapd, const char *pin,
+			   int timeout);
 
 #else /* CONFIG_WPS */
 
@@ -37,6 +43,10 @@
 }
 
 static inline void hostapd_deinit_wps(struct hostapd_data *hapd)
+{
+}
+
+static inline void hostapd_update_wps(struct hostapd_data *hapd)
 {
 }
 

Modified: hostapd/trunk/src/common/version.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/version.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/common/version.h (original)
+++ hostapd/trunk/src/common/version.h Tue Sep  7 17:48:37 2010
@@ -1,6 +1,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define VERSION_STR "0.7.2"
+#define VERSION_STR "0.7.3"
 
 #endif /* VERSION_H */

Modified: hostapd/trunk/src/common/wpa_ctrl.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/common/wpa_ctrl.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/common/wpa_ctrl.h (original)
+++ hostapd/trunk/src/common/wpa_ctrl.h Tue Sep  7 17:48:37 2010
@@ -92,6 +92,9 @@
 #define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
 #define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
 #define WPS_EVENT_AP_SETUP_LOCKED "WPS-AP-SETUP-LOCKED "
+#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED "
+#define WPS_EVENT_AP_PIN_ENABLED "WPS-AP-PIN-ENABLED "
+#define WPS_EVENT_AP_PIN_DISABLED "WPS-AP-PIN-DISABLED "
 #define AP_STA_CONNECTED "AP-STA-CONNECTED "
 #define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
 

Modified: hostapd/trunk/src/crypto/crypto_openssl.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/crypto/crypto_openssl.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/crypto/crypto_openssl.c (original)
+++ hostapd/trunk/src/crypto/crypto_openssl.c Tue Sep  7 17:48:37 2010
@@ -434,7 +434,7 @@
 	if (DH_generate_key(dh) != 1)
 		goto err;
 
-	publen = BN_num_bytes(dh->p);
+	publen = BN_num_bytes(dh->pub_key);
 	pubkey = wpabuf_alloc(publen);
 	if (pubkey == NULL)
 		goto err;

Modified: hostapd/trunk/src/drivers/driver_atheros.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_atheros.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_atheros.c (original)
+++ hostapd/trunk/src/drivers/driver_atheros.c Tue Sep  7 17:48:37 2010
@@ -74,6 +74,7 @@
 
 static int madwifi_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
 			      int reason_code);
+static int madwifi_set_privacy(void *priv, int enabled);
 
 static const char * athr_get_ioctl_name(int op)
 {
@@ -343,8 +344,11 @@
 
 	if (!params->enabled) {
 		/* XXX restore state */
-		return set80211param(priv, IEEE80211_PARAM_AUTHMODE,
-			IEEE80211_AUTH_AUTO);
+		if (set80211param(priv, IEEE80211_PARAM_AUTHMODE,
+				  IEEE80211_AUTH_AUTO) < 0)
+			return -1;
+		/* IEEE80211_AUTH_AUTO ends up enabling Privacy; clear that */
+		return madwifi_set_privacy(drv, 0);
 	}
 	if (!params->wpa && !params->ieee802_1x) {
 		hostapd_logger(drv->hapd, NULL, HOSTAPD_MODULE_DRIVER,
@@ -1184,6 +1188,8 @@
 
 	return drv;
 bad:
+	if (drv->sock_recv != NULL && drv->sock_recv != drv->sock_xmit)
+		l2_packet_deinit(drv->sock_recv);
 	if (drv->sock_xmit != NULL)
 		l2_packet_deinit(drv->sock_xmit);
 	if (drv->ioctl_sock >= 0)
@@ -1271,7 +1277,7 @@
 const struct wpa_driver_ops wpa_driver_atheros_ops = {
 	.name			= "atheros",
 	.hapd_init		= madwifi_init,
-	.deinit			= madwifi_deinit,
+	.hapd_deinit		= madwifi_deinit,
 	.set_ieee8021x		= madwifi_set_ieee8021x,
 	.set_privacy		= madwifi_set_privacy,
 	.set_key		= madwifi_set_key,

Modified: hostapd/trunk/src/drivers/driver_nl80211.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/drivers/driver_nl80211.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/drivers/driver_nl80211.c (original)
+++ hostapd/trunk/src/drivers/driver_nl80211.c Tue Sep  7 17:48:37 2010
@@ -101,7 +101,6 @@
 	int disable_11b_rates;
 
 	unsigned int pending_remain_on_chan:1;
-	unsigned int pending_send_action:1;
 	unsigned int added_bridge:1;
 	unsigned int added_if_into_bridge:1;
 
@@ -702,12 +701,28 @@
 	const u8 *bssid = NULL;
 	u16 reason_code = 0;
 
+	mgmt = (const struct ieee80211_mgmt *) frame;
+	if (len >= 24) {
+		bssid = mgmt->bssid;
+
+		if (drv->associated != 0 &&
+		    os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
+		    os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {
+			/*
+			 * We have presumably received this deauth as a
+			 * response to a clear_state_mismatch() outgoing
+			 * deauth.  Don't let it take us offline!
+			 */
+			wpa_printf(MSG_DEBUG, "nl80211: Deauth received "
+				   "from Unknown BSSID " MACSTR " -- ignoring",
+				   MAC2STR(bssid));
+			return;
+		}
+	}
+
 	drv->associated = 0;
 	os_memset(&event, 0, sizeof(event));
 
-	mgmt = (const struct ieee80211_mgmt *) frame;
-	if (len >= 24)
-		bssid = mgmt->bssid;
 	/* Note: Same offset for Reason Code in both frame subtypes */
 	if (len >= 24 + sizeof(mgmt->u.deauth))
 		reason_code = le_to_host16(mgmt->u.deauth.reason_code);
@@ -2422,10 +2437,6 @@
 	wpa_hexdump(MSG_DEBUG, "  * IEs", params->ie, params->ie_len);
 	if (params->ie)
 		NLA_PUT(msg, NL80211_ATTR_IE, params->ie_len, params->ie);
-	/*
-	 * TODO: if multiple auth_alg options enabled, try them one by one if
-	 * the AP rejects authentication due to unknown auth alg
-	 */
 	if (params->auth_alg & WPA_AUTH_ALG_OPEN)
 		type = NL80211_AUTHTYPE_OPEN_SYSTEM;
 	else if (params->auth_alg & WPA_AUTH_ALG_SHARED)
@@ -5002,7 +5013,6 @@
 	wpa_printf(MSG_DEBUG, "nl80211: Action TX command accepted; "
 		   "cookie 0x%llx", (long long unsigned int) cookie);
 	drv->send_action_cookie = cookie;
-	drv->pending_send_action = 1;
 	ret = 0;
 
 nla_put_failure:

Modified: hostapd/trunk/src/eap_peer/eap_wsc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_peer/eap_wsc.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/eap_peer/eap_wsc.c (original)
+++ hostapd/trunk/src/eap_peer/eap_wsc.c Tue Sep  7 17:48:37 2010
@@ -225,6 +225,10 @@
 		wps_registrar_add_pin(data->wps_ctx->registrar, NULL,
 				      cfg.pin, cfg.pin_len, 0);
 	}
+
+	/* Use reduced client timeout for WPS to avoid long wait */
+	if (sm->ClientTimeout > 30)
+		sm->ClientTimeout = 30;
 
 	return data;
 }
@@ -381,6 +385,7 @@
 	u16 message_length = 0;
 	enum wps_process_res res;
 	struct wpabuf tmpbuf;
+	struct wpabuf *r;
 
 	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, reqData,
 			       &len);
@@ -506,7 +511,13 @@
 	}
 
 	eap_wsc_state(data, MESG);
-	return eap_wsc_build_msg(data, ret, id);
+	r = eap_wsc_build_msg(data, ret, id);
+	if (data->state == FAIL && ret->methodState == METHOD_DONE) {
+		/* Use reduced client timeout for WPS to avoid long wait */
+		if (sm->ClientTimeout > 2)
+			sm->ClientTimeout = 2;
+	}
+	return r;
 }
 
 

Modified: hostapd/trunk/src/eap_server/eap_server_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_server/eap_server_fast.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/eap_server/eap_server_fast.c (original)
+++ hostapd/trunk/src/eap_server/eap_server_fast.c Tue Sep  7 17:48:37 2010
@@ -791,6 +791,11 @@
 	
 	/* Note: headers may be misaligned after A-ID */
 
+	if (sm->identity) {
+		eap_fast_put_tlv(buf, PAC_TYPE_I_ID, sm->identity,
+				 sm->identity_len);
+	}
+
 	/* A-ID-Info (inside PAC-Info) */
 	eap_fast_put_tlv(buf, PAC_TYPE_A_ID_INFO, data->srv_id_info,
 			 srv_id_info_len);

Modified: hostapd/trunk/src/eap_server/eap_server_wsc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/eap_server/eap_server_wsc.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/eap_server/eap_server_wsc.c (original)
+++ hostapd/trunk/src/eap_server/eap_server_wsc.c Tue Sep  7 17:48:37 2010
@@ -119,13 +119,19 @@
 		}
 	} else {
 		if (sm->user == NULL || sm->user->password == NULL) {
-			wpa_printf(MSG_INFO, "EAP-WSC: No AP PIN (password) "
-				   "configured for Enrollee functionality");
-			os_free(data);
-			return NULL;
-		}
-		cfg.pin = sm->user->password;
-		cfg.pin_len = sm->user->password_len;
+			/*
+			 * In theory, this should not really be needed, but
+			 * Windows 7 uses Registrar mode to probe AP's WPS
+			 * capabilities before trying to use Enrollee and fails
+			 * if the AP does not allow that probing to happen..
+			 */
+			wpa_printf(MSG_DEBUG, "EAP-WSC: No AP PIN (password) "
+				   "configured for Enrollee functionality - "
+				   "allow for probing capabilities (M1)");
+		} else {
+			cfg.pin = sm->user->password;
+			cfg.pin_len = sm->user->password_len;
+		}
 	}
 	cfg.assoc_wps_ie = sm->assoc_wps_ie;
 	cfg.peer_addr = sm->peer_addr;

Modified: hostapd/trunk/src/l2_packet/l2_packet_ndis.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/l2_packet/l2_packet_ndis.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/l2_packet/l2_packet_ndis.c (original)
+++ hostapd/trunk/src/l2_packet/l2_packet_ndis.c Tue Sep  7 17:48:37 2010
@@ -137,11 +137,17 @@
 		DWORD err = GetLastError();
 #ifndef _WIN32_WCE
 		if (err == ERROR_IO_PENDING) {
-			/* For now, just assume that the packet will be sent in
-			 * time before the next write happens. This could be
-			 * cleaned up at some point to actually wait for
-			 * completion before starting new writes.
-			 */
+			wpa_printf(MSG_DEBUG, "L2(NDISUIO): Wait for pending "
+				   "write to complete");
+			res = GetOverlappedResult(
+				driver_ndis_get_ndisuio_handle(), &overlapped,
+				&written, TRUE);
+			if (!res) {
+				wpa_printf(MSG_DEBUG, "L2(NDISUIO): "
+					   "GetOverlappedResult failed: %d",
+					   (int) GetLastError());
+				return -1;
+			}
 			return 0;
 		}
 #endif /* _WIN32_WCE */

Modified: hostapd/trunk/src/rsn_supp/preauth.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/rsn_supp/preauth.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/rsn_supp/preauth.c (original)
+++ hostapd/trunk/src/rsn_supp/preauth.c Tue Sep  7 17:48:37 2010
@@ -49,8 +49,10 @@
 		return;
 
 	dl_list_for_each_safe(entry, n, &sm->pmksa_candidates,
-			      struct rsn_pmksa_candidate, list)
+			      struct rsn_pmksa_candidate, list) {
+		dl_list_del(&entry->list);
 		os_free(entry);
+	}
 }
 
 
@@ -378,6 +380,7 @@
 	}
 
 	if (cand) {
+		dl_list_del(&cand->list);
 		if (prio < PMKID_CANDIDATE_PRIO_SCAN)
 			cand->priority = prio;
 	} else {

Modified: hostapd/trunk/src/rsn_supp/wpa.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/rsn_supp/wpa.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/rsn_supp/wpa.c (original)
+++ hostapd/trunk/src/rsn_supp/wpa.c Tue Sep  7 17:48:37 2010
@@ -231,6 +231,7 @@
 			wpa_sm_ether_send(sm, sm->bssid, ETH_P_EAPOL,
 					  buf, buflen);
 			os_free(buf);
+			return -2;
 		}
 
 		return -1;
@@ -361,6 +362,7 @@
 	struct wpa_eapol_ie_parse ie;
 	struct wpa_ptk *ptk;
 	u8 buf[8];
+	int res;
 
 	if (wpa_sm_get_network_ctx(sm) == NULL) {
 		wpa_printf(MSG_WARNING, "WPA: No SSID info found (msg 1 of "
@@ -388,7 +390,13 @@
 	}
 #endif /* CONFIG_NO_WPA2 */
 
-	if (wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid))
+	res = wpa_supplicant_get_pmk(sm, src_addr, ie.pmkid);
+	if (res == -2) {
+		wpa_printf(MSG_DEBUG, "RSN: Do not reply to msg 1/4 - "
+			   "requesting full EAP authentication");
+		return;
+	}
+	if (res)
 		goto failed;
 
 	if (sm->renew_snonce) {

Modified: hostapd/trunk/src/tls/x509v3.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/tls/x509v3.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/tls/x509v3.c (original)
+++ hostapd/trunk/src/tls/x509v3.c Tue Sep  7 17:48:37 2010
@@ -22,14 +22,15 @@
 
 static void x509_free_name(struct x509_name *name)
 {
-	os_free(name->cn);
-	os_free(name->c);
-	os_free(name->l);
-	os_free(name->st);
-	os_free(name->o);
-	os_free(name->ou);
+	size_t i;
+
+	for (i = 0; i < name->num_attr; i++) {
+		os_free(name->attr[i].value);
+		name->attr[i].value = NULL;
+		name->attr[i].type = X509_NAME_ATTR_NOT_USED;
+	}
+	name->num_attr = 0;
 	os_free(name->email);
-	name->cn = name->c = name->l = name->st = name->o = name->ou = NULL;
 	name->email = NULL;
 
 	os_free(name->alt_email);
@@ -152,6 +153,7 @@
 int x509_name_compare(struct x509_name *a, struct x509_name *b)
 {
 	int res;
+	size_t i;
 
 	if (!a && b)
 		return -1;
@@ -159,25 +161,20 @@
 		return 1;
 	if (!a && !b)
 		return 0;
-
-	res = x509_str_compare(a->cn, b->cn);
-	if (res)
-		return res;
-	res = x509_str_compare(a->c, b->c);
-	if (res)
-		return res;
-	res = x509_str_compare(a->l, b->l);
-	if (res)
-		return res;
-	res = x509_str_compare(a->st, b->st);
-	if (res)
-		return res;
-	res = x509_str_compare(a->o, b->o);
-	if (res)
-		return res;
-	res = x509_str_compare(a->ou, b->ou);
-	if (res)
-		return res;
+	if (a->num_attr < b->num_attr)
+		return -1;
+	if (a->num_attr > b->num_attr)
+		return 1;
+
+	for (i = 0; i < a->num_attr; i++) {
+		if (a->attr[i].type < b->attr[i].type)
+			return -1;
+		if (a->attr[i].type > b->attr[i].type)
+			return -1;
+		res = x509_str_compare(a->attr[i].value, b->attr[i].value);
+		if (res)
+			return res;
+	}
 	res = x509_str_compare(a->email, b->email);
 	if (res)
 		return res;
@@ -304,7 +301,7 @@
 	struct asn1_hdr hdr;
 	const u8 *pos, *end, *set_pos, *set_end, *seq_pos, *seq_end;
 	struct asn1_oid oid;
-	char **fieldp;
+	char *val;
 
 	/*
 	 * Name ::= CHOICE { RDNSequence }
@@ -334,6 +331,8 @@
 	end = *next = pos + hdr.length;
 
 	while (pos < end) {
+		enum x509_name_attr_type type;
+
 		if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
 		    hdr.class != ASN1_CLASS_UNIVERSAL ||
 		    hdr.tag != ASN1_TAG_SET) {
@@ -381,34 +380,34 @@
 		 * pseudonym, generation qualifier.
 		 * MUST: domainComponent (RFC 2247).
 		 */
-		fieldp = NULL;
+		type = X509_NAME_ATTR_NOT_USED;
 		if (oid.len == 4 &&
 		    oid.oid[0] == 2 && oid.oid[1] == 5 && oid.oid[2] == 4) {
 			/* id-at ::= 2.5.4 */
 			switch (oid.oid[3]) {
 			case 3:
 				/* commonName */
-				fieldp = &name->cn;
+				type = X509_NAME_ATTR_CN;
 				break;
 			case 6:
 				/*  countryName */
-				fieldp = &name->c;
+				type = X509_NAME_ATTR_C;
 				break;
 			case 7:
 				/* localityName */
-				fieldp = &name->l;
+				type = X509_NAME_ATTR_L;
 				break;
 			case 8:
 				/* stateOrProvinceName */
-				fieldp = &name->st;
+				type = X509_NAME_ATTR_ST;
 				break;
 			case 10:
 				/* organizationName */
-				fieldp = &name->o;
+				type = X509_NAME_ATTR_O;
 				break;
 			case 11:
 				/* organizationalUnitName */
-				fieldp = &name->ou;
+				type = X509_NAME_ATTR_OU;
 				break;
 			}
 		} else if (oid.len == 7 &&
@@ -417,10 +416,25 @@
 			   oid.oid[4] == 1 && oid.oid[5] == 9 &&
 			   oid.oid[6] == 1) {
 			/* 1.2.840.113549.1.9.1 - e-mailAddress */
-			fieldp = &name->email;
-		}
-
-		if (fieldp == NULL) {
+			os_free(name->email);
+			name->email = os_malloc(hdr.length + 1);
+			if (name->email == NULL) {
+				x509_free_name(name);
+				return -1;
+			}
+			os_memcpy(name->email, hdr.payload, hdr.length);
+			name->email[hdr.length] = '\0';
+			continue;
+		} else if (oid.len == 7 &&
+			   oid.oid[0] == 0 && oid.oid[1] == 9 &&
+			   oid.oid[2] == 2342 && oid.oid[3] == 19200300 &&
+			   oid.oid[4] == 100 && oid.oid[5] == 1 &&
+			   oid.oid[6] == 25) {
+			/* 0.9.2342.19200300.100.1.25 - domainComponent */
+			type = X509_NAME_ATTR_DC;
+		}
+
+		if (type == X509_NAME_ATTR_NOT_USED) {
 			wpa_hexdump(MSG_DEBUG, "X509: Unrecognized OID",
 				    (u8 *) oid.oid,
 				    oid.len * sizeof(oid.oid[0]));
@@ -429,24 +443,57 @@
 			continue;
 		}
 
-		os_free(*fieldp);
-		*fieldp = os_malloc(hdr.length + 1);
-		if (*fieldp == NULL) {
+		if (name->num_attr == X509_MAX_NAME_ATTRIBUTES) {
+			wpa_printf(MSG_INFO, "X509: Too many Name attributes");
 			x509_free_name(name);
 			return -1;
 		}
-		os_memcpy(*fieldp, hdr.payload, hdr.length);
-		(*fieldp)[hdr.length] = '\0';
-		if (os_strlen(*fieldp) != hdr.length) {
+
+		val = os_malloc(hdr.length + 1);
+		if (val == NULL) {
+			x509_free_name(name);
+			return -1;
+		}
+		os_memcpy(val, hdr.payload, hdr.length);
+		val[hdr.length] = '\0';
+		if (os_strlen(val) != hdr.length) {
 			wpa_printf(MSG_INFO, "X509: Reject certificate with "
 				   "embedded NUL byte in a string (%s[NUL])",
-				   *fieldp);
+				   val);
 			x509_free_name(name);
 			return -1;
 		}
+
+		name->attr[name->num_attr].type = type;
+		name->attr[name->num_attr].value = val;
+		name->num_attr++;
 	}
 
 	return 0;
+}
+
+
+static char * x509_name_attr_str(enum x509_name_attr_type type)
+{
+	switch (type) {
+	case X509_NAME_ATTR_NOT_USED:
+		return "[N/A]";
+	case X509_NAME_ATTR_DC:
+		return "DC";
+	case X509_NAME_ATTR_CN:
+		return "CN";
+	case X509_NAME_ATTR_C:
+		return "C";
+	case X509_NAME_ATTR_L:
+		return "L";
+	case X509_NAME_ATTR_ST:
+		return "ST";
+	case X509_NAME_ATTR_O:
+		return "O";
+	case X509_NAME_ATTR_OU:
+		return "OU";
+	}
+	return "?";
 }
 
 
@@ -460,6 +507,7 @@
 {
 	char *pos, *end;
 	int ret;
+	size_t i;
 
 	if (len == 0)
 		return;
@@ -467,46 +515,20 @@
 	pos = buf;
 	end = buf + len;
 
-	if (name->c) {
-		ret = os_snprintf(pos, end - pos, "C=%s, ", name->c);
+	for (i = 0; i < name->num_attr; i++) {
+		ret = os_snprintf(pos, end - pos, "%s=%s, ",
+				  x509_name_attr_str(name->attr[i].type),
+				  name->attr[i].value);
 		if (ret < 0 || ret >= end - pos)
 			goto done;
 		pos += ret;
 	}
-	if (name->st) {
-		ret = os_snprintf(pos, end - pos, "ST=%s, ", name->st);
-		if (ret < 0 || ret >= end - pos)
-			goto done;
-		pos += ret;
-	}
-	if (name->l) {
-		ret = os_snprintf(pos, end - pos, "L=%s, ", name->l);
-		if (ret < 0 || ret >= end - pos)
-			goto done;
-		pos += ret;
-	}
-	if (name->o) {
-		ret = os_snprintf(pos, end - pos, "O=%s, ", name->o);
-		if (ret < 0 || ret >= end - pos)
-			goto done;
-		pos += ret;
-	}
-	if (name->ou) {
-		ret = os_snprintf(pos, end - pos, "OU=%s, ", name->ou);
-		if (ret < 0 || ret >= end - pos)
-			goto done;
-		pos += ret;
-	}
-	if (name->cn) {
-		ret = os_snprintf(pos, end - pos, "CN=%s, ", name->cn);
-		if (ret < 0 || ret >= end - pos)
-			goto done;
-		pos += ret;
-	}
 
 	if (pos > buf + 1 && pos[-1] == ' ' && pos[-2] == ',') {
-		*pos-- = '\0';
-		*pos-- = '\0';
+		pos--;
+		*pos = '\0';
+		pos--;
+		*pos = '\0';
 	}
 
 	if (name->email) {

Modified: hostapd/trunk/src/tls/x509v3.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/tls/x509v3.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/tls/x509v3.h (original)
+++ hostapd/trunk/src/tls/x509v3.h Tue Sep  7 17:48:37 2010
@@ -21,13 +21,25 @@
 	struct asn1_oid oid;
 };
 
+struct x509_name_attr {
+	enum x509_name_attr_type {
+		X509_NAME_ATTR_NOT_USED,
+		X509_NAME_ATTR_DC,
+		X509_NAME_ATTR_CN,
+		X509_NAME_ATTR_C,
+		X509_NAME_ATTR_L,
+		X509_NAME_ATTR_ST,
+		X509_NAME_ATTR_O,
+		X509_NAME_ATTR_OU
+	} type;
+	char *value;
+};
+
+#define X509_MAX_NAME_ATTRIBUTES 20
+
 struct x509_name {
-	char *cn; /* commonName */
-	char *c; /* countryName */
-	char *l; /* localityName */
-	char *st; /* stateOrProvinceName */
-	char *o; /* organizationName */
-	char *ou; /* organizationalUnitName */
+	struct x509_name_attr attr[X509_MAX_NAME_ATTRIBUTES];
+	size_t num_attr;
 	char *email; /* emailAddress */
 
 	/* from alternative name extension */

Modified: hostapd/trunk/src/utils/eloop.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/eloop.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/utils/eloop.c (original)
+++ hostapd/trunk/src/utils/eloop.c Tue Sep  7 17:48:37 2010
@@ -529,6 +529,8 @@
 		eloop_process_pending_signals();
 
 		/* check if some registered timeouts have occurred */
+		timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
+					list);
 		if (timeout) {
 			os_get_time(&now);
 			if (!os_time_before(&now, &timeout->time)) {

Modified: hostapd/trunk/src/utils/os_unix.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/utils/os_unix.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/utils/os_unix.c (original)
+++ hostapd/trunk/src/utils/os_unix.c Tue Sep  7 17:48:37 2010
@@ -370,7 +370,7 @@
 	if (ptr == NULL)
 		return os_malloc(size);
 
-	a = ptr - sizeof(*a);
+	a = (struct os_alloc_trace *) ptr - 1;
 	if (a->magic != ALLOC_MAGIC) {
 		wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s",
 			   a, a->magic,
@@ -396,7 +396,7 @@
 
 	if (ptr == NULL)
 		return;
-	a = ptr - sizeof(*a);
+	a = (struct os_alloc_trace *) ptr - 1;
 	if (a->magic != ALLOC_MAGIC) {
 		wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s",
 			   a, a->magic,

Modified: hostapd/trunk/src/wps/wps.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps.c (original)
+++ hostapd/trunk/src/wps/wps.c Tue Sep  7 17:48:37 2010
@@ -289,6 +289,39 @@
 
 
 /**
+ * wps_build_assoc_resp_ie - Build WPS IE for (Re)Association Response
+ * Returns: WPS IE or %NULL on failure
+ *
+ * The caller is responsible for freeing the buffer.
+ */
+struct wpabuf * wps_build_assoc_resp_ie(void)
+{
+	struct wpabuf *ie;
+	u8 *len;
+
+	wpa_printf(MSG_DEBUG, "WPS: Building WPS IE for (Re)Association "
+		   "Response");
+	ie = wpabuf_alloc(100);
+	if (ie == NULL)
+		return NULL;
+
+	wpabuf_put_u8(ie, WLAN_EID_VENDOR_SPECIFIC);
+	len = wpabuf_put(ie, 1);
+	wpabuf_put_be32(ie, WPS_DEV_OUI_WFA);
+
+	if (wps_build_version(ie) ||
+	    wps_build_resp_type(ie, WPS_RESP_AP)) {
+		wpabuf_free(ie);
+		return NULL;
+	}
+
+	*len = wpabuf_len(ie) - 2;
+
+	return ie;
+}
+
+
+/**
  * wps_build_probe_req_ie - Build WPS IE for Probe Request
  * @pbc: Whether searching for PBC mode APs
  * @dev: Device attributes

Modified: hostapd/trunk/src/wps/wps.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps.h (original)
+++ hostapd/trunk/src/wps/wps.h Tue Sep  7 17:48:37 2010
@@ -198,6 +198,7 @@
 const u8 * wps_get_uuid_e(const struct wpabuf *msg);
 
 struct wpabuf * wps_build_assoc_req_ie(enum wps_request_type req_type);
+struct wpabuf * wps_build_assoc_resp_ie(void);
 struct wpabuf * wps_build_probe_req_ie(int pbc, struct wps_device_data *dev,
 				       const u8 *uuid,
 				       enum wps_request_type req_type);

Modified: hostapd/trunk/src/wps/wps_attr_build.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_attr_build.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_attr_build.c (original)
+++ hostapd/trunk/src/wps/wps_attr_build.c Tue Sep  7 17:48:37 2010
@@ -74,6 +74,16 @@
 }
 
 
+int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type)
+{
+	wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", type);
+	wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
+	wpabuf_put_be16(msg, 1);
+	wpabuf_put_u8(msg, type);
+	return 0;
+}
+
+
 int wps_build_config_methods(struct wpabuf *msg, u16 methods)
 {
 	wpa_printf(MSG_DEBUG, "WPS:  * Config Methods (%x)", methods);

Modified: hostapd/trunk/src/wps/wps_attr_parse.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_attr_parse.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_attr_parse.c (original)
+++ hostapd/trunk/src/wps/wps_attr_parse.c Tue Sep  7 17:48:37 2010
@@ -17,6 +17,8 @@
 #include "common.h"
 #include "wps_i.h"
 
+#define WPS_WORKAROUNDS
+
 
 static int wps_set_attr(struct wps_parse_attr *attr, u16 type,
 			const u8 *pos, u16 len)
@@ -332,7 +334,7 @@
 				   "length %u", len);
 			return -1;
 		}
-		attr->request_type = pos;
+		attr->response_type = pos;
 		break;
 	case ATTR_MANUFACTURER:
 		attr->manufacturer = pos;
@@ -435,6 +437,25 @@
 			return -1;
 		}
 
+#ifdef WPS_WORKAROUNDS
+		if (type == 0 && len == 0) {
+			/*
+			 * Mac OS X 10.6 seems to be adding 0x00 padding to the
+			 * end of M1. Skip those to avoid interop issues.
+			 */
+			int i;
+			for (i = 0; i < end - pos; i++) {
+				if (pos[i])
+					break;
+			}
+			if (i == end - pos) {
+				wpa_printf(MSG_DEBUG, "WPS: Workaround - skip "
+					   "unexpected message padding");
+				break;
+			}
+		}
+#endif /* WPS_WORKAROUNDS */
+
 		if (wps_set_attr(attr, type, pos, len) < 0)
 			return -1;
 

Modified: hostapd/trunk/src/wps/wps_attr_process.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_attr_process.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_attr_process.c (original)
+++ hostapd/trunk/src/wps/wps_attr_process.c Tue Sep  7 17:48:37 2010
@@ -177,6 +177,13 @@
 	if (key == NULL) {
 		wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
 			   "Network Key");
+		if (cred->auth_type == WPS_AUTH_OPEN &&
+		    cred->encr_type == WPS_ENCR_NONE) {
+			wpa_printf(MSG_DEBUG, "WPS: Workaround - Allow "
+				   "missing mandatory Network Key attribute "
+				   "for open network");
+			return 0;
+		}
 		return -1;
 	}
 

Modified: hostapd/trunk/src/wps/wps_defs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_defs.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_defs.h (original)
+++ hostapd/trunk/src/wps/wps_defs.h Tue Sep  7 17:48:37 2010
@@ -115,7 +115,7 @@
 	ATTR_PERMITTED_CFG_METHODS = 0x1052,
 	ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053,
 	ATTR_PRIMARY_DEV_TYPE = 0x1054,
-	ATTR_SECONDARY_DEV_TYP_ELIST = 0x1055,
+	ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055,
 	ATTR_PORTABLE_DEV = 0x1056,
 	ATTR_AP_SETUP_LOCKED = 0x1057,
 	ATTR_APPLICATION_EXT = 0x1058,

Modified: hostapd/trunk/src/wps/wps_enrollee.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_enrollee.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_enrollee.c (original)
+++ hostapd/trunk/src/wps/wps_enrollee.c Tue Sep  7 17:48:37 2010
@@ -774,18 +774,23 @@
 
 	if (wps_process_registrar_nonce(wps, attr->registrar_nonce) ||
 	    wps_process_enrollee_nonce(wps, attr->enrollee_nonce) ||
-	    wps_process_uuid_r(wps, attr->uuid_r) ||
-	    wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
-	    wps_process_authenticator(wps, attr->authenticator, msg) ||
-	    wps_process_device_attrs(&wps->peer_dev, attr)) {
-		wps->state = SEND_WSC_NACK;
-		return WPS_CONTINUE;
-	}
-
-	if (wps->wps->ap && wps->wps->ap_setup_locked) {
+	    wps_process_uuid_r(wps, attr->uuid_r)) {
+		wps->state = SEND_WSC_NACK;
+		return WPS_CONTINUE;
+	}
+
+	if (wps->wps->ap &&
+	    (wps->wps->ap_setup_locked || wps->dev_password == NULL)) {
 		wpa_printf(MSG_DEBUG, "WPS: AP Setup is locked - refuse "
 			   "registration of a new Registrar");
 		wps->config_error = WPS_CFG_SETUP_LOCKED;
+		wps->state = SEND_WSC_NACK;
+		return WPS_CONTINUE;
+	}
+
+	if (wps_process_pubkey(wps, attr->public_key, attr->public_key_len) ||
+	    wps_process_authenticator(wps, attr->authenticator, msg) ||
+	    wps_process_device_attrs(&wps->peer_dev, attr)) {
 		wps->state = SEND_WSC_NACK;
 		return WPS_CONTINUE;
 	}

Modified: hostapd/trunk/src/wps/wps_er.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_er.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_er.c (original)
+++ hostapd/trunk/src/wps/wps_er.c Tue Sep  7 17:48:37 2010
@@ -85,6 +85,7 @@
 	os_free(sta->dev_name);
 	http_client_free(sta->http);
 	eloop_cancel_timeout(wps_er_sta_timeout, sta, NULL);
+	os_free(sta->cred);
 	os_free(sta);
 }
 
@@ -953,6 +954,17 @@
 		return;
 	sta->wps->er = 1;
 	sta->wps->use_cred = sta->ap->ap_settings;
+	if (sta->ap->ap_settings) {
+		os_free(sta->cred);
+		sta->cred = os_malloc(sizeof(*sta->cred));
+		if (sta->cred) {
+			os_memcpy(sta->cred, sta->ap->ap_settings,
+				  sizeof(*sta->cred));
+			sta->cred->cred_attr = NULL;
+			os_memcpy(sta->cred->mac_addr, sta->addr, ETH_ALEN);
+			sta->wps->use_cred = sta->cred;
+		}
+	}
 
 	wps_er_sta_process(sta, msg, WSC_MSG);
 }
@@ -1160,6 +1172,8 @@
 		wps_er_deinit(er, NULL, NULL);
 		return NULL;
 	}
+	/* Limit event_id to < 32 bits to avoid issues with atoi() */
+	er->event_id &= 0x0fffffff;
 
 	if (get_netif_info(ifname, &er->ip_addr, &er->ip_addr_text,
 			   er->mac_addr)) {

Modified: hostapd/trunk/src/wps/wps_er.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_er.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_er.h (original)
+++ hostapd/trunk/src/wps/wps_er.h Tue Sep  7 17:48:37 2010
@@ -33,6 +33,7 @@
 	char *dev_name;
 	struct wps_data *wps;
 	struct http_client *http;
+	struct wps_credential *cred;
 };
 
 struct wps_er_ap {

Modified: hostapd/trunk/src/wps/wps_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_i.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_i.h (original)
+++ hostapd/trunk/src/wps/wps_i.h Tue Sep  7 17:48:37 2010
@@ -218,6 +218,7 @@
 /* wps_attr_build.c */
 int wps_build_public_key(struct wps_data *wps, struct wpabuf *msg);
 int wps_build_req_type(struct wpabuf *msg, enum wps_request_type type);
+int wps_build_resp_type(struct wpabuf *msg, enum wps_response_type type);
 int wps_build_config_methods(struct wpabuf *msg, u16 methods);
 int wps_build_uuid_e(struct wpabuf *msg, const u8 *uuid);
 int wps_build_dev_password_id(struct wpabuf *msg, u16 id);

Modified: hostapd/trunk/src/wps/wps_registrar.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_registrar.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_registrar.c (original)
+++ hostapd/trunk/src/wps/wps_registrar.c Tue Sep  7 17:48:37 2010
@@ -426,17 +426,6 @@
 }
 
 
-static int wps_build_resp_type(struct wps_registrar *reg, struct wpabuf *msg)
-{
-	u8 resp = reg->wps->ap ? WPS_RESP_AP : WPS_RESP_REGISTRAR;
-	wpa_printf(MSG_DEBUG, "WPS:  * Response Type (%d)", resp);
-	wpabuf_put_be16(msg, ATTR_RESPONSE_TYPE);
-	wpabuf_put_be16(msg, 1);
-	wpabuf_put_u8(msg, resp);
-	return 0;
-}
-
-
 /**
  * wps_registrar_init - Initialize WPS Registrar data
  * @wps: Pointer to longterm WPS context
@@ -940,7 +929,8 @@
 	    wps_build_selected_registrar(reg, probe) ||
 	    wps_build_sel_reg_dev_password_id(reg, probe) ||
 	    wps_build_sel_reg_config_methods(reg, probe) ||
-	    wps_build_resp_type(reg, probe) ||
+	    wps_build_resp_type(probe, reg->wps->ap ? WPS_RESP_AP :
+				WPS_RESP_REGISTRAR) ||
 	    wps_build_uuid_e(probe, reg->wps->uuid) ||
 	    wps_build_device_attrs(&reg->wps->dev, probe) ||
 	    wps_build_probe_config_methods(reg, probe) ||
@@ -2125,6 +2115,23 @@
 		wps->pbc = 1;
 	}
 
+#ifdef WPS_WORKAROUNDS
+	/*
+	 * It looks like Mac OS X 10.6.3 and 10.6.4 do not like Network Key in
+	 * passphrase format. To avoid interop issues, force PSK format to be
+	 * used.
+	 */
+	if (!wps->use_psk_key &&
+	    wps->peer_dev.manufacturer &&
+	    os_strncmp(wps->peer_dev.manufacturer, "Apple ", 6) == 0 &&
+	    wps->peer_dev.model_name &&
+	    os_strcmp(wps->peer_dev.model_name, "AirPort") == 0) {
+		wpa_printf(MSG_DEBUG, "WPS: Workaround - Force Network Key in "
+			   "PSK format");
+		wps->use_psk_key = 1;
+	}
+#endif /* WPS_WORKAROUNDS */
+
 	wps->state = SEND_M2;
 	return WPS_CONTINUE;
 }

Modified: hostapd/trunk/src/wps/wps_upnp.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp.c (original)
+++ hostapd/trunk/src/wps/wps_upnp.c Tue Sep  7 17:48:37 2010
@@ -1074,3 +1074,20 @@
 {
 	return !dl_list_empty(&sm->subscriptions);
 }
+
+
+int upnp_wps_set_ap_pin(struct upnp_wps_device_sm *sm, const char *ap_pin)
+{
+	if (sm == NULL)
+		return 0;
+
+	os_free(sm->ctx->ap_pin);
+	if (ap_pin) {
+		sm->ctx->ap_pin = os_strdup(ap_pin);
+		if (sm->ctx->ap_pin == NULL)
+			return -1;
+	} else
+		sm->ctx->ap_pin = NULL;
+
+	return 0;
+}

Modified: hostapd/trunk/src/wps/wps_upnp.h
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp.h?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp.h (original)
+++ hostapd/trunk/src/wps/wps_upnp.h Tue Sep  7 17:48:37 2010
@@ -46,5 +46,6 @@
 				    enum upnp_wps_wlanevent_type ev_type,
 				    const struct wpabuf *msg);
 int upnp_wps_subscribers(struct upnp_wps_device_sm *sm);
+int upnp_wps_set_ap_pin(struct upnp_wps_device_sm *sm, const char *ap_pin);
 
 #endif /* WPS_UPNP_H */

Modified: hostapd/trunk/src/wps/wps_upnp_web.c
URL: http://svn.debian.org/wsvn/pkg-wpa/hostapd/trunk/src/wps/wps_upnp_web.c?rev=1547&op=diff
==============================================================================
--- hostapd/trunk/src/wps/wps_upnp_web.c (original)
+++ hostapd/trunk/src/wps/wps_upnp_web.c Tue Sep  7 17:48:37 2010
@@ -412,6 +412,9 @@
 
 	wpa_printf(MSG_DEBUG, "WPS UPnP: GetDeviceInfo");
 
+	if (sm->ctx->ap_pin == NULL)
+		return HTTP_INTERNAL_SERVER_ERROR;
+
 	/*
 	 * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS
 	 * registration over UPnP with the AP acting as an Enrollee. It should




More information about the Pkg-wpa-devel mailing list