[pkg-wpa-devel] r1305 - in /wpasupplicant/trunk: debian/ debian/config/ patches/ src/ src/common/ src/crypto/ src/drivers/ src/eap_common/ src/eap_peer/ src/eap_server/ src/eapol_supp/ src/l2_packet/ src/radius/ src/rsn_supp/ src/tls/ src/utils/ src/wps/ wpa_supplicant/ wpa_supplicant/doc/ wpa_supplicant/doc/docbook/ wpa_supplicant/wpa_gui-qt4/ wpa_supplicant/wpa_gui/

kelmo-guest at users.alioth.debian.org kelmo-guest at users.alioth.debian.org
Sat Jan 10 09:03:51 UTC 2009


Author: kelmo-guest
Date: Sat Jan 10 09:03:49 2009
New Revision: 1305

URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=1305
Log:
* New upstream release.
* Enable CONFIG_WPS in debian/config/*.
* Install README-WPS to docs directory.
* Refresh debian/copyright for new years which are covered by
  copyright.

Added:
    wpasupplicant/trunk/src/common/nl80211_copy.h
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/src/common/nl80211_copy.h
    wpasupplicant/trunk/src/eap_common/eap_wsc_common.c
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.c
    wpasupplicant/trunk/src/eap_common/eap_wsc_common.h
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.h
    wpasupplicant/trunk/src/eap_peer/eap_wsc.c
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c
    wpasupplicant/trunk/src/eap_server/eap_wsc.c
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/src/eap_server/eap_wsc.c
    wpasupplicant/trunk/src/wps/
      - copied from r1304, wpasupplicant/branches/upstream/current/src/wps/
    wpasupplicant/trunk/wpa_supplicant/README-WPS
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/wpa_supplicant/README-WPS
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/addinterface.cpp
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/addinterface.h
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_gui-qt4/addinterface.h
    wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.nsi
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.nsi
    wpasupplicant/trunk/wpa_supplicant/wps_supplicant.c
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/wpa_supplicant/wps_supplicant.c
    wpasupplicant/trunk/wpa_supplicant/wps_supplicant.h
      - copied unchanged from r1304, wpasupplicant/branches/upstream/current/wpa_supplicant/wps_supplicant.h
Removed:
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/setup-mingw-cross-compiling
Modified:
    wpasupplicant/trunk/debian/changelog
    wpasupplicant/trunk/debian/config/kfreebsd
    wpasupplicant/trunk/debian/config/linux
    wpasupplicant/trunk/debian/copyright
    wpasupplicant/trunk/debian/wpasupplicant.docs
    wpasupplicant/trunk/patches/openssl-0.9.8i-tls-extensions.patch
    wpasupplicant/trunk/patches/openssl-0.9.9-session-ticket.patch
    wpasupplicant/trunk/src/Makefile
    wpasupplicant/trunk/src/common/defs.h
    wpasupplicant/trunk/src/common/ieee802_11_common.c
    wpasupplicant/trunk/src/common/ieee802_11_common.h
    wpasupplicant/trunk/src/common/ieee802_11_defs.h
    wpasupplicant/trunk/src/common/version.h
    wpasupplicant/trunk/src/common/wpa_ctrl.h
    wpasupplicant/trunk/src/crypto/crypto_internal.c
    wpasupplicant/trunk/src/crypto/ms_funcs.c
    wpasupplicant/trunk/src/crypto/sha1.c
    wpasupplicant/trunk/src/crypto/tls_openssl.c
    wpasupplicant/trunk/src/drivers/Apple80211.h
    wpasupplicant/trunk/src/drivers/driver.h
    wpasupplicant/trunk/src/drivers/driver_ndis.c
    wpasupplicant/trunk/src/drivers/driver_nl80211.c
    wpasupplicant/trunk/src/drivers/driver_privsep.c
    wpasupplicant/trunk/src/drivers/driver_test.c
    wpasupplicant/trunk/src/drivers/driver_wext.c
    wpasupplicant/trunk/src/drivers/ndis_events.c
    wpasupplicant/trunk/src/drivers/scan_helpers.c
    wpasupplicant/trunk/src/eap_common/eap_defs.h
    wpasupplicant/trunk/src/eap_common/eap_peap_common.c
    wpasupplicant/trunk/src/eap_common/eap_sim_common.c
    wpasupplicant/trunk/src/eap_common/eap_sim_common.h
    wpasupplicant/trunk/src/eap_peer/eap.c
    wpasupplicant/trunk/src/eap_peer/eap.h
    wpasupplicant/trunk/src/eap_peer/eap_aka.c
    wpasupplicant/trunk/src/eap_peer/eap_config.h
    wpasupplicant/trunk/src/eap_peer/eap_fast.c
    wpasupplicant/trunk/src/eap_peer/eap_gpsk.c
    wpasupplicant/trunk/src/eap_peer/eap_i.h
    wpasupplicant/trunk/src/eap_peer/eap_methods.c
    wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c
    wpasupplicant/trunk/src/eap_peer/eap_peap.c
    wpasupplicant/trunk/src/eap_peer/eap_tls_common.c
    wpasupplicant/trunk/src/eap_peer/eap_ttls.c
    wpasupplicant/trunk/src/eap_peer/tncc.c
    wpasupplicant/trunk/src/eap_peer/tncc.h
    wpasupplicant/trunk/src/eap_server/eap.c
    wpasupplicant/trunk/src/eap_server/eap.h
    wpasupplicant/trunk/src/eap_server/eap_aka.c
    wpasupplicant/trunk/src/eap_server/eap_fast.c
    wpasupplicant/trunk/src/eap_server/eap_i.h
    wpasupplicant/trunk/src/eap_server/eap_identity.c
    wpasupplicant/trunk/src/eap_server/eap_methods.c
    wpasupplicant/trunk/src/eap_server/eap_mschapv2.c
    wpasupplicant/trunk/src/eap_server/eap_peap.c
    wpasupplicant/trunk/src/eap_server/eap_sim_db.c
    wpasupplicant/trunk/src/eap_server/eap_sim_db.h
    wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c
    wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.h
    wpasupplicant/trunk/src/l2_packet/l2_packet.h
    wpasupplicant/trunk/src/l2_packet/l2_packet_winpcap.c
    wpasupplicant/trunk/src/radius/radius_client.c
    wpasupplicant/trunk/src/radius/radius_server.c
    wpasupplicant/trunk/src/radius/radius_server.h
    wpasupplicant/trunk/src/rsn_supp/wpa_ft.c
    wpasupplicant/trunk/src/tls/bignum.c
    wpasupplicant/trunk/src/tls/tlsv1_client.c
    wpasupplicant/trunk/src/utils/eloop_win.c
    wpasupplicant/trunk/src/utils/includes.h
    wpasupplicant/trunk/src/utils/ip_addr.c
    wpasupplicant/trunk/src/utils/os_unix.c
    wpasupplicant/trunk/src/utils/pcsc_funcs.c
    wpasupplicant/trunk/src/utils/state_machine.h
    wpasupplicant/trunk/src/utils/uuid.c
    wpasupplicant/trunk/src/utils/uuid.h
    wpasupplicant/trunk/src/utils/wpa_debug.h
    wpasupplicant/trunk/wpa_supplicant/ChangeLog
    wpasupplicant/trunk/wpa_supplicant/Makefile
    wpasupplicant/trunk/wpa_supplicant/README
    wpasupplicant/trunk/wpa_supplicant/README-Windows.txt
    wpasupplicant/trunk/wpa_supplicant/config.c
    wpasupplicant/trunk/wpa_supplicant/config.h
    wpasupplicant/trunk/wpa_supplicant/config_file.c
    wpasupplicant/trunk/wpa_supplicant/config_winreg.c
    wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c
    wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c
    wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus_handlers.c
    wpasupplicant/trunk/wpa_supplicant/ctrl_iface_named_pipe.c
    wpasupplicant/trunk/wpa_supplicant/dbus_dict_helpers.c
    wpasupplicant/trunk/wpa_supplicant/defconfig
    wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen
    wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
    wpasupplicant/trunk/wpa_supplicant/doc/doxygen.fast
    wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full
    wpasupplicant/trunk/wpa_supplicant/doc/kerneldoc2doxygen.pl
    wpasupplicant/trunk/wpa_supplicant/doc/porting.doxygen
    wpasupplicant/trunk/wpa_supplicant/eap_testing.txt
    wpasupplicant/trunk/wpa_supplicant/eapol_test.c
    wpasupplicant/trunk/wpa_supplicant/events.c
    wpasupplicant/trunk/wpa_supplicant/main.c
    wpasupplicant/trunk/wpa_supplicant/main_winsvc.c
    wpasupplicant/trunk/wpa_supplicant/mlme.c
    wpasupplicant/trunk/wpa_supplicant/scan.c
    wpasupplicant/trunk/wpa_supplicant/win_example.reg
    wpasupplicant/trunk/wpa_supplicant/wpa_cli.c
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.h
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.ui
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.h
    wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.ui
    wpasupplicant/trunk/wpa_supplicant/wpa_gui/networkconfig.ui.h
    wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c
    wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf
    wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h
    wpasupplicant/trunk/wpa_supplicant/wpas_glue.c

Modified: wpasupplicant/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/changelog?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/changelog (original)
+++ wpasupplicant/trunk/debian/changelog Sat Jan 10 09:03:49 2009
@@ -1,3 +1,13 @@
+wpasupplicant (0.6.7-1) experimental; urgency=low
+
+  * New upstream release.
+  * Enable CONFIG_WPS in debian/config/*.
+  * Install README-WPS to docs directory.
+  * Refresh debian/copyright for new years which are covered by
+    copyright.
+
+ -- Kel Modderman <kel at otaku42.de>  Sat, 10 Jan 2009 18:57:32 +1000
+
 wpasupplicant (0.6.6-2) experimental; urgency=low
 
   [ Martin Pitt ]

Modified: wpasupplicant/trunk/debian/config/kfreebsd
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/config/kfreebsd?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/config/kfreebsd (original)
+++ wpasupplicant/trunk/debian/config/kfreebsd Sat Jan 10 09:03:49 2009
@@ -130,8 +130,8 @@
 # EAP-TNC and related Trusted Network Connect support (experimental)
 #CONFIG_EAP_TNC=y
 
-# EAP-WSC for Wi-Fi Protected Setup
-CONFIG_EAP_WSC=y
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
 
 # EAP-IKEv2
 #CONFIG_EAP_IKEV2=y

Modified: wpasupplicant/trunk/debian/config/linux
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/config/linux?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/config/linux (original)
+++ wpasupplicant/trunk/debian/config/linux Sat Jan 10 09:03:49 2009
@@ -132,6 +132,9 @@
 
 # EAP-TNC and related Trusted Network Connect support (experimental)
 #CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+CONFIG_WPS=y
 
 # EAP-IKEv2
 #CONFIG_EAP_IKEV2=y

Modified: wpasupplicant/trunk/debian/copyright
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/copyright?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/copyright (original)
+++ wpasupplicant/trunk/debian/copyright Sat Jan 10 09:03:49 2009
@@ -9,7 +9,7 @@
 License: BSD | GPL-2
 
 Files: *
-Copyright: Copyright (c) 2002-2007, Jouni Malinen <j at w1.fi> and contributors
+Copyright: Copyright (c) 2002-2009, Jouni Malinen <j at w1.fi> and contributors
 License: BSD | GPL-2
 
 Files: src/common/wireless_copy.h

Modified: wpasupplicant/trunk/debian/wpasupplicant.docs
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/wpasupplicant.docs?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/wpasupplicant.docs (original)
+++ wpasupplicant/trunk/debian/wpasupplicant.docs Sat Jan 10 09:03:49 2009
@@ -1,1 +1,2 @@
 wpa_supplicant/README
+wpa_supplicant/README-WPS

Modified: wpasupplicant/trunk/patches/openssl-0.9.8i-tls-extensions.patch
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/patches/openssl-0.9.8i-tls-extensions.patch?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/patches/openssl-0.9.8i-tls-extensions.patch (original)
+++ wpasupplicant/trunk/patches/openssl-0.9.8i-tls-extensions.patch Sat Jan 10 09:03:49 2009
@@ -9,31 +9,33 @@
 command line.
 
 
-diff -upr openssl-0.9.8i.orig/ssl/s3_clnt.c openssl-0.9.8i/ssl/s3_clnt.c
+Index: openssl-0.9.8i/ssl/s3_clnt.c
+===================================================================
 --- openssl-0.9.8i.orig/ssl/s3_clnt.c	2008-06-16 19:56:41.000000000 +0300
-+++ openssl-0.9.8i/ssl/s3_clnt.c	2008-09-28 16:50:18.000000000 +0300
-@@ -759,6 +759,20 @@ int ssl3_get_server_hello(SSL *s)
++++ openssl-0.9.8i/ssl/s3_clnt.c	2008-11-23 20:39:40.000000000 +0200
+@@ -759,6 +759,21 @@
  		goto f_err;
  		}
  
 +#ifndef OPENSSL_NO_TLSEXT
 +	/* check if we want to resume the session based on external pre-shared secret */
 +	if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
-+	{
++		{
 +		SSL_CIPHER *pref_cipher=NULL;
 +		s->session->master_key_length=sizeof(s->session->master_key);
 +		if (s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length,
 +			NULL, &pref_cipher, s->tls_session_secret_cb_arg))
-+		{
-+			s->session->cipher=pref_cipher ? pref_cipher : ssl_get_cipher_by_char(s,p+j);
++			{
++			s->session->cipher=pref_cipher ?
++				pref_cipher : ssl_get_cipher_by_char(s,p+j);
++			}
 +		}
-+	}
 +#endif /* OPENSSL_NO_TLSEXT */
 +
  	if (j != 0 && j == s->session->session_id_length
  	    && memcmp(p,s->session->session_id,j) == 0)
  	    {
-@@ -2701,11 +2715,8 @@ static int ssl3_check_finished(SSL *s)
+@@ -2701,11 +2716,8 @@
  	{
  	int ok;
  	long n;
@@ -47,10 +49,11 @@
  		return 1;
  	/* this function is called when we really expect a Certificate
  	 * message, so permit appropriate message length */
-diff -upr openssl-0.9.8i.orig/ssl/s3_srvr.c openssl-0.9.8i/ssl/s3_srvr.c
+Index: openssl-0.9.8i/ssl/s3_srvr.c
+===================================================================
 --- openssl-0.9.8i.orig/ssl/s3_srvr.c	2008-09-14 21:16:09.000000000 +0300
-+++ openssl-0.9.8i/ssl/s3_srvr.c	2008-09-28 16:50:18.000000000 +0300
-@@ -959,6 +959,59 @@ int ssl3_get_client_hello(SSL *s)
++++ openssl-0.9.8i/ssl/s3_srvr.c	2008-11-23 20:37:40.000000000 +0200
+@@ -959,6 +959,59 @@
  			SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
  			goto err;
  		}
@@ -66,20 +69,20 @@
 +		pos=s->s3->server_random;
 +		l2n(Time,pos);
 +		if (RAND_pseudo_bytes(pos,SSL3_RANDOM_SIZE-4) <= 0)
-+		{
++			{
 +			al=SSL_AD_INTERNAL_ERROR;
 +			goto f_err;
-+		}
++			}
 +	}
 +
 +	if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb)
-+	{
++		{
 +		SSL_CIPHER *pref_cipher=NULL;
 +
 +		s->session->master_key_length=sizeof(s->session->master_key);
 +		if(s->tls_session_secret_cb(s, s->session->master_key, &s->session->master_key_length, 
 +			ciphers, &pref_cipher, s->tls_session_secret_cb_arg))
-+		{
++			{
 +			s->hit=1;
 +			s->session->ciphers=ciphers;
 +			s->session->verify_result=X509_V_OK;
@@ -105,12 +108,12 @@
 +
 +			s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
 +			s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
++			}
 +		}
-+	}
  #endif
  	/* Worst case, we will use the NULL compression, but if we have other
  	 * options, we will now look for them.  We have i-1 compression
-@@ -1097,16 +1150,22 @@ int ssl3_send_server_hello(SSL *s)
+@@ -1097,16 +1150,22 @@
  	unsigned char *buf;
  	unsigned char *p,*d;
  	int i,sl;
@@ -134,44 +137,51 @@
  		/* Do the message type and length last */
  		d=p= &(buf[4]);
  
-diff -upr openssl-0.9.8i.orig/ssl/ssl_err.c openssl-0.9.8i/ssl/ssl_err.c
+Index: openssl-0.9.8i/ssl/ssl_err.c
+===================================================================
 --- openssl-0.9.8i.orig/ssl/ssl_err.c	2008-08-13 22:44:44.000000000 +0300
-+++ openssl-0.9.8i/ssl/ssl_err.c	2008-09-28 16:50:18.000000000 +0300
-@@ -253,6 +253,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
++++ openssl-0.9.8i/ssl/ssl_err.c	2008-11-23 20:33:43.000000000 +0200
+@@ -253,6 +253,7 @@
  {ERR_FUNC(SSL_F_TLS1_ENC),	"TLS1_ENC"},
  {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK),	"TLS1_SETUP_KEY_BLOCK"},
  {ERR_FUNC(SSL_F_WRITE_PENDING),	"WRITE_PENDING"},
-+{ERR_FUNC(SSL_F_SSL_SET_HELLO_EXTENSION), "SSL_set_hello_extension"},
++{ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), "SSL_set_session_ticket_ext"},
  {0,NULL}
  	};
  
-diff -upr openssl-0.9.8i.orig/ssl/ssl.h openssl-0.9.8i/ssl/ssl.h
+Index: openssl-0.9.8i/ssl/ssl.h
+===================================================================
 --- openssl-0.9.8i.orig/ssl/ssl.h	2008-08-13 22:44:44.000000000 +0300
-+++ openssl-0.9.8i/ssl/ssl.h	2008-09-28 16:50:18.000000000 +0300
-@@ -344,6 +344,7 @@ extern "C" {
++++ openssl-0.9.8i/ssl/ssl.h	2008-11-23 20:35:41.000000000 +0200
+@@ -344,6 +344,7 @@
   * 'struct ssl_st *' function parameters used to prototype callbacks
   * in SSL_CTX. */
  typedef struct ssl_st *ssl_crock_st;
-+typedef struct tls_extension_st TLS_EXTENSION;
++typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
  
  /* used to hold info on the particular ciphers used */
  typedef struct ssl_cipher_st
-@@ -362,6 +363,8 @@ typedef struct ssl_cipher_st
+@@ -362,6 +363,9 @@
  
  DECLARE_STACK_OF(SSL_CIPHER)
  
++typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg);
 +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg);
 +
  /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
  typedef struct ssl_method_st
  	{
-@@ -1034,6 +1037,14 @@ struct ssl_st
+@@ -1034,6 +1038,18 @@
  
  	/* RFC4507 session ticket expected to be received or sent */
  	int tlsext_ticket_expected;
 +
-+	/* TLS extensions */
-+	TLS_EXTENSION *tls_extension;
++	/* TLS Session Ticket extension override */
++	TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
++
++	/* TLS Session Ticket extension callback */
++	tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
++	void *tls_session_ticket_ext_cb_arg;
 +
 +	/* TLS pre-shared secret session resumption */
 +	tls_session_secret_cb_fn tls_session_secret_cb;
@@ -180,12 +190,15 @@
  	SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */
  #define session_ctx initial_ctx
  #else
-@@ -1632,6 +1643,12 @@ void *SSL_COMP_get_compression_methods(v
+@@ -1632,6 +1648,15 @@
  int SSL_COMP_add_compression_method(int id,void *cm);
  #endif
  
 +/* TLS extensions functions */
-+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len);
++int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
++
++int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
++				  void *arg);
 +
 +/* Pre-shared secret session resumption functions */
 +int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg);
@@ -193,112 +206,122 @@
  /* BEGIN ERROR CODES */
  /* The following lines are auto generated by the script mkerr.pl. Any changes
   * made after this point may be overwritten when the script is next run.
-@@ -1824,6 +1841,7 @@ void ERR_load_SSL_strings(void);
+@@ -1824,6 +1849,7 @@
  #define SSL_F_TLS1_ENC					 210
  #define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
  #define SSL_F_WRITE_PENDING				 212
-+#define SSL_F_SSL_SET_HELLO_EXTENSION			 213
++#define SSL_F_SSL_SET_SESSION_TICKET_EXT		 213
  
  /* Reason codes. */
  #define SSL_R_APP_DATA_IN_HANDSHAKE			 100
-diff -upr openssl-0.9.8i.orig/ssl/ssl_sess.c openssl-0.9.8i/ssl/ssl_sess.c
+Index: openssl-0.9.8i/ssl/ssl_sess.c
+===================================================================
 --- openssl-0.9.8i.orig/ssl/ssl_sess.c	2008-06-04 21:35:27.000000000 +0300
-+++ openssl-0.9.8i/ssl/ssl_sess.c	2008-09-28 16:50:18.000000000 +0300
-@@ -707,6 +707,52 @@ long SSL_CTX_get_timeout(const SSL_CTX *
++++ openssl-0.9.8i/ssl/ssl_sess.c	2008-11-23 20:32:24.000000000 +0200
+@@ -707,6 +707,61 @@
  	return(s->session_timeout);
  	}
  
 +#ifndef OPENSSL_NO_TLSEXT
-+int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len, 
++int SSL_set_session_secret_cb(SSL *s, int (*tls_session_secret_cb)(SSL *s, void *secret, int *secret_len,
 +	STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg), void *arg)
-+{
++	{
 +	if (s == NULL) return(0);
 +	s->tls_session_secret_cb = tls_session_secret_cb;
 +	s->tls_session_secret_cb_arg = arg;
 +	return(1);
-+}
-+
-+int SSL_set_hello_extension(SSL *s, int ext_type, void *ext_data, int ext_len)
-+{
-+	if(s->version >= TLS1_VERSION)
++	}
++
++int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
++				  void *arg)
 +	{
-+		if(s->tls_extension)
++	if (s == NULL) return(0);
++	s->tls_session_ticket_ext_cb = cb;
++	s->tls_session_ticket_ext_cb_arg = arg;
++	return(1);
++	}
++
++int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
++	{
++	if (s->version >= TLS1_VERSION)
 +		{
-+			OPENSSL_free(s->tls_extension);
-+			s->tls_extension = NULL;
++		if (s->tlsext_session_ticket)
++			{
++			OPENSSL_free(s->tlsext_session_ticket);
++			s->tlsext_session_ticket = NULL;
++			}
++
++		s->tlsext_session_ticket = OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
++		if (!s->tlsext_session_ticket)
++			{
++			SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
++			return 0;
++			}
++
++		if (ext_data)
++			{
++			s->tlsext_session_ticket->length = ext_len;
++			s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
++			memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
++			}
++		else
++			{
++			s->tlsext_session_ticket->length = 0;
++			s->tlsext_session_ticket->data = NULL;
++			}
++
++		return 1;
 +		}
 +
-+		s->tls_extension = OPENSSL_malloc(sizeof(TLS_EXTENSION) + ext_len);
-+		if(!s->tls_extension)
-+		{
-+			SSLerr(SSL_F_SSL_SET_HELLO_EXTENSION, ERR_R_MALLOC_FAILURE);
-+			return 0;
-+		}
-+
-+		s->tls_extension->type = ext_type;
-+
-+		if(ext_data)
-+		{
-+			s->tls_extension->length = ext_len;
-+			s->tls_extension->data = s->tls_extension + 1;
-+			memcpy(s->tls_extension->data, ext_data, ext_len);
-+		} else {
-+			s->tls_extension->length = 0;
-+			s->tls_extension->data = NULL;
-+		}
-+
-+		return 1;
++	return 0;
 +	}
-+
-+	return 0;
-+}
 +#endif /* OPENSSL_NO_TLSEXT */
 +
  typedef struct timeout_param_st
  	{
  	SSL_CTX *ctx;
-diff -upr openssl-0.9.8i.orig/ssl/t1_lib.c openssl-0.9.8i/ssl/t1_lib.c
+Index: openssl-0.9.8i/ssl/t1_lib.c
+===================================================================
 --- openssl-0.9.8i.orig/ssl/t1_lib.c	2008-09-04 01:13:04.000000000 +0300
-+++ openssl-0.9.8i/ssl/t1_lib.c	2008-09-28 16:50:18.000000000 +0300
-@@ -106,6 +106,12 @@ int tls1_new(SSL *s)
++++ openssl-0.9.8i/ssl/t1_lib.c	2008-11-23 20:31:20.000000000 +0200
+@@ -106,6 +106,12 @@
  
  void tls1_free(SSL *s)
  	{
 +#ifndef OPENSSL_NO_TLSEXT
-+	if(s->tls_extension)
-+	{
-+		OPENSSL_free(s->tls_extension);
-+	}
++	if (s->tlsext_session_ticket)
++		{
++		OPENSSL_free(s->tlsext_session_ticket);
++		}
 +#endif
  	ssl3_free(s);
  	}
  
-@@ -175,8 +181,24 @@ unsigned char *ssl_add_clienthello_tlsex
+@@ -175,8 +181,23 @@
  		int ticklen;
  		if (s->session && s->session->tlsext_tick)
  			ticklen = s->session->tlsext_ticklen;
-+		else if (s->session && s->tls_extension &&
-+			s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
-+			s->tls_extension->data)
-+		{
-+			ticklen = s->tls_extension->length;
++		else if (s->session && s->tlsext_session_ticket &&
++			 s->tlsext_session_ticket->data)
++			{
++			ticklen = s->tlsext_session_ticket->length;
 +			s->session->tlsext_tick = OPENSSL_malloc(ticklen);
 +			if (!s->session->tlsext_tick)
 +				return NULL;
-+			memcpy(s->session->tlsext_tick, s->tls_extension->data,
++			memcpy(s->session->tlsext_tick,
++			       s->tlsext_session_ticket->data,
 +			       ticklen);
 +			s->session->tlsext_ticklen = ticklen;
-+		}
++			}
  		else
  			ticklen = 0;
-+		if (ticklen == 0 && s->tls_extension &&
-+		    s->tls_extension->type == TLSEXT_TYPE_session_ticket &&
-+		    s->tls_extension->data == NULL)
++		if (ticklen == 0 && s->tlsext_session_ticket &&
++		    s->tlsext_session_ticket->data == NULL)
 +			goto skip_ext;
  		/* Check for enough room 2 for extension type, 2 for len
   		 * rest for ticket
    		 */
-@@ -190,6 +212,7 @@ unsigned char *ssl_add_clienthello_tlsex
+@@ -190,6 +211,7 @@
  			ret += ticklen;
  			}
  		}
@@ -306,39 +329,76 @@
  
  	if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
  		{
-@@ -776,6 +799,8 @@ int tls1_process_ticket(SSL *s, unsigned
+@@ -407,6 +429,15 @@
+ 				}
+ 
+ 			}
++		else if (type == TLSEXT_TYPE_session_ticket)
++			{
++			if (s->tls_session_ticket_ext_cb &&
++			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
++				{
++				*al = TLS1_AD_INTERNAL_ERROR;
++				return 0;
++				}
++			}
+ 		else if (type == TLSEXT_TYPE_status_request
+ 						&& s->ctx->tlsext_status_cb)
+ 			{
+@@ -553,6 +584,12 @@
+ 			}
+ 		else if (type == TLSEXT_TYPE_session_ticket)
+ 			{
++			if (s->tls_session_ticket_ext_cb &&
++			    !s->tls_session_ticket_ext_cb(s, data, size, s->tls_session_ticket_ext_cb_arg))
++				{
++				*al = TLS1_AD_INTERNAL_ERROR;
++				return 0;
++				}
+ 			if ((SSL_get_options(s) & SSL_OP_NO_TICKET)
+ 				|| (size > 0))
+ 				{
+@@ -776,6 +813,15 @@
  				s->tlsext_ticket_expected = 1;
  				return 0;	/* Cache miss */
  				}
 +			if (s->tls_session_secret_cb)
++				{
++				/* Indicate cache miss here and instead of
++				 * generating the session from ticket now,
++				 * trigger abbreviated handshake based on
++				 * external mechanism to calculate the master
++				 * secret later. */
 +				return 0;
++				}
  			return tls_decrypt_ticket(s, p, size, session_id, len,
  									ret);
  			}
-diff -upr openssl-0.9.8i.orig/ssl/tls1.h openssl-0.9.8i/ssl/tls1.h
+Index: openssl-0.9.8i/ssl/tls1.h
+===================================================================
 --- openssl-0.9.8i.orig/ssl/tls1.h	2008-04-30 19:11:33.000000000 +0300
-+++ openssl-0.9.8i/ssl/tls1.h	2008-09-28 16:50:18.000000000 +0300
-@@ -398,6 +398,14 @@ SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_T
++++ openssl-0.9.8i/ssl/tls1.h	2008-11-23 20:22:38.000000000 +0200
+@@ -398,6 +398,13 @@
  #define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
  #endif
  
 +/* TLS extension struct */
-+struct tls_extension_st
-+{
-+	unsigned short type;
++struct tls_session_ticket_ext_st
++	{
 +	unsigned short length;
 +	void *data;
-+};
++	};
 +
  #ifdef  __cplusplus
  }
  #endif
-diff -upr openssl-0.9.8i.orig/util/ssleay.num openssl-0.9.8i/util/ssleay.num
+Index: openssl-0.9.8i/util/ssleay.num
+===================================================================
 --- openssl-0.9.8i.orig/util/ssleay.num	2008-06-05 13:57:21.000000000 +0300
-+++ openssl-0.9.8i/util/ssleay.num	2008-09-28 16:50:57.000000000 +0300
-@@ -242,3 +242,5 @@ SSL_set_SSL_CTX                         
++++ openssl-0.9.8i/util/ssleay.num	2008-11-23 20:22:05.000000000 +0200
+@@ -242,3 +242,5 @@
  SSL_get_servername                      291	EXIST::FUNCTION:TLSEXT
  SSL_get_servername_type                 292	EXIST::FUNCTION:TLSEXT
  SSL_CTX_set_client_cert_engine          293	EXIST::FUNCTION:ENGINE
-+SSL_set_hello_extension			305	EXIST::FUNCTION:TLSEXT
-+SSL_set_session_secret_cb		306	EXIST::FUNCTION:TLSEXT
++SSL_set_session_ticket_ext		306	EXIST::FUNCTION:TLSEXT
++SSL_set_session_secret_cb		307	EXIST::FUNCTION:TLSEXT

Modified: wpasupplicant/trunk/patches/openssl-0.9.9-session-ticket.patch
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/patches/openssl-0.9.9-session-ticket.patch?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/patches/openssl-0.9.9-session-ticket.patch (original)
+++ wpasupplicant/trunk/patches/openssl-0.9.9-session-ticket.patch Sat Jan 10 09:03:49 2009
@@ -3,6 +3,10 @@
 
 This is based on the patch from Alexey Kobozev <akobozev at cisco.com>
 (sent to openssl-dev mailing list on Tue, 07 Jun 2005 15:40:58 +0300).
+
+NOTE: This patch (without SSL_set_hello_extension() wrapper) was
+merged into the upstream OpenSSL 0.9.9 tree and as such, an external
+patch for EAP-FAST support is not needed anymore.
 
 
 

Modified: wpasupplicant/trunk/src/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/Makefile?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/Makefile (original)
+++ wpasupplicant/trunk/src/Makefile Sat Jan 10 09:03:49 2009
@@ -1,4 +1,4 @@
-SUBDIRS=common crypto drivers hlr_auc_gw eapol_supp eap_common eap_peer eap_server l2_packet radius rsn_supp tls utils
+SUBDIRS=common crypto drivers hlr_auc_gw eapol_supp eap_common eap_peer eap_server l2_packet radius rsn_supp tls utils wps
 
 all:
 	@echo Nothing to be made.

Modified: wpasupplicant/trunk/src/common/defs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/defs.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/defs.h (original)
+++ wpasupplicant/trunk/src/common/defs.h Sat Jan 10 09:03:49 2009
@@ -42,6 +42,7 @@
 #define WPA_KEY_MGMT_FT_PSK BIT(6)
 #define WPA_KEY_MGMT_IEEE8021X_SHA256 BIT(7)
 #define WPA_KEY_MGMT_PSK_SHA256 BIT(8)
+#define WPA_KEY_MGMT_WPS BIT(9)
 
 static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
 {
@@ -85,7 +86,8 @@
 typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
 	       KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE,
 	       KEY_MGMT_FT_802_1X, KEY_MGMT_FT_PSK,
-	       KEY_MGMT_802_1X_SHA256, KEY_MGMT_PSK_SHA256
+	       KEY_MGMT_802_1X_SHA256, KEY_MGMT_PSK_SHA256,
+	       KEY_MGMT_WPS
 } wpa_key_mgmt;
 
 /**

Modified: wpasupplicant/trunk/src/common/ieee802_11_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/ieee802_11_common.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/ieee802_11_common.c (original)
+++ wpasupplicant/trunk/src/common/ieee802_11_common.c Sat Jan 10 09:03:49 2009
@@ -75,8 +75,28 @@
 				return -1;
 			}
 			break;
+		case 4:
+			/* Wi-Fi Protected Setup (WPS) IE */
+			elems->wps_ie = pos;
+			elems->wps_ie_len = elen;
+			break;
 		default:
 			wpa_printf(MSG_MSGDUMP, "Unknown Microsoft "
+				   "information element ignored "
+				   "(type=%d len=%lu)\n",
+				   pos[3], (unsigned long) elen);
+			return -1;
+		}
+		break;
+
+	case OUI_BROADCOM:
+		switch (pos[3]) {
+		case VENDOR_HT_CAPAB_OUI_TYPE:
+			elems->vendor_ht_cap = pos;
+			elems->vendor_ht_cap_len = elen;
+			break;
+		default:
+			wpa_printf(MSG_MSGDUMP, "Unknown Broadcom "
 				   "information element ignored "
 				   "(type=%d len=%lu)\n",
 				   pos[3], (unsigned long) elen);

Modified: wpasupplicant/trunk/src/common/ieee802_11_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/ieee802_11_common.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/ieee802_11_common.h (original)
+++ wpasupplicant/trunk/src/common/ieee802_11_common.h Sat Jan 10 09:03:49 2009
@@ -45,6 +45,8 @@
 	u8 wme_len;
 	u8 *wme_tspec;
 	u8 wme_tspec_len;
+	u8 *wps_ie;
+	u8 wps_ie_len;
 	u8 *power_cap;
 	u8 power_cap_len;
 	u8 *supp_channels;
@@ -59,6 +61,8 @@
 	u8 ht_operation_len;
 	u8 *assoc_comeback;
 	u8 assoc_comeback_len;
+	u8 *vendor_ht_cap;
+	u8 vendor_ht_cap_len;
 };
 
 typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;

Modified: wpasupplicant/trunk/src/common/ieee802_11_defs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/ieee802_11_defs.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/ieee802_11_defs.h (original)
+++ wpasupplicant/trunk/src/common/ieee802_11_defs.h Sat Jan 10 09:03:49 2009
@@ -118,6 +118,7 @@
 #define WLAN_STATUS_ASSOC_DENIED_NO_DSSS_OFDM 27
 /* IEEE 802.11w */
 #define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30
+#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31
 /* IEEE 802.11i */
 #define WLAN_STATUS_INVALID_IE 40
 #define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41
@@ -164,9 +165,6 @@
 #define WLAN_REASON_INVALID_RSN_IE_CAPAB 22
 #define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23
 #define WLAN_REASON_CIPHER_SUITE_REJECTED 24
-/* IEEE 802.11w */
-#define WLAN_REASON_INVALID_GROUP_MGMT_CIPHER 25
-#define WLAN_REASON_ROBUST_MGMT_FRAME_POLICY_VIOLATION 26
 
 
 /* Information Element IDs */
@@ -216,14 +214,14 @@
 #define WLAN_ACTION_BLOCK_ACK 3
 #define WLAN_ACTION_RADIO_MEASUREMENT 5
 #define WLAN_ACTION_FT 6
-#define WLAN_ACTION_PING 8
+#define WLAN_ACTION_SA_QUERY 8
 #define WLAN_ACTION_WMM 17
 
-/* Ping Action frame (IEEE 802.11w/D6.0, 7.4.9) */
-#define WLAN_PING_REQUEST 0
-#define WLAN_PING_RESPONSE 1
-
-#define WLAN_PING_TRANS_ID_LEN 16
+/* SA Query Action frame (IEEE 802.11w/D7.0, 7.4.9) */
+#define WLAN_SA_QUERY_REQUEST 0
+#define WLAN_SA_QUERY_RESPONSE 1
+
+#define WLAN_SA_QUERY_TR_ID_LEN 16
 
 
 #ifdef _MSC_VER
@@ -323,12 +321,12 @@
 				} STRUCT_PACKED ft_action_resp;
 				struct {
 					u8 action;
-					u8 trans_id[WLAN_PING_TRANS_ID_LEN];
-				} STRUCT_PACKED ping_req;
+					u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+				} STRUCT_PACKED sa_query_req;
 				struct {
 					u8 action; /* */
-					u8 trans_id[WLAN_PING_TRANS_ID_LEN];
-				} STRUCT_PACKED ping_resp;
+					u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
+				} STRUCT_PACKED sa_query_resp;
 			} u;
 		} STRUCT_PACKED action;
 	} u;
@@ -344,10 +342,6 @@
 
 
 /* HT Capability element */
-
-#define MIMO_PWR_DONT_SEND_MIMO_SEQS            0
-#define MIMO_PWR_NEED2PRECEDE_MIMO_SEQS_BY_RTS  1
-#define MIMO_PWR_NO_LIMIT_ON_MIMO_SEQS          3
 
 enum {
 	MAX_RX_AMPDU_FACTOR_8KB = 0,
@@ -431,19 +425,25 @@
 	(((_var_) & (((u32)7) << (_shift_))) >> (_shift_))
 
 
-#define HT_CAP_INFO_ADVANCED_CODDING_CAP	((u16) BIT(0))
+#define HT_CAP_INFO_LDPC_CODING_CAP		((u16) BIT(0))
 #define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET	((u16) BIT(1))
-#define HT_CAP_INFO_MIMO_PWR_SAVE_OFFSET	2
+#define HT_CAP_INFO_SMPS_MASK			((u16) (BIT(2) | BIT(3)))
+#define HT_CAP_INFO_SMPS_STATIC			((u16) 0)
+#define HT_CAP_INFO_SMPS_DYNAMIC		((u16) BIT(2))
+#define HT_CAP_INFO_SMPS_DISABLED		((u16) (BIT(2) | BIT(3)))
 #define HT_CAP_INFO_GREEN_FIELD			((u16) BIT(4))
 #define HT_CAP_INFO_SHORT_GI20MHZ		((u16) BIT(5))
 #define HT_CAP_INFO_SHORT_GI40MHZ		((u16) BIT(6))
 #define HT_CAP_INFO_TX_STBC			((u16) BIT(7))
-#define HT_CAP_INFO_RX_STBC_OFFSET		8
+#define HT_CAP_INFO_RX_STBC_MASK		((u16) (BIT(8) | BIT(9)))
+#define HT_CAP_INFO_RX_STBC_1			((u16) BIT(8))
+#define HT_CAP_INFO_RX_STBC_12			((u16) BIT(9))
+#define HT_CAP_INFO_RX_STBC_123			((u16) (BIT(8) | BIT(9)))
 #define HT_CAP_INFO_DELAYED_BA			((u16) BIT(10))
 #define HT_CAP_INFO_MAX_AMSDU_SIZE		((u16) BIT(11))
 #define HT_CAP_INFO_DSSS_CCK40MHZ		((u16) BIT(12))
 #define HT_CAP_INFO_PSMP_SUPP			((u16) BIT(13))
-#define HT_CAP_INFO_STBC_CTRL_FRAME_SUPP	((u16) BIT(14))
+#define HT_CAP_INFO_40MHZ_INTOLERANT		((u16) BIT(14))
 #define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT	((u16) BIT(15))
 
 
@@ -493,10 +493,6 @@
 } STRUCT_PACKED;
 
 
-#define EXT_CHNL_OFF_NONE   0
-#define EXT_CHNL_OFF_ABOVE  1
-#define EXT_CHNL_OFF_BELOW  3
-
 #define REC_TRANS_CHNL_WIDTH_20     0
 #define REC_TRANS_CHNL_WIDTH_ANY    1
 
@@ -505,7 +501,9 @@
 #define OP_MODE_20MHZ_HT_STA_ASSOCED    2
 #define OP_MODE_MIXED                   3
 
-#define HT_INFO_HT_PARAM_EXT_CHNL_OFF_OFFSET		0
+#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK	((u8) BIT(0) | BIT(1))
+#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE		((u8) BIT(0))
+#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW		((u8) BIT(0) | BIT(1))
 #define HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH		((u8) BIT(2))
 #define HT_INFO_HT_PARAM_RIFS_MODE			((u8) BIT(3))
 #define HT_INFO_HT_PARAM_CTRL_ACCESS_ONLY		((u8) BIT(4))
@@ -578,4 +576,9 @@
 #define WME_TSPEC_DIRECTION_DOWNLINK 1
 #define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3
 
+
+#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */
+
+#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */
+
 #endif /* IEEE802_11_DEFS_H */

Modified: wpasupplicant/trunk/src/common/version.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/version.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/version.h (original)
+++ wpasupplicant/trunk/src/common/version.h Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define VERSION_STR "0.6.6"
+#define VERSION_STR "0.6.7"
 
 #endif /* VERSION_H */

Modified: wpasupplicant/trunk/src/common/wpa_ctrl.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/wpa_ctrl.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/wpa_ctrl.h (original)
+++ wpasupplicant/trunk/src/common/wpa_ctrl.h Sat Jan 10 09:03:49 2009
@@ -49,6 +49,28 @@
 /** New scan results available */
 #define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
 
+/** WPS overlap detected in PBC mode */
+#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
+/** Available WPS AP with active PBC found in scan results */
+#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC "
+/** Available WPS AP with recently selected PIN registrar found in scan results
+ */
+#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN "
+/** Available WPS AP found in scan results */
+#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE "
+/** A new credential received */
+#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
+/** M2D received */
+#define WPS_EVENT_M2D "WPS-M2D "
+/** WPS registration failed after M2/M2D */
+#define WPS_EVENT_FAIL "WPS-FAIL "
+/** WPS registration completed successfully */
+#define WPS_EVENT_SUCCESS "WPS-SUCCESS "
+
+/* hostapd control interface - fixed message prefixes */
+#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
+#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
+
 
 /* wpa_supplicant/hostapd control interface access */
 

Modified: wpasupplicant/trunk/src/crypto/crypto_internal.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/crypto_internal.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/crypto_internal.c (original)
+++ wpasupplicant/trunk/src/crypto/crypto_internal.c Sat Jan 10 09:03:49 2009
@@ -790,7 +790,7 @@
 }
 
 
-#ifdef EAP_FAST
+#if defined(EAP_FAST) || defined(CONFIG_WPS)
 
 int crypto_mod_exp(const u8 *base, size_t base_len,
 		   const u8 *power, size_t power_len,
@@ -827,7 +827,7 @@
 	return ret;
 }
 
-#endif /* EAP_FAST */
+#endif /* EAP_FAST || CONFIG_WPS */
 
 
 #endif /* CONFIG_TLS_INTERNAL */

Modified: wpasupplicant/trunk/src/crypto/ms_funcs.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/ms_funcs.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/ms_funcs.c (original)
+++ wpasupplicant/trunk/src/crypto/ms_funcs.c Sat Jan 10 09:03:49 2009
@@ -110,7 +110,7 @@
 /**
  * generate_nt_response - GenerateNTResponse() - RFC 2759, Sect. 8.1
  * @auth_challenge: 16-octet AuthenticatorChallenge (IN)
- * @peer_hallenge: 16-octet PeerChallenge (IN)
+ * @peer_challenge: 16-octet PeerChallenge (IN)
  * @username: 0-to-256-char UserName (IN)
  * @username_len: Length of username
  * @password: 0-to-256-unicode-char Password (IN; ASCII)
@@ -135,7 +135,7 @@
 /**
  * generate_nt_response_pwhash - GenerateNTResponse() - RFC 2759, Sect. 8.1
  * @auth_challenge: 16-octet AuthenticatorChallenge (IN)
- * @peer_hallenge: 16-octet PeerChallenge (IN)
+ * @peer_challenge: 16-octet PeerChallenge (IN)
  * @username: 0-to-256-char UserName (IN)
  * @username_len: Length of username
  * @password_hash: 16-octet PasswordHash (IN)
@@ -164,7 +164,7 @@
  * @username: 0-to-256-char UserName (IN)
  * @username_len: Length of username
  * @response: 20-octet AuthenticatorResponse (OUT) (note: this value is usually
- * encoded as a 42-octet ASCII string (S=<hexdump of response>)
+ * encoded as a 42-octet ASCII string (S=hexdump_of_response)
  */
 void generate_authenticator_response_pwhash(
 	const u8 *password_hash,
@@ -219,7 +219,7 @@
  * @username: 0-to-256-char UserName (IN)
  * @username_len: Length of username
  * @response: 20-octet AuthenticatorResponse (OUT) (note: this value is usually
- * encoded as a 42-octet ASCII string (S=<hexdump of response>)
+ * encoded as a 42-octet ASCII string (S=hexdump_of_response)
  */
 void generate_authenticator_response(const u8 *password, size_t password_len,
 				     const u8 *peer_challenge,
@@ -429,7 +429,7 @@
  * @new_password_len: Length of new_password
  * @old_password: 0-to-256-unicode-char OldPassword (IN; ASCII)
  * @old_password_len: Length of old_password
- * @encrypted_password_ash: 16-octet EncryptedPasswordHash (OUT)
+ * @encrypted_password_hash: 16-octet EncryptedPasswordHash (OUT)
  */
 void old_nt_password_hash_encrypted_with_new_nt_password_hash(
 	const u8 *new_password, size_t new_password_len,

Modified: wpasupplicant/trunk/src/crypto/sha1.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/sha1.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/sha1.c (original)
+++ wpasupplicant/trunk/src/crypto/sha1.c Sat Jan 10 09:03:49 2009
@@ -345,7 +345,7 @@
  * @passphrase: ASCII passphrase
  * @ssid: SSID
  * @ssid_len: SSID length in bytes
- * @interations: Number of iterations to run
+ * @iterations: Number of iterations to run
  * @buf: Buffer for the generated key
  * @buflen: Length of the buffer in bytes
  *

Modified: wpasupplicant/trunk/src/crypto/tls_openssl.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls_openssl.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls_openssl.c (original)
+++ wpasupplicant/trunk/src/crypto/tls_openssl.c Sat Jan 10 09:03:49 2009
@@ -37,7 +37,7 @@
 #define OPENSSL_d2i_TYPE unsigned char **
 #endif
 
-#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+#ifdef SSL_F_SSL_SET_SESSION_TICKET_EXT
 #ifdef SSL_OP_NO_TICKET
 /*
  * Session ticket override patch was merged into OpenSSL 0.9.9 tree on
@@ -120,10 +120,12 @@
 				     DWORD *pdwKeySpec, BOOL *pfCallerFreeProv)
 = NULL; /* to be loaded from crypt32.dll */
 
+#ifdef CONFIG_MINGW32_LOAD_CERTENUM
 static PCCERT_CONTEXT WINAPI
 (*CertEnumCertificatesInStore)(HCERTSTORE hCertStore,
 			       PCCERT_CONTEXT pPrevCertContext)
 = NULL; /* to be loaded from crypt32.dll */
+#endif /* CONFIG_MINGW32_LOAD_CERTENUM */
 
 static int mingw_load_crypto_func(void)
 {
@@ -151,6 +153,7 @@
 		return -1;
 	}
 
+#ifdef CONFIG_MINGW32_LOAD_CERTENUM
 	CertEnumCertificatesInStore = (void *) GetProcAddress(
 		dll, "CertEnumCertificatesInStore");
 	if (CertEnumCertificatesInStore == NULL) {
@@ -159,6 +162,7 @@
 			   "crypt32 library");
 		return -1;
 	}
+#endif /* CONFIG_MINGW32_LOAD_CERTENUM */
 
 	return 0;
 }

Modified: wpasupplicant/trunk/src/drivers/Apple80211.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/Apple80211.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/Apple80211.h (original)
+++ wpasupplicant/trunk/src/drivers/Apple80211.h Sat Jan 10 09:03:49 2009
@@ -105,11 +105,13 @@
  * channel: CFNumber(kCFNumberSInt32Type)
  * signal: CFNumber(kCFNumberSInt32Type)
  * appleIE: CFData
+ * WPSNOPINRequired: CFBoolean
  * noise: CFNumber(kCFNumberSInt32Type)
  * capability: CFNumber(kCFNumberSInt32Type)
  * uniCipher: CFArray of CFNumber(kCFNumberSInt32Type)
  * appleIE_Version: CFNumber(kCFNumberSInt32Type)
  * appleIE_Robust: CFBoolean
+ * WPSConfigured: CFBoolean
  * scanWasDirected: CFBoolean
  * appleIE_Product: CFNumber(kCFNumberSInt32Type)
  * authModes: CFArray of CFNumber(kCFNumberSInt32Type)

Modified: wpasupplicant/trunk/src/drivers/driver.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver.h (original)
+++ wpasupplicant/trunk/src/drivers/driver.h Sat Jan 10 09:03:49 2009
@@ -126,6 +126,23 @@
 };
 
 /**
+ * struct wpa_interface_info - Network interface information
+ * @next: Pointer to the next interface or NULL if this is the last one
+ * @ifname: Interface name that can be used with init() or init2()
+ * @desc: Human readable adapter description (e.g., vendor/model) or NULL if
+ *	not available
+ * @drv_bame: struct wpa_driver_ops::name (note: unlike other strings, this one
+ *	is not an allocated copy, i.e., get_interfaces() caller will not free
+ *	this)
+ */
+struct wpa_interface_info {
+	struct wpa_interface_info *next;
+	char *ifname;
+	char *desc;
+	const char *drv_name;
+};
+
+/**
  * struct wpa_driver_associate_params - Association parameters
  * Data for struct wpa_driver_ops::associate().
  */
@@ -164,6 +181,8 @@
 	 * instead. The driver can determine which version is used by
 	 * looking at the first byte of the IE (0xdd for WPA, 0x30 for
 	 * WPA2/RSN).
+	 *
+	 * When using WPS, wpa_ie is used for WPS IE instead of WPA/RSN IE.
 	 */
 	const u8 *wpa_ie;
 	/**
@@ -922,13 +941,13 @@
 	 struct wpa_scan_results * (*get_scan_results2)(void *priv);
 
 	/**
-	 * * set_probe_req_ie - Set information element(s) for Probe Request
+	 * set_probe_req_ie - Set information element(s) for Probe Request
 	 * @priv: private driver interface data
 	 * @ies: Information elements to append or %NULL to remove extra IEs
 	 * @ies_len: Length of the IE buffer in octets
 	 * Returns: 0 on success, -1 on failure
 	 */
-	int (*set_probe_req_ie)(void *, const u8 *ies, size_t ies_len);
+	int (*set_probe_req_ie)(void *priv, const u8 *ies, size_t ies_len);
 
  	/**
 	 * set_mode - Request driver to set the operating mode
@@ -943,6 +962,61 @@
 	 * Returns: 0 on success, -1 on failure
 	 */
 	int (*set_mode)(void *priv, int mode);
+
+	/**
+	 * set_country - Set country
+	 * @priv: Private driver interface data
+	 * @alpha2: country to which to switch to
+	 * Returns: 0 on success, -1 on failure
+	 *
+	 * This function is for drivers which support some form
+	 * of setting a regulatory domain.
+	 */
+	int (*set_country)(void *priv, const char *alpha2);
+
+	/**
+	 * global_init - Global driver initialization
+	 * Returns: Pointer to private data (global), %NULL on failure
+	 *
+	 * This optional function is called to initialize the driver wrapper
+	 * for global data, i.e., data that applies to all interfaces. If this
+	 * function is implemented, global_deinit() will also need to be
+	 * implemented to free the private data. The driver will also likely
+	 * use init2() function instead of init() to get the pointer to global
+	 * data available to per-interface initializer.
+	 */
+	void * (*global_init)(void);
+
+	/**
+	 * global_deinit - Global driver deinitialization
+	 * @priv: private driver global data from global_init()
+	 *
+	 * Terminate any global driver related functionality and free the
+	 * global data structure.
+	 */
+	void (*global_deinit)(void *priv);
+
+	/**
+	 * init2 - Initialize driver interface (with global data)
+	 * @ctx: context to be used when calling wpa_supplicant functions,
+	 * e.g., wpa_supplicant_event()
+	 * @ifname: interface name, e.g., wlan0
+	 * @global_priv: private driver global data from global_init()
+	 * Returns: Pointer to private data, %NULL on failure
+	 *
+	 * This function can be used instead of init() if the driver wrapper
+	 * uses global data.
+	 */
+	void * (*init2)(void *ctx, const char *ifname, void *global_priv);
+
+	/**
+	 * get_interfaces - Get information about available interfaces
+	 * @global_priv: private driver global data from global_init()
+	 * Returns: Allocated buffer of interface information (caller is
+	 * responsible for freeing the data structure) on success, NULL on
+	 * failure
+	 */
+	struct wpa_interface_info * (*get_interfaces)(void *global_priv);
 };
 
 /* Function to check whether a driver is for wired connections */
@@ -1239,8 +1313,11 @@
 
 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie);
 #define WPA_IE_VENDOR_TYPE 0x0050f201
+#define WPS_IE_VENDOR_TYPE 0x0050f204
 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
 				  u32 vendor_type);
+struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
+					     u32 vendor_type);
 int wpa_scan_get_max_rate(const struct wpa_scan_res *res);
 void wpa_scan_results_free(struct wpa_scan_results *res);
 void wpa_scan_sort_results(struct wpa_scan_results *res);

Modified: wpasupplicant/trunk/src/drivers/driver_ndis.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_ndis.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_ndis.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_ndis.c Sat Jan 10 09:03:49 2009
@@ -25,7 +25,11 @@
 #else /* CONFIG_USE_NDISUIO */
 #include <Packet32.h>
 #endif /* CONFIG_USE_NDISUIO */
+#ifdef __MINGW32_VERSION
+#include <ddk/ntddndis.h>
+#else /* __MINGW32_VERSION */
 #include <ntddndis.h>
+#endif /* __MINGW32_VERSION */
 
 #ifdef _WIN32_WCE
 #include <winioctl.h>
@@ -489,7 +493,7 @@
 	char txt[50];
 
 	os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid);
-	wpa_hexdump_key(MSG_MSGDUMP, txt, data, len);
+	wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len);
 
 	buflen = sizeof(*o) + len;
 	reallen = buflen - sizeof(o->Data);
@@ -517,7 +521,7 @@
 	char txt[50];
 
 	os_snprintf(txt, sizeof(txt), "NDIS: Set OID %08x", oid);
-	wpa_hexdump_key(MSG_MSGDUMP, txt, data, len);
+	wpa_hexdump_key(MSG_MSGDUMP, txt, (const u8 *) data, len);
 
 	buf = os_zalloc(sizeof(*o) + len);
 	if (buf == NULL)
@@ -615,8 +619,8 @@
 		return 0;
 	}
 
-	return ndis_get_oid(drv, OID_802_11_BSSID, bssid, ETH_ALEN) < 0 ?
-		-1 : 0;
+	return ndis_get_oid(drv, OID_802_11_BSSID, (char *) bssid, ETH_ALEN) <
+		0 ? -1 : 0;
 }
 
 
@@ -675,7 +679,7 @@
 	int i;
 	for (i = 0; i < 32; i++)
 		ssid[i] = rand() & 0xff;
-	return wpa_driver_ndis_set_ssid(drv, ssid, 32);
+	return wpa_driver_ndis_set_ssid(drv, (u8 *) ssid, 32);
 }
 
 
@@ -900,7 +904,7 @@
 	os_memcpy(wep->KeyMaterial, key, key_len);
 
 	wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_WEP",
-			(char *) wep, len);
+			(u8 *) wep, len);
 	res = ndis_set_oid(drv, OID_802_11_ADD_WEP, (char *) wep, len);
 
 	os_free(wep);
@@ -971,7 +975,7 @@
 	}
 
 	wpa_hexdump_key(MSG_MSGDUMP, "NDIS: OID_802_11_ADD_KEY",
-			(char *) nkey, len);
+			(u8 *) nkey, len);
 	res = ndis_set_oid(drv, OID_802_11_ADD_KEY, (char *) nkey, len);
 	os_free(nkey);
 
@@ -1039,6 +1043,11 @@
 			auth_mode = Ndis802_11AuthModeWPA2PSK;
 		else
 			auth_mode = Ndis802_11AuthModeWPA2;
+#ifdef CONFIG_WPS
+	} else if (params->key_mgmt_suite == KEY_MGMT_WPS) {
+		auth_mode = Ndis802_11AuthModeOpen;
+		priv_mode = Ndis802_11PrivFilterAcceptAll;
+#endif /* CONFIG_WPS */
 	} else {
 		priv_mode = Ndis802_11PrivFilter8021xWEP;
 		if (params->key_mgmt_suite == KEY_MGMT_WPA_NONE)
@@ -1084,7 +1093,8 @@
 	ndis_set_encr_status(drv, encr);
 
 	if (params->bssid) {
-		ndis_set_oid(drv, OID_802_11_BSSID, params->bssid, ETH_ALEN);
+		ndis_set_oid(drv, OID_802_11_BSSID, (char *) params->bssid,
+			     ETH_ALEN);
 		drv->oid_bssid_set = 1;
 	} else if (drv->oid_bssid_set) {
 		ndis_set_oid(drv, OID_802_11_BSSID, "\xff\xff\xff\xff\xff\xff",
@@ -1123,7 +1133,7 @@
 		os_memcpy(&p->BSSIDInfo[i].PMKID, entry->pmkid, 16);
 		entry = entry->next;
 	}
-	wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (char *) p, len);
+	wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID", (u8 *) p, len);
 	ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) p, len);
 	os_free(p);
 	return ret;
@@ -1229,7 +1239,7 @@
 	p.Length = 8;
 	p.BSSIDInfoCount = 0;
 	wpa_hexdump(MSG_MSGDUMP, "NDIS: OID_802_11_PMKID (flush)",
-		    (char *) &p, 8);
+		    (u8 *) &p, 8);
 	ret = ndis_set_oid(drv, OID_802_11_PMKID, (char *) &p, 8);
 
 	if (prev_authmode != Ndis802_11AuthModeWPA2)
@@ -1275,7 +1285,8 @@
 			len = sizeof(buf);
 		}
 	}
-	wpa_hexdump(MSG_MSGDUMP, "NDIS: association information", buf, len);
+	wpa_hexdump(MSG_MSGDUMP, "NDIS: association information",
+		    (u8 *) buf, len);
 	if (len < sizeof(*ai)) {
 		wpa_printf(MSG_DEBUG, "NDIS: too short association "
 			   "information");
@@ -1296,14 +1307,14 @@
 	}
 
 	wpa_hexdump(MSG_MSGDUMP, "NDIS: Request IEs",
-		    buf + ai->OffsetRequestIEs, ai->RequestIELength);
+		    (u8 *) buf + ai->OffsetRequestIEs, ai->RequestIELength);
 	wpa_hexdump(MSG_MSGDUMP, "NDIS: Response IEs",
-		    buf + ai->OffsetResponseIEs, ai->ResponseIELength);
+		    (u8 *) buf + ai->OffsetResponseIEs, ai->ResponseIELength);
 
 	os_memset(&data, 0, sizeof(data));
-	data.assoc_info.req_ies = buf + ai->OffsetRequestIEs;
+	data.assoc_info.req_ies = (u8 *) buf + ai->OffsetRequestIEs;
 	data.assoc_info.req_ies_len = ai->RequestIELength;
-	data.assoc_info.resp_ies = buf + ai->OffsetResponseIEs;
+	data.assoc_info.resp_ies = (u8 *) buf + ai->OffsetResponseIEs;
 	data.assoc_info.resp_ies_len = ai->ResponseIELength;
 
 	blen = 65535;
@@ -1658,7 +1669,7 @@
 		return;
 	}
 
-	wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", buf, len);
+	wpa_hexdump(MSG_MSGDUMP, "OID_802_11_CAPABILITY", (u8 *) buf, len);
 	c = (NDIS_802_11_CAPABILITY *) buf;
 	if (len < sizeof(*c) || c->Version != 2) {
 		wpa_printf(MSG_DEBUG, "NDIS: unsupported "
@@ -2734,7 +2745,7 @@
 	}
 
 	if (ndis_get_oid(drv, OID_802_3_CURRENT_ADDRESS,
-			 drv->own_addr, ETH_ALEN) < 0) {
+			 (char *) drv->own_addr, ETH_ALEN) < 0) {
 		wpa_printf(MSG_DEBUG, "NDIS: Get OID_802_3_CURRENT_ADDRESS "
 			   "failed");
 		wpa_driver_ndis_adapter_close(drv);
@@ -2830,6 +2841,240 @@
 #endif /* _WIN32_WCE */
 	os_free(drv->adapter_desc);
 	os_free(drv);
+}
+
+
+static struct wpa_interface_info *
+wpa_driver_ndis_get_interfaces(void *global_priv)
+{
+	struct wpa_interface_info *iface = NULL, *niface;
+
+#ifdef CONFIG_USE_NDISUIO
+	NDISUIO_QUERY_BINDING *b;
+	size_t blen = sizeof(*b) + 1024;
+	int i, error;
+	DWORD written;
+	char name[256], desc[256];
+	WCHAR *pos;
+	size_t j, len;
+	HANDLE ndisuio;
+
+	ndisuio = CreateFile(NDISUIO_DEVICE_NAME,
+			     GENERIC_READ | GENERIC_WRITE, 0, NULL,
+			     OPEN_EXISTING,
+			     FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+			     INVALID_HANDLE_VALUE);
+	if (ndisuio == INVALID_HANDLE_VALUE) {
+		wpa_printf(MSG_ERROR, "NDIS: Failed to open connection to "
+			   "NDISUIO: %d", (int) GetLastError());
+		return NULL;
+	}
+
+#ifndef _WIN32_WCE
+	if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_BIND_WAIT, NULL, 0,
+			     NULL, 0, &written, NULL)) {
+		wpa_printf(MSG_ERROR, "NDIS: IOCTL_NDISUIO_BIND_WAIT failed: "
+			   "%d", (int) GetLastError());
+		CloseHandle(ndisuio);
+		return NULL;
+	}
+#endif /* _WIN32_WCE */
+
+	b = os_malloc(blen);
+	if (b == NULL) {
+		CloseHandle(ndisuio);
+		return NULL;
+	}
+
+	for (i = 0; ; i++) {
+		os_memset(b, 0, blen);
+		b->BindingIndex = i;
+		if (!DeviceIoControl(ndisuio, IOCTL_NDISUIO_QUERY_BINDING,
+				     b, sizeof(NDISUIO_QUERY_BINDING), b, blen,
+				     &written, NULL)) {
+			error = (int) GetLastError();
+			if (error == ERROR_NO_MORE_ITEMS)
+				break;
+			wpa_printf(MSG_DEBUG, "IOCTL_NDISUIO_QUERY_BINDING "
+				   "failed: %d", error);
+			break;
+		}
+
+		pos = (WCHAR *) ((char *) b + b->DeviceNameOffset);
+		len = b->DeviceNameLength;
+		if (len >= sizeof(name))
+			len = sizeof(name) - 1;
+		for (j = 0; j < len; j++)
+			name[j] = (char) pos[j];
+		name[len] = '\0';
+
+		pos = (WCHAR *) ((char *) b + b->DeviceDescrOffset);
+		len = b->DeviceDescrLength;
+		if (len >= sizeof(desc))
+			len = sizeof(desc) - 1;
+		for (j = 0; j < len; j++)
+			desc[j] = (char) pos[j];
+		desc[len] = '\0';
+
+		wpa_printf(MSG_DEBUG, "NDIS: %d - %s - %s", i, name, desc);
+
+		niface = os_zalloc(sizeof(*niface));
+		if (niface == NULL)
+			break;
+		niface->drv_name = "ndis";
+		if (os_strncmp(name, "\\DEVICE\\", 8) == 0)
+			niface->ifname = os_strdup(name + 8);
+		else
+			niface->ifname = os_strdup(name);
+		if (niface->ifname == NULL) {
+			os_free(niface);
+			break;
+		}
+		niface->desc = os_strdup(desc);
+		niface->next = iface;
+		iface = niface;
+	}
+
+	os_free(b);
+	CloseHandle(ndisuio);
+#else /* CONFIG_USE_NDISUIO */
+	PTSTR _names;
+	char *names, *pos, *pos2;
+	ULONG len;
+	BOOLEAN res;
+	char *name[MAX_ADAPTERS];
+	char *desc[MAX_ADAPTERS];
+	int num_name, num_desc, i;
+
+	wpa_printf(MSG_DEBUG, "NDIS: Packet.dll version: %s",
+		   PacketGetVersion());
+
+	len = 8192;
+	_names = os_zalloc(len);
+	if (_names == NULL)
+		return NULL;
+
+	res = PacketGetAdapterNames(_names, &len);
+	if (!res && len > 8192) {
+		os_free(_names);
+		_names = os_zalloc(len);
+		if (_names == NULL)
+			return NULL;
+		res = PacketGetAdapterNames(_names, &len);
+	}
+
+	if (!res) {
+		wpa_printf(MSG_ERROR, "NDIS: Failed to get adapter list "
+			   "(PacketGetAdapterNames)");
+		os_free(_names);
+		return NULL;
+	}
+
+	names = (char *) _names;
+	if (names[0] && names[1] == '\0' && names[2] && names[3] == '\0') {
+		wpa_printf(MSG_DEBUG, "NDIS: Looks like adapter names are in "
+			   "UNICODE");
+		/* Convert to ASCII */
+		pos2 = pos = names;
+		while (pos2 < names + len) {
+			if (pos2[0] == '\0' && pos2[1] == '\0' &&
+			    pos2[2] == '\0' && pos2[3] == '\0') {
+				pos2 += 4;
+				break;
+			}
+			*pos++ = pos2[0];
+			pos2 += 2;
+		}
+		os_memcpy(pos + 2, names, pos - names);
+		pos += 2;
+	} else
+		pos = names;
+
+	num_name = 0;
+	while (pos < names + len) {
+		name[num_name] = pos;
+		while (*pos && pos < names + len)
+			pos++;
+		if (pos + 1 >= names + len) {
+			os_free(names);
+			return NULL;
+		}
+		pos++;
+		num_name++;
+		if (num_name >= MAX_ADAPTERS) {
+			wpa_printf(MSG_DEBUG, "NDIS: Too many adapters");
+			os_free(names);
+			return NULL;
+		}
+		if (*pos == '\0') {
+			wpa_printf(MSG_DEBUG, "NDIS: %d adapter names found",
+				   num_name);
+			pos++;
+			break;
+		}
+	}
+
+	num_desc = 0;
+	while (pos < names + len) {
+		desc[num_desc] = pos;
+		while (*pos && pos < names + len)
+			pos++;
+		if (pos + 1 >= names + len) {
+			os_free(names);
+			return NULL;
+		}
+		pos++;
+		num_desc++;
+		if (num_desc >= MAX_ADAPTERS) {
+			wpa_printf(MSG_DEBUG, "NDIS: Too many adapter "
+				   "descriptions");
+			os_free(names);
+			return NULL;
+		}
+		if (*pos == '\0') {
+			wpa_printf(MSG_DEBUG, "NDIS: %d adapter descriptions "
+				   "found", num_name);
+			pos++;
+			break;
+		}
+	}
+
+	/*
+	 * Windows 98 with Packet.dll 3.0 alpha3 does not include adapter
+	 * descriptions. Fill in dummy descriptors to work around this.
+	 */
+	while (num_desc < num_name)
+		desc[num_desc++] = "dummy description";
+
+	if (num_name != num_desc) {
+		wpa_printf(MSG_DEBUG, "NDIS: mismatch in adapter name and "
+			   "description counts (%d != %d)",
+			   num_name, num_desc);
+		os_free(names);
+		return NULL;
+	}
+
+	for (i = 0; i < num_name; i++) {
+		niface = os_zalloc(sizeof(*niface));
+		if (niface == NULL)
+			break;
+		niface->drv_name = "ndis";
+		if (os_strncmp(name[i], "\\Device\\NPF_", 12) == 0)
+			niface->ifname = os_strdup(name[i] + 12);
+		else
+			niface->ifname = os_strdup(name[i]);
+		if (niface->ifname == NULL) {
+			os_free(niface);
+			break;
+		}
+		niface->desc = os_strdup(desc[i]);
+		niface->next = iface;
+		iface = niface;
+	}
+
+#endif /* CONFIG_USE_NDISUIO */
+
+	return iface;
 }
 
 
@@ -2872,5 +3117,10 @@
 	NULL /* send_ft_action */,
 	wpa_driver_ndis_get_scan_results,
 	NULL /* set_probe_req_ie */,
-	NULL /* set_mode */
+	NULL /* set_mode */,
+	NULL /* set_country */,
+	NULL /* global_init */,
+	NULL /* global_deinit */,
+	NULL /* init2 */,
+	wpa_driver_ndis_get_interfaces
 };

Modified: wpasupplicant/trunk/src/drivers/driver_nl80211.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_nl80211.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_nl80211.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_nl80211.c Sat Jan 10 09:03:49 2009
@@ -18,7 +18,7 @@
 #include <netlink/genl/genl.h>
 #include <netlink/genl/family.h>
 #include <netlink/genl/ctrl.h>
-#include <linux/nl80211.h>
+#include "nl80211_copy.h"
 #ifdef CONFIG_CLIENT_MLME
 #include <netpacket/packet.h>
 #include <linux/if_ether.h>
@@ -958,6 +958,41 @@
 }
 
 
+/**
+ * wpa_driver_nl80211_set_country - ask nl80211 to set the regulatory domain
+ * @priv: driver_nl80211 private data
+ * @alpha2_arg: country to which to switch to
+ * Returns: 0 on success, -1 on failure
+ *
+ * This asks nl80211 to set the regulatory domain for given
+ * country ISO / IEC alpha2.
+ */
+static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
+{
+	struct wpa_driver_nl80211_data *drv = priv;
+	char alpha2[3];
+	struct nl_msg *msg;
+
+	msg = nlmsg_alloc();
+	if (!msg)
+		goto nla_put_failure;
+
+	alpha2[0] = alpha2_arg[0];
+	alpha2[1] = alpha2_arg[1];
+	alpha2[2] = '\0';
+
+	genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
+		    0, NL80211_CMD_REQ_SET_REG, 0);
+
+	NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
+	if (send_and_recv_msgs(drv, msg, NULL, NULL))
+		return -EINVAL;
+	return 0;
+nla_put_failure:
+	return -EINVAL;
+}
+
+
 #ifdef CONFIG_CLIENT_MLME
 
 static int nl80211_set_vif(struct wpa_driver_nl80211_data *drv,
@@ -1211,13 +1246,13 @@
 
 
 /**
- * wpa_driver_nl80211_init - Initialize WE driver interface
+ * wpa_driver_nl80211_init - Initialize nl80211 driver interface
  * @ctx: context to be used when calling wpa_supplicant functions,
  * e.g., wpa_supplicant_event()
  * @ifname: interface name, e.g., wlan0
  * Returns: Pointer to private data, %NULL on failure
  */
-void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
+static void * wpa_driver_nl80211_init(void *ctx, const char *ifname)
 {
 	int s;
 	struct sockaddr_nl local;
@@ -1351,13 +1386,13 @@
 
 
 /**
- * wpa_driver_nl80211_deinit - Deinitialize WE driver interface
- * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
+ * wpa_driver_nl80211_deinit - Deinitialize nl80211 driver interface
+ * @priv: Pointer to private nl80211 data from wpa_driver_nl80211_init()
  *
  * Shut down driver interface and processing of driver events. Free
  * private data buffer if one was allocated in wpa_driver_nl80211_init().
  */
-void wpa_driver_nl80211_deinit(void *priv)
+static void wpa_driver_nl80211_deinit(void *priv)
 {
 	struct wpa_driver_nl80211_data *drv = priv;
 	int flags;
@@ -1814,7 +1849,8 @@
  * @priv: Pointer to private wext data from wpa_driver_nl80211_init()
  * Returns: Scan results on success, -1 on failure
  */
-struct wpa_scan_results * wpa_driver_nl80211_get_scan_results(void *priv)
+static struct wpa_scan_results *
+wpa_driver_nl80211_get_scan_results(void *priv)
 {
 	struct wpa_driver_nl80211_data *drv = priv;
 	size_t ap_num = 0, len;
@@ -2858,6 +2894,7 @@
 	.flush_pmkid = wpa_driver_nl80211_flush_pmkid,
 	.get_capa = wpa_driver_nl80211_get_capa,
 	.set_operstate = wpa_driver_nl80211_set_operstate,
+	.set_country = wpa_driver_nl80211_set_country,
 #ifdef CONFIG_CLIENT_MLME
 	.get_hw_feature_data = wpa_driver_nl80211_get_hw_feature_data,
 	.set_channel = wpa_driver_nl80211_set_channel,

Modified: wpasupplicant/trunk/src/drivers/driver_privsep.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_privsep.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_privsep.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_privsep.c Sat Jan 10 09:03:49 2009
@@ -774,7 +774,12 @@
 	NULL /* send_ft_action */,
 	wpa_driver_privsep_get_scan_results2,
 	NULL /* set_probe_req_ie */,
-	wpa_driver_privsep_set_mode
+	wpa_driver_privsep_set_mode,
+	NULL /* set_country */,
+	NULL /* global_init */,
+	NULL /* global_deinit */,
+	NULL /* init2 */,
+	NULL /* get_interfaces */
 };
 
 

Modified: wpasupplicant/trunk/src/drivers/driver_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_test.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_test.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_test.c Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - testing driver interface
- * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2008, 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
@@ -12,10 +12,20 @@
  * See README and COPYING for more details.
  */
 
+/* Make dure we get winsock2.h for Windows build to get sockaddr_storage */
+#include "build_config.h"
+#ifdef CONFIG_NATIVE_WINDOWS
+#include <winsock2.h>
+#endif /* CONFIG_NATIVE_WINDOWS */
+
 #include "includes.h"
+
+#ifndef CONFIG_NATIVE_WINDOWS
 #include <sys/un.h>
 #include <dirent.h>
 #include <sys/stat.h>
+#define DRIVER_TEST_UNIX
+#endif /* CONFIG_NATIVE_WINDOWS */
 
 #include "common.h"
 #include "driver.h"
@@ -25,12 +35,21 @@
 #include "ieee802_11_defs.h"
 
 
+struct wpa_driver_test_global {
+	int dummy;
+};
+
 struct wpa_driver_test_data {
+	struct wpa_driver_test_global *global;
 	void *ctx;
 	u8 own_addr[ETH_ALEN];
 	int test_socket;
+#ifdef DRIVER_TEST_UNIX
 	struct sockaddr_un hostapd_addr;
+#endif /* DRIVER_TEST_UNIX */
 	int hostapd_addr_set;
+	struct sockaddr_in hostapd_addr_udp;
+	int hostapd_addr_udp_set;
 	char *own_socket_path;
 	char *test_dir;
 	u8 bssid[ETH_ALEN];
@@ -44,6 +63,8 @@
 	size_t assoc_wpa_ie_len;
 	int use_mlme;
 	int associated;
+	u8 *probe_req_ie;
+	size_t probe_req_ie_len;
 };
 
 
@@ -51,6 +72,7 @@
 {
 	struct wpa_driver_test_data *drv = eloop_ctx;
 
+#ifdef DRIVER_TEST_UNIX
 	if (drv->associated && drv->hostapd_addr_set) {
 		struct stat st;
 		if (stat(drv->hostapd_addr.sun_path, &st) < 0) {
@@ -60,6 +82,7 @@
 			wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
 		}
 	}
+#endif /* DRIVER_TEST_UNIX */
 
 	eloop_register_timeout(1, 0, wpa_driver_test_poll, drv, NULL);
 }
@@ -79,16 +102,34 @@
 }
 
 
+#ifdef DRIVER_TEST_UNIX
 static void wpa_driver_scan_dir(struct wpa_driver_test_data *drv,
 				const char *path)
 {
 	struct dirent *dent;
 	DIR *dir;
 	struct sockaddr_un addr;
+	char cmd[512], *pos, *end;
+	int ret;
 
 	dir = opendir(path);
 	if (dir == NULL)
 		return;
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = os_snprintf(pos, end - pos, "SCAN " MACSTR,
+			  MAC2STR(drv->own_addr));
+	if (ret >= 0 && ret < end - pos)
+		pos += ret;
+	if (drv->probe_req_ie) {
+		ret = os_snprintf(pos, end - pos, " ");
+		if (ret >= 0 && ret < end - pos)
+			pos += ret;
+		pos += wpa_snprintf_hex(pos, end - pos, drv->probe_req_ie,
+					drv->probe_req_ie_len);
+	}
+	end[-1] = '\0';
 
 	while ((dent = readdir(dir))) {
 		if (os_strncmp(dent->d_name, "AP-", 3) != 0)
@@ -100,13 +141,14 @@
 		os_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/%s",
 			    path, dent->d_name);
 
-		if (sendto(drv->test_socket, "SCAN", 4, 0,
+		if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
 			   (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 			perror("sendto(test_socket)");
 		}
 	}
 	closedir(dir);
 }
+#endif /* DRIVER_TEST_UNIX */
 
 
 static int wpa_driver_test_scan(void *priv, const u8 *ssid, size_t ssid_len)
@@ -116,6 +158,7 @@
 
 	drv->num_scanres = 0;
 
+#ifdef DRIVER_TEST_UNIX
 	if (drv->test_socket >= 0 && drv->test_dir)
 		wpa_driver_scan_dir(drv, drv->test_dir);
 
@@ -123,6 +166,14 @@
 	    sendto(drv->test_socket, "SCAN", 4, 0,
 		   (struct sockaddr *) &drv->hostapd_addr,
 		   sizeof(drv->hostapd_addr)) < 0) {
+		perror("sendto(test_socket)");
+	}
+#endif /* DRIVER_TEST_UNIX */
+
+	if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
+	    sendto(drv->test_socket, "SCAN", 4, 0,
+		   (struct sockaddr *) &drv->hostapd_addr_udp,
+		   sizeof(drv->hostapd_addr_udp)) < 0) {
 		perror("sendto(test_socket)");
 	}
 
@@ -213,6 +264,7 @@
 	} else
 		drv->assoc_wpa_ie_len = 0;
 
+#ifdef DRIVER_TEST_UNIX
 	if (drv->test_dir && params->bssid) {
 		os_memset(&drv->hostapd_addr, 0, sizeof(drv->hostapd_addr));
 		drv->hostapd_addr.sun_family = AF_UNIX;
@@ -222,8 +274,10 @@
 			    drv->test_dir, MAC2STR(params->bssid));
 		drv->hostapd_addr_set = 1;
 	}
-
-	if (drv->test_socket >= 0 && drv->hostapd_addr_set) {
+#endif /* DRIVER_TEST_UNIX */
+
+	if (drv->test_socket >= 0 &&
+	    (drv->hostapd_addr_set || drv->hostapd_addr_udp_set)) {
 		char cmd[200], *pos, *end;
 		int ret;
 		end = cmd + sizeof(cmd);
@@ -240,12 +294,22 @@
 		pos += wpa_snprintf_hex(pos, end - pos, params->wpa_ie,
 					params->wpa_ie_len);
 		end[-1] = '\0';
-		if (sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
+#ifdef DRIVER_TEST_UNIX
+		if (drv->hostapd_addr_set &&
+		    sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
 			   (struct sockaddr *) &drv->hostapd_addr,
 			   sizeof(drv->hostapd_addr)) < 0) {
 			perror("sendto(test_socket)");
 			return -1;
 		}
+#endif /* DRIVER_TEST_UNIX */
+		if (drv->hostapd_addr_udp_set &&
+		    sendto(drv->test_socket, cmd, os_strlen(cmd), 0,
+			   (struct sockaddr *) &drv->hostapd_addr_udp,
+			   sizeof(drv->hostapd_addr_udp)) < 0) {
+			perror("sendto(test_socket)");
+			return -1;
+		}
 
 		os_memcpy(drv->ssid, params->ssid, params->ssid_len);
 		drv->ssid_len = params->ssid_len;
@@ -276,6 +340,7 @@
 
 static int wpa_driver_test_send_disassoc(struct wpa_driver_test_data *drv)
 {
+#ifdef DRIVER_TEST_UNIX
 	if (drv->test_socket >= 0 &&
 	    sendto(drv->test_socket, "DISASSOC", 8, 0,
 		   (struct sockaddr *) &drv->hostapd_addr,
@@ -283,6 +348,14 @@
 		perror("sendto(test_socket)");
 		return -1;
 	}
+#endif /* DRIVER_TEST_UNIX */
+	if (drv->test_socket >= 0 && drv->hostapd_addr_udp_set &&
+	    sendto(drv->test_socket, "DISASSOC", 8, 0,
+		   (struct sockaddr *) &drv->hostapd_addr_udp,
+		   sizeof(drv->hostapd_addr_udp)) < 0) {
+		perror("sendto(test_socket)");
+		return -1;
+	}
 	return 0;
 }
 
@@ -314,7 +387,7 @@
 
 
 static void wpa_driver_test_scanresp(struct wpa_driver_test_data *drv,
-				     struct sockaddr_un *from,
+				     struct sockaddr *from,
 				     socklen_t fromlen,
 				     const char *data)
 {
@@ -401,7 +474,7 @@
 
 
 static void wpa_driver_test_assocresp(struct wpa_driver_test_data *drv,
-				      struct sockaddr_un *from,
+				      struct sockaddr *from,
 				      socklen_t fromlen,
 				      const char *data)
 {
@@ -423,7 +496,7 @@
 
 
 static void wpa_driver_test_disassoc(struct wpa_driver_test_data *drv,
-				     struct sockaddr_un *from,
+				     struct sockaddr *from,
 				     socklen_t fromlen)
 {
 	drv->associated = 0;
@@ -432,7 +505,7 @@
 
 
 static void wpa_driver_test_eapol(struct wpa_driver_test_data *drv,
-				  struct sockaddr_un *from,
+				  struct sockaddr *from,
 				  socklen_t fromlen,
 				  const u8 *data, size_t data_len)
 {
@@ -449,7 +522,7 @@
 
 
 static void wpa_driver_test_mlme(struct wpa_driver_test_data *drv,
-				 struct sockaddr_un *from,
+				 struct sockaddr *from,
 				 socklen_t fromlen,
 				 const u8 *data, size_t data_len)
 {
@@ -467,7 +540,7 @@
 	struct wpa_driver_test_data *drv = eloop_ctx;
 	char *buf;
 	int res;
-	struct sockaddr_un from;
+	struct sockaddr_storage from;
 	socklen_t fromlen = sizeof(from);
 	const size_t buflen = 2000;
 
@@ -486,18 +559,22 @@
 	wpa_printf(MSG_DEBUG, "test_driver: received %u bytes", res);
 
 	if (os_strncmp(buf, "SCANRESP ", 9) == 0) {
-		wpa_driver_test_scanresp(drv, &from, fromlen, buf + 9);
+		wpa_driver_test_scanresp(drv, (struct sockaddr *) &from,
+					 fromlen, buf + 9);
 	} else if (os_strncmp(buf, "ASSOCRESP ", 10) == 0) {
-		wpa_driver_test_assocresp(drv, &from, fromlen, buf + 10);
+		wpa_driver_test_assocresp(drv, (struct sockaddr *) &from,
+					  fromlen, buf + 10);
 	} else if (os_strcmp(buf, "DISASSOC") == 0) {
-		wpa_driver_test_disassoc(drv, &from, fromlen);
+		wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
+					 fromlen);
 	} else if (os_strcmp(buf, "DEAUTH") == 0) {
-		wpa_driver_test_disassoc(drv, &from, fromlen);
+		wpa_driver_test_disassoc(drv, (struct sockaddr *) &from,
+					 fromlen);
 	} else if (os_strncmp(buf, "EAPOL ", 6) == 0) {
-		wpa_driver_test_eapol(drv, &from, fromlen,
+		wpa_driver_test_eapol(drv, (struct sockaddr *) &from, fromlen,
 				      (const u8 *) buf + 6, res - 6);
 	} else if (os_strncmp(buf, "MLME ", 5) == 0) {
-		wpa_driver_test_mlme(drv, &from, fromlen,
+		wpa_driver_test_mlme(drv, (struct sockaddr *) &from, fromlen,
 				     (const u8 *) buf + 5, res - 5);
 	} else {
 		wpa_hexdump_ascii(MSG_DEBUG, "Unknown test_socket command",
@@ -507,13 +584,15 @@
 }
 
 
-static void * wpa_driver_test_init(void *ctx, const char *ifname)
+static void * wpa_driver_test_init2(void *ctx, const char *ifname,
+				    void *global_priv)
 {
 	struct wpa_driver_test_data *drv;
 
 	drv = os_zalloc(sizeof(*drv));
 	if (drv == NULL)
 		return NULL;
+	drv->global = global_priv;
 	drv->ctx = ctx;
 	drv->test_socket = -1;
 
@@ -564,6 +643,7 @@
 	os_free(drv->test_dir);
 	for (i = 0; i < MAX_SCAN_RESULTS; i++)
 		os_free(drv->scanres[i]);
+	os_free(drv->probe_req_ie);
 	os_free(drv);
 }
 
@@ -571,6 +651,7 @@
 static int wpa_driver_test_attach(struct wpa_driver_test_data *drv,
 				  const char *dir)
 {
+#ifdef DRIVER_TEST_UNIX
 	static unsigned int counter = 0;
 	struct sockaddr_un addr;
 	size_t len;
@@ -617,22 +698,73 @@
 				 wpa_driver_test_receive_unix, drv, NULL);
 
 	return 0;
+#else /* DRIVER_TEST_UNIX */
+	return -1;
+#endif /* DRIVER_TEST_UNIX */
+}
+
+
+static int wpa_driver_test_attach_udp(struct wpa_driver_test_data *drv,
+				      char *dst)
+{
+	char *pos;
+
+	pos = os_strchr(dst, ':');
+	if (pos == NULL)
+		return -1;
+	*pos++ = '\0';
+	wpa_printf(MSG_DEBUG, "%s: addr=%s port=%s", __func__, dst, pos);
+
+	drv->test_socket = socket(PF_INET, SOCK_DGRAM, 0);
+	if (drv->test_socket < 0) {
+		perror("socket(PF_INET)");
+		return -1;
+	}
+
+	os_memset(&drv->hostapd_addr_udp, 0, sizeof(drv->hostapd_addr_udp));
+	drv->hostapd_addr_udp.sin_family = AF_INET;
+#if defined(CONFIG_NATIVE_WINDOWS) || defined(CONFIG_ANSI_C_EXTRA)
+	{
+		int a[4];
+		u8 *pos;
+		sscanf(dst, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]);
+		pos = (u8 *) &drv->hostapd_addr_udp.sin_addr;
+		*pos++ = a[0];
+		*pos++ = a[1];
+		*pos++ = a[2];
+		*pos++ = a[3];
+	}
+#else /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
+	inet_aton(dst, &drv->hostapd_addr_udp.sin_addr);
+#endif /* CONFIG_NATIVE_WINDOWS or CONFIG_ANSI_C_EXTRA */
+	drv->hostapd_addr_udp.sin_port = htons(atoi(pos));
+
+	drv->hostapd_addr_udp_set = 1;
+
+	eloop_register_read_sock(drv->test_socket,
+				 wpa_driver_test_receive_unix, drv, NULL);
+
+	return 0;
 }
 
 
 static int wpa_driver_test_set_param(void *priv, const char *param)
 {
 	struct wpa_driver_test_data *drv = priv;
-	const char *pos, *pos2;
-	size_t len;
+	const char *pos;
 
 	wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
 	if (param == NULL)
 		return 0;
 
 	wpa_driver_test_close_test_socket(drv);
+
+#ifdef DRIVER_TEST_UNIX
 	pos = os_strstr(param, "test_socket=");
 	if (pos) {
+		const char *pos2;
+		size_t len;
+
 		pos += 12;
 		pos2 = os_strchr(pos, ' ');
 		if (pos2)
@@ -646,6 +778,7 @@
 		os_memcpy(drv->hostapd_addr.sun_path, pos, len);
 		drv->hostapd_addr_set = 1;
 	}
+#endif /* DRIVER_TEST_UNIX */
 
 	pos = os_strstr(param, "test_dir=");
 	if (pos) {
@@ -657,9 +790,24 @@
 		end = os_strchr(drv->test_dir, ' ');
 		if (end)
 			*end = '\0';
-		wpa_driver_test_attach(drv, drv->test_dir);
-	} else
-		wpa_driver_test_attach(drv, NULL);
+		if (wpa_driver_test_attach(drv, drv->test_dir))
+			return -1;
+	} else {
+		pos = os_strstr(param, "test_udp=");
+		if (pos) {
+			char *dst, *epos;
+			dst = os_strdup(pos + 9);
+			if (dst == NULL)
+				return -1;
+			epos = os_strchr(dst, ' ');
+			if (epos)
+				*epos = '\0';
+			if (wpa_driver_test_attach_udp(drv, dst))
+				return -1;
+			os_free(dst);
+		} else if (wpa_driver_test_attach(drv, NULL))
+			return -1;
+	}
 
 	if (os_strstr(param, "use_associnfo=1")) {
 		wpa_printf(MSG_DEBUG, "test_driver: Use AssocInfo events");
@@ -689,10 +837,14 @@
 				      const u8 *data, size_t data_len)
 {
 	struct wpa_driver_test_data *drv = priv;
-	struct msghdr msg;
-	struct iovec io[3];
+	char *msg;
+	size_t msg_len;
 	struct l2_ethhdr eth;
-	struct sockaddr_un addr;
+	struct sockaddr *addr;
+	socklen_t alen;
+#ifdef DRIVER_TEST_UNIX
+	struct sockaddr_un addr_un;
+#endif /* DRIVER_TEST_UNIX */
 
 	wpa_hexdump(MSG_MSGDUMP, "test_send_eapol TX frame", data, data_len);
 
@@ -701,40 +853,55 @@
 	os_memcpy(eth.h_source, drv->own_addr, ETH_ALEN);
 	eth.h_proto = host_to_be16(proto);
 
-	io[0].iov_base = "EAPOL ";
-	io[0].iov_len = 6;
-	io[1].iov_base = (u8 *) &eth;
-	io[1].iov_len = sizeof(eth);
-	io[2].iov_base = (u8 *) data;
-	io[2].iov_len = data_len;
-
-	os_memset(&msg, 0, sizeof(msg));
-	msg.msg_iov = io;
-	msg.msg_iovlen = 3;
+	msg_len = 6 + sizeof(eth) + data_len;
+	msg = os_malloc(msg_len);
+	if (msg == NULL)
+		return -1;
+	os_memcpy(msg, "EAPOL ", 6);
+	os_memcpy(msg + 6, &eth, sizeof(eth));
+	os_memcpy(msg + 6 + sizeof(eth), data, data_len);
+
 	if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
 	    drv->test_dir == NULL) {
-		msg.msg_name = &drv->hostapd_addr;
-		msg.msg_namelen = sizeof(drv->hostapd_addr);
+		if (drv->hostapd_addr_udp_set) {
+			addr = (struct sockaddr *) &drv->hostapd_addr_udp;
+			alen = sizeof(drv->hostapd_addr_udp);
+		} else {
+#ifdef DRIVER_TEST_UNIX
+			addr = (struct sockaddr *) &drv->hostapd_addr;
+			alen = sizeof(drv->hostapd_addr);
+#else /* DRIVER_TEST_UNIX */
+			os_free(msg);
+			return -1;
+#endif /* DRIVER_TEST_UNIX */
+		}
 	} else {
+#ifdef DRIVER_TEST_UNIX
 		struct stat st;
-		os_memset(&addr, 0, sizeof(addr));
-		addr.sun_family = AF_UNIX;
-		os_snprintf(addr.sun_path, sizeof(addr.sun_path),
+		os_memset(&addr_un, 0, sizeof(addr_un));
+		addr_un.sun_family = AF_UNIX;
+		os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
 			    "%s/STA-" MACSTR, drv->test_dir, MAC2STR(dest));
-		if (stat(addr.sun_path, &st) < 0) {
-			os_snprintf(addr.sun_path, sizeof(addr.sun_path),
+		if (stat(addr_un.sun_path, &st) < 0) {
+			os_snprintf(addr_un.sun_path, sizeof(addr_un.sun_path),
 				    "%s/AP-" MACSTR,
 				    drv->test_dir, MAC2STR(dest));
 		}
-		msg.msg_name = &addr;
-		msg.msg_namelen = sizeof(addr);
-	}
-
-	if (sendmsg(drv->test_socket, &msg, 0) < 0) {
+		addr = (struct sockaddr *) &addr_un;
+		alen = sizeof(addr_un);
+#else /* DRIVER_TEST_UNIX */
+		os_free(msg);
+		return -1;
+#endif /* DRIVER_TEST_UNIX */
+	}
+
+	if (sendto(drv->test_socket, msg, msg_len, 0, addr, alen) < 0) {
 		perror("sendmsg(test_socket)");
+		os_free(msg);
 		return -1;
 	}
 
+	os_free(msg);
 	return 0;
 }
 
@@ -811,8 +978,8 @@
 }
 
 
-int wpa_driver_test_set_channel(void *priv, wpa_hw_mode phymode, int chan,
-				int freq)
+static int wpa_driver_test_set_channel(void *priv, wpa_hw_mode phymode,
+				       int chan, int freq)
 {
 	wpa_printf(MSG_DEBUG, "%s: phymode=%d chan=%d freq=%d",
 		   __func__, phymode, chan, freq);
@@ -846,8 +1013,15 @@
 	msg.msg_iovlen = 2;
 	if (os_memcmp(dest, drv->bssid, ETH_ALEN) == 0 ||
 	    drv->test_dir == NULL) {
-		msg.msg_name = &drv->hostapd_addr;
-		msg.msg_namelen = sizeof(drv->hostapd_addr);
+		if (drv->hostapd_addr_udp_set) {
+			msg.msg_name = &drv->hostapd_addr_udp;
+			msg.msg_namelen = sizeof(drv->hostapd_addr_udp);
+		} else {
+#ifdef DRIVER_TEST_UNIX
+			msg.msg_name = &drv->hostapd_addr;
+			msg.msg_namelen = sizeof(drv->hostapd_addr);
+#endif /* DRIVER_TEST_UNIX */
+		}
 	} else if (os_memcmp(dest, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0)
 	{
 		dir = opendir(drv->test_dir);
@@ -921,19 +1095,81 @@
 }
 
 
-int wpa_driver_test_set_ssid(void *priv, const u8 *ssid, size_t ssid_len)
+static int wpa_driver_test_set_ssid(void *priv, const u8 *ssid,
+				    size_t ssid_len)
 {
 	wpa_printf(MSG_DEBUG, "%s", __func__);
 	return 0;
 }
 
 
-int wpa_driver_test_set_bssid(void *priv, const u8 *bssid)
+static int wpa_driver_test_set_bssid(void *priv, const u8 *bssid)
 {
 	wpa_printf(MSG_DEBUG, "%s: bssid=" MACSTR, __func__, MAC2STR(bssid));
 	return 0;
 }
 #endif /* CONFIG_CLIENT_MLME */
+
+
+static int wpa_driver_test_set_probe_req_ie(void *priv, const u8 *ies,
+					    size_t ies_len)
+{
+	struct wpa_driver_test_data *drv = priv;
+
+	os_free(drv->probe_req_ie);
+	if (ies) {
+		drv->probe_req_ie = os_malloc(ies_len);
+		if (drv->probe_req_ie == NULL) {
+			drv->probe_req_ie_len = 0;
+			return -1;
+		}
+		os_memcpy(drv->probe_req_ie, ies, ies_len);
+		drv->probe_req_ie_len = ies_len;
+	} else {
+		drv->probe_req_ie = NULL;
+		drv->probe_req_ie_len = 0;
+	}
+	return 0;
+}
+
+
+static void * wpa_driver_test_global_init(void)
+{
+	struct wpa_driver_test_global *global;
+
+	global = os_zalloc(sizeof(*global));
+	return global;
+}
+
+
+static void wpa_driver_test_global_deinit(void *priv)
+{
+	struct wpa_driver_test_global *global = priv;
+	os_free(global);
+}
+
+
+static struct wpa_interface_info *
+wpa_driver_test_get_interfaces(void *global_priv)
+{
+	/* struct wpa_driver_test_global *global = priv; */
+	struct wpa_interface_info *iface;
+
+	iface = os_zalloc(sizeof(*iface));
+	if (iface == NULL)
+		return iface;
+	iface->ifname = os_strdup("sta0");
+	iface->desc = os_strdup("test interface 0");
+	iface->drv_name = "test";
+	iface->next = os_zalloc(sizeof(*iface));
+	if (iface->next) {
+		iface->next->ifname = os_strdup("sta1");
+		iface->next->desc = os_strdup("test interface 1");
+		iface->next->drv_name = "test";
+	}
+
+	return iface;
+}
 
 
 const struct wpa_driver_ops wpa_driver_test_ops = {
@@ -943,7 +1179,7 @@
 	wpa_driver_test_get_ssid,
 	wpa_driver_test_set_wpa,
 	wpa_driver_test_set_key,
-	wpa_driver_test_init,
+	NULL /* init */,
 	wpa_driver_test_deinit,
 	wpa_driver_test_set_param,
 	NULL /* set_countermeasures */,
@@ -984,6 +1220,11 @@
 	NULL /* update_ft_ies */,
 	NULL /* send_ft_action */,
 	wpa_driver_test_get_scan_results2,
-	NULL /* set_probe_req_ie */,
-	NULL /* set_mode */
+	wpa_driver_test_set_probe_req_ie,
+	NULL /* set_mode */,
+	NULL /* set_country */,
+	wpa_driver_test_global_init,
+	wpa_driver_test_global_deinit,
+	wpa_driver_test_init2,
+	wpa_driver_test_get_interfaces
 };

Modified: wpasupplicant/trunk/src/drivers/driver_wext.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_wext.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_wext.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_wext.c Sat Jan 10 09:03:49 2009
@@ -1726,13 +1726,11 @@
 	case WPA_ALG_PMK:
 		ext->alg = IW_ENCODE_ALG_PMK;
 		break;
-#ifdef WEXT_MFP_PENDING
 #ifdef CONFIG_IEEE80211W
 	case WPA_ALG_IGTK:
 		ext->alg = IW_ENCODE_ALG_AES_CMAC;
 		break;
 #endif /* CONFIG_IEEE80211W */
-#endif /* WEXT_MFP_PENDING */
 	default:
 		wpa_printf(MSG_DEBUG, "%s: Unknown algorithm %d",
 			   __FUNCTION__, alg);
@@ -2084,7 +2082,6 @@
 					   IW_AUTH_RX_UNENCRYPTED_EAPOL,
 					   allow_unencrypted_eapol) < 0)
 		ret = -1;
-#ifdef WEXT_MFP_PENDING
 #ifdef CONFIG_IEEE80211W
 	switch (params->mgmt_frame_protection) {
 	case NO_MGMT_FRAME_PROTECTION:
@@ -2100,7 +2097,6 @@
 	if (wpa_driver_wext_set_auth_param(drv, IW_AUTH_MFP, value) < 0)
 		ret = -1;
 #endif /* CONFIG_IEEE80211W */
-#endif /* WEXT_MFP_PENDING */
 	if (params->freq && wpa_driver_wext_set_freq(drv, params->freq) < 0)
 		ret = -1;
 	if (wpa_driver_wext_set_ssid(drv, params->ssid, params->ssid_len) < 0)

Modified: wpasupplicant/trunk/src/drivers/ndis_events.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/ndis_events.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/ndis_events.c (original)
+++ wpasupplicant/trunk/src/drivers/ndis_events.c Sat Jan 10 09:03:49 2009
@@ -281,7 +281,7 @@
 		SafeArrayGetElement(V_ARRAY(&vt), &k, &ch);
 		*pos++ = ch;
 	}
-	wpa_hexdump(MSG_DEBUG, "MediaSpecificEvent", data, data_len);
+	wpa_hexdump(MSG_DEBUG, "MediaSpecificEvent", (u8 *) data, data_len);
 
 	VariantClear(&vt);
 
@@ -752,7 +752,8 @@
 	}
 
 	hr = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
-			      &IID_IWbemLocator, (LPVOID *) &events->pLoc);
+			      &IID_IWbemLocator,
+			      (LPVOID *) (void *) &events->pLoc);
 	if (FAILED(hr)) {
 		wpa_printf(MSG_ERROR, "CoCreateInstance() failed - returned "
 			   "0x%x", (int) hr);

Modified: wpasupplicant/trunk/src/drivers/scan_helpers.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/scan_helpers.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/scan_helpers.c (original)
+++ wpasupplicant/trunk/src/drivers/scan_helpers.c Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - Helper functions for scan result processing
- * Copyright (c) 2007, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2007-2008, 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
@@ -56,6 +56,37 @@
 	}
 
 	return NULL;
+}
+
+
+struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
+					     u32 vendor_type)
+{
+	struct wpabuf *buf;
+	const u8 *end, *pos;
+
+	buf = wpabuf_alloc(res->ie_len);
+	if (buf == NULL)
+		return NULL;
+
+	pos = (const u8 *) (res + 1);
+	end = pos + res->ie_len;
+
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			break;
+		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
+		    vendor_type == WPA_GET_BE32(&pos[2]))
+			wpabuf_put_data(buf, pos + 2 + 4, pos[1] - 4);
+		pos += 2 + pos[1];
+	}
+
+	if (wpabuf_len(buf) == 0) {
+		wpabuf_free(buf);
+		buf = NULL;
+	}
+
+	return buf;
 }
 
 

Modified: wpasupplicant/trunk/src/eap_common/eap_defs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_defs.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_defs.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_defs.h Sat Jan 10 09:03:49 2009
@@ -66,9 +66,9 @@
 	EAP_TYPE_PSK = 47 /* RFC 4764 */,
 	EAP_TYPE_SAKE = 48 /* RFC 4763 */,
 	EAP_TYPE_IKEV2 = 49 /* RFC 5106 */,
-	EAP_TYPE_EXPANDED = 254 /* RFC 3748 */,
-	EAP_TYPE_GPSK = 255 /* EXPERIMENTAL - type not yet allocated
-			     * draft-ietf-emu-eap-gpsk-01.txt */
+	EAP_TYPE_AKA_PRIME = 50 /* draft-arkko-eap-aka-kdf-10.txt */,
+	EAP_TYPE_GPSK = 51 /* draft-ietf-emu-eap-gpsk-17.txt */,
+	EAP_TYPE_EXPANDED = 254 /* RFC 3748 */
 } EapType;
 
 

Modified: wpasupplicant/trunk/src/eap_common/eap_peap_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_peap_common.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_peap_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_peap_common.c Sat Jan 10 09:03:49 2009
@@ -16,6 +16,7 @@
 
 #include "common.h"
 #include "sha1.h"
+#include "eap_peap_common.h"
 
 void peap_prfplus(int version, const u8 *key, size_t key_len,
 		  const char *label, const u8 *seed, size_t seed_len,

Modified: wpasupplicant/trunk/src/eap_common/eap_sim_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_sim_common.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_sim_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_sim_common.c Sat Jan 10 09:03:49 2009
@@ -1,5 +1,5 @@
 /*
- * EAP peer/server: EAP-SIM/AKA shared routines
+ * EAP peer/server: EAP-SIM/AKA/AKA' shared routines
  * Copyright (c) 2004-2008, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,6 +17,7 @@
 #include "common.h"
 #include "eap_common/eap_defs.h"
 #include "sha1.h"
+#include "sha256.h"
 #include "crypto.h"
 #include "aes_wrap.h"
 #include "wpabuf.h"
@@ -230,6 +231,272 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Add MAC: MAC",
 		    mac, EAP_SIM_MAC_LEN);
 }
+
+
+#ifdef EAP_AKA_PRIME
+static void prf_prime(const u8 *k, const char *seed1,
+		      const u8 *seed2, size_t seed2_len,
+		      const u8 *seed3, size_t seed3_len,
+		      u8 *res, size_t res_len)
+{
+	const u8 *addr[5];
+	size_t len[5];
+	u8 hash[SHA256_MAC_LEN];
+	u8 iter;
+
+	/*
+	 * PRF'(K,S) = T1 | T2 | T3 | T4 | ...
+	 * T1 = HMAC-SHA-256 (K, S | 0x01)
+	 * T2 = HMAC-SHA-256 (K, T1 | S | 0x02)
+	 * T3 = HMAC-SHA-256 (K, T2 | S | 0x03)
+	 * T4 = HMAC-SHA-256 (K, T3 | S | 0x04)
+	 * ...
+	 */
+
+	addr[0] = hash;
+	len[0] = 0;
+	addr[1] = (const u8 *) seed1;
+	len[1] = os_strlen(seed1);
+	addr[2] = seed2;
+	len[2] = seed2_len;
+	addr[3] = seed3;
+	len[3] = seed3_len;
+	addr[4] = &iter;
+	len[4] = 1;
+
+	iter = 0;
+	while (res_len) {
+		size_t hlen;
+		iter++;
+		hmac_sha256_vector(k, 32, 5, addr, len, hash);
+		len[0] = SHA256_MAC_LEN;
+		hlen = res_len > SHA256_MAC_LEN ? SHA256_MAC_LEN : res_len;
+		os_memcpy(res, hash, hlen);
+		res += hlen;
+		res_len -= hlen;
+	}
+}
+
+
+void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
+			       const u8 *ik, const u8 *ck, u8 *k_encr,
+			       u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk)
+{
+	u8 key[EAP_AKA_IK_LEN + EAP_AKA_CK_LEN];
+	u8 keys[EAP_SIM_K_ENCR_LEN + EAP_AKA_PRIME_K_AUT_LEN +
+		EAP_AKA_PRIME_K_RE_LEN + EAP_MSK_LEN + EAP_EMSK_LEN];
+	u8 *pos;
+
+	/*
+	 * MK = PRF'(IK'|CK',"EAP-AKA'"|Identity)
+	 * K_encr = MK[0..127]
+	 * K_aut  = MK[128..383]
+	 * K_re   = MK[384..639]
+	 * MSK    = MK[640..1151]
+	 * EMSK   = MK[1152..1663]
+	 */
+
+	os_memcpy(key, ik, EAP_AKA_IK_LEN);
+	os_memcpy(key + EAP_AKA_IK_LEN, ck, EAP_AKA_CK_LEN);
+
+	prf_prime(key, "EAP-AKA'", identity, identity_len, NULL, 0,
+		  keys, sizeof(keys));
+
+	pos = keys;
+	os_memcpy(k_encr, pos, EAP_SIM_K_ENCR_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_encr",
+			k_encr, EAP_SIM_K_ENCR_LEN);
+	pos += EAP_SIM_K_ENCR_LEN;
+
+	os_memcpy(k_aut, pos, EAP_AKA_PRIME_K_AUT_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_aut",
+			k_aut, EAP_AKA_PRIME_K_AUT_LEN);
+	pos += EAP_AKA_PRIME_K_AUT_LEN;
+
+	os_memcpy(k_re, pos, EAP_AKA_PRIME_K_RE_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': K_re",
+			k_re, EAP_AKA_PRIME_K_RE_LEN);
+	pos += EAP_AKA_PRIME_K_RE_LEN;
+
+	os_memcpy(msk, pos, EAP_MSK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': MSK", msk, EAP_MSK_LEN);
+	pos += EAP_MSK_LEN;
+
+	os_memcpy(emsk, pos, EAP_EMSK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': EMSK", emsk, EAP_EMSK_LEN);
+}
+
+
+int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
+				     const u8 *identity, size_t identity_len,
+				     const u8 *nonce_s, u8 *msk, u8 *emsk)
+{
+	u8 seed3[2 + EAP_SIM_NONCE_S_LEN];
+	u8 keys[EAP_MSK_LEN + EAP_EMSK_LEN];
+	u8 *pos;
+
+	/*
+	 * MK = PRF'(K_re,"EAP-AKA' re-auth"|Identity|counter|NONCE_S)
+	 * MSK  = MK[0..511]
+	 * EMSK = MK[512..1023]
+	 */
+
+	WPA_PUT_BE16(seed3, counter);
+	os_memcpy(seed3 + 2, nonce_s, EAP_SIM_NONCE_S_LEN);
+
+	prf_prime(k_re, "EAP-AKA' re-auth", identity, identity_len,
+		  seed3, sizeof(seed3),
+		  keys, sizeof(keys));
+
+	pos = keys;
+	os_memcpy(msk, pos, EAP_MSK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': MSK", msk, EAP_MSK_LEN);
+	pos += EAP_MSK_LEN;
+
+	os_memcpy(emsk, pos, EAP_EMSK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': EMSK", emsk, EAP_EMSK_LEN);
+
+	os_memset(keys, 0, sizeof(keys));
+
+	return 0;
+}
+
+
+int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
+			      const u8 *mac, const u8 *extra, size_t extra_len)
+{
+	unsigned char hmac[SHA256_MAC_LEN];
+	const u8 *addr[2];
+	size_t len[2];
+	u8 *tmp;
+
+	if (mac == NULL || wpabuf_len(req) < EAP_SIM_MAC_LEN ||
+	    mac < wpabuf_head_u8(req) ||
+	    mac > wpabuf_head_u8(req) + wpabuf_len(req) - EAP_SIM_MAC_LEN)
+		return -1;
+
+	tmp = os_malloc(wpabuf_len(req));
+	if (tmp == NULL)
+		return -1;
+
+	addr[0] = tmp;
+	len[0] = wpabuf_len(req);
+	addr[1] = extra;
+	len[1] = extra_len;
+
+	/* HMAC-SHA-256-128 */
+	os_memcpy(tmp, wpabuf_head(req), wpabuf_len(req));
+	os_memset(tmp + (mac - wpabuf_head_u8(req)), 0, EAP_SIM_MAC_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - msg",
+		    tmp, wpabuf_len(req));
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC - extra data",
+		    extra, extra_len);
+	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Verify MAC - K_aut",
+			k_aut, EAP_AKA_PRIME_K_AUT_LEN);
+	hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Verify MAC: MAC",
+		    hmac, EAP_SIM_MAC_LEN);
+	os_free(tmp);
+
+	return (os_memcmp(hmac, mac, EAP_SIM_MAC_LEN) == 0) ? 0 : 1;
+}
+
+
+void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len,
+			    u8 *mac, const u8 *extra, size_t extra_len)
+{
+	unsigned char hmac[SHA256_MAC_LEN];
+	const u8 *addr[2];
+	size_t len[2];
+
+	addr[0] = msg;
+	len[0] = msg_len;
+	addr[1] = extra;
+	len[1] = extra_len;
+
+	/* HMAC-SHA-256-128 */
+	os_memset(mac, 0, EAP_SIM_MAC_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - msg", msg, msg_len);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC - extra data",
+		    extra, extra_len);
+	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA': Add MAC - K_aut",
+			k_aut, EAP_AKA_PRIME_K_AUT_LEN);
+	hmac_sha256_vector(k_aut, EAP_AKA_PRIME_K_AUT_LEN, 2, addr, len, hmac);
+	os_memcpy(mac, hmac, EAP_SIM_MAC_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA': Add MAC: MAC",
+		    mac, EAP_SIM_MAC_LEN);
+}
+
+
+void eap_aka_prime_derive_ck_ik_prime(u8 *ck, u8 *ik, const u8 *sqn_ak,
+				      const u8 *network_name,
+				      size_t network_name_len)
+{
+	u8 key[EAP_AKA_CK_LEN + EAP_AKA_IK_LEN];
+	u8 hash[SHA256_MAC_LEN];
+	const u8 *addr[5];
+	size_t len[5];
+	u8 fc;
+	u8 l0[2], l1[2];
+
+	/* 3GPP TS 33.402 V8.0.0
+	 * (CK', IK') = F(CK, IK, <access network identity>)
+	 */
+	/* TODO: CK', IK' generation should really be moved into the actual
+	 * AKA procedure with network name passed in there and option to use
+	 * AMF separation bit = 1 (3GPP TS 33.401). */
+
+	/* Change Request 33.402 CR 0033 to version 8.1.1 from
+	 * 3GPP TSG-SA WG3 Meeting #53 in September 2008:
+	 *
+	 * CK' || IK' = HMAC-SHA-256(Key, S)
+	 * S = FC || P0 || L0 || P1 || L1 || ... || Pn || Ln
+	 * Key = CK || IK
+	 * FC = 0x20
+	 * P0 = access network identity (3GPP TS 24.302)
+	 * L0 = length of acceess network identity (2 octets, big endian)
+	 * P1 = SQN xor AK (if AK is not used, AK is treaded as 000..0
+	 * L1 = 0x00 0x06
+	 */
+
+	fc = 0x20;
+
+	wpa_printf(MSG_DEBUG, "EAP-AKA': Derive (CK',IK') from (CK,IK)");
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': CK", ck, EAP_AKA_CK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': IK", ik, EAP_AKA_IK_LEN);
+	wpa_printf(MSG_DEBUG, "EAP-AKA': FC = 0x%x", fc);
+	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': P0 = Access network identity",
+			  network_name, network_name_len);
+	wpa_hexdump(MSG_DEBUG, "EAP-AKA': P1 = SQN xor AK", sqn_ak, 6);
+
+	os_memcpy(key, ck, EAP_AKA_CK_LEN);
+	os_memcpy(key + EAP_AKA_CK_LEN, ik, EAP_AKA_IK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': Key = CK || IK",
+			key, sizeof(key));
+
+	addr[0] = &fc;
+	len[0] = 1;
+	addr[1] = network_name;
+	len[1] = network_name_len;
+	WPA_PUT_BE16(l0, network_name_len);
+	addr[2] = l0;
+	len[2] = 2;
+	addr[3] = sqn_ak;
+	len[3] = 6;
+	WPA_PUT_BE16(l1, 6);
+	addr[4] = l1;
+	len[4] = 2;
+
+	hmac_sha256_vector(key, sizeof(key), 5, addr, len, hash);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': KDF output (CK' || IK')",
+			hash, sizeof(hash));
+
+	os_memcpy(ck, hash, EAP_AKA_CK_LEN);
+	os_memcpy(ik, hash + EAP_AKA_CK_LEN, EAP_AKA_IK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': CK'", ck, EAP_AKA_CK_LEN);
+	wpa_hexdump_key(MSG_DEBUG, "EAP-AKA': IK'", ik, EAP_AKA_IK_LEN);
+}
+#endif /* EAP_AKA_PRIME */
 
 
 int eap_sim_parse_attr(const u8 *start, const u8 *end,
@@ -357,8 +624,20 @@
 			break;
 		case EAP_SIM_AT_IDENTITY:
 			wpa_printf(MSG_DEBUG, "EAP-SIM: AT_IDENTITY");
-			attr->identity = apos + 2;
-			attr->identity_len = alen - 2;
+			plen = WPA_GET_BE16(apos);
+			apos += 2;
+			alen -= 2;
+			if (plen > alen) {
+				wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
+					   "AT_IDENTITY (Actual Length %lu, "
+					   "remaining length %lu)",
+					   (unsigned long) plen,
+					   (unsigned long) alen);
+				return -1;
+			}
+
+			attr->identity = apos;
+			attr->identity_len = plen;
 			break;
 		case EAP_SIM_AT_VERSION_LIST:
 			if (aka) {
@@ -554,7 +833,8 @@
 			}
 			apos += 2;
 			alen -= 2;
-			if (alen != 0 && alen != EAP_AKA_CHECKCODE_LEN) {
+			if (alen != 0 && alen != EAP_AKA_CHECKCODE_LEN &&
+			    alen != EAP_AKA_PRIME_CHECKCODE_LEN) {
 				wpa_printf(MSG_INFO, "EAP-AKA: Invalid "
 					   "AT_CHECKCODE (len %lu)",
 					   (unsigned long) alen);
@@ -578,6 +858,62 @@
 			wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RESULT_IND");
 			attr->result_ind = 1;
 			break;
+#ifdef EAP_AKA_PRIME
+		case EAP_SIM_AT_KDF_INPUT:
+			if (aka != 2) {
+				wpa_printf(MSG_INFO, "EAP-AKA: Unexpected "
+					   "AT_KDF_INPUT");
+				return -1;
+			}
+
+			wpa_printf(MSG_DEBUG, "EAP-AKA: AT_KDF_INPUT");
+			plen = WPA_GET_BE16(apos);
+			apos += 2;
+			alen -= 2;
+			if (plen > alen) {
+				wpa_printf(MSG_INFO, "EAP-AKA': Invalid "
+					   "AT_KDF_INPUT (Actual Length %lu, "
+					   "remaining length %lu)",
+					   (unsigned long) plen,
+					   (unsigned long) alen);
+				return -1;
+			}
+			attr->kdf_input = apos;
+			attr->kdf_input_len = plen;
+			break;
+		case EAP_SIM_AT_KDF:
+			if (aka != 2) {
+				wpa_printf(MSG_INFO, "EAP-AKA: Unexpected "
+					   "AT_KDF");
+				return -1;
+			}
+
+			wpa_printf(MSG_DEBUG, "EAP-AKA: AT_KDF");
+			if (alen != 2) {
+				wpa_printf(MSG_INFO, "EAP-AKA': Invalid "
+					   "AT_KDF (len %lu)",
+					   (unsigned long) alen);
+				return -1;
+			}
+			if (attr->kdf_count == EAP_AKA_PRIME_KDF_MAX) {
+				wpa_printf(MSG_DEBUG, "EAP-AKA': Too many "
+					   "AT_KDF attributes - ignore this");
+				continue;
+			}
+			attr->kdf[attr->kdf_count] = WPA_GET_BE16(apos);
+			attr->kdf_count++;
+			break;
+		case EAP_SIM_AT_BIDDING:
+			wpa_printf(MSG_DEBUG, "EAP-AKA: AT_BIDDING");
+			if (alen != 2) {
+				wpa_printf(MSG_INFO, "EAP-AKA: Invalid "
+					   "AT_BIDDING (len %lu)",
+					   (unsigned long) alen);
+				return -1;
+			}
+			attr->bidding = apos;
+			break;
+#endif /* EAP_AKA_PRIME */
 		default:
 			if (pos[0] < 128) {
 				wpa_printf(MSG_INFO, "EAP-SIM: Unrecognized "
@@ -641,6 +977,7 @@
 struct eap_sim_msg {
 	struct wpabuf *buf;
 	size_t mac, iv, encr; /* index from buf */
+	int type;
 };
 
 
@@ -654,6 +991,7 @@
 	if (msg == NULL)
 		return NULL;
 
+	msg->type = type;
 	msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN);
 	if (msg->buf == NULL) {
 		os_free(msg);
@@ -685,6 +1023,14 @@
 	eap = wpabuf_mhead(msg->buf);
 	eap->length = host_to_be16(wpabuf_len(msg->buf));
 
+#ifdef EAP_AKA_PRIME
+	if (k_aut && msg->mac && msg->type == EAP_TYPE_AKA_PRIME) {
+		eap_sim_add_mac_sha256(k_aut, (u8 *) wpabuf_head(msg->buf),
+				       wpabuf_len(msg->buf),
+				       (u8 *) wpabuf_mhead(msg->buf) +
+				       msg->mac, extra, extra_len);
+	} else
+#endif /* EAP_AKA_PRIME */
 	if (k_aut && msg->mac) {
 		eap_sim_add_mac(k_aut, (u8 *) wpabuf_head(msg->buf),
 				wpabuf_len(msg->buf),

Modified: wpasupplicant/trunk/src/eap_common/eap_sim_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_sim_common.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_sim_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_sim_common.h Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 /*
- * EAP peer/server: EAP-SIM/AKA shared routines
- * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
+ * EAP peer/server: EAP-SIM/AKA/AKA' shared routines
+ * Copyright (c) 2004-2008, 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
@@ -70,6 +70,10 @@
 #define EAP_AKA_MIN_RES_LEN 4
 #define EAP_AKA_MAX_RES_LEN 16
 #define EAP_AKA_CHECKCODE_LEN 20
+
+#define EAP_AKA_PRIME_K_AUT_LEN 32
+#define EAP_AKA_PRIME_CHECKCODE_LEN 32
+#define EAP_AKA_PRIME_K_RE_LEN 32
 
 struct wpabuf;
 
@@ -89,6 +93,49 @@
 		       const u8 *mac, const u8 *extra, size_t extra_len);
 void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
 		     const u8 *extra, size_t extra_len);
+
+#ifdef EAP_AKA_PRIME
+void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
+			       const u8 *ik, const u8 *ck, u8 *k_encr,
+			       u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk);
+int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
+				     const u8 *identity, size_t identity_len,
+				     const u8 *nonce_s, u8 *msk, u8 *emsk);
+int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
+			      const u8 *mac, const u8 *extra,
+			      size_t extra_len);
+void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len,
+			    u8 *mac, const u8 *extra, size_t extra_len);
+
+void eap_aka_prime_derive_ck_ik_prime(u8 *ck, u8 *ik, const u8 *sqn_ak,
+				      const u8 *network_name,
+				      size_t network_name_len);
+#else /* EAP_AKA_PRIME */
+static inline void eap_aka_prime_derive_keys(const u8 *identity,
+					     size_t identity_len,
+					     const u8 *ik, const u8 *ck,
+					     u8 *k_encr, u8 *k_aut, u8 *k_re,
+					     u8 *msk, u8 *emsk)
+{
+}
+
+static inline int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
+						   const u8 *identity,
+						   size_t identity_len,
+						   const u8 *nonce_s, u8 *msk,
+						   u8 *emsk)
+{
+	return -1;
+}
+
+static inline int eap_sim_verify_mac_sha256(const u8 *k_aut,
+					    const struct wpabuf *req,
+					    const u8 *mac, const u8 *extra,
+					    size_t extra_len)
+{
+	return -1;
+}
+#endif /* EAP_AKA_PRIME */
 
 
 /* EAP-SIM/AKA Attributes (0..127 non-skippable) */
@@ -110,12 +157,15 @@
 #define EAP_SIM_AT_COUNTER_TOO_SMALL 20 /* only encrypted */
 #define EAP_SIM_AT_NONCE_S 21 /* only encrypted */
 #define EAP_SIM_AT_CLIENT_ERROR_CODE 22 /* only send */
+#define EAP_SIM_AT_KDF_INPUT 23 /* only AKA' */
+#define EAP_SIM_AT_KDF 24 /* only AKA' */
 #define EAP_SIM_AT_IV 129
 #define EAP_SIM_AT_ENCR_DATA 130
 #define EAP_SIM_AT_NEXT_PSEUDONYM 132 /* only encrypted */
 #define EAP_SIM_AT_NEXT_REAUTH_ID 133 /* only encrypted */
 #define EAP_SIM_AT_CHECKCODE 134 /* only AKA */
 #define EAP_SIM_AT_RESULT_IND 135
+#define EAP_SIM_AT_BIDDING 136
 
 /* AT_NOTIFICATION notification code values */
 #define EAP_SIM_GENERAL_FAILURE_AFTER_AUTH 0
@@ -124,6 +174,12 @@
 #define EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH 16384
 #define EAP_SIM_SUCCESS 32768
 
+/* EAP-AKA' AT_KDF Key Derivation Function values */
+#define EAP_AKA_PRIME_KDF 1
+
+/* AT_BIDDING flags */
+#define EAP_AKA_BIDDING_FLAG_D 0x8000
+
 
 enum eap_sim_id_req {
 	NO_ID_REQ, ANY_ID, FULLAUTH_ID, PERMANENT_ID
@@ -135,14 +191,20 @@
 	const u8 *next_pseudonym, *next_reauth_id;
 	const u8 *nonce_mt, *identity, *res, *auts;
 	const u8 *checkcode;
+	const u8 *kdf_input;
+	const u8 *bidding;
 	size_t num_chal, version_list_len, encr_data_len;
 	size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
 	size_t res_len_bits;
 	size_t checkcode_len;
+	size_t kdf_input_len;
 	enum eap_sim_id_req id_req;
 	int notification, counter, selected_version, client_error_code;
 	int counter_too_small;
 	int result_ind;
+#define EAP_AKA_PRIME_KDF_MAX 10
+	u16 kdf[EAP_AKA_PRIME_KDF_MAX];
+	size_t kdf_count;
 };
 
 int eap_sim_parse_attr(const u8 *start, const u8 *end,

Modified: wpasupplicant/trunk/src/eap_peer/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap.c Sat Jan 10 09:03:49 2009
@@ -31,6 +31,7 @@
 #include "pcsc_funcs.h"
 #include "wpa_ctrl.h"
 #include "state_machine.h"
+#include "eap_common/eap_wsc_common.h"
 
 #define STATE_MACHINE_DATA struct eap_sm
 #define STATE_MACHINE_DEBUG_PREFIX "EAP"
@@ -105,7 +106,7 @@
  * @method: EAP type
  * Returns: 1 = allowed EAP method, 0 = not allowed
  */
-static int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method)
+int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method)
 {
 	struct eap_peer_config *config = eap_get_config(sm);
 	int i;
@@ -1177,8 +1178,7 @@
 	sm->eapol_cb = eapol_cb;
 	sm->msg_ctx = msg_ctx;
 	sm->ClientTimeout = 60;
-	if (conf->mac_addr)
-		os_memcpy(sm->mac_addr, conf->mac_addr, ETH_ALEN);
+	sm->wps = conf->wps;
 
 	os_memset(&tlsconf, 0, sizeof(tlsconf));
 	tlsconf.opensc_engine_path = conf->opensc_engine_path;
@@ -2043,3 +2043,29 @@
 	if (sm)
 		eap_deinit_prev_method(sm, "invalidate");
 }
+
+
+int eap_is_wps_pbc_enrollee(struct eap_peer_config *conf)
+{
+	if (conf->identity_len != WSC_ID_ENROLLEE_LEN ||
+	    os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN))
+		return 0; /* Not a WPS Enrollee */
+
+	if (conf->phase1 == NULL || os_strstr(conf->phase1, "pbc=1") == NULL)
+		return 0; /* Not using PBC */
+
+	return 1;
+}
+
+
+int eap_is_wps_pin_enrollee(struct eap_peer_config *conf)
+{
+	if (conf->identity_len != WSC_ID_ENROLLEE_LEN ||
+	    os_memcmp(conf->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN))
+		return 0; /* Not a WPS Enrollee */
+
+	if (conf->phase1 == NULL || os_strstr(conf->phase1, "pin=") == NULL)
+		return 0; /* Not using PIN */
+
+	return 1;
+}

Modified: wpasupplicant/trunk/src/eap_peer/eap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap.h Sat Jan 10 09:03:49 2009
@@ -246,11 +246,11 @@
 	 */
 	const char *pkcs11_module_path;
 	/**
-	 * mac_addr - MAC address of the peer
-	 *
-	 * This can be left %NULL if not available.
-	 */
-	const u8 *mac_addr;
+	 * wps - WPS context data
+	 *
+	 * This is only used by EAP-WSC and can be left %NULL if not available.
+	 */
+	struct wps_context *wps;
 };
 
 struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
@@ -283,6 +283,9 @@
 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx);
 void eap_invalidate_cached_session(struct eap_sm *sm);
 
+int eap_is_wps_pbc_enrollee(struct eap_peer_config *conf);
+int eap_is_wps_pin_enrollee(struct eap_peer_config *conf);
+
 #endif /* IEEE8021X_EAPOL */
 
 #endif /* EAP_H */

Modified: wpasupplicant/trunk/src/eap_peer/eap_aka.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_aka.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_aka.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_aka.c Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 /*
- * EAP peer method: EAP-AKA (RFC 4187)
- * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
+ * EAP peer method: EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf)
+ * Copyright (c) 2004-2008, 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
@@ -19,6 +19,7 @@
 #include "pcsc_funcs.h"
 #include "eap_common/eap_sim_common.h"
 #include "sha1.h"
+#include "sha256.h"
 #include "crypto.h"
 #include "eap_peer/eap_config.h"
 #ifdef CONFIG_USIM_SIMULATOR
@@ -31,8 +32,9 @@
 	size_t res_len;
 	u8 nonce_s[EAP_SIM_NONCE_S_LEN];
 	u8 mk[EAP_SIM_MK_LEN];
-	u8 k_aut[EAP_SIM_K_AUT_LEN];
+	u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
 	u8 k_encr[EAP_SIM_K_ENCR_LEN];
+	u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */
 	u8 msk[EAP_SIM_KEYING_DATA_LEN];
 	u8 emsk[EAP_EMSK_LEN];
 	u8 rand[EAP_AKA_RAND_LEN], autn[EAP_AKA_AUTN_LEN];
@@ -54,6 +56,10 @@
 	struct wpabuf *id_msgs;
 	int prev_id;
 	int result_ind, use_result_ind;
+	u8 eap_method;
+	u8 *network_name;
+	size_t network_name_len;
+	u16 kdf;
 };
 
 
@@ -96,6 +102,8 @@
 	if (data == NULL)
 		return NULL;
 
+	data->eap_method = EAP_TYPE_AKA;
+
 	eap_aka_state(data, CONTINUE);
 	data->prev_id = -1;
 
@@ -103,6 +111,18 @@
 
 	return data;
 }
+
+
+#ifdef EAP_AKA_PRIME
+static void * eap_aka_prime_init(struct eap_sm *sm)
+{
+	struct eap_aka_data *data = eap_aka_init(sm);
+	if (data == NULL)
+		return NULL;
+	data->eap_method = EAP_TYPE_AKA_PRIME;
+	return data;
+}
+#endif /* EAP_AKA_PRIME */
 
 
 static void eap_aka_deinit(struct eap_sm *sm, void *priv)
@@ -113,6 +133,7 @@
 		os_free(data->reauth_id);
 		os_free(data->last_eap_identity);
 		wpabuf_free(data->id_msgs);
+		os_free(data->network_name);
 		os_free(data);
 	}
 }
@@ -302,7 +323,7 @@
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
 
 	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
 
@@ -315,14 +336,20 @@
 		return;
 	}
 
-	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	/* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
-	sha1_vector(1, &addr, &len, hash);
+#ifdef EAP_AKA_PRIME
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+#endif /* EAP_AKA_PRIME */
+		sha1_vector(1, &addr, &len, hash);
 
 	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
-			EAP_AKA_CHECKCODE_LEN);
+			data->eap_method == EAP_TYPE_AKA_PRIME ?
+			EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
 }
 
 
@@ -331,7 +358,8 @@
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
+	size_t hash_len;
 
 	if (checkcode == NULL)
 		return -1;
@@ -346,19 +374,27 @@
 		return 0;
 	}
 
-	if (checkcode_len != EAP_AKA_CHECKCODE_LEN) {
+	hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
+		EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
+
+	if (checkcode_len != hash_len) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
 			   "indicates that AKA/Identity message were not "
 			   "used, but they were");
 		return -1;
 	}
 
-	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	/* Checkcode is SHA1/SHA256 hash over all EAP-AKA/Identity packets. */
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
-	sha1_vector(1, &addr, &len, hash);
-
-	if (os_memcmp(hash, checkcode, EAP_AKA_CHECKCODE_LEN) != 0) {
+#ifdef EAP_AKA_PRIME
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+#endif /* EAP_AKA_PRIME */
+		sha1_vector(1, &addr, &len, hash);
+
+	if (os_memcmp(hash, checkcode, hash_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
 		return -1;
 	}
@@ -376,7 +412,7 @@
 	data->num_id_req = 0;
 	data->num_notification = 0;
 
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_CLIENT_ERROR);
 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
@@ -394,7 +430,7 @@
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject "
 		   "(id=%d)", id);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
 	return eap_sim_msg_finish(msg, NULL, NULL, 0);
 }
@@ -410,7 +446,7 @@
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure "
 		   "(id=%d)", id);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE);
 	wpa_printf(MSG_DEBUG, "   AT_AUTS");
 	eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
@@ -449,7 +485,7 @@
 		eap_aka_clear_identities(data, CLEAR_EAP_ID);
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_IDENTITY);
 
 	if (identity) {
@@ -469,7 +505,7 @@
 	struct eap_sim_msg *msg;
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_CHALLENGE);
 	wpa_printf(MSG_DEBUG, "   AT_RES");
 	eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len * 8,
@@ -494,7 +530,7 @@
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",
 		   id);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_REAUTHENTICATION);
 	wpa_printf(MSG_DEBUG, "   AT_IV");
 	wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
@@ -535,7 +571,7 @@
 	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_NOTIFICATION);
 	if (k_aut && data->reauth) {
 		wpa_printf(MSG_DEBUG, "   AT_IV");
@@ -611,6 +647,101 @@
 }
 
 
+static int eap_aka_verify_mac(struct eap_aka_data *data,
+			      const struct wpabuf *req,
+			      const u8 *mac, const u8 *extra,
+			      size_t extra_len)
+{
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra,
+						 extra_len);
+	return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len);
+}
+
+
+#ifdef EAP_AKA_PRIME
+static struct wpabuf * eap_aka_prime_kdf_select(struct eap_aka_data *data,
+						u8 id, u16 kdf)
+{
+	struct eap_sim_msg *msg;
+
+	data->kdf = kdf;
+	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d) (KDF "
+		   "select)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, data->eap_method,
+			       EAP_AKA_SUBTYPE_CHALLENGE);
+	wpa_printf(MSG_DEBUG, "   AT_KDF");
+	eap_sim_msg_add(msg, EAP_SIM_AT_KDF, kdf, NULL, 0);
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_prime_kdf_neg(struct eap_aka_data *data,
+					     u8 id, struct eap_sim_attrs *attr)
+{
+	size_t i;
+
+	for (i = 0; i < attr->kdf_count; i++) {
+		if (attr->kdf[i] == EAP_AKA_PRIME_KDF)
+			return eap_aka_prime_kdf_select(data, id,
+							EAP_AKA_PRIME_KDF);
+	}
+
+	/* No matching KDF found - fail authentication as if AUTN had been
+	 * incorrect */
+	return eap_aka_authentication_reject(data, id);
+}
+
+
+static int eap_aka_prime_kdf_valid(struct eap_aka_data *data,
+				   struct eap_sim_attrs *attr)
+{
+	size_t i, j;
+
+	if (attr->kdf_count == 0)
+		return 0;
+
+	/* The only allowed (and required) duplication of a KDF is the addition
+	 * of the selected KDF into the beginning of the list. */
+
+	if (data->kdf) {
+		if (attr->kdf[0] != data->kdf) {
+			wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
+				   "accept the selected KDF");
+			return 0;
+		}
+
+		for (i = 1; i < attr->kdf_count; i++) {
+			if (attr->kdf[i] == data->kdf)
+				break;
+		}
+		if (i == attr->kdf_count &&
+		    attr->kdf_count < EAP_AKA_PRIME_KDF_MAX) {
+			wpa_printf(MSG_WARNING, "EAP-AKA': The server did not "
+				   "duplicate the selected KDF");
+			return 0;
+		}
+
+		/* TODO: should check that the list is identical to the one
+		 * used in the previous Challenge message apart from the added
+		 * entry in the beginning. */
+	}
+
+	for (i = data->kdf ? 1 : 0; i < attr->kdf_count; i++) {
+		for (j = i + 1; j < attr->kdf_count; j++) {
+			if (attr->kdf[i] == attr->kdf[j]) {
+				wpa_printf(MSG_WARNING, "EAP-AKA': The server "
+					   "included a duplicated KDF");
+				return 0;
+			}
+		}
+	}
+
+	return 1;
+}
+#endif /* EAP_AKA_PRIME */
+
+
 static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
 						 struct eap_aka_data *data,
 						 u8 id,
@@ -632,6 +763,52 @@
 		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
+
+#ifdef EAP_AKA_PRIME
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		if (!attr->kdf_input || attr->kdf_input_len == 0) {
+			wpa_printf(MSG_WARNING, "EAP-AKA': Challenge message "
+				   "did not include non-empty AT_KDF_INPUT");
+			/* Fail authentication as if AUTN had been incorrect */
+			return eap_aka_authentication_reject(data, id);
+		}
+		os_free(data->network_name);
+		data->network_name = os_malloc(attr->kdf_input_len);
+		if (data->network_name == NULL) {
+			wpa_printf(MSG_WARNING, "EAP-AKA': No memory for "
+				   "storing Network Name");
+			return eap_aka_authentication_reject(data, id);
+		}
+		os_memcpy(data->network_name, attr->kdf_input,
+			  attr->kdf_input_len);
+		data->network_name_len = attr->kdf_input_len;
+		wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA': Network Name "
+				  "(AT_KDF_INPUT)",
+				  data->network_name, data->network_name_len);
+		/* TODO: check Network Name per 3GPP.33.402 */
+
+		if (!eap_aka_prime_kdf_valid(data, attr))
+			return eap_aka_authentication_reject(data, id);
+
+		if (attr->kdf[0] != EAP_AKA_PRIME_KDF)
+			return eap_aka_prime_kdf_neg(data, id, attr);
+
+		data->kdf = EAP_AKA_PRIME_KDF;
+		wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf);
+	}
+
+	if (data->eap_method == EAP_TYPE_AKA && attr->bidding) {
+		u16 flags = WPA_GET_BE16(attr->bidding);
+		if ((flags & EAP_AKA_BIDDING_FLAG_D) &&
+		    eap_allowed_method(sm, EAP_VENDOR_IETF,
+				       EAP_TYPE_AKA_PRIME)) {
+			wpa_printf(MSG_WARNING, "EAP-AKA: Bidding down from "
+				   "AKA' to AKA detected");
+			/* Fail authentication as if AUTN had been incorrect */
+			return eap_aka_authentication_reject(data, id);
+		}
+	}
+#endif /* EAP_AKA_PRIME */
 
 	data->reauth = 0;
 	if (!attr->mac || !attr->rand || !attr->autn) {
@@ -660,6 +837,16 @@
 		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
+#ifdef EAP_AKA_PRIME
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		/* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the
+		 * needed 6-octet SQN ^AK for CK',IK' derivation */
+		eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik,
+						 data->autn,
+						 data->network_name,
+						 data->network_name_len);
+	}
+#endif /* EAP_AKA_PRIME */
 	if (data->last_eap_identity) {
 		identity = data->last_eap_identity;
 		identity_len = data->last_eap_identity_len;
@@ -670,12 +857,17 @@
 		identity = eap_get_config_identity(sm, &identity_len);
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Selected identity for MK "
 			  "derivation", identity, identity_len);
-	eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
-			  data->mk);
-	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
-			    data->emsk);
-	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
-	{
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		eap_aka_prime_derive_keys(identity, identity_len, data->ik,
+					  data->ck, data->k_encr, data->k_aut,
+					  data->k_re, data->msk, data->emsk);
+	} else {
+		eap_aka_derive_mk(identity, identity_len, data->ik, data->ck,
+				  data->mk);
+		eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
+				    data->msk, data->emsk);
+	}
+	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
 			   "used invalid AT_MAC");
 		return eap_aka_client_error(data, id,
@@ -763,8 +955,7 @@
 		return -1;
 	}
 
-	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
-	{
+	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
 			   "used invalid AT_MAC");
 		return -1;
@@ -842,8 +1033,7 @@
 	}
 
 	data->reauth = 1;
-	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
-	{
+	if (eap_aka_verify_mac(data, reqData, attr->mac, (u8 *) "", 0)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
 			   "did not have valid AT_MAC");
 		return eap_aka_client_error(data, id,
@@ -881,10 +1071,6 @@
 		wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter "
 			   "(%d <= %d)", eattr.counter, data->counter);
 		data->counter_too_small = eattr.counter;
-
-		eap_sim_derive_keys_reauth(eattr.counter, data->reauth_id,
-					   data->reauth_id_len, eattr.nonce_s,
-					   data->mk, NULL, NULL);
 
 		/* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current
 		 * reauth_id must not be used to start a new reauthentication.
@@ -908,10 +1094,18 @@
 	wpa_hexdump(MSG_DEBUG, "EAP-AKA: (encr) AT_NONCE_S",
 		    data->nonce_s, EAP_SIM_NONCE_S_LEN);
 
-	eap_sim_derive_keys_reauth(data->counter,
-				   data->reauth_id, data->reauth_id_len,
-				   data->nonce_s, data->mk, data->msk,
-				   data->emsk);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
+						 data->reauth_id,
+						 data->reauth_id_len,
+						 data->nonce_s,
+						 data->msk, data->emsk);
+	} else {
+		eap_sim_derive_keys_reauth(data->counter, data->reauth_id,
+					   data->reauth_id_len,
+					   data->nonce_s, data->mk,
+					   data->msk, data->emsk);
+	}
 	eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 	eap_aka_learn_ids(data, &eattr);
 
@@ -955,7 +1149,8 @@
 		return NULL;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, reqData, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, reqData,
+			       &len);
 	if (pos == NULL || len < 1) {
 		ret->ignore = TRUE;
 		return NULL;
@@ -973,7 +1168,8 @@
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
 	pos += 2; /* Reserved */
 
-	if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 1,
+	if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr,
+			       data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
 			       0)) {
 		res = eap_aka_client_error(data, id,
 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
@@ -1152,3 +1348,35 @@
 		eap_peer_method_free(eap);
 	return ret;
 }
+
+
+#ifdef EAP_AKA_PRIME
+int eap_peer_aka_prime_register(void)
+{
+	struct eap_method *eap;
+	int ret;
+
+	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
+				    EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME,
+				    "AKA'");
+	if (eap == NULL)
+		return -1;
+
+	eap->init = eap_aka_prime_init;
+	eap->deinit = eap_aka_deinit;
+	eap->process = eap_aka_process;
+	eap->isKeyAvailable = eap_aka_isKeyAvailable;
+	eap->getKey = eap_aka_getKey;
+	eap->has_reauth_data = eap_aka_has_reauth_data;
+	eap->deinit_for_reauth = eap_aka_deinit_for_reauth;
+	eap->init_for_reauth = eap_aka_init_for_reauth;
+	eap->get_identity = eap_aka_get_identity;
+	eap->get_emsk = eap_aka_get_emsk;
+
+	ret = eap_peer_method_register(eap);
+	if (ret)
+		eap_peer_method_free(eap);
+
+	return ret;
+}
+#endif /* EAP_AKA_PRIME */

Modified: wpasupplicant/trunk/src/eap_peer/eap_config.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_config.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_config.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_config.h Sat Jan 10 09:03:49 2009
@@ -83,10 +83,10 @@
 	 * wpa_supplicant is run in the background.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 *
 	 * On Windows, trusted CA certificates can be loaded from the system
-	 * certificate store by setting this to cert_store://<name>, e.g.,
+	 * certificate store by setting this to cert_store://name, e.g.,
 	 * ca_cert="cert_store://CA" or ca_cert="cert_store://ROOT".
 	 * Note that when running wpa_supplicant as an application, the user
 	 * certificate store (My user account) is used, whereas computer store
@@ -115,7 +115,7 @@
 	 * wpa_supplicant is run in the background.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *client_cert;
 
@@ -142,7 +142,7 @@
 	 * (Computer account) is used when running wpasvc as a service.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *private_key;
 
@@ -167,7 +167,7 @@
 	 * wpa_supplicant is run in the background.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *dh_file;
 
@@ -215,7 +215,7 @@
 	 * EAP-TTLS/PEAP/FAST tunnel) authentication.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *ca_cert2;
 
@@ -242,7 +242,7 @@
 	 * wpa_supplicant is run in the background.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *client_cert2;
 
@@ -255,7 +255,7 @@
 	 * wpa_supplicant is run in the background.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *private_key2;
 
@@ -276,7 +276,7 @@
 	 * wpa_supplicant is run in the background.
 	 *
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	u8 *dh_file2;
 
@@ -344,7 +344,7 @@
 	 * 2 = allow authenticated provisioning,
 	 * 3 = allow both unauthenticated and authenticated provisioning
 	 *
-	 * fast_max_pac_list_len=<num> option can be used to set the maximum
+	 * fast_max_pac_list_len=num option can be used to set the maximum
 	 * number of PAC entries to store in a PAC list (default: 10).
 	 *
 	 * fast_pac_format=binary option can be used to select binary format
@@ -356,6 +356,9 @@
 	 * 0 = do not use cryptobinding (default)
 	 * 1 = use cryptobinding if server supports it
 	 * 2 = require cryptobinding
+	 *
+	 * EAP-WSC (WPS) uses following options: pin=Device_Password and
+	 * uuid=Device_UUID
 	 */
 	char *phase1;
 
@@ -575,7 +578,7 @@
 	 * to the file should be used since working directory may change when
 	 * wpa_supplicant is run in the background.
 	 * Alternatively, a named configuration blob can be used by setting
-	 * this to blob://<blob name>.
+	 * this to blob://blob_name.
 	 */
 	char *pac_file;
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_fast.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_fast.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_fast.c Sat Jan 10 09:03:49 2009
@@ -343,10 +343,8 @@
 		sm->peer_challenge = data->key_block_p->client_challenge;
 	}
 	sm->init_phase2 = 1;
-	sm->mschapv2_full_key = 1;
 	data->phase2_priv = data->phase2_method->init(sm);
 	sm->init_phase2 = 0;
-	sm->mschapv2_full_key = 0;
 	sm->auth_challenge = NULL;
 	sm->peer_challenge = NULL;
 
@@ -661,7 +659,18 @@
 
 	if (key_len > isk_len)
 		key_len = isk_len;
-	os_memcpy(isk, key, key_len);
+	if (key_len == 32 &&
+	    data->phase2_method->vendor == EAP_VENDOR_IETF &&
+	    data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
+		/*
+		 * EAP-FAST uses reverse order for MS-MPPE keys when deriving
+		 * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
+		 * ISK for EAP-FAST cryptobinding.
+		 */
+		os_memcpy(isk, key + 16, 16);
+		os_memcpy(isk + 16, key, 16);
+	} else
+		os_memcpy(isk, key, key_len);
 	os_free(key);
 
 	return 0;

Modified: wpasupplicant/trunk/src/eap_peer/eap_gpsk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_gpsk.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_gpsk.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_gpsk.c Sat Jan 10 09:03:49 2009
@@ -130,8 +130,8 @@
 }
 
 
-const u8 * eap_gpsk_process_id_server(struct eap_gpsk_data *data,
-				      const u8 *pos, const u8 *end)
+static const u8 * eap_gpsk_process_id_server(struct eap_gpsk_data *data,
+					     const u8 *pos, const u8 *end)
 {
 	u16 alen;
 
@@ -161,8 +161,8 @@
 }
 
 
-const u8 * eap_gpsk_process_rand_server(struct eap_gpsk_data *data,
-					const u8 *pos, const u8 *end)
+static const u8 * eap_gpsk_process_rand_server(struct eap_gpsk_data *data,
+					       const u8 *pos, const u8 *end)
 {
 	if (pos == NULL)
 		return NULL;
@@ -219,10 +219,11 @@
 }
 
 
-const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm,
-					struct eap_gpsk_data *data,
-					const u8 **list, size_t *list_len,
-					const u8 *pos, const u8 *end)
+static const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm,
+					       struct eap_gpsk_data *data,
+					       const u8 **list,
+					       size_t *list_len,
+					       const u8 *pos, const u8 *end)
 {
 	if (pos == NULL)
 		return NULL;
@@ -374,8 +375,8 @@
 }
 
 
-const u8 * eap_gpsk_validate_rand(struct eap_gpsk_data *data, const u8 *pos,
-				  const u8 *end)
+static const u8 * eap_gpsk_validate_rand(struct eap_gpsk_data *data,
+					 const u8 *pos, const u8 *end)
 {
 	if (end - pos < EAP_GPSK_RAND_LEN) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
@@ -413,8 +414,8 @@
 }
 
 
-const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data,
-				       const u8 *pos, const u8 *end)
+static const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data,
+					      const u8 *pos, const u8 *end)
 {
 	size_t len;
 
@@ -444,6 +445,7 @@
 				  data->id_server, data->id_server_len);
 		wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3",
 				  pos, len);
+		return NULL;
 	}
 
 	pos += len;
@@ -452,8 +454,8 @@
 }
 
 
-const u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data, const u8 *pos,
-				    const u8 *end)
+static const u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data,
+					   const u8 *pos, const u8 *end)
 {
 	int vendor, specifier;
 	const struct eap_gpsk_csuite *csuite;
@@ -481,8 +483,8 @@
 }
 
 
-const u8 * eap_gpsk_validate_pd_payload_2(struct eap_gpsk_data *data,
-					  const u8 *pos, const u8 *end)
+static const u8 * eap_gpsk_validate_pd_payload_2(struct eap_gpsk_data *data,
+						 const u8 *pos, const u8 *end)
 {
 	u16 alen;
 
@@ -508,9 +510,9 @@
 }
 
 
-const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data,
-					const u8 *payload,
-					const u8 *pos, const u8 *end)
+static const u8 * eap_gpsk_validate_gpsk_3_mic(struct eap_gpsk_data *data,
+					       const u8 *payload,
+					       const u8 *pos, const u8 *end)
 {
 	size_t miclen;
 	u8 mic[EAP_GPSK_MAX_MIC_LEN];

Modified: wpasupplicant/trunk/src/eap_peer/eap_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_i.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_i.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_i.h Sat Jan 10 09:03:49 2009
@@ -328,12 +328,11 @@
 
 	/* Optional challenges generated in Phase 1 (EAP-FAST) */
 	u8 *peer_challenge, *auth_challenge;
-	int mschapv2_full_key; /* Request full MSCHAPv2 key */
 
 	int num_rounds;
 	int force_disabled;
 
-	u8 mac_addr[ETH_ALEN];
+	struct wps_context *wps;
 };
 
 const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
@@ -349,5 +348,6 @@
 const struct wpa_config_blob *
 eap_get_config_blob(struct eap_sm *sm, const char *name);
 void eap_notify_pending(struct eap_sm *sm);
+int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method);
 
 #endif /* EAP_I_H */

Modified: wpasupplicant/trunk/src/eap_peer/eap_methods.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_methods.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_methods.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_methods.c Sat Jan 10 09:03:49 2009
@@ -427,6 +427,13 @@
 	}
 #endif /* EAP_AKA */
 
+#ifdef EAP_AKA_PRIME
+	if (ret == 0) {
+		int eap_peer_aka_prime_register(void);
+		ret = eap_peer_aka_prime_register();
+	}
+#endif /* EAP_AKA_PRIME */
+
 #ifdef EAP_FAST
 	if (ret == 0) {
 		int eap_peer_fast_register(void);
@@ -454,6 +461,13 @@
 		ret = eap_peer_gpsk_register();
 	}
 #endif /* EAP_GPSK */
+
+#ifdef EAP_WSC
+	if (ret == 0) {
+		int eap_peer_wsc_register(void);
+		ret = eap_peer_wsc_register();
+	}
+#endif /* EAP_WSC */
 
 #ifdef EAP_IKEV2
 	if (ret == 0) {

Modified: wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c Sat Jan 10 09:03:49 2009
@@ -93,7 +93,6 @@
 	 */
 	u8 *peer_challenge;
 	u8 *auth_challenge;
-	int full_key;
 
 	int phase2;
 	u8 master_key[MSCHAPV2_MASTER_KEY_LEN];
@@ -114,10 +113,7 @@
 	if (data == NULL)
 		return NULL;
 
-	data->full_key = sm->mschapv2_full_key;
-
 	if (sm->peer_challenge) {
-		data->full_key = 1;
 		data->peer_challenge = os_malloc(MSCHAPV2_CHAL_LEN);
 		if (data->peer_challenge == NULL) {
 			eap_mschapv2_deinit(sm, data);
@@ -830,27 +826,17 @@
 	if (!data->master_key_valid || !data->success)
 		return NULL;
 
-	if (data->full_key) {
-		/* EAP-FAST needs both send and receive keys */
-		key_len = 2 * MSCHAPV2_KEY_LEN;
-	} else {
-		key_len = MSCHAPV2_KEY_LEN;
-	}
+	key_len = 2 * MSCHAPV2_KEY_LEN;
 
 	key = os_malloc(key_len);
 	if (key == NULL)
 		return NULL;
 
-	if (data->full_key) {
-		get_asymetric_start_key(data->master_key, key,
-					MSCHAPV2_KEY_LEN, 0, 0);
-		get_asymetric_start_key(data->master_key,
-					key + MSCHAPV2_KEY_LEN,
-					MSCHAPV2_KEY_LEN, 1, 0);
-	} else {
-		get_asymetric_start_key(data->master_key, key,
-					MSCHAPV2_KEY_LEN, 1, 0);
-	}
+	/* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key, i.e.,
+	 *	peer MS-MPPE-Send-Key | MS-MPPE-Recv-Key */
+	get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 1, 0);
+	get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
+				MSCHAPV2_KEY_LEN, 0, 0);
 
 	wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key",
 			key, key_len);

Modified: wpasupplicant/trunk/src/eap_peer/eap_peap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_peap.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_peap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_peap.c Sat Jan 10 09:03:49 2009
@@ -60,6 +60,7 @@
 				 * EAP-Success and expect AS to send outer
 				 * (unencrypted) EAP-Success after this */
 	int resuming; /* starting a resumed session */
+	int reauth; /* reauthentication */
 	u8 *key_data;
 
 	struct wpabuf *pending_phase2_req;
@@ -118,9 +119,15 @@
 	}
 
 #ifdef EAP_TNC
-	if (os_strstr(phase1, "tnc=soh")) {
+	if (os_strstr(phase1, "tnc=soh2")) {
+		data->soh = 2;
+		wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled");
+	} else if (os_strstr(phase1, "tnc=soh1")) {
 		data->soh = 1;
-		wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH enabled");
+		wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 1 enabled");
+	} else if (os_strstr(phase1, "tnc=soh")) {
+		data->soh = 2;
+		wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled");
 	}
 #endif /* EAP_TNC */
 
@@ -140,7 +147,7 @@
 	data->peap_version = EAP_PEAP_VERSION;
 	data->force_peap_version = -1;
 	data->peap_outer_success = 2;
-	data->crypto_binding = NO_BINDING;
+	data->crypto_binding = OPTIONAL_BINDING;
 
 	if (config && config->phase1 &&
 	    eap_peap_parse_phase1(data, config->phase1) < 0) {
@@ -231,21 +238,6 @@
 		return -1;
 	}
 
-	if (key_len == 32 &&
-	    data->phase2_method->vendor == EAP_VENDOR_IETF &&
-	    data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
-		/*
-		 * Microsoft uses reverse order for MS-MPPE keys in
-		 * EAP-PEAP when compared to EAP-FAST derivation of
-		 * ISK. Swap the keys here to get the correct ISK for
-		 * EAP-PEAPv0 cryptobinding.
-		 */
-		u8 tmp[16];
-		os_memcpy(tmp, key, 16);
-		os_memcpy(key, key + 16, 16);
-		os_memcpy(key + 16, tmp, 16);
-	}
-
 	if (key_len > isk_len)
 		key_len = isk_len;
 	os_memcpy(isk, key, key_len);
@@ -268,6 +260,18 @@
 	if (tk == NULL)
 		return -1;
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: TK", tk, 60);
+
+	if (data->reauth &&
+	    tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
+		/* Fast-connect: IPMK|CMK = TK */
+		os_memcpy(data->ipmk, tk, 40);
+		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK from TK",
+				data->ipmk, 40);
+		os_memcpy(data->cmk, tk + 40, 20);
+		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: CMK from TK",
+				data->cmk, 20);
+		return 0;
+	}
 
 	if (eap_peap_get_isk(sm, data, isk, sizeof(isk)) < 0)
 		return -1;
@@ -286,7 +290,6 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IMCK (IPMKj)",
 			imck, sizeof(imck));
 
-	/* TODO: fast-connect: IPMK|CMK = TK */
 	os_memcpy(data->ipmk, imck, 40);
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: IPMK (S-IPMKj)", data->ipmk, 40);
 	os_memcpy(data->cmk, imck + 40, 20);
@@ -656,7 +659,8 @@
 				struct wpabuf *buf;
 				wpa_printf(MSG_DEBUG,
 					   "EAP-PEAP: SoH EAP Extensions");
-				buf = tncc_process_soh_request(epos, eleft);
+				buf = tncc_process_soh_request(data->soh,
+							       epos, eleft);
 				if (buf) {
 					*resp = eap_msg_alloc(
 						EAP_VENDOR_MICROSOFT, 0x21,
@@ -712,11 +716,9 @@
 				data->phase2_type.method);
 			if (data->phase2_method) {
 				sm->init_phase2 = 1;
-				sm->mschapv2_full_key = 1;
 				data->phase2_priv =
 					data->phase2_method->init(sm);
 				sm->init_phase2 = 0;
-				sm->mschapv2_full_key = 0;
 			}
 		}
 		if (data->phase2_priv == NULL || data->phase2_method == NULL) {
@@ -1191,6 +1193,7 @@
 	data->phase2_eap_success = 0;
 	data->phase2_eap_started = 0;
 	data->resuming = 1;
+	data->reauth = 1;
 	sm->peap_done = FALSE;
 	return priv;
 }

Modified: wpasupplicant/trunk/src/eap_peer/eap_tls_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tls_common.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tls_common.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tls_common.c Sat Jan 10 09:03:49 2009
@@ -501,6 +501,17 @@
 	length_included = data->tls_out_pos == 0 &&
 		(data->tls_out_len > data->tls_out_limit ||
 		 data->include_tls_length);
+	if (!length_included &&
+	    eap_type == EAP_TYPE_PEAP && peap_version == 0 &&
+	    !tls_connection_established(data->eap->ssl_ctx, data->conn)) {
+		/*
+		 * Windows Server 2008 NPS really wants to have the TLS Message
+		 * length included in phase 0 even for unfragmented frames or
+		 * it will get very confused with Compound MAC calculation and
+		 * Outer TLVs.
+		 */
+		length_included = 1;
+	}
 
 	*out_data = eap_msg_alloc(EAP_VENDOR_IETF, eap_type,
 				  1 + length_included * 4 + len,
@@ -738,8 +749,21 @@
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	*flags = *pos++;
-	left--;
+	if (left == 0) {
+		wpa_printf(MSG_DEBUG, "SSL: Invalid TLS message: no Flags "
+			   "octet included");
+		if (!sm->workaround) {
+			ret->ignore = TRUE;
+			return NULL;
+		}
+
+		wpa_printf(MSG_DEBUG, "SSL: Workaround - assume no Flags "
+			   "indicates ACK frame");
+		*flags = 0;
+	} else {
+		*flags = *pos++;
+		left--;
+	}
 	wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - "
 		   "Flags 0x%02x", (unsigned long) wpabuf_len(reqData),
 		   *flags);

Modified: wpasupplicant/trunk/src/eap_peer/eap_ttls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_ttls.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_ttls.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_ttls.c Sat Jan 10 09:03:49 2009
@@ -558,10 +558,8 @@
 			EAP_VENDOR_IETF, method);
 		if (data->phase2_method) {
 			sm->init_phase2 = 1;
-			sm->mschapv2_full_key = 1;
 			data->phase2_priv = data->phase2_method->init(sm);
 			sm->init_phase2 = 0;
-			sm->mschapv2_full_key = 0;
 		}
 	}
 	if (data->phase2_priv == NULL || data->phase2_method == NULL) {

Modified: wpasupplicant/trunk/src/eap_peer/tncc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/tncc.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/tncc.c (original)
+++ wpasupplicant/trunk/src/eap_peer/tncc.c Sat Jan 10 09:03:49 2009
@@ -1218,12 +1218,11 @@
 }
 
 
-static struct wpabuf * tncc_build_soh(void)
+static struct wpabuf * tncc_build_soh(int ver)
 {
 	struct wpabuf *buf;
 	u8 *tlv_len, *tlv_len2, *outer_len, *inner_len, *ssoh_len, *end;
 	u8 correlation_id[24];
-	int ver = 2;
 	/* TODO: get correct name */
 	char *machinename = "wpa_supplicant at w1.fi";
 
@@ -1332,7 +1331,7 @@
 }
 
 
-struct wpabuf * tncc_process_soh_request(const u8 *data, size_t len)
+struct wpabuf * tncc_process_soh_request(int ver, const u8 *data, size_t len)
 {
 	const u8 *pos;
 
@@ -1365,5 +1364,5 @@
 
 	wpa_printf(MSG_DEBUG, "TNC: SoH Request TLV received");
 
-	return tncc_build_soh();
-}
+	return tncc_build_soh(2);
+}

Modified: wpasupplicant/trunk/src/eap_peer/tncc.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/tncc.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/tncc.h (original)
+++ wpasupplicant/trunk/src/eap_peer/tncc.h Sat Jan 10 09:03:49 2009
@@ -37,6 +37,6 @@
 enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
 					    const u8 *msg, size_t len);
 
-struct wpabuf * tncc_process_soh_request(const u8 *data, size_t len);
+struct wpabuf * tncc_process_soh_request(int ver, const u8 *data, size_t len);
 
 #endif /* TNCC_H */

Modified: wpasupplicant/trunk/src/eap_server/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap.c Sat Jan 10 09:03:49 2009
@@ -792,10 +792,51 @@
 				   int eapSRTT, int eapRTTVAR,
 				   int methodTimeout)
 {
-	/* For now, retransmission is done in EAPOL state machines, so make
-	 * sure EAP state machine does not end up trying to retransmit packets.
+	int rto, i;
+
+	if (methodTimeout) {
+		/*
+		 * EAP method (either internal or through AAA server, provided
+		 * timeout hint. Use that as-is as a timeout for retransmitting
+		 * the EAP request if no response is received.
+		 */
+		wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
+			   "(from EAP method hint)", methodTimeout);
+		return methodTimeout;
+	}
+
+	/*
+	 * RFC 3748 recommends algorithms described in RFC 2988 for estimation
+	 * of the retransmission timeout. This should be implemented once
+	 * round-trip time measurements are available. For nowm a simple
+	 * backoff mechanism is used instead if there are no EAP method
+	 * specific hints.
+	 *
+	 * SRTT = smoothed round-trip time
+	 * RTTVAR = round-trip time variation
+	 * RTO = retransmission timeout
 	 */
-	return 1;
+
+	/*
+	 * RFC 2988, 2.1: before RTT measurement, set RTO to 3 seconds for
+	 * initial retransmission and then double the RTO to provide back off
+	 * per 5.5. Limit the maximum RTO to 20 seconds per RFC 3748, 4.3
+	 * modified RTOmax.
+	 */
+	rto = 3;
+	for (i = 0; i < retransCount; i++) {
+		rto *= 2;
+		if (rto >= 20) {
+			rto = 20;
+			break;
+		}
+	}
+
+	wpa_printf(MSG_DEBUG, "EAP: retransmit timeout %d seconds "
+		   "(from dynamic back off; retransCount=%d)",
+		   rto, retransCount);
+
+	return rto;
 }
 
 
@@ -1051,9 +1092,28 @@
 	}
 
 	if ((sm->user == NULL || sm->update_user) && sm->identity) {
+		/*
+		 * Allow Identity method to be started once to allow identity
+		 * selection hint to be sent from the authentication server,
+		 * but prevent a loop of Identity requests by only allowing
+		 * this to happen once.
+		 */
+		int id_req = 0;
+		if (sm->user && sm->currentMethod == EAP_TYPE_IDENTITY &&
+		    sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
+		    sm->user->methods[0].method == EAP_TYPE_IDENTITY)
+			id_req = 1;
 		if (eap_user_get(sm, sm->identity, sm->identity_len, 0) != 0) {
 			wpa_printf(MSG_DEBUG, "EAP: getDecision: user not "
 				   "found from database -> FAILURE");
+			return DECISION_FAILURE;
+		}
+		if (id_req && sm->user &&
+		    sm->user->methods[0].vendor == EAP_VENDOR_IETF &&
+		    sm->user->methods[0].method == EAP_TYPE_IDENTITY) {
+			wpa_printf(MSG_DEBUG, "EAP: getDecision: stop "
+				   "identity request loop -> FAILURE");
+			sm->update_user = TRUE;
 			return DECISION_FAILURE;
 		}
 		sm->update_user = FALSE;
@@ -1139,7 +1199,7 @@
 		return NULL;
 	sm->eapol_ctx = eapol_ctx;
 	sm->eapol_cb = eapol_cb;
-	sm->MaxRetrans = 10;
+	sm->MaxRetrans = 5; /* RFC 3748: max 3-5 retransmissions suggested */
 	sm->ssl_ctx = conf->ssl_ctx;
 	sm->eap_sim_db_priv = conf->eap_sim_db_priv;
 	sm->backend_auth = conf->backend_auth;
@@ -1166,6 +1226,9 @@
 	sm->pac_key_refresh_time = conf->pac_key_refresh_time;
 	sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
 	sm->tnc = conf->tnc;
+	sm->wps = conf->wps;
+	if (conf->assoc_wps_ie)
+		sm->assoc_wps_ie = wpabuf_dup(conf->assoc_wps_ie);
 
 	wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
 
@@ -1199,6 +1262,7 @@
 	wpabuf_free(sm->eap_if.aaaEapRespData);
 	os_free(sm->eap_if.aaaEapKeyData);
 	eap_user_free(sm->user);
+	wpabuf_free(sm->assoc_wps_ie);
 	os_free(sm);
 }
 

Modified: wpasupplicant/trunk/src/eap_server/eap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap.h Sat Jan 10 09:03:49 2009
@@ -103,6 +103,8 @@
 	int pac_key_refresh_time;
 	int eap_sim_aka_result_ind;
 	int tnc;
+	struct wps_context *wps;
+	const struct wpabuf *assoc_wps_ie;
 };
 
 

Modified: wpasupplicant/trunk/src/eap_server/eap_aka.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_aka.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_aka.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_aka.c Sat Jan 10 09:03:49 2009
@@ -1,5 +1,5 @@
 /*
- * hostapd / EAP-AKA (RFC 4187)
+ * hostapd / EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf)
  * Copyright (c) 2005-2008, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -19,14 +19,16 @@
 #include "eap_common/eap_sim_common.h"
 #include "eap_server/eap_sim_db.h"
 #include "sha1.h"
+#include "sha256.h"
 #include "crypto.h"
 
 
 struct eap_aka_data {
 	u8 mk[EAP_SIM_MK_LEN];
 	u8 nonce_s[EAP_SIM_NONCE_S_LEN];
-	u8 k_aut[EAP_SIM_K_AUT_LEN];
+	u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
 	u8 k_encr[EAP_SIM_K_ENCR_LEN];
+	u8 k_re[EAP_AKA_PRIME_K_RE_LEN]; /* EAP-AKA' only */
 	u8 msk[EAP_SIM_KEYING_DATA_LEN];
 	u8 emsk[EAP_EMSK_LEN];
 	u8 rand[EAP_AKA_RAND_LEN];
@@ -49,6 +51,10 @@
 
 	struct wpabuf *id_msgs;
 	int pending_id;
+	u8 eap_method;
+	u8 *network_name;
+	size_t network_name_len;
+	u16 kdf;
 };
 
 
@@ -99,12 +105,50 @@
 	data = os_zalloc(sizeof(*data));
 	if (data == NULL)
 		return NULL;
+
+	data->eap_method = EAP_TYPE_AKA;
+
 	data->state = IDENTITY;
 	eap_aka_determine_identity(sm, data, 1, 0);
 	data->pending_id = -1;
 
 	return data;
 }
+
+
+#ifdef EAP_AKA_PRIME
+static void * eap_aka_prime_init(struct eap_sm *sm)
+{
+	struct eap_aka_data *data;
+	/* TODO: make ANID configurable; see 3GPP TS 24.302 */
+	char *network_name = "WLAN";
+
+	if (sm->eap_sim_db_priv == NULL) {
+		wpa_printf(MSG_WARNING, "EAP-AKA: eap_sim_db not configured");
+		return NULL;
+	}
+
+	data = os_zalloc(sizeof(*data));
+	if (data == NULL)
+		return NULL;
+
+	data->eap_method = EAP_TYPE_AKA_PRIME;
+	data->network_name = os_malloc(os_strlen(network_name));
+	if (data->network_name == NULL) {
+		os_free(data);
+		return NULL;
+	}
+
+	data->network_name_len = os_strlen(network_name);
+	os_memcpy(data->network_name, network_name, data->network_name_len);
+
+	data->state = IDENTITY;
+	eap_aka_determine_identity(sm, data, 1, 0);
+	data->pending_id = -1;
+
+	return data;
+}
+#endif /* EAP_AKA_PRIME */
 
 
 static void eap_aka_reset(struct eap_sm *sm, void *priv)
@@ -113,6 +157,7 @@
 	os_free(data->next_pseudonym);
 	os_free(data->next_reauth_id);
 	wpabuf_free(data->id_msgs);
+	os_free(data->network_name);
 	os_free(data);
 }
 
@@ -141,7 +186,7 @@
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
 
 	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
 
@@ -158,10 +203,14 @@
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
-	sha1_vector(1, &addr, &len, hash);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+		sha1_vector(1, &addr, &len, hash);
 
 	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
-			EAP_AKA_CHECKCODE_LEN);
+			data->eap_method == EAP_TYPE_AKA_PRIME ?
+			EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN);
 }
 
 
@@ -170,7 +219,8 @@
 {
 	const u8 *addr;
 	size_t len;
-	u8 hash[SHA1_MAC_LEN];
+	u8 hash[SHA256_MAC_LEN];
+	size_t hash_len;
 
 	if (checkcode == NULL)
 		return -1;
@@ -185,7 +235,10 @@
 		return 0;
 	}
 
-	if (checkcode_len != EAP_AKA_CHECKCODE_LEN) {
+	hash_len = data->eap_method == EAP_TYPE_AKA_PRIME ?
+		EAP_AKA_PRIME_CHECKCODE_LEN : EAP_AKA_CHECKCODE_LEN;
+
+	if (checkcode_len != hash_len) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from peer indicates "
 			   "that AKA/Identity message were not used, but they "
 			   "were");
@@ -195,9 +248,12 @@
 	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
 	addr = wpabuf_head(data->id_msgs);
 	len = wpabuf_len(data->id_msgs);
-	sha1_vector(1, &addr, &len, hash);
-
-	if (os_memcmp(hash, checkcode, EAP_AKA_CHECKCODE_LEN) != 0) {
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		sha256_vector(1, &addr, &len, hash);
+	else
+		sha1_vector(1, &addr, &len, hash);
+
+	if (os_memcmp(hash, checkcode, hash_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
 		return -1;
 	}
@@ -213,7 +269,7 @@
 	struct wpabuf *buf;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Identity");
-	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_IDENTITY);
 	if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity,
 				      sm->identity_len)) {
@@ -309,11 +365,23 @@
 	struct eap_sim_msg *msg;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Challenge");
-	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_CHALLENGE);
 	wpa_printf(MSG_DEBUG, "   AT_RAND");
 	eap_sim_msg_add(msg, EAP_SIM_AT_RAND, 0, data->rand, EAP_AKA_RAND_LEN);
 	eap_sim_msg_add(msg, EAP_SIM_AT_AUTN, 0, data->autn, EAP_AKA_AUTN_LEN);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		if (data->kdf) {
+			/* Add the selected KDF into the beginning */
+			eap_sim_msg_add(msg, EAP_SIM_AT_KDF, data->kdf,
+					NULL, 0);
+		}
+		eap_sim_msg_add(msg, EAP_SIM_AT_KDF, EAP_AKA_PRIME_KDF,
+				NULL, 0);
+		eap_sim_msg_add(msg, EAP_SIM_AT_KDF_INPUT,
+				data->network_name_len,
+				data->network_name, data->network_name_len);
+	}
 
 	if (eap_aka_build_encr(sm, data, msg, 0, NULL)) {
 		eap_sim_msg_free(msg);
@@ -326,6 +394,35 @@
 		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
 		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
 	}
+
+#ifdef EAP_AKA_PRIME
+	if (data->eap_method == EAP_TYPE_AKA) {
+		u16 flags = 0;
+		int i;
+		int aka_prime_preferred = 0;
+
+		i = 0;
+		while (sm->user && i < EAP_MAX_METHODS &&
+		       (sm->user->methods[i].vendor != EAP_VENDOR_IETF ||
+			sm->user->methods[i].method != EAP_TYPE_NONE)) {
+			if (sm->user->methods[i].vendor == EAP_VENDOR_IETF) {
+				if (sm->user->methods[i].method ==
+				    EAP_TYPE_AKA)
+					break;
+				if (sm->user->methods[i].method ==
+				    EAP_TYPE_AKA_PRIME) {
+					aka_prime_preferred = 1;
+					break;
+				}
+			}
+			i++;
+		}
+
+		if (aka_prime_preferred)
+			flags |= EAP_AKA_BIDDING_FLAG_D;
+		eap_sim_msg_add(msg, EAP_SIM_AT_BIDDING, flags, NULL, 0);
+	}
+#endif /* EAP_AKA_PRIME */
 
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
@@ -345,13 +442,21 @@
 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S",
 			data->nonce_s, EAP_SIM_NONCE_S_LEN);
 
-	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
-			    data->emsk);
-	eap_sim_derive_keys_reauth(data->counter, sm->identity,
-				   sm->identity_len, data->nonce_s, data->mk,
-				   data->msk, data->emsk);
-
-	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_AKA,
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		eap_aka_prime_derive_keys_reauth(data->k_re, data->counter,
+						 sm->identity,
+						 sm->identity_len,
+						 data->nonce_s,
+						 data->msk, data->emsk);
+	} else {
+		eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
+				    data->msk, data->emsk);
+		eap_sim_derive_keys_reauth(data->counter, sm->identity,
+					   sm->identity_len, data->nonce_s,
+					   data->mk, data->msk, data->emsk);
+	}
+
+	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_REAUTHENTICATION);
 
 	if (eap_aka_build_encr(sm, data, msg, data->counter, data->nonce_s)) {
@@ -379,7 +484,7 @@
 	struct eap_sim_msg *msg;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Notification");
-	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_AKA,
+	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, data->eap_method,
 			       EAP_AKA_SUBTYPE_NOTIFICATION);
 	wpa_printf(MSG_DEBUG, "   AT_NOTIFICATION (%d)", data->notification);
 	eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification,
@@ -437,10 +542,12 @@
 static Boolean eap_aka_check(struct eap_sm *sm, void *priv,
 			     struct wpabuf *respData)
 {
+	struct eap_aka_data *data = priv;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, respData, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData,
+			       &len);
 	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-AKA: Invalid frame");
 		return TRUE;
@@ -523,14 +630,33 @@
 			data->reauth = eap_sim_db_get_reauth_entry(
 				sm->eap_sim_db_priv, sm->identity,
 				sm->identity_len);
+			if (data->reauth &&
+			    data->reauth->aka_prime !=
+			    (data->eap_method == EAP_TYPE_AKA_PRIME)) {
+				wpa_printf(MSG_DEBUG, "EAP-AKA: Reauth data "
+					   "was for different AKA version");
+				data->reauth = NULL;
+			}
 			if (data->reauth) {
 				wpa_printf(MSG_DEBUG, "EAP-AKA: Using fast "
 					   "re-authentication");
 				identity = data->reauth->identity;
 				identity_len = data->reauth->identity_len;
 				data->counter = data->reauth->counter;
-				os_memcpy(data->mk, data->reauth->mk,
-					  EAP_SIM_MK_LEN);
+				if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+					os_memcpy(data->k_encr,
+						  data->reauth->k_encr,
+						  EAP_SIM_K_ENCR_LEN);
+					os_memcpy(data->k_aut,
+						  data->reauth->k_aut,
+						  EAP_AKA_PRIME_K_AUT_LEN);
+					os_memcpy(data->k_re,
+						  data->reauth->k_re,
+						  EAP_AKA_PRIME_K_RE_LEN);
+				} else {
+					os_memcpy(data->mk, data->reauth->mk,
+						  EAP_SIM_MK_LEN);
+				}
 			}
 		}
 	}
@@ -571,6 +697,17 @@
 		return;
 	}
 
+#ifdef EAP_AKA_PRIME
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		/* Note: AUTN = (SQN ^ AK) || AMF || MAC which gives us the
+		 * needed 6-octet SQN ^AK for CK',IK' derivation */
+		eap_aka_prime_derive_ck_ik_prime(data->ck, data->ik,
+						 data->autn,
+						 data->network_name,
+						 data->network_name_len);
+	}
+#endif /* EAP_AKA_PRIME */
+
 	data->reauth = NULL;
 	data->counter = 0; /* reset re-auth counter since this is full auth */
 
@@ -596,10 +733,16 @@
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-AKA: Identity for MK derivation",
 			  sm->identity, identity_len);
 
-	eap_aka_derive_mk(sm->identity, identity_len, data->ik, data->ck,
-			  data->mk);
-	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
-			    data->emsk);
+	if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+		eap_aka_prime_derive_keys(identity, identity_len, data->ik,
+					  data->ck, data->k_encr, data->k_aut,
+					  data->k_re, data->msk, data->emsk);
+	} else {
+		eap_aka_derive_mk(sm->identity, identity_len, data->ik,
+				  data->ck, data->mk);
+		eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut,
+				    data->msk, data->emsk);
+	}
 
 	eap_aka_state(data, CHALLENGE);
 }
@@ -638,6 +781,18 @@
 }
 
 
+static int eap_aka_verify_mac(struct eap_aka_data *data,
+			      const struct wpabuf *req,
+			      const u8 *mac, const u8 *extra,
+			      size_t extra_len)
+{
+	if (data->eap_method == EAP_TYPE_AKA_PRIME)
+		return eap_sim_verify_mac_sha256(data->k_aut, req, mac, extra,
+						 extra_len);
+	return eap_sim_verify_mac(data->k_aut, req, mac, extra, extra_len);
+}
+
+
 static void eap_aka_process_challenge(struct eap_sm *sm,
 				      struct eap_aka_data *data,
 				      struct wpabuf *respData,
@@ -647,6 +802,31 @@
 	size_t identity_len;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Challenge");
+
+#ifdef EAP_AKA_PRIME
+#if 0
+	/* KDF negotiation; to be enabled only after more than one KDF is
+	 * supported */
+	if (data->eap_method == EAP_TYPE_AKA_PRIME &&
+	    attr->kdf_count == 1 && attr->mac == NULL) {
+		if (attr->kdf[0] != EAP_AKA_PRIME_KDF) {
+			wpa_printf(MSG_WARNING, "EAP-AKA': Peer selected "
+				   "unknown KDF");
+			data->notification =
+				EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
+			eap_aka_state(data, NOTIFICATION);
+			return;
+		}
+
+		data->kdf = attr->kdf[0];
+
+		/* Allow negotiation to continue with the selected KDF by
+		 * sending another Challenge message */
+		wpa_printf(MSG_DEBUG, "EAP-AKA': KDF %d selected", data->kdf);
+		return;
+	}
+#endif
+#endif /* EAP_AKA_PRIME */
 
 	if (attr->checkcode &&
 	    eap_aka_verify_checkcode(data, attr->checkcode,
@@ -658,7 +838,7 @@
 		return;
 	}
 	if (attr->mac == NULL ||
-	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, NULL, 0)) {
+	    eap_aka_verify_mac(data, respData, attr->mac, NULL, 0)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
 			   "did not include valid AT_MAC");
 		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
@@ -707,10 +887,23 @@
 		data->next_pseudonym = NULL;
 	}
 	if (data->next_reauth_id) {
-		eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
-				      identity_len,
-				      data->next_reauth_id, data->counter + 1,
-				      data->mk);
+		if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+#ifdef EAP_AKA_PRIME
+			eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,
+						    identity,
+						    identity_len,
+						    data->next_reauth_id,
+						    data->counter + 1,
+						    data->k_encr, data->k_aut,
+						    data->k_re);
+#endif /* EAP_AKA_PRIME */
+		} else {
+			eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
+					      identity_len,
+					      data->next_reauth_id,
+					      data->counter + 1,
+					      data->mk);
+		}
 		data->next_reauth_id = NULL;
 	}
 }
@@ -763,7 +956,7 @@
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication");
 
 	if (attr->mac == NULL ||
-	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,
+	    eap_aka_verify_mac(data, respData, attr->mac, data->nonce_s,
 			       EAP_SIM_NONCE_S_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "
 			   "did not include valid AT_MAC");
@@ -833,9 +1026,23 @@
 		data->next_pseudonym = NULL;
 	}
 	if (data->next_reauth_id) {
-		eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
-				      identity_len, data->next_reauth_id,
-				      data->counter + 1, data->mk);
+		if (data->eap_method == EAP_TYPE_AKA_PRIME) {
+#ifdef EAP_AKA_PRIME
+			eap_sim_db_add_reauth_prime(sm->eap_sim_db_priv,
+						    identity,
+						    identity_len,
+						    data->next_reauth_id,
+						    data->counter + 1,
+						    data->k_encr, data->k_aut,
+						    data->k_re);
+#endif /* EAP_AKA_PRIME */
+		} else {
+			eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
+					      identity_len,
+					      data->next_reauth_id,
+					      data->counter + 1,
+					      data->mk);
+		}
 		data->next_reauth_id = NULL;
 	} else {
 		eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
@@ -898,7 +1105,8 @@
 	size_t len;
 	struct eap_sim_attrs attr;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, respData, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, data->eap_method, respData,
+			       &len);
 	if (pos == NULL || len < 3)
 		return;
 
@@ -914,7 +1122,9 @@
 		return;
 	}
 
-	if (eap_sim_parse_attr(pos, end, &attr, 1, 0)) {
+	if (eap_sim_parse_attr(pos, end, &attr,
+			       data->eap_method == EAP_TYPE_AKA_PRIME ? 2 : 1,
+			       0)) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes");
 		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
 		eap_aka_state(data, NOTIFICATION);
@@ -1031,3 +1241,34 @@
 		eap_server_method_free(eap);
 	return ret;
 }
+
+
+#ifdef EAP_AKA_PRIME
+int eap_server_aka_prime_register(void)
+{
+	struct eap_method *eap;
+	int ret;
+
+	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
+				      EAP_VENDOR_IETF, EAP_TYPE_AKA_PRIME,
+				      "AKA'");
+	if (eap == NULL)
+		return -1;
+
+	eap->init = eap_aka_prime_init;
+	eap->reset = eap_aka_reset;
+	eap->buildReq = eap_aka_buildReq;
+	eap->check = eap_aka_check;
+	eap->process = eap_aka_process;
+	eap->isDone = eap_aka_isDone;
+	eap->getKey = eap_aka_getKey;
+	eap->isSuccess = eap_aka_isSuccess;
+	eap->get_emsk = eap_aka_get_emsk;
+
+	ret = eap_server_method_register(eap);
+	if (ret)
+		eap_server_method_free(eap);
+
+	return ret;
+}
+#endif /* EAP_AKA_PRIME */

Modified: wpasupplicant/trunk/src/eap_server/eap_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_fast.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_fast.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_fast.c Sat Jan 10 09:03:49 2009
@@ -354,7 +354,18 @@
 
 	if (key_len > isk_len)
 		key_len = isk_len;
-	os_memcpy(isk, key, key_len);
+	if (key_len == 32 &&
+	    data->phase2_method->vendor == EAP_VENDOR_IETF &&
+	    data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
+		/*
+		 * EAP-FAST uses reverse order for MS-MPPE keys when deriving
+		 * MSK from EAP-MSCHAPv2. Swap the keys here to get the correct
+		 * ISK for EAP-FAST cryptobinding.
+		 */
+		os_memcpy(isk, key + 16, 16);
+		os_memcpy(isk + 16, key, 16);
+	} else
+		os_memcpy(isk, key, key_len);
 	os_free(key);
 
 	return 0;

Modified: wpasupplicant/trunk/src/eap_server/eap_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_i.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_i.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap_i.h Sat Jan 10 09:03:49 2009
@@ -181,6 +181,8 @@
 	int pac_key_refresh_time;
 	int eap_sim_aka_result_ind;
 	int tnc;
+	struct wps_context *wps;
+	struct wpabuf *assoc_wps_ie;
 };
 
 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,

Modified: wpasupplicant/trunk/src/eap_server/eap_identity.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_identity.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_identity.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_identity.c Sat Jan 10 09:03:49 2009
@@ -125,6 +125,8 @@
 		return; /* Should not happen - frame already validated */
 
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len);
+	if (sm->identity)
+		sm->update_user = TRUE;
 	os_free(sm->identity);
 	sm->identity = os_malloc(len ? len : 1);
 	if (sm->identity == NULL) {

Modified: wpasupplicant/trunk/src/eap_server/eap_methods.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_methods.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_methods.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_methods.c Sat Jan 10 09:03:49 2009
@@ -68,7 +68,7 @@
  * EAP_SERVER_METHOD_INTERFACE_VERSION)
  * @vendor: EAP Vendor-ID (EAP_VENDOR_*) (0 = IETF)
  * @method: EAP type number (EAP_TYPE_*)
- * name: Name of the method (e.g., "TLS")
+ * @name: Name of the method (e.g., "TLS")
  * Returns: Allocated EAP method structure or %NULL on failure
  *
  * The returned structure should be freed with eap_server_method_free() when it
@@ -212,6 +212,13 @@
 	}
 #endif /* EAP_AKA */
 
+#ifdef EAP_AKA_PRIME
+	if (ret == 0) {
+		int eap_server_aka_prime_register(void);
+		ret = eap_server_aka_prime_register();
+	}
+#endif /* EAP_AKA_PRIME */
+
 #ifdef EAP_PAX
 	if (ret == 0) {
 		int eap_server_pax_register(void);
@@ -253,6 +260,13 @@
 		ret = eap_server_fast_register();
 	}
 #endif /* EAP_FAST */
+
+#ifdef EAP_WSC
+	if (ret == 0) {
+		int eap_server_wsc_register(void);
+		ret = eap_server_wsc_register();
+	}
+#endif /* EAP_WSC */
 
 #ifdef EAP_IKEV2
 	if (ret == 0) {

Modified: wpasupplicant/trunk/src/eap_server/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_mschapv2.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_mschapv2.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_mschapv2.c Sat Jan 10 09:03:49 2009
@@ -524,9 +524,10 @@
 	key = os_malloc(*len);
 	if (key == NULL)
 		return NULL;
-	get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0, 0);
+	/* MSK = server MS-MPPE-Recv-Key | MS-MPPE-Send-Key */
+	get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0, 1);
 	get_asymetric_start_key(data->master_key, key + MSCHAPV2_KEY_LEN,
-				MSCHAPV2_KEY_LEN, 1, 0);
+				MSCHAPV2_KEY_LEN, 1, 1);
 	wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: Derived key", key, *len);
 
 	return key;

Modified: wpasupplicant/trunk/src/eap_server/eap_peap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_peap.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_peap.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_peap.c Sat Jan 10 09:03:49 2009
@@ -975,21 +975,6 @@
 			eap_peap_phase2_init(sm, data, EAP_TYPE_NONE);
 			return;
 		}
-
-		if (data->phase2_key_len == 32 &&
-		    data->phase2_method->vendor == EAP_VENDOR_IETF &&
-		    data->phase2_method->method == EAP_TYPE_MSCHAPV2) {
-			/*
-			 * Microsoft uses reverse order for MS-MPPE keys in
-			 * EAP-PEAP when compared to EAP-FAST derivation of
-			 * ISK. Swap the keys here to get the correct ISK for
-			 * EAP-PEAPv0 cryptobinding.
-			 */
-			u8 tmp[16];
-			os_memcpy(tmp, data->phase2_key, 16);
-			os_memcpy(data->phase2_key, data->phase2_key + 16, 16);
-			os_memcpy(data->phase2_key + 16, tmp, 16);
-		}
 	}
 
 	switch (data->state) {

Modified: wpasupplicant/trunk/src/eap_server/eap_sim_db.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_sim_db.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_sim_db.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_sim_db.c Sat Jan 10 09:03:49 2009
@@ -942,27 +942,12 @@
 }
 
 
-/**
- * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry
- * @priv: Private data pointer from eap_sim_db_init()
- * @identity: Identity of the user (may be permanent identity or pseudonym)
- * @identity_len: Length of identity
- * @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
- * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
- * free it.
- * @mk: 16-byte MK from the previous full authentication
- * Returns: 0 on success, -1 on failure
- *
- * This function adds a new re-authentication entry for an EAP-SIM user.
- * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
- * anymore.
- */
-int eap_sim_db_add_reauth(void *priv, const u8 *identity,
-			  size_t identity_len, char *reauth_id, u16 counter,
-			  const u8 *mk)
-{
-	struct eap_sim_db_data *data = priv;
+static struct eap_sim_reauth *
+eap_sim_db_add_reauth_data(struct eap_sim_db_data *data, const u8 *identity,
+			   size_t identity_len, char *reauth_id, u16 counter)
+{
 	struct eap_sim_reauth *r;
+
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Add reauth_id for identity",
 			  identity, identity_len);
 	wpa_printf(MSG_DEBUG, "EAP-SIM DB: reauth_id: %s", reauth_id);
@@ -980,7 +965,7 @@
 		r = os_zalloc(sizeof(*r));
 		if (r == NULL) {
 			os_free(reauth_id);
-			return -1;
+			return NULL;
 		}
 
 		r->next = data->reauths;
@@ -988,7 +973,7 @@
 		if (r->identity == NULL) {
 			os_free(r);
 			os_free(reauth_id);
-			return -1;
+			return NULL;
 		}
 		os_memcpy(r->identity, identity, identity_len);
 		r->identity_len = identity_len;
@@ -998,10 +983,86 @@
 	}
 
 	r->counter = counter;
+
+	return r;
+}
+
+
+/**
+ * eap_sim_db_add_reauth - EAP-SIM DB: Add new re-authentication entry
+ * @priv: Private data pointer from eap_sim_db_init()
+ * @identity: Identity of the user (may be permanent identity or pseudonym)
+ * @identity_len: Length of identity
+ * @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
+ * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
+ * free it.
+ * @counter: AT_COUNTER value for fast re-authentication
+ * @mk: 16-byte MK from the previous full authentication or %NULL
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function adds a new re-authentication entry for an EAP-SIM user.
+ * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
+ * anymore.
+ */
+int eap_sim_db_add_reauth(void *priv, const u8 *identity,
+			  size_t identity_len, char *reauth_id, u16 counter,
+			  const u8 *mk)
+{
+	struct eap_sim_db_data *data = priv;
+	struct eap_sim_reauth *r;
+
+	r = eap_sim_db_add_reauth_data(data, identity, identity_len, reauth_id,
+				       counter);
+	if (r == NULL)
+		return -1;
+
 	os_memcpy(r->mk, mk, EAP_SIM_MK_LEN);
+	r->aka_prime = 0;
 
 	return 0;
 }
+
+
+#ifdef EAP_AKA_PRIME
+/**
+ * eap_sim_db_add_reauth_prime - EAP-AKA' DB: Add new re-authentication entry
+ * @priv: Private data pointer from eap_sim_db_init()
+ * @identity: Identity of the user (may be permanent identity or pseudonym)
+ * @identity_len: Length of identity
+ * @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
+ * e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
+ * free it.
+ * @counter: AT_COUNTER value for fast re-authentication
+ * @k_encr: K_encr from the previous full authentication
+ * @k_aut: K_aut from the previous full authentication
+ * @k_re: 32-byte K_re from the previous full authentication
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function adds a new re-authentication entry for an EAP-AKA' user.
+ * EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
+ * anymore.
+ */
+int eap_sim_db_add_reauth_prime(void *priv, const u8 *identity,
+				size_t identity_len, char *reauth_id,
+				u16 counter, const u8 *k_encr, const u8 *k_aut,
+				const u8 *k_re)
+{
+	struct eap_sim_db_data *data = priv;
+	struct eap_sim_reauth *r;
+
+	r = eap_sim_db_add_reauth_data(data, identity, identity_len, reauth_id,
+				       counter);
+	if (r == NULL)
+		return -1;
+
+	r->aka_prime = 1;
+	os_memcpy(r->k_encr, k_encr, EAP_SIM_K_ENCR_LEN);
+	os_memcpy(r->k_aut, k_aut, EAP_AKA_PRIME_K_AUT_LEN);
+	os_memcpy(r->k_re, k_re, EAP_AKA_PRIME_K_RE_LEN);
+
+	return 0;
+}
+#endif /* EAP_AKA_PRIME */
 
 
 /**
@@ -1038,7 +1099,6 @@
  * @identity: Identity of the user (may be permanent identity, pseudonym, or
  * reauth_id)
  * @identity_len: Length of identity
- * @len: Buffer for length of the returned permanent identity
  * Returns: Pointer to the re-auth entry, or %NULL if not found
  */
 struct eap_sim_reauth *

Modified: wpasupplicant/trunk/src/eap_server/eap_sim_db.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_sim_db.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_sim_db.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap_sim_db.h Sat Jan 10 09:03:49 2009
@@ -54,6 +54,10 @@
 int eap_sim_db_add_reauth(void *priv, const u8 *identity,
 			  size_t identity_len, char *reauth_id, u16 counter,
 			  const u8 *mk);
+int eap_sim_db_add_reauth_prime(void *priv, const u8 *identity,
+				size_t identity_len, char *reauth_id,
+				u16 counter, const u8 *k_encr, const u8 *k_aut,
+				const u8 *k_re);
 
 const u8 * eap_sim_db_get_permanent(void *priv, const u8 *identity,
 				    size_t identity_len, size_t *len);
@@ -64,7 +68,11 @@
 	size_t identity_len;
 	char *reauth_id;
 	u16 counter;
+	int aka_prime;
 	u8 mk[EAP_SIM_MK_LEN];
+	u8 k_encr[EAP_SIM_K_ENCR_LEN];
+	u8 k_aut[EAP_AKA_PRIME_K_AUT_LEN];
+	u8 k_re[EAP_AKA_PRIME_K_RE_LEN];
 };
 
 struct eap_sim_reauth *

Modified: wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c (original)
+++ wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c Sat Jan 10 09:03:49 2009
@@ -1804,6 +1804,7 @@
 	conf.pkcs11_engine_path = ctx->pkcs11_engine_path;
 	conf.pkcs11_module_path = ctx->pkcs11_module_path;
 #endif /* EAP_TLS_OPENSSL */
+	conf.wps = ctx->wps;
 
 	sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf);
 	if (sm->eap == NULL) {

Modified: wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.h (original)
+++ wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.h Sat Jan 10 09:03:49 2009
@@ -199,6 +199,13 @@
 	 */
 	const char *pkcs11_module_path;
 #endif /* EAP_TLS_OPENSSL */
+
+	/**
+	 * wps - WPS context data
+	 *
+	 * This is only used by EAP-WSC and can be left %NULL if not available.
+	 */
+	struct wps_context *wps;
 
 	/**
 	 * eap_param_needed - Notify that EAP parameter is needed

Modified: wpasupplicant/trunk/src/l2_packet/l2_packet.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/l2_packet/l2_packet.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/l2_packet/l2_packet.h (original)
+++ wpasupplicant/trunk/src/l2_packet/l2_packet.h Sat Jan 10 09:03:49 2009
@@ -38,7 +38,7 @@
 struct l2_ethhdr {
 	u8 h_dest[ETH_ALEN];
 	u8 h_source[ETH_ALEN];
-	u16 h_proto;
+	be16 h_proto;
 } STRUCT_PACKED;
 
 #ifdef _MSC_VER

Modified: wpasupplicant/trunk/src/l2_packet/l2_packet_winpcap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/l2_packet/l2_packet_winpcap.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/l2_packet/l2_packet_winpcap.c (original)
+++ wpasupplicant/trunk/src/l2_packet/l2_packet_winpcap.c Sat Jan 10 09:03:49 2009
@@ -336,5 +336,6 @@
 
 void l2_packet_notify_auth_start(struct l2_packet_data *l2)
 {
-	SetEvent(l2->rx_notify);
-}
+	if (l2)
+		SetEvent(l2->rx_notify);
+}

Modified: wpasupplicant/trunk/src/radius/radius_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_client.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_client.c (original)
+++ wpasupplicant/trunk/src/radius/radius_client.c Sat Jan 10 09:03:49 2009
@@ -712,9 +712,9 @@
 }
 
 
-void radius_client_update_acct_msgs(struct radius_client_data *radius,
-				    u8 *shared_secret,
-				    size_t shared_secret_len)
+static void radius_client_update_acct_msgs(struct radius_client_data *radius,
+					   u8 *shared_secret,
+					   size_t shared_secret_len)
 {
 	struct radius_msg_list *entry;
 

Modified: wpasupplicant/trunk/src/radius/radius_server.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_server.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_server.c (original)
+++ wpasupplicant/trunk/src/radius/radius_server.c Sat Jan 10 09:03:49 2009
@@ -93,11 +93,14 @@
 	int pac_key_refresh_time;
 	int eap_sim_aka_result_ind;
 	int tnc;
+	struct wps_context *wps;
 	int ipv6;
 	struct os_time start_time;
 	struct radius_server_counters counters;
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);
+	char *eap_req_id_text;
+	size_t eap_req_id_text_len;
 };
 
 
@@ -323,6 +326,7 @@
 	eap_conf.pac_key_refresh_time = data->pac_key_refresh_time;
 	eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
 	eap_conf.tnc = data->tnc;
+	eap_conf.wps = data->wps;
 	sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
 				       &eap_conf);
 	if (sess->eap == NULL) {
@@ -1040,6 +1044,15 @@
 	data->get_eap_user = conf->get_eap_user;
 	data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
 	data->tnc = conf->tnc;
+	data->wps = conf->wps;
+	if (conf->eap_req_id_text) {
+		data->eap_req_id_text = os_malloc(conf->eap_req_id_text_len);
+		if (data->eap_req_id_text) {
+			os_memcpy(data->eap_req_id_text, conf->eap_req_id_text,
+				  conf->eap_req_id_text_len);
+			data->eap_req_id_text_len = conf->eap_req_id_text_len;
+		}
+	}
 
 	data->clients = radius_server_read_clients(conf->client_file,
 						   conf->ipv6);
@@ -1087,6 +1100,7 @@
 	os_free(data->pac_opaque_encr_key);
 	os_free(data->eap_fast_a_id);
 	os_free(data->eap_fast_a_id_info);
+	os_free(data->eap_req_id_text);
 	os_free(data);
 }
 
@@ -1214,9 +1228,19 @@
 }
 
 
+static const char * radius_server_get_eap_req_id_text(void *ctx, size_t *len)
+{
+	struct radius_session *sess = ctx;
+	struct radius_server_data *data = sess->server;
+	*len = data->eap_req_id_text_len;
+	return data->eap_req_id_text;
+}
+
+
 static struct eapol_callbacks radius_server_eapol_cb =
 {
 	.get_eap_user = radius_server_get_eap_user,
+	.get_eap_req_id_text = radius_server_get_eap_req_id_text,
 };
 
 

Modified: wpasupplicant/trunk/src/radius/radius_server.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_server.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_server.h (original)
+++ wpasupplicant/trunk/src/radius/radius_server.h Sat Jan 10 09:03:49 2009
@@ -33,9 +33,12 @@
 	int pac_key_refresh_time;
 	int eap_sim_aka_result_ind;
 	int tnc;
+	struct wps_context *wps;
 	int ipv6;
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);
+	const char *eap_req_id_text;
+	size_t eap_req_id_text_len;
 };
 
 

Modified: wpasupplicant/trunk/src/rsn_supp/wpa_ft.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/rsn_supp/wpa_ft.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/rsn_supp/wpa_ft.c (original)
+++ wpasupplicant/trunk/src/rsn_supp/wpa_ft.c Sat Jan 10 09:03:49 2009
@@ -692,18 +692,24 @@
 	wpa_hexdump_key(MSG_DEBUG, "FT: Received IGTK in Reassoc Resp",
 			igtk_elem, igtk_elem_len);
 
-	if (igtk_elem_len != 2 + 6 + 24) {
+	if (igtk_elem_len != 2 + 6 + 1 + WPA_IGTK_LEN + 8) {
 		wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem "
 			   "length %lu", (unsigned long) igtk_elem_len);
 		return -1;
 	}
-	if (aes_unwrap(sm->ptk.kek, WPA_IGTK_LEN / 8, igtk_elem + 8, igtk)) {
+	if (igtk_elem[8] != WPA_IGTK_LEN) {
+		wpa_printf(MSG_DEBUG, "FT: Invalid IGTK sub-elem Key Length "
+			   "%d", igtk_elem[8]);
+		return -1;
+	}
+
+	if (aes_unwrap(sm->ptk.kek, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk)) {
 		wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
 			   "decrypt IGTK");
 		return -1;
 	}
 
-	/* KeyID[2] | PN[6] | Key[16+8] */
+	/* KeyID[2] | IPN[6] | Key Length[1] | Key[16+8] */
 
 	keyidx = WPA_GET_LE16(igtk_elem);
 

Modified: wpasupplicant/trunk/src/tls/bignum.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/bignum.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/bignum.c (original)
+++ wpasupplicant/trunk/src/tls/bignum.c Sat Jan 10 09:03:49 2009
@@ -97,7 +97,7 @@
 
 /**
  * bignum_set_unsigned_bin - Set bignum based on unsigned binary buffer
- * @a: Bignum from bignum_init(); to be set to the given value
+ * @n: Bignum from bignum_init(); to be set to the given value
  * @buf: Buffer with unsigned binary value
  * @len: Length of buf in octets
  * Returns: 0 on success, -1 on failure

Modified: wpasupplicant/trunk/src/tls/tlsv1_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/tlsv1_client.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/tlsv1_client.c (original)
+++ wpasupplicant/trunk/src/tls/tlsv1_client.c Sat Jan 10 09:03:49 2009
@@ -124,6 +124,8 @@
  * @in_data: Input data from TLS peer
  * @in_len: Input data length
  * @out_len: Length of the output buffer.
+ * @appl_data: Pointer to application data pointer, or %NULL if dropped
+ * @appl_data_len: Pointer to variable that is set to appl_data length
  * Returns: Pointer to output data, %NULL on failure
  */
 u8 * tlsv1_client_handshake(struct tlsv1_client *conn,

Modified: wpasupplicant/trunk/src/utils/eloop_win.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/eloop_win.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/eloop_win.c (original)
+++ wpasupplicant/trunk/src/utils/eloop_win.c Sat Jan 10 09:03:49 2009
@@ -463,12 +463,11 @@
 	while (!eloop.terminate &&
 	       (eloop.timeout || eloop.reader_count > 0 ||
 		eloop.event_count > 0)) {
+		tv.sec = tv.usec = 0;
 		if (eloop.timeout) {
 			os_get_time(&now);
 			if (os_time_before(&now, &eloop.timeout->time))
 				os_time_sub(&eloop.timeout->time, &now, &tv);
-			else
-				tv.sec = tv.usec = 0;
 		}
 
 		count = 0;

Modified: wpasupplicant/trunk/src/utils/includes.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/includes.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/includes.h (original)
+++ wpasupplicant/trunk/src/utils/includes.h Sat Jan 10 09:03:49 2009
@@ -12,7 +12,7 @@
  * See README and COPYING for more details.
  *
  * This header file is included into all C files so that commonly used header
- * files can be selected with OS specific #ifdefs in one place instead of
+ * files can be selected with OS specific ifdef blocks in one place instead of
  * having to have OS/C library specific selection in many files.
  */
 

Modified: wpasupplicant/trunk/src/utils/ip_addr.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/ip_addr.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/ip_addr.c (original)
+++ wpasupplicant/trunk/src/utils/ip_addr.c Sat Jan 10 09:03:49 2009
@@ -53,8 +53,7 @@
 		break;
 #ifdef CONFIG_IPV6
 	case AF_INET6:
-		if (os_memcpy(&a->u.v6, &b->u.v6, sizeof(a->u.v6))
-		    != 0)
+		if (os_memcmp(&a->u.v6, &b->u.v6, sizeof(a->u.v6)) != 0)
 			return 1;
 		break;
 #endif /* CONFIG_IPV6 */

Modified: wpasupplicant/trunk/src/utils/os_unix.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/os_unix.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/os_unix.c (original)
+++ wpasupplicant/trunk/src/utils/os_unix.c Sat Jan 10 09:03:49 2009
@@ -78,9 +78,9 @@
 
 int os_daemonize(const char *pid_file)
 {
-#ifdef __unclinux
+#ifdef __uClinux__
 	return -1;
-#else /* __uclinux */
+#else /* __uClinux__ */
 	if (daemon(0, 0)) {
 		perror("daemon");
 		return -1;
@@ -95,7 +95,7 @@
 	}
 
 	return -0;
-#endif /* __uclinux */
+#endif /* __uClinux__ */
 }
 
 

Modified: wpasupplicant/trunk/src/utils/pcsc_funcs.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/pcsc_funcs.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/pcsc_funcs.c (original)
+++ wpasupplicant/trunk/src/utils/pcsc_funcs.c Sat Jan 10 09:03:49 2009
@@ -611,7 +611,7 @@
 /**
  * scard_set_pin - Set PIN (CHV1/PIN1) code for accessing SIM/USIM commands
  * @scard: Pointer to private data from scard_init()
- * pin: PIN code as an ASCII string (e.g., "1234")
+ * @pin: PIN code as an ASCII string (e.g., "1234")
  * Returns: 0 on success, -1 on failure
  */
 int scard_set_pin(struct scard_data *scard, const char *pin)

Modified: wpasupplicant/trunk/src/utils/state_machine.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/state_machine.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/state_machine.h (original)
+++ wpasupplicant/trunk/src/utils/state_machine.h Sat Jan 10 09:03:49 2009
@@ -14,7 +14,7 @@
  * This file includes a set of pre-processor macros that can be used to
  * implement a state machine. In addition to including this header file, each
  * file implementing a state machine must define STATE_MACHINE_DATA to be the
- * data structure including state variables (enum <machine>_state,
+ * data structure including state variables (enum machine_state,
  * Boolean changed), and STATE_MACHINE_DEBUG_PREFIX to be a string that is used
  * as a prefix for all debug messages. If SM_ENTRY_MA macro is used to define
  * a group of state machines with shared data structure, STATE_MACHINE_ADDR
@@ -61,7 +61,7 @@
  * SM_ENTRY_M - State machine function entry point for state machine group
  * @machine: State machine name
  * @_state: State machine state
- * @data: State variable prefix (full variable: <prefix>_state)
+ * @data: State variable prefix (full variable: prefix_state)
  *
  * This macro is like SM_ENTRY, but for state machine groups that use a shared
  * data structure for more than one state machine. Both machine and prefix
@@ -80,7 +80,7 @@
  * SM_ENTRY_MA - State machine function entry point for state machine group
  * @machine: State machine name
  * @_state: State machine state
- * @data: State variable prefix (full variable: <prefix>_state)
+ * @data: State variable prefix (full variable: prefix_state)
  *
  * This macro is like SM_ENTRY_M, but a MAC address is included in debug
  * output. STATE_MACHINE_ADDR has to be defined to point to the MAC address to

Modified: wpasupplicant/trunk/src/utils/uuid.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/uuid.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/uuid.c (original)
+++ wpasupplicant/trunk/src/utils/uuid.c Sat Jan 10 09:03:49 2009
@@ -15,6 +15,8 @@
 #include "includes.h"
 
 #include "common.h"
+#include "crypto.h"
+#include "sha1.h"
 #include "uuid.h"
 
 int uuid_str2bin(const char *str, u8 *bin)
@@ -65,3 +67,41 @@
 		return -1;
 	return 0;
 }
+
+
+int is_nil_uuid(const u8 *uuid)
+{
+	int i;
+	for (i = 0; i < UUID_LEN; i++)
+		if (uuid[i])
+			return 0;
+	return 1;
+}
+
+
+void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid)
+{
+	const u8 *addr[2];
+	size_t len[2];
+	u8 hash[SHA1_MAC_LEN];
+	u8 nsid[16] = {
+		0x52, 0x64, 0x80, 0xf8,
+		0xc9, 0x9b,
+		0x4b, 0xe5,
+		0xa6, 0x55,
+		0x58, 0xed, 0x5f, 0x5d, 0x60, 0x84
+	};
+
+	addr[0] = nsid;
+	len[0] = sizeof(nsid);
+	addr[1] = mac_addr;
+	len[1] = 6;
+	sha1_vector(2, addr, len, hash);
+	os_memcpy(uuid, hash, 16);
+
+	/* Version: 5 = named-based version using SHA-1 */
+	uuid[6] = (5 << 4) | (uuid[6] & 0x0f);
+
+	/* Variant specified in RFC 4122 */
+	uuid[8] = 0x80 | (uuid[8] & 0x3f);
+}

Modified: wpasupplicant/trunk/src/utils/uuid.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/uuid.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/uuid.h (original)
+++ wpasupplicant/trunk/src/utils/uuid.h Sat Jan 10 09:03:49 2009
@@ -19,5 +19,7 @@
 
 int uuid_str2bin(const char *str, u8 *bin);
 int uuid_bin2str(const u8 *bin, char *str, size_t max_len);
+int is_nil_uuid(const u8 *uuid);
+void uuid_gen_mac_addr(const u8 *mac_addr, u8 *uuid);
 
 #endif /* UUID_H */

Modified: wpasupplicant/trunk/src/utils/wpa_debug.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/wpa_debug.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/wpa_debug.h (original)
+++ wpasupplicant/trunk/src/utils/wpa_debug.h Sat Jan 10 09:03:49 2009
@@ -43,7 +43,7 @@
 /**
  * wpa_debug_printf_timestamp - Print timestamp for debug output
  *
- * This function prints a timestamp in <seconds from 1970>.<microsoconds>
+ * This function prints a timestamp in seconds_from_1970.microsoconds
  * format if debug output has been configured to include timestamps in debug
  * messages.
  */

Modified: wpasupplicant/trunk/wpa_supplicant/ChangeLog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ChangeLog?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ChangeLog (original)
+++ wpasupplicant/trunk/wpa_supplicant/ChangeLog Sat Jan 10 09:03:49 2009
@@ -1,4 +1,26 @@
 ChangeLog for wpa_supplicant
+
+2009-01-06 - v0.6.7
+	* added support for Wi-Fi Protected Setup (WPS)
+	  (wpa_supplicant can now be configured to act as a WPS Enrollee to
+	  enroll credentials for a network using PIN and PBC methods; in
+	  addition, wpa_supplicant can act as a wireless WPS Registrar to
+	  configure an AP); WPS support can be enabled by adding CONFIG_WPS=y
+	  into .config and setting the runtime configuration variables in
+	  wpa_supplicant.conf (see WPS section in the example configuration
+	  file); new wpa_cli commands wps_pin, wps_pbc, and wps_reg are used to
+	  manage WPS negotiation; see README-WPS for more details
+	* added support for EAP-AKA' (draft-arkko-eap-aka-kdf)
+	* added support for using driver_test over UDP socket
+	* fixed PEAPv0 Cryptobinding interoperability issue with Windows Server
+	  2008 NPS; optional cryptobinding is now enabled (again) by default
+	* fixed PSK editing in wpa_gui
+	* changed EAP-GPSK to use the IANA assigned EAP method type 51
+	* added a Windows installer that includes WinPcap and all the needed
+	  DLLs; in addition, it set up the registry automatically so that user
+	  will only need start wpa_gui to get prompted to start the wpasvc
+	  servide and add a new interface if needed through wpa_gui dialog
+	* updated management frame protection to use IEEE 802.11w/D7.0
 
 2008-11-23 - v0.6.6
 	* added Milenage SIM/USIM emulator for EAP-SIM/EAP-AKA

Modified: wpasupplicant/trunk/wpa_supplicant/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/Makefile?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/Makefile (original)
+++ wpasupplicant/trunk/wpa_supplicant/Makefile Sat Jan 10 09:03:49 2009
@@ -427,6 +427,16 @@
 CONFIG_EAP_SIM_COMMON=y
 endif
 
+ifdef CONFIG_EAP_AKA_PRIME
+# EAP-AKA'
+ifeq ($(CONFIG_EAP_AKA_PRIME), dyn)
+CFLAGS += -DEAP_AKA_PRIME_DYNAMIC
+else
+CFLAGS += -DEAP_AKA_PRIME
+endif
+NEED_SHA256=y
+endif
+
 ifdef CONFIG_EAP_SIM_COMMON
 OBJS += ../src/eap_common/eap_sim_common.o
 OBJS_h += ../src/eap_server/eap_sim_db.o
@@ -491,6 +501,32 @@
 CFLAGS += -DEAP_GPSK_SHA256
 endif
 NEED_SHA256=y
+endif
+
+ifdef CONFIG_WPS
+# EAP-WSC
+ifeq ($(CONFIG_EAP_WSC), dyn)
+CFLAGS += -DCONFIG_WPS -DEAP_WSC_DYNAMIC
+EAPDYN += ../src/eap_peer/eap_wsc.so
+else
+CFLAGS += -DCONFIG_WPS -DEAP_WSC
+OBJS += wps_supplicant.o
+OBJS += ../src/utils/uuid.o
+OBJS += ../src/eap_peer/eap_wsc.o ../src/eap_common/eap_wsc_common.o
+OBJS += ../src/wps/wps.o
+OBJS += ../src/wps/wps_common.o
+OBJS += ../src/wps/wps_attr_parse.o
+OBJS += ../src/wps/wps_attr_build.o
+OBJS += ../src/wps/wps_attr_process.o
+OBJS += ../src/wps/wps_dev_attr.o
+OBJS += ../src/wps/wps_enrollee.o
+OBJS += ../src/wps/wps_registrar.o
+OBJS_h += ../src/eap_server/eap_wsc.o
+endif
+CONFIG_IEEE8021X_EAPOL=y
+NEED_DH_GROUPS=y
+NEED_SHA256=y
+NEED_BASE64=y
 endif
 
 ifdef CONFIG_EAP_IKEV2
@@ -1080,6 +1116,10 @@
 	$(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
 		-Deap_peer_sake_register=eap_peer_method_dynamic_init
 
+eap_wsc.so: ../src/eap_peer/eap_wsc.c ../src/eap_common/eap_wsc_common.c ../src/wps/wps.c
+	$(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-Deap_peer_wsc_register=eap_peer_method_dynamic_init
+
 eap_ikev2.so: ../src/eap_peer/eap_ikev2.c ../src/eap_peer/ikev2.c ../src/eap_common/eap_ikev2_common.o ../src/eap_common/ikev2_common.c
 	$(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
 		-Deap_peer_ikev2_register=eap_peer_method_dynamic_init
@@ -1184,16 +1224,10 @@
 	cp doc/latex/refman.pdf wpa_supplicant-devel.pdf
 
 docs-fast: docs-pics
-	doxygen doc/doxygen.fast
+	(cd ..; doxygen wpa_supplicant/doc/doxygen.fast; cd wpa_supplicant)
 
 clean-docs:
 	rm -rf doc/latex doc/html
 	rm -f doc/wpa_supplicant.{eps,png} wpa_supplicant-devel.pdf
 
-wpa_supplicant-sparse: .config $(OBJS)
-	@echo Sparse run completed
-
-run-sparse:
-	CC="sparse -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -D__INT_MAX__=2147483647 -D__SHRT_MAX__=32767 -D__LONG_MAX__=2147483647 -D__SCHAR_MAX__=127 -Wbitwise" $(MAKE) wpa_supplicant-sparse
-
 -include $(OBJS:%.o=%.d)

Modified: wpasupplicant/trunk/wpa_supplicant/README
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/README?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/README (original)
+++ wpasupplicant/trunk/wpa_supplicant/README Sat Jan 10 09:03:49 2009
@@ -1,7 +1,7 @@
 WPA Supplicant
 ==============
 
-Copyright (c) 2003-2008, Jouni Malinen <j at w1.fi> and contributors
+Copyright (c) 2003-2009, Jouni Malinen <j at w1.fi> and contributors
 All Rights Reserved.
 
 This program is dual-licensed under both the GPL version 2 and BSD

Modified: wpasupplicant/trunk/wpa_supplicant/README-Windows.txt
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/README-Windows.txt?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/README-Windows.txt (original)
+++ wpasupplicant/trunk/wpa_supplicant/README-Windows.txt Sat Jan 10 09:03:49 2009
@@ -1,8 +1,7 @@
 wpa_supplicant for Windows
 ==========================
 
-Copyright (c) 2003-2008, Jouni Malinen <j at w1.fi> and
-contributors
+Copyright (c) 2003-2009, Jouni Malinen <j at w1.fi> and contributors
 All Rights Reserved.
 
 This program is dual-licensed under both the GPL version 2 and BSD

Modified: wpasupplicant/trunk/wpa_supplicant/config.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/config.c Sat Jan 10 09:03:49 2009
@@ -60,14 +60,19 @@
 static char * wpa_config_parse_string(const char *value, size_t *len)
 {
 	if (*value == '"') {
-		char *pos;
+		const char *pos;
+		char *str;
 		value++;
 		pos = os_strrchr(value, '"');
 		if (pos == NULL || pos[1] != '\0')
 			return NULL;
-		*pos = '\0';
-		*len = os_strlen(value);
-		return os_strdup(value);
+		*len = pos - value;
+		str = os_malloc(*len + 1);
+		if (str == NULL)
+			return NULL;
+		os_memcpy(str, value, *len);
+		str[*len] = '\0';
+		return str;
 	} else {
 		u8 *str;
 		size_t tlen, hlen = os_strlen(value);
@@ -515,6 +520,10 @@
 		else if (os_strcmp(start, "WPA-EAP-SHA256") == 0)
 			val |= WPA_KEY_MGMT_IEEE8021X_SHA256;
 #endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_WPS
+		else if (os_strcmp(start, "WPS") == 0)
+			val |= WPA_KEY_MGMT_WPS;
+#endif /* CONFIG_WPS */
 		else {
 			wpa_printf(MSG_ERROR, "Line %d: invalid key_mgmt '%s'",
 				   line, start);
@@ -620,6 +629,12 @@
 		pos += os_snprintf(pos, end - pos, "%sWPA-EAP-SHA256",
 				   pos == buf ? "" : " ");
 #endif /* CONFIG_IEEE80211W */
+
+#ifdef CONFIG_WPS
+	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
+		pos += os_snprintf(pos, end - pos, "%sWPS",
+				   pos == buf ? "" : " ");
+#endif /* CONFIG_WPS */
 
 	return buf;
 }
@@ -1034,8 +1049,8 @@
 				   "password.", line);
 			return -1;
 		}
-		wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
-				  (u8 *) tmp, res_len);
+		wpa_hexdump_ascii_key(MSG_MSGDUMP, data->name,
+				      (u8 *) tmp, res_len);
 
 		os_free(ssid->eap.password);
 		ssid->eap.password = (u8 *) tmp;
@@ -1306,7 +1321,7 @@
 	{ FUNC(eap) },
 	{ STR_LENe(identity) },
 	{ STR_LENe(anonymous_identity) },
-	{ FUNC(password) },
+	{ FUNC_KEY(password) },
 	{ STRe(ca_cert) },
 	{ STRe(ca_path) },
 	{ STRe(client_cert) },
@@ -1567,6 +1582,12 @@
 	os_free(config->pkcs11_module_path);
 #endif /* EAP_TLS_OPENSSL */
 	os_free(config->driver_param);
+	os_free(config->device_name);
+	os_free(config->manufacturer);
+	os_free(config->model_name);
+	os_free(config->model_number);
+	os_free(config->serial_number);
+	os_free(config->device_type);
 	os_free(config->pssid);
 	os_free(config);
 }

Modified: wpasupplicant/trunk/wpa_supplicant/config.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/config.h Sat Jan 10 09:03:49 2009
@@ -154,7 +154,7 @@
 	 * ctrl_interface_group - Control interface group (DEPRECATED)
 	 *
 	 * This variable is only used for backwards compatibility. Group for
-	 * UNIX domain sockets should now be specified using GROUP=<group> in
+	 * UNIX domain sockets should now be specified using GROUP=group in
 	 * ctrl_interface variable.
 	 */
 	char *ctrl_interface_group;
@@ -247,6 +247,71 @@
 	 * blobs - Configuration blobs
 	 */
 	struct wpa_config_blob *blobs;
+
+	/**
+	 * uuid - Universally Unique IDentifier (UUID; see RFC 4122) for WPS
+	 */
+	u8 uuid[16];
+
+	/**
+	 * device_name - Device Name (WPS)
+	 * User-friendly description of device; up to 32 octets encoded in
+	 * UTF-8
+	 */
+	char *device_name;
+
+	/**
+	 * manufacturer - Manufacturer (WPS)
+	 * The manufacturer of the device (up to 64 ASCII characters)
+	 */
+	char *manufacturer;
+
+	/**
+	 * model_name - Model Name (WPS)
+	 * Model of the device (up to 32 ASCII characters)
+	 */
+	char *model_name;
+
+	/**
+	 * model_number - Model Number (WPS)
+	 * Additional device description (up to 32 ASCII characters)
+	 */
+	char *model_number;
+
+	/**
+	 * serial_number - Serial Number (WPS)
+	 * Serial number of the device (up to 32 characters)
+	 */
+	char *serial_number;
+
+	/**
+	 * device_type - Primary Device Type (WPS)
+	 * Used format: categ-OUI-subcateg
+	 * categ = Category as an integer value
+	 * OUI = OUI and type octet as a 4-octet hex-encoded value;
+	 *	0050F204 for default WPS OUI
+	 * subcateg = OUI-specific Sub Category as an integer value
+	 * Examples:
+	 *   1-0050F204-1 (Computer / PC)
+	 *   1-0050F204-2 (Computer / Server)
+	 *   5-0050F204-1 (Storage / NAS)
+	 *   6-0050F204-1 (Network Infrastructure / AP)
+	 */
+	char *device_type;
+
+	/**
+	 * os_version - OS Version (WPS)
+	 * 4-octet operating system version number
+	 */
+	u8 os_version[4];
+
+	/**
+	 * country - Country code
+	 *
+	 * This is the ISO/IEC alpha2 country code for which we are operating
+	 * in
+	 */
+	char country[2];
 };
 
 

Modified: wpasupplicant/trunk/wpa_supplicant/config_file.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config_file.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config_file.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/config_file.c Sat Jan 10 09:03:49 2009
@@ -21,6 +21,7 @@
 #include "common.h"
 #include "config.h"
 #include "base64.h"
+#include "uuid.h"
 #include "eap_peer/eap_methods.h"
 
 
@@ -269,147 +270,97 @@
 #endif /* CONFIG_NO_CONFIG_BLOBS */
 
 
-#ifdef CONFIG_CTRL_IFACE
-static int wpa_config_process_ctrl_interface(struct wpa_config *config,
-					     char *pos)
-{
-	os_free(config->ctrl_interface);
-	config->ctrl_interface = os_strdup(pos);
-	wpa_printf(MSG_DEBUG, "ctrl_interface='%s'", config->ctrl_interface);
+struct global_parse_data {
+	char *name;
+	int (*parser)(const struct global_parse_data *data,
+		      struct wpa_config *config, int line, const char *value);
+	void *param1, *param2, *param3;
+};
+
+
+static int wpa_config_parse_int(const struct global_parse_data *data,
+				struct wpa_config *config, int line,
+				const char *pos)
+{
+	int *dst;
+	dst = (int *) (((u8 *) config) + (long) data->param1);
+	*dst = atoi(pos);
+	wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst);
+
+	if (data->param2 && *dst < (long) data->param2) {
+		wpa_printf(MSG_ERROR, "Line %d: too small %s (value=%d "
+			   "min_value=%ld)", line, data->name, *dst,
+			   (long) data->param2);
+		*dst = (long) data->param2;
+		return -1;
+	}
+
+	if (data->param3 && *dst > (long) data->param3) {
+		wpa_printf(MSG_ERROR, "Line %d: too large %s (value=%d "
+			   "max_value=%ld)", line, data->name, *dst,
+			   (long) data->param3);
+		*dst = (long) data->param3;
+		return -1;
+	}
+
 	return 0;
 }
 
 
-static int wpa_config_process_ctrl_interface_group(struct wpa_config *config,
-						   char *pos)
-{
-	os_free(config->ctrl_interface_group);
-	config->ctrl_interface_group = os_strdup(pos);
-	wpa_printf(MSG_DEBUG, "ctrl_interface_group='%s' (DEPRECATED)",
-		   config->ctrl_interface_group);
+static int wpa_config_parse_str(const struct global_parse_data *data,
+				struct wpa_config *config, int line,
+				const char *pos)
+{
+	size_t len;
+	char **dst, *tmp;
+
+	len = os_strlen(pos);
+	if (data->param2 && len < (size_t) data->param2) {
+		wpa_printf(MSG_ERROR, "Line %d: too short %s (len=%lu "
+			   "min_len=%ld)", line, data->name,
+			   (unsigned long) len, (long) data->param2);
+		return -1;
+	}
+
+	if (data->param3 && len > (size_t) data->param3) {
+		wpa_printf(MSG_ERROR, "Line %d: too long %s (len=%lu "
+			   "max_len=%ld)", line, data->name,
+			   (unsigned long) len, (long) data->param3);
+		return -1;
+	}
+
+	tmp = os_strdup(pos);
+	if (tmp == NULL)
+		return -1;
+
+	dst = (char **) (((u8 *) config) + (long) data->param1);
+	os_free(*dst);
+	*dst = tmp;
+	wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst);
+
 	return 0;
 }
-#endif /* CONFIG_CTRL_IFACE */
-
-
-static int wpa_config_process_eapol_version(struct wpa_config *config,
-					    int line, char *pos)
-{
-	config->eapol_version = atoi(pos);
-	if (config->eapol_version < 1 || config->eapol_version > 2) {
-		wpa_printf(MSG_ERROR, "Line %d: Invalid EAPOL version (%d): "
-			   "'%s'.", line, config->eapol_version, pos);
-		return -1;
-	}
-	wpa_printf(MSG_DEBUG, "eapol_version=%d", config->eapol_version);
+
+
+static int wpa_config_process_country(const struct global_parse_data *data,
+				      struct wpa_config *config, int line,
+				      const char *pos)
+{
+	if (!pos[0] || !pos[1]) {
+		wpa_printf(MSG_DEBUG, "Invalid country set");
+		return -1;
+	}
+	config->country[0] = pos[0];
+	config->country[1] = pos[1];
+	wpa_printf(MSG_DEBUG, "country='%c%c'",
+		   config->country[0], config->country[1]);
 	return 0;
 }
 
 
-static int wpa_config_process_ap_scan(struct wpa_config *config, char *pos)
-{
-	config->ap_scan = atoi(pos);
-	wpa_printf(MSG_DEBUG, "ap_scan=%d", config->ap_scan);
-	return 0;
-}
-
-
-static int wpa_config_process_fast_reauth(struct wpa_config *config, char *pos)
-{
-	config->fast_reauth = atoi(pos);
-	wpa_printf(MSG_DEBUG, "fast_reauth=%d", config->fast_reauth);
-	return 0;
-}
-
-
-#ifdef EAP_TLS_OPENSSL
-
-static int wpa_config_process_opensc_engine_path(struct wpa_config *config,
-						 char *pos)
-{
-	os_free(config->opensc_engine_path);
-	config->opensc_engine_path = os_strdup(pos);
-	wpa_printf(MSG_DEBUG, "opensc_engine_path='%s'",
-		   config->opensc_engine_path);
-	return 0;
-}
-
-
-static int wpa_config_process_pkcs11_engine_path(struct wpa_config *config,
-						 char *pos)
-{
-	os_free(config->pkcs11_engine_path);
-	config->pkcs11_engine_path = os_strdup(pos);
-	wpa_printf(MSG_DEBUG, "pkcs11_engine_path='%s'",
-		   config->pkcs11_engine_path);
-	return 0;
-}
-
-
-static int wpa_config_process_pkcs11_module_path(struct wpa_config *config,
-						 char *pos)
-{
-	os_free(config->pkcs11_module_path);
-	config->pkcs11_module_path = os_strdup(pos);
-	wpa_printf(MSG_DEBUG, "pkcs11_module_path='%s'",
-		   config->pkcs11_module_path);
-	return 0;
-}
-
-#endif /* EAP_TLS_OPENSSL */
-
-
-static int wpa_config_process_driver_param(struct wpa_config *config,
-					   char *pos)
-{
-	os_free(config->driver_param);
-	config->driver_param = os_strdup(pos);
-	wpa_printf(MSG_DEBUG, "driver_param='%s'", config->driver_param);
-	return 0;
-}
-
-
-static int wpa_config_process_pmk_lifetime(struct wpa_config *config,
-					   char *pos)
-{
-	config->dot11RSNAConfigPMKLifetime = atoi(pos);
-	wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKLifetime=%d",
-		   config->dot11RSNAConfigPMKLifetime);
-	return 0;
-}
-
-
-static int wpa_config_process_pmk_reauth_threshold(struct wpa_config *config,
-						   char *pos)
-{
-	config->dot11RSNAConfigPMKReauthThreshold = atoi(pos);
-	wpa_printf(MSG_DEBUG, "dot11RSNAConfigPMKReauthThreshold=%d",
-		   config->dot11RSNAConfigPMKReauthThreshold);
-	return 0;
-}
-
-
-static int wpa_config_process_sa_timeout(struct wpa_config *config, char *pos)
-{
-	config->dot11RSNAConfigSATimeout = atoi(pos);
-	wpa_printf(MSG_DEBUG, "dot11RSNAConfigSATimeout=%d",
-		   config->dot11RSNAConfigSATimeout);
-	return 0;
-}
-
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-static int wpa_config_process_update_config(struct wpa_config *config,
-					    char *pos)
-{
-	config->update_config = atoi(pos);
-	wpa_printf(MSG_DEBUG, "update_config=%d", config->update_config);
-	return 0;
-}
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-
-static int wpa_config_process_load_dynamic_eap(int line, char *so)
+static int wpa_config_process_load_dynamic_eap(
+	const struct global_parse_data *data, struct wpa_config *config,
+	int line, const char *so)
 {
 	int ret;
 	wpa_printf(MSG_DEBUG, "load_dynamic_eap=%s", so);
@@ -427,61 +378,125 @@
 }
 
 
+#ifdef CONFIG_WPS
+
+static int wpa_config_process_uuid(const struct global_parse_data *data,
+				   struct wpa_config *config, int line,
+				   const char *pos)
+{
+	char buf[40];
+	if (uuid_str2bin(pos, config->uuid)) {
+		wpa_printf(MSG_ERROR, "Line %d: invalid UUID", line);
+		return -1;
+	}
+	uuid_bin2str(config->uuid, buf, sizeof(buf));
+	wpa_printf(MSG_DEBUG, "uuid=%s", buf);
+	return 0;
+}
+
+
+static int wpa_config_process_os_version(const struct global_parse_data *data,
+					 struct wpa_config *config, int line,
+					 const char *pos)
+{
+	if (hexstr2bin(pos, config->os_version, 4)) {
+		wpa_printf(MSG_ERROR, "Line %d: invalid os_version", line);
+		return -1;
+	}
+	wpa_printf(MSG_DEBUG, "os_version=%08x",
+		   WPA_GET_BE32(config->os_version));
+	return 0;
+}
+
+#endif /* CONFIG_WPS */
+
+
+#ifdef OFFSET
+#undef OFFSET
+#endif /* OFFSET */
+/* OFFSET: Get offset of a variable within the wpa_config structure */
+#define OFFSET(v) ((void *) &((struct wpa_config *) 0)->v)
+
+#define FUNC(f) #f, wpa_config_process_ ## f, OFFSET(f), NULL, NULL
+#define FUNC_NO_VAR(f) #f, wpa_config_process_ ## f, NULL, NULL, NULL
+#define _INT(f) #f, wpa_config_parse_int, OFFSET(f)
+#define INT(f) _INT(f), NULL, NULL
+#define INT_RANGE(f, min, max) _INT(f), (void *) min, (void *) max
+#define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
+#define STR(f) _STR(f), NULL, NULL
+#define STR_RANGE(f, min, max) _STR(f), (void *) min, (void *) max
+
+static const struct global_parse_data global_fields[] = {
+#ifdef CONFIG_CTRL_IFACE
+	{ STR(ctrl_interface) },
+	{ STR(ctrl_interface_group) } /* deprecated */,
+#endif /* CONFIG_CTRL_IFACE */
+	{ INT_RANGE(eapol_version, 1, 2) },
+	{ INT(ap_scan) },
+	{ INT(fast_reauth) },
+#ifdef EAP_TLS_OPENSSL
+	{ STR(opensc_engine_path) },
+	{ STR(pkcs11_engine_path) },
+	{ STR(pkcs11_module_path) },
+#endif /* EAP_TLS_OPENSSL */
+	{ STR(driver_param) },
+	{ INT(dot11RSNAConfigPMKLifetime) },
+	{ INT(dot11RSNAConfigPMKReauthThreshold) },
+	{ INT(dot11RSNAConfigSATimeout) },
+#ifndef CONFIG_NO_CONFIG_WRITE
+	{ INT(update_config) },
+#endif /* CONFIG_NO_CONFIG_WRITE */
+	{ FUNC_NO_VAR(load_dynamic_eap) },
+#ifdef CONFIG_WPS
+	{ FUNC(uuid) },
+	{ STR_RANGE(device_name, 0, 32) },
+	{ STR_RANGE(manufacturer, 0, 64) },
+	{ STR_RANGE(model_name, 0, 32) },
+	{ STR_RANGE(model_number, 0, 32) },
+	{ STR_RANGE(serial_number, 0, 32) },
+	{ STR(device_type) },
+	{ FUNC(os_version) },
+#endif /* CONFIG_WPS */
+	{ FUNC(country) }
+};
+
+#undef FUNC
+#undef _INT
+#undef INT
+#undef INT_RANGE
+#undef _STR
+#undef STR
+#undef STR_RANGE
+#define NUM_GLOBAL_FIELDS (sizeof(global_fields) / sizeof(global_fields[0]))
+
+
 static int wpa_config_process_global(struct wpa_config *config, char *pos,
 				     int line)
 {
-#ifdef CONFIG_CTRL_IFACE
-	if (os_strncmp(pos, "ctrl_interface=", 15) == 0)
-		return wpa_config_process_ctrl_interface(config, pos + 15);
-
-	if (os_strncmp(pos, "ctrl_interface_group=", 21) == 0)
-		return wpa_config_process_ctrl_interface_group(config,
-							       pos + 21);
-#endif /* CONFIG_CTRL_IFACE */
-
-	if (os_strncmp(pos, "eapol_version=", 14) == 0)
-		return wpa_config_process_eapol_version(config, line,
-							pos + 14);
-
-	if (os_strncmp(pos, "ap_scan=", 8) == 0)
-		return wpa_config_process_ap_scan(config, pos + 8);
-
-	if (os_strncmp(pos, "fast_reauth=", 12) == 0)
-		return wpa_config_process_fast_reauth(config, pos + 12);
-
-#ifdef EAP_TLS_OPENSSL
-	if (os_strncmp(pos, "opensc_engine_path=", 19) == 0)
-		return wpa_config_process_opensc_engine_path(config, pos + 19);
-
-	if (os_strncmp(pos, "pkcs11_engine_path=", 19) == 0)
-		return wpa_config_process_pkcs11_engine_path(config, pos + 19);
-
-	if (os_strncmp(pos, "pkcs11_module_path=", 19) == 0)
-		return wpa_config_process_pkcs11_module_path(config, pos + 19);
-#endif /* EAP_TLS_OPENSSL */
-
-	if (os_strncmp(pos, "driver_param=", 13) == 0)
-		return wpa_config_process_driver_param(config, pos + 13);
-
-	if (os_strncmp(pos, "dot11RSNAConfigPMKLifetime=", 27) == 0)
-		return wpa_config_process_pmk_lifetime(config, pos + 27);
-
-	if (os_strncmp(pos, "dot11RSNAConfigPMKReauthThreshold=", 34) == 0)
-		return wpa_config_process_pmk_reauth_threshold(config,
-							       pos + 34);
-
-	if (os_strncmp(pos, "dot11RSNAConfigSATimeout=", 25) == 0)
-		return wpa_config_process_sa_timeout(config, pos + 25);
-
-#ifndef CONFIG_NO_CONFIG_WRITE
-	if (os_strncmp(pos, "update_config=", 14) == 0)
-		return wpa_config_process_update_config(config, pos + 14);
-#endif /* CONFIG_NO_CONFIG_WRITE */
-
-	if (os_strncmp(pos, "load_dynamic_eap=", 17) == 0)
-		return wpa_config_process_load_dynamic_eap(line, pos + 17);
-
-	return -1;
+	size_t i;
+	int ret = 0;
+
+	for (i = 0; i < NUM_GLOBAL_FIELDS; i++) {
+		const struct global_parse_data *field = &global_fields[i];
+		size_t flen = os_strlen(field->name);
+		if (os_strncmp(pos, field->name, flen) != 0 ||
+		    pos[flen] != '=')
+			continue;
+
+		if (field->parser(field, config, line, pos + flen + 1)) {
+			wpa_printf(MSG_ERROR, "Line %d: failed to "
+				   "parse '%s'.", line, pos);
+			ret = -1;
+		}
+		break;
+	}
+	if (i == NUM_GLOBAL_FIELDS) {
+		wpa_printf(MSG_ERROR, "Line %d: unknown global field '%s'.",
+			   line, pos);
+		ret = -1;
+	}
+
+	return ret;
 }
 
 
@@ -845,6 +860,32 @@
 			config->dot11RSNAConfigSATimeout);
 	if (config->update_config)
 		fprintf(f, "update_config=%d\n", config->update_config);
+#ifdef CONFIG_WPS
+	if (!is_nil_uuid(config->uuid)) {
+		char buf[40];
+		uuid_bin2str(config->uuid, buf, sizeof(buf));
+		fprintf(f, "uuid=%s\n", buf);
+	}
+	if (config->device_name)
+		fprintf(f, "device_name=%s\n", config->device_name);
+	if (config->manufacturer)
+		fprintf(f, "manufacturer=%s\n", config->manufacturer);
+	if (config->model_name)
+		fprintf(f, "model_name=%s\n", config->model_name);
+	if (config->model_number)
+		fprintf(f, "model_number=%s\n", config->model_number);
+	if (config->serial_number)
+		fprintf(f, "serial_number=%s\n", config->serial_number);
+	if (config->device_type)
+		fprintf(f, "device_type=%s\n", config->device_type);
+	if (WPA_GET_BE32(config->os_version))
+		fprintf(f, "os_version=%08x\n",
+			WPA_GET_BE32(config->os_version));
+#endif /* CONFIG_WPS */
+	if (config->country[0] && config->country[1]) {
+		fprintf(f, "country=%c%c\n",
+			config->country[0], config->country[1]);
+	}
 }
 
 #endif /* CONFIG_NO_CONFIG_WRITE */
@@ -871,6 +912,8 @@
 	wpa_config_write_global(f, config);
 
 	for (ssid = config->ssid; ssid; ssid = ssid->next) {
+		if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
+			continue; /* do not save temporary WPS networks */
 		fprintf(f, "\nnetwork={\n");
 		wpa_config_write_network(f, ssid);
 		fprintf(f, "}\n");

Modified: wpasupplicant/trunk/wpa_supplicant/config_winreg.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config_winreg.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config_winreg.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/config_winreg.c Sat Jan 10 09:03:49 2009
@@ -11,12 +11,13 @@
  *
  * See README and COPYING for more details.
  *
- * This file implements a configuration backend for Windows registry.. All the
+ * This file implements a configuration backend for Windows registry. All the
  * configuration information is stored in the registry and the format for
  * network configuration fields is same as described in the sample
  * configuration file, wpa_supplicant.conf.
  *
- * Configuration data is in HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs
+ * Configuration data is in
+ * \a HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant\\configs
  * key. Each configuration profile has its own key under this. In terms of text
  * files, each profile would map to a separate text file with possibly multiple
  * networks. Under each profile, there is a networks key that lists all
@@ -24,14 +25,18 @@
  * network block in the configuration file. In addition, blobs subkey has
  * possible blobs as values.
  *
- * HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks\0000
- *    ssid="example"
- *    key_mgmt=WPA-PSK
+ * Example network configuration block:
+ * \verbatim
+HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\networks\0000
+   ssid="example"
+   key_mgmt=WPA-PSK
+\endverbatim
  */
 
 #include "includes.h"
 
 #include "common.h"
+#include "uuid.h"
 #include "config.h"
 
 #ifndef WPA_KEY_ROOT
@@ -161,6 +166,45 @@
 }
 
 
+#ifdef CONFIG_WPS
+static int wpa_config_read_global_uuid(struct wpa_config *config, HKEY hk)
+{
+	char *str;
+	int ret = 0;
+
+	str = wpa_config_read_reg_string(hk, TEXT("uuid"));
+	if (str == NULL)
+		return 0;
+
+	if (uuid_str2bin(str, config->uuid))
+		ret = -1;
+
+	os_free(str);
+
+	return ret;
+}
+
+
+static int wpa_config_read_global_os_version(struct wpa_config *config,
+					     HKEY hk)
+{
+	char *str;
+	int ret = 0;
+
+	str = wpa_config_read_reg_string(hk, TEXT("os_version"));
+	if (str == NULL)
+		return 0;
+
+	if (hexstr2bin(str, config->os_version, 4))
+		ret = -1;
+
+	os_free(str);
+
+	return ret;
+}
+#endif /* CONFIG_WPS */
+
+
 static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
 {
 	int errors = 0;
@@ -169,12 +213,13 @@
 	wpa_config_read_reg_dword(hk, TEXT("fast_reauth"),
 				  &config->fast_reauth);
 	wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigPMKLifetime"),
-				  &config->dot11RSNAConfigPMKLifetime);
+				  (int *) &config->dot11RSNAConfigPMKLifetime);
 	wpa_config_read_reg_dword(hk,
 				  TEXT("dot11RSNAConfigPMKReauthThreshold"),
+				  (int *)
 				  &config->dot11RSNAConfigPMKReauthThreshold);
 	wpa_config_read_reg_dword(hk, TEXT("dot11RSNAConfigSATimeout"),
-				  &config->dot11RSNAConfigSATimeout);
+				  (int *) &config->dot11RSNAConfigSATimeout);
 	wpa_config_read_reg_dword(hk, TEXT("update_config"),
 				  &config->update_config);
 
@@ -190,6 +235,23 @@
 
 	config->ctrl_interface = wpa_config_read_reg_string(
 		hk, TEXT("ctrl_interface"));
+
+#ifdef CONFIG_WPS
+	if (wpa_config_read_global_uuid(config, hk))
+		errors++;
+	config->device_name = wpa_config_read_reg_string(
+		hk, TEXT("device_name"));
+	config->manufacturer = wpa_config_read_reg_string(
+		hk, TEXT("manufacturer"));
+	config->model_name = wpa_config_read_reg_string(
+		hk, TEXT("model_name"));
+	config->serial_number = wpa_config_read_reg_string(
+		hk, TEXT("serial_number"));
+	config->device_type = wpa_config_read_reg_string(
+		hk, TEXT("device_type"));
+	if (wpa_config_read_global_os_version(config, hk))
+		errors++;
+#endif /* CONFIG_WPS */
 
 	return errors ? -1 : 0;
 }
@@ -492,6 +554,26 @@
 	wpa_config_write_reg_dword(hk, TEXT("update_config"),
 				   config->update_config,
 				   0);
+#ifdef CONFIG_WPS
+	if (!is_nil_uuid(config->uuid)) {
+		char buf[40];
+		uuid_bin2str(config->uuid, buf, sizeof(buf));
+		wpa_config_write_reg_string(hk, "uuid", buf);
+	}
+	wpa_config_write_reg_string(hk, "device_name", config->device_name);
+	wpa_config_write_reg_string(hk, "manufacturer", config->manufacturer);
+	wpa_config_write_reg_string(hk, "model_name", config->model_name);
+	wpa_config_write_reg_string(hk, "model_number", config->model_number);
+	wpa_config_write_reg_string(hk, "serial_number",
+				    config->serial_number);
+	wpa_config_write_reg_string(hk, "device_type", config->device_type);
+	if (WPA_GET_BE32(config->os_version)) {
+		char vbuf[10];
+		os_snprintf(vbuf, sizeof(vbuf), "%08x",
+			    WPA_GET_BE32(config->os_version));
+		wpa_config_write_reg_string(hk, "os_version", vbuf);
+	}
+#endif /* CONFIG_WPS */
 
 	return 0;
 }
@@ -874,6 +956,8 @@
 
 	wpa_config_delete_subkeys(hk, TEXT("networks"));
 	for (ssid = config->ssid, id = 0; ssid; ssid = ssid->next, id++) {
+		if (ssid->key_mgmt == WPA_KEY_MGMT_WPS)
+			continue; /* do not save temporary WPS networks */
 		if (wpa_config_write_network(hk, ssid, id))
 			errors++;
 	}

Modified: wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c Sat Jan 10 09:03:49 2009
@@ -27,8 +27,11 @@
 #include "wpa_ctrl.h"
 #include "eap_peer/eap.h"
 #include "ieee802_11_defs.h"
-
-
+#include "wps_supplicant.h"
+#include "wps/wps.h"
+
+static int wpa_supplicant_global_iface_list(struct wpa_global *global,
+					    char *buf, int len);
 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
 						  char *buf, int len);
 
@@ -137,6 +140,91 @@
 	return wpa_ft_start_over_ds(wpa_s->wpa, target_ap);
 }
 #endif /* CONFIG_IEEE80211R */
+
+
+#ifdef CONFIG_WPS
+static int wpa_supplicant_ctrl_iface_wps_pbc(struct wpa_supplicant *wpa_s,
+					     char *cmd)
+{
+	u8 bssid[ETH_ALEN];
+
+	if (cmd == NULL || os_strcmp(cmd, "any") == 0)
+		return wpas_wps_start_pbc(wpa_s, NULL);
+
+	if (hwaddr_aton(cmd, bssid)) {
+		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PBC: invalid BSSID '%s'",
+			   cmd);
+		return -1;
+	}
+
+	return wpas_wps_start_pbc(wpa_s, bssid);
+}
+
+
+static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s,
+					     char *cmd, char *buf,
+					     size_t buflen)
+{
+	u8 bssid[ETH_ALEN], *_bssid = bssid;
+	char *pin;
+	int ret;
+
+	pin = os_strchr(cmd, ' ');
+	if (pin)
+		*pin++ = '\0';
+
+	if (os_strcmp(cmd, "any") == 0)
+		_bssid = NULL;
+	else if (hwaddr_aton(cmd, bssid)) {
+		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'",
+			   cmd);
+		return -1;
+	}
+
+	if (pin) {
+		ret = wpas_wps_start_pin(wpa_s, _bssid, pin);
+		if (ret < 0)
+			return -1;
+		ret = os_snprintf(buf, buflen, "%s", pin);
+		if (ret < 0 || (size_t) ret >= buflen)
+			return -1;
+		return ret;
+	}
+
+	ret = wpas_wps_start_pin(wpa_s, _bssid, NULL);
+	if (ret < 0)
+		return -1;
+
+	/* Return the generated PIN */
+	ret = os_snprintf(buf, buflen, "%08d", ret);
+	if (ret < 0 || (size_t) ret >= buflen)
+		return -1;
+	return ret;
+}
+
+
+static int wpa_supplicant_ctrl_iface_wps_reg(struct wpa_supplicant *wpa_s,
+					     char *cmd)
+{
+	u8 bssid[ETH_ALEN], *_bssid = bssid;
+	char *pin;
+
+	pin = os_strchr(cmd, ' ');
+	if (pin == NULL)
+		return -1;
+	*pin++ = '\0';
+
+	if (os_strcmp(cmd, "any") == 0)
+		_bssid = NULL;
+	else if (hwaddr_aton(cmd, bssid)) {
+		wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_REG: invalid BSSID '%s'",
+			   cmd);
+		return -1;
+	}
+
+	return wpas_wps_start_reg(wpa_s, _bssid, pin);
+}
+#endif /* CONFIG_WPS */
 
 
 static int wpa_supplicant_ctrl_iface_ctrl_rsp(struct wpa_supplicant *wpa_s,
@@ -528,6 +616,34 @@
 	return pos;
 }
 
+static char * wpa_supplicant_wps_ie_txt(char *pos, char *end,
+					const struct wpa_scan_res *res)
+{
+#ifdef CONFIG_WPS
+	struct wpabuf *wps_ie;
+	int ret;
+	const char *txt;
+
+	wps_ie = wpa_scan_get_vendor_ie_multi(res, WPS_IE_VENDOR_TYPE);
+	if (wps_ie == NULL)
+		return pos;
+
+	if (wps_is_selected_pbc_registrar(wps_ie))
+		txt = "[WPS-PBC]";
+	else if (wps_is_selected_pin_registrar(wps_ie))
+		txt = "[WPS-PIN]";
+	else
+		txt = "[WPS]";
+
+	ret = os_snprintf(pos, end - pos, "%s", txt);
+	if (ret >= 0 && ret < end - pos)
+		pos += ret;
+	wpabuf_free(wps_ie);
+#endif /* CONFIG_WPS */
+
+	return pos;
+}
+
 
 /* Format one result on one text line into a buffer. */
 static int wpa_supplicant_ctrl_iface_scan_result(
@@ -551,6 +667,7 @@
 	ie2 = wpa_scan_get_ie(res, WLAN_EID_RSN);
 	if (ie2)
 		pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
+	pos = wpa_supplicant_wps_ie_txt(pos, end, res);
 	if (!ie && !ie2 && res->caps & IEEE80211_CAP_PRIVACY) {
 		ret = os_snprintf(pos, end - pos, "[WEP]");
 		if (ret < 0 || ret >= end - pos)
@@ -1314,6 +1431,7 @@
 	ie2 = wpa_scan_get_ie(bss, WLAN_EID_RSN);
 	if (ie2)
 		pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
+	pos = wpa_supplicant_wps_ie_txt(pos, end, bss);
 	if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
 		ret = os_snprintf(pos, end - pos, "[WEP]");
 		if (ret < 0 || ret >= end - pos)
@@ -1432,6 +1550,21 @@
 		if (wpa_supplicant_ctrl_iface_ft_ds(wpa_s, buf + 6))
 			reply_len = -1;
 #endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_WPS
+	} else if (os_strcmp(buf, "WPS_PBC") == 0) {
+		if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, NULL))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "WPS_PBC ", 8) == 0) {
+		if (wpa_supplicant_ctrl_iface_wps_pbc(wpa_s, buf + 8))
+			reply_len = -1;
+	} else if (os_strncmp(buf, "WPS_PIN ", 8) == 0) {
+		reply_len = wpa_supplicant_ctrl_iface_wps_pin(wpa_s, buf + 8,
+							      reply,
+							      reply_size);
+	} else if (os_strncmp(buf, "WPS_REG ", 8) == 0) {
+		if (wpa_supplicant_ctrl_iface_wps_reg(wpa_s, buf + 8))
+			reply_len = -1;
+#endif /* CONFIG_WPS */
 	} else if (os_strncmp(buf, WPA_CTRL_RSP, os_strlen(WPA_CTRL_RSP)) == 0)
 	{
 		if (wpa_supplicant_ctrl_iface_ctrl_rsp(
@@ -1492,6 +1625,9 @@
 	} else if (os_strncmp(buf, "AP_SCAN ", 8) == 0) {
 		if (wpa_supplicant_ctrl_iface_ap_scan(wpa_s, buf + 8))
 			reply_len = -1;
+	} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
+		reply_len = wpa_supplicant_global_iface_list(
+			wpa_s->global, reply, reply_size);
 	} else if (os_strcmp(buf, "INTERFACES") == 0) {
 		reply_len = wpa_supplicant_global_iface_interfaces(
 			wpa_s->global, reply, reply_size);
@@ -1607,6 +1743,63 @@
 }
 
 
+static void wpa_free_iface_info(struct wpa_interface_info *iface)
+{
+	struct wpa_interface_info *prev;
+
+	while (iface) {
+		prev = iface;
+		iface = iface->next;
+
+		os_free(prev->ifname);
+		os_free(prev->desc);
+		os_free(prev);
+	}
+}
+
+
+static int wpa_supplicant_global_iface_list(struct wpa_global *global,
+					    char *buf, int len)
+{
+	int i, res;
+	struct wpa_interface_info *iface = NULL, *last = NULL, *tmp;
+	char *pos, *end;
+
+	for (i = 0; wpa_supplicant_drivers[i]; i++) {
+		struct wpa_driver_ops *drv = wpa_supplicant_drivers[i];
+		if (drv->get_interfaces == NULL)
+			continue;
+		tmp = drv->get_interfaces(global->drv_priv);
+		if (tmp == NULL)
+			continue;
+
+		if (last == NULL)
+			iface = last = tmp;
+		else
+			last->next = tmp;
+		while (last->next)
+			last = last->next;
+	}
+
+	pos = buf;
+	end = buf + len;
+	for (tmp = iface; tmp; tmp = tmp->next) {
+		res = os_snprintf(pos, end - pos, "%s\t%s\t%s\n",
+				  tmp->drv_name, tmp->ifname,
+				  tmp->desc ? tmp->desc : "");
+		if (res < 0 || res >= end - pos) {
+			*pos = '\0';
+			break;
+		}
+		pos += res;
+	}
+
+	wpa_free_iface_info(iface);
+
+	return pos - buf;
+}
+
+
 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
 						  char *buf, int len)
 {
@@ -1659,6 +1852,9 @@
 	} else if (os_strncmp(buf, "INTERFACE_REMOVE ", 17) == 0) {
 		if (wpa_supplicant_global_iface_remove(global, buf + 17))
 			reply_len = -1;
+	} else if (os_strcmp(buf, "INTERFACE_LIST") == 0) {
+		reply_len = wpa_supplicant_global_iface_list(
+			global, reply, reply_size);
 	} else if (os_strcmp(buf, "INTERFACES") == 0) {
 		reply_len = wpa_supplicant_global_iface_interfaces(
 			global, reply, reply_size);

Modified: wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c Sat Jan 10 09:03:49 2009
@@ -920,7 +920,6 @@
 
 /**
  * wpas_dbus_register_new_iface - Register a new interface with dbus
- * @global: Global %wpa_supplicant data
  * @wpa_s: %wpa_supplicant interface description structure to register
  * Returns: 0 on success, -1 on error
  *

Modified: wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus_handlers.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus_handlers.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus_handlers.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus_handlers.c Sat Jan 10 09:03:49 2009
@@ -153,7 +153,7 @@
 	 * Try to get the wpa_supplicant record for this iface, return
 	 * an error if we already control it.
 	 */
-	if (wpa_supplicant_get_iface(global, iface.ifname) != 0) {
+	if (wpa_supplicant_get_iface(global, iface.ifname) != NULL) {
 		reply = dbus_message_new_error(message,
 					       WPAS_ERROR_EXISTS_ERROR,
 					       "wpa_supplicant already "
@@ -415,6 +415,14 @@
 	ie = wpa_scan_get_ie(res, WLAN_EID_RSN);
 	if (ie) {
 		if (!wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie",
+						     (const char *) ie,
+						     ie[1] + 2))
+			goto error;
+	}
+
+	ie = wpa_scan_get_vendor_ie(res, WPS_IE_VENDOR_TYPE);
+	if (ie) {
+		if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie",
 						     (const char *) ie,
 						     ie[1] + 2))
 			goto error;
@@ -1279,7 +1287,7 @@
 /**
  * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
  * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
+ * @wpa_s: %wpa_supplicant data structure
  * Returns: A dbus message containing a UINT32 indicating success (1) or
  *          failure (0)
  *
@@ -1362,7 +1370,7 @@
 /**
  * wpas_dbus_iface_remove_blob - Remove named binary blobs
  * @message: Pointer to incoming dbus message
- * @global: %wpa_supplicant global data structure
+ * @wpa_s: %wpa_supplicant data structure
  * Returns: A dbus message containing a UINT32 indicating success (1) or
  *          failure (0)
  *

Modified: wpasupplicant/trunk/wpa_supplicant/ctrl_iface_named_pipe.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ctrl_iface_named_pipe.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ctrl_iface_named_pipe.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/ctrl_iface_named_pipe.c Sat Jan 10 09:03:49 2009
@@ -412,7 +412,8 @@
 		return -1;
 	if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
 		    t_sddl, SDDL_REVISION_1,
-		    (PSECURITY_DESCRIPTOR *) &priv->attr.lpSecurityDescriptor,
+		    (PSECURITY_DESCRIPTOR *) (void *)
+		    &priv->attr.lpSecurityDescriptor,
 		    NULL)) {
 		os_free(t_sddl);
 		wpa_printf(MSG_ERROR, "CTRL: SDDL='%s' - could not convert to "

Modified: wpasupplicant/trunk/wpa_supplicant/dbus_dict_helpers.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/dbus_dict_helpers.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/dbus_dict_helpers.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/dbus_dict_helpers.c Sat Jan 10 09:03:49 2009
@@ -21,7 +21,7 @@
 
 /**
  * Start a dict in a dbus message.  Should be paired with a call to
- * {@link wpa_dbus_dict_close_write}.
+ * wpa_dbus_dict_close_write().
  *
  * @param iter A valid dbus message iterator
  * @param iter_dict (out) A dict iterator to pass to further dict functions
@@ -50,12 +50,12 @@
 
 /**
  * End a dict element in a dbus message.  Should be paired with
- * a call to {@link wpa_dbus_dict_open_write}.
+ * a call to wpa_dbus_dict_open_write().
  *
  * @param iter valid dbus message iterator, same as passed to
  *    wpa_dbus_dict_open_write()
  * @param iter_dict a dbus dict iterator returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @return TRUE on success, FALSE on failure
  *
  */
@@ -209,7 +209,7 @@
  * Add a string entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The string value
  * @return TRUE on success, FALSE on failure
@@ -229,7 +229,7 @@
  * Add a byte entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The byte value
  * @return TRUE on success, FALSE on failure
@@ -249,7 +249,7 @@
  * Add a boolean entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The boolean value
  * @return TRUE on success, FALSE on failure
@@ -269,7 +269,7 @@
  * Add a 16-bit signed integer entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The 16-bit signed integer value
  * @return TRUE on success, FALSE on failure
@@ -290,7 +290,7 @@
  * Add a 16-bit unsigned integer entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The 16-bit unsigned integer value
  * @return TRUE on success, FALSE on failure
@@ -311,7 +311,7 @@
  * Add a 32-bit signed integer to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The 32-bit signed integer value
  * @return TRUE on success, FALSE on failure
@@ -332,7 +332,7 @@
  * Add a 32-bit unsigned integer entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The 32-bit unsigned integer value
  * @return TRUE on success, FALSE on failure
@@ -353,7 +353,7 @@
  * Add a 64-bit integer entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The 64-bit integer value
  * @return TRUE on success, FALSE on failure
@@ -374,7 +374,7 @@
  * Add a 64-bit unsigned integer entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The 64-bit unsigned integer value
  * @return TRUE on success, FALSE on failure
@@ -395,7 +395,7 @@
  * Add a double-precision floating point entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The double-precision floating point value
  * @return TRUE on success, FALSE on failure
@@ -416,7 +416,7 @@
  * Add a DBus object path entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The DBus object path value
  * @return TRUE on success, FALSE on failure
@@ -437,7 +437,7 @@
  * Add a byte array entry to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_write}
+ *    wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param value The byte array
  * @param value_len The length of the byte array, in bytes
@@ -462,14 +462,14 @@
  * Begin a string array entry in the dict
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *                  {@link nmu_dbus_dict_open_write}
+ *                  wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param iter_dict_entry A private DBusMessageIter provided by the caller to
- *                        be passed to {@link wpa_dbus_dict_end_string_array}
+ *                        be passed to wpa_dbus_dict_end_string_array()
  * @param iter_dict_val A private DBusMessageIter provided by the caller to
- *                      be passed to {@link wpa_dbus_dict_end_string_array}
+ *                      be passed to wpa_dbus_dict_end_string_array()
  * @param iter_array On return, the DBusMessageIter to be passed to
- *                   {@link wpa_dbus_dict_string_array_add_element}
+ *                   wpa_dbus_dict_string_array_add_element()
  * @return TRUE on success, FALSE on failure
  *
  */
@@ -506,7 +506,7 @@
  * Add a single string element to a string array dict entry
  *
  * @param iter_array A valid DBusMessageIter returned from
- *                   {@link wpa_dbus_dict_begin_string_array}'s
+ *                   wpa_dbus_dict_begin_string_array()'s
  *                   iter_array parameter
  * @param elem The string element to be added to the dict entry's string array
  * @return TRUE on success, FALSE on failure
@@ -527,13 +527,13 @@
  * End a string array dict entry
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *                  {@link nmu_dbus_dict_open_write}
+ *                  wpa_dbus_dict_open_write()
  * @param iter_dict_entry A private DBusMessageIter returned from
- *                        {@link wpa_dbus_dict_end_string_array}
+ *                        wpa_dbus_dict_end_string_array()
  * @param iter_dict_val A private DBusMessageIter returned from
- *                      {@link wpa_dbus_dict_end_string_array}
+ *                      wpa_dbus_dict_end_string_array()
  * @param iter_array A DBusMessageIter returned from
- *                   {@link wpa_dbus_dict_end_string_array}
+ *                   wpa_dbus_dict_end_string_array()
  * @return TRUE on success, FALSE on failure
  *
  */
@@ -560,7 +560,7 @@
  * Convenience function to add an entire string array to the dict.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *                  {@link nmu_dbus_dict_open_write}
+ *                  wpa_dbus_dict_open_write()
  * @param key The key of the dict item
  * @param items The array of strings
  * @param num_items The number of strings in the array
@@ -608,7 +608,7 @@
  *
  * @param iter A valid DBusMessageIter pointing to the start of the dict
  * @param iter_dict (out) A DBusMessageIter to be passed to
- *    {@link wpa_dbus_dict_read_next_entry}
+ *    wpa_dbus_dict_read_next_entry()
  * @return TRUE on success, FALSE on failure
  *
  */
@@ -868,14 +868,14 @@
 /**
  * Read the current key/value entry from the dict.  Entries are dynamically
  * allocated when needed and must be freed after use with the
- * {@link wpa_dbus_dict_entry_clear} function.
+ * wpa_dbus_dict_entry_clear() function.
  *
  * The returned entry object will be filled with the type and value of the next
  * entry in the dict, or the type will be DBUS_TYPE_INVALID if an error
  * occurred.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_read}
+ *    wpa_dbus_dict_open_read()
  * @param entry A valid dict entry object into which the dict key and value
  *    will be placed
  * @return TRUE on success, FALSE on failure
@@ -927,7 +927,7 @@
  * Return whether or not there are additional dictionary entries.
  *
  * @param iter_dict A valid DBusMessageIter returned from
- *    {@link wpa_dbus_dict_open_read}
+ *    wpa_dbus_dict_open_read()
  * @return TRUE if more dict entries exists, FALSE if no more dict entries
  * exist
  */

Modified: wpasupplicant/trunk/wpa_supplicant/defconfig
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/defconfig?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/defconfig (original)
+++ wpasupplicant/trunk/wpa_supplicant/defconfig Sat Jan 10 09:03:49 2009
@@ -156,6 +156,10 @@
 # EAP-AKA (enable CONFIG_PCSC, if EAP-AKA is used)
 #CONFIG_EAP_AKA=y
 
+# EAP-AKA' (enable CONFIG_PCSC, if EAP-AKA' is used).
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
 # Enable USIM simulator (Milenage) for EAP-AKA
 #CONFIG_USIM_SIMULATOR=y
 
@@ -169,6 +173,9 @@
 
 # EAP-TNC and related Trusted Network Connect support (experimental)
 #CONFIG_EAP_TNC=y
+
+# Wi-Fi Protected Setup (WPS)
+#CONFIG_WPS=y
 
 # EAP-IKEv2
 #CONFIG_EAP_IKEV2=y

Modified: wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen Sat Jan 10 09:03:49 2009
@@ -148,7 +148,7 @@
 	TLS library wrapper for GnuTLS
 
 
-\section crypto_func Cryptographic functions
+\section tls_func TLS library
 
 asn1.c and asn1.h
 	ASN.1 DER parsing

Modified: wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.sgml?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.sgml (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.sgml Sat Jan 10 09:03:49 2009
@@ -66,7 +66,7 @@
 
     <para>Before wpa_supplicant can do its work, the network interface
     must be available.  That means that the physical device must be
-    present and enabled, and the driver for the device must have be
+    present and enabled, and the driver for the device must be
     loaded. The daemon will exit immediately if the device is not already
     available.</para>
 

Modified: wpasupplicant/trunk/wpa_supplicant/doc/doxygen.fast
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/doxygen.fast?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/doxygen.fast (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/doxygen.fast Sat Jan 10 09:03:49 2009
@@ -1,14 +1,13 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.4.4
 
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME           = wpa_supplicant
 PROJECT_NUMBER         = 0.6.x
-OUTPUT_DIRECTORY       = doc
+OUTPUT_DIRECTORY       = wpa_supplicant/doc
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
-USE_WINDOWS_ENCODING   = NO
 BRIEF_MEMBER_DESC      = YES
 REPEAT_BRIEF           = YES
 ABBREVIATE_BRIEF       = "The $name class" \
@@ -33,6 +32,7 @@
 DETAILS_AT_TOP         = NO
 INHERIT_DOCS           = YES
 DISTRIBUTE_GROUP_DOC   = NO
+SEPARATE_MEMBER_PAGES  = NO
 TAB_SIZE               = 8
 ALIASES                = 
 OPTIMIZE_OUTPUT_FOR_C  = YES
@@ -65,14 +65,14 @@
 ENABLED_SECTIONS       = 
 MAX_INITIALIZER_LINES  = 30
 SHOW_USED_FILES        = YES
-SHOW_DIRECTORIES       = NO
+SHOW_DIRECTORIES       = YES
 FILE_VERSION_FILTER    = 
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
 QUIET                  = NO
 WARNINGS               = YES
-WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_UNDOCUMENTED   = NO
 WARN_IF_DOC_ERROR      = YES
 WARN_NO_PARAMDOC       = YES
 WARN_FORMAT            = "$file:$line: $text"
@@ -80,25 +80,27 @@
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
-INPUT                  = . \
-	../src/crypto \
-	../src/utils \
-	../src/eap_peer \
-	../src/eap_common \
-	../src/l2_packet \
-	../src/rsn_supp \
-	../src/drivers/driver.h \
-	../src/drivers/drivers.c \
-	../src/tls
-FILE_PATTERNS          = *.c *.h *.doxygen
+INPUT                  = wpa_supplicant \
+	src/common \
+	src/crypto \
+	src/drivers \
+	src/eap_common \
+	src/eapol_supp \
+	src/eap_peer \
+	src/l2_packet \
+	src/rsn_supp \
+	src/tls \
+	src/utils \
+	src/wps
+FILE_PATTERNS          = *.c *.h *.cpp *.m *.doxygen
 RECURSIVE              = YES
-EXCLUDE                = 
+EXCLUDE                = wpa_supplicant/wpa_gui
 EXCLUDE_SYMLINKS       = NO
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       = */.moc/* */.ui/*
 EXAMPLE_PATH           = 
 EXAMPLE_PATTERNS       = *
 EXAMPLE_RECURSIVE      = NO
-IMAGE_PATH             = doc
+IMAGE_PATH             = wpa_supplicant/doc
 INPUT_FILTER           = kerneldoc2doxygen.pl
 FILTER_PATTERNS        = 
 FILTER_SOURCE_FILES    = YES
@@ -196,7 +198,7 @@
 SEARCH_INCLUDES        = YES
 INCLUDE_PATH           = 
 INCLUDE_FILE_PATTERNS  = 
-PREDEFINED             = IEEE8021X_EAPOL
+PREDEFINED             = IEEE8021X_EAPOL CONFIG_CTRL_IFACE
 EXPAND_AS_DEFINED      = 
 SKIP_FUNCTION_MACROS   = YES
 #---------------------------------------------------------------------------
@@ -226,8 +228,6 @@
 DOT_IMAGE_FORMAT       = png
 DOT_PATH               = 
 DOTFILE_DIRS           = 
-MAX_DOT_GRAPH_WIDTH    = 1024
-MAX_DOT_GRAPH_HEIGHT   = 1024
 MAX_DOT_GRAPH_DEPTH    = 1000
 DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = NO

Modified: wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full Sat Jan 10 09:03:49 2009
@@ -1,4 +1,4 @@
-# Doxyfile 1.4.1
+# Doxyfile 1.4.4
 
 #---------------------------------------------------------------------------
 # Project related configuration options
@@ -8,7 +8,6 @@
 OUTPUT_DIRECTORY       = wpa_supplicant/doc
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
-USE_WINDOWS_ENCODING   = NO
 BRIEF_MEMBER_DESC      = YES
 REPEAT_BRIEF           = YES
 ABBREVIATE_BRIEF       = "The $name class" \
@@ -24,7 +23,7 @@
                          the
 ALWAYS_DETAILED_SEC    = NO
 INLINE_INHERITED_MEMB  = NO
-FULL_PATH_NAMES        = NO
+FULL_PATH_NAMES        = YES
 STRIP_FROM_PATH        =
 STRIP_FROM_INC_PATH    = 
 SHORT_NAMES            = NO
@@ -33,6 +32,7 @@
 DETAILS_AT_TOP         = NO
 INHERIT_DOCS           = YES
 DISTRIBUTE_GROUP_DOC   = NO
+SEPARATE_MEMBER_PAGES  = NO
 TAB_SIZE               = 8
 ALIASES                = 
 OPTIMIZE_OUTPUT_FOR_C  = YES
@@ -72,7 +72,7 @@
 #---------------------------------------------------------------------------
 QUIET                  = NO
 WARNINGS               = YES
-WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_UNDOCUMENTED   = NO
 WARN_IF_DOC_ERROR      = YES
 WARN_NO_PARAMDOC       = YES
 WARN_FORMAT            = "$file:$line: $text"
@@ -90,16 +90,17 @@
 	src/l2_packet \
 	src/rsn_supp \
 	src/tls \
-	src/utils
+	src/utils \
+	src/wps
 FILE_PATTERNS          = *.c *.h *.cpp *.m *.doxygen
 RECURSIVE              = YES
-EXCLUDE                = 
+EXCLUDE                = wpa_supplicant/wpa_gui
 EXCLUDE_SYMLINKS       = NO
-EXCLUDE_PATTERNS       = 
+EXCLUDE_PATTERNS       = */.moc/* */.ui/*
 EXAMPLE_PATH           = 
 EXAMPLE_PATTERNS       = *
 EXAMPLE_RECURSIVE      = NO
-IMAGE_PATH             = doc
+IMAGE_PATH             = wpa_supplicant/doc
 INPUT_FILTER           = kerneldoc2doxygen.pl
 FILTER_PATTERNS        = 
 FILTER_SOURCE_FILES    = YES
@@ -227,8 +228,6 @@
 DOT_IMAGE_FORMAT       = png
 DOT_PATH               = 
 DOTFILE_DIRS           = 
-MAX_DOT_GRAPH_WIDTH    = 1024
-MAX_DOT_GRAPH_HEIGHT   = 1024
 MAX_DOT_GRAPH_DEPTH    = 1000
 DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = NO

Modified: wpasupplicant/trunk/wpa_supplicant/doc/kerneldoc2doxygen.pl
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/kerneldoc2doxygen.pl?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/kerneldoc2doxygen.pl (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/kerneldoc2doxygen.pl Sat Jan 10 09:03:49 2009
@@ -20,7 +20,7 @@
 #
 ##########################################################################
 # Copyright (C) 2003 Jonathan Foster <jon at jon-foster.co.uk>
-# Copyright (C) 2005 Jouni Malinen <j at w1.fi>
+# Copyright (C) 2005-2008 Jouni Malinen <j at w1.fi>
 # (modified for kerneldoc format used in wpa_supplicant)
 #
 # This program is free software; you can redistribute it and/or modify
@@ -69,6 +69,11 @@
 #
 sub fixcomment {
     $t = $_[0];
+
+    # wpa_supplicant -> %wpa_supplicant except for struct wpa_supplicant
+    $t =~ s/struct wpa_supplicant/struct STRUCTwpa_supplicant/sg;
+    $t =~ s/ wpa_supplicant/ \%wpa_supplicant/sg;
+    $t =~ s/struct STRUCTwpa_supplicant/struct wpa_supplicant/sg;
 
     # " * func: foo" --> "\brief foo\n"
     # " * struct bar: foo" --> "\brief foo\n"

Modified: wpasupplicant/trunk/wpa_supplicant/doc/porting.doxygen
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/porting.doxygen?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/porting.doxygen (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/porting.doxygen Sat Jan 10 09:03:49 2009
@@ -19,9 +19,9 @@
 %wpa_supplicant is mostly using ANSI C functions that are available on
 most targets. However, couple of additional functions that are common
 on modern UNIX systems are used. Number of these are listed with
-prototypes in common.h (the #ifdef CONFIG_ANSI_C_EXTRA block). These
-functions may need to be implemented or at least defined as macros to
-native functions in the target OS or C library.
+prototypes in common.h (the \verbatim #ifdef CONFIG_ANSI_C_EXTRA \endverbatim
+block). These functions may need to be implemented or at least defined
+as macros to native functions in the target OS or C library.
 
 Many of the common ANSI C functions are used through a wrapper
 definitions in os.h to allow these to be replaced easily with a

Modified: wpasupplicant/trunk/wpa_supplicant/eap_testing.txt
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/eap_testing.txt?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/eap_testing.txt (original)
+++ wpasupplicant/trunk/wpa_supplicant/eap_testing.txt Sat Jan 10 09:03:49 2009
@@ -94,20 +94,21 @@
 EAP-TTLS + TNC		-   -   -   -   -   +   -   -   -   -   +   -
 EAP-SIM			+   -   -   ?   -   +   -   ?   -   -   +   -
 EAP-AKA			-   -   -   -   -   +   -   -   -   -   +   -
+EAP-AKA'		-   -   -   -   -   -   -   -   -   -   +   -
 EAP-PSK			+7  -   -   -   -   +   -   -   -   -   +   -
 EAP-PAX			-   -   -   -   -   +   -   -   -   -   +   -
 EAP-SAKE		-   -   -   -   -   -   -   -   -   -   +   -
 EAP-GPSK		-   -   -   -   -   -   -   -   -   -   +   -
-EAP-FAST/MSCHAPv2(prov)	-   -   -   +   -   -   -   -   -   +   +   +
-EAP-FAST/GTC(auth)	-   -   -   +   -   -   -   -   -   +   +   +
-EAP-FAST/MSCHAPv2(aprov)-   -   -   -   -   -   -   -   -   -   +   +
-EAP-FAST/GTC(aprov)	-   -   -   -   -   -   -   -   -   -   +   +
-EAP-FAST/MD5(aprov)	-   -   -   -   -   -   -   -   -   -   +   -
+EAP-FAST/MSCHAPv2(prov)	-   -   -   +   -   +   -   -   -   +   +   +
+EAP-FAST/GTC(auth)	-   -   -   +   -   +   -   -   -   +   +   +
+EAP-FAST/MSCHAPv2(aprov)-   -   -   -   -   +   -   -   -   -   +   +
+EAP-FAST/GTC(aprov)	-   -   -   -   -   +   -   -   -   -   +   +
+EAP-FAST/MD5(aprov)	-   -   -   -   -   +   -   -   -   -   +   -
 EAP-FAST/TLS(aprov)	-   -   -   -   -   -   -   -   -   -   +   +
 EAP-FAST/SIM(aprov)	-   -   -   -   -   -   -   -   -   -   +   -
 EAP-FAST/AKA(aprov)	-   -   -   -   -   -   -   -   -   -   +   -
-EAP-FAST/MSCHAPv2(auth)	-   -   -   -   -   -   -   -   -   -   +   +
-EAP-FAST/MD5(auth)	-   -   -   -   -   -   -   -   -   -   +   -
+EAP-FAST/MSCHAPv2(auth)	-   -   -   -   -   +   -   -   -   -   +   +
+EAP-FAST/MD5(auth)	-   -   -   -   -   +   -   -   -   -   +   -
 EAP-FAST/TLS(auth)	-   -   -   -   -   -   -   -   -   -   +   +
 EAP-FAST/SIM(auth)	-   -   -   -   -   -   -   -   -   -   +   -
 EAP-FAST/AKA(auth)	-   -   -   -   -   -   -   -   -   -   +   -

Modified: wpasupplicant/trunk/wpa_supplicant/eapol_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/eapol_test.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/eapol_test.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/eapol_test.c Sat Jan 10 09:03:49 2009
@@ -38,6 +38,13 @@
 struct wpa_driver_ops *wpa_supplicant_drivers[] = { NULL };
 
 
+struct extra_radius_attr {
+	u8 type;
+	char syntax;
+	char *data;
+	struct extra_radius_attr *next;
+};
+
 struct eapol_test_data {
 	struct wpa_supplicant *wpa_s;
 
@@ -66,8 +73,7 @@
 
 	char *connect_info;
 	u8 own_addr[ETH_ALEN];
-	int cui_flag;
-	char *cui_str;
+	struct extra_radius_attr *extra_attrs;
 };
 
 static struct eapol_test_data eapol_test;
@@ -84,6 +90,69 @@
 			   MAC2STR(addr), txt);
 	else
 		wpa_printf(MSG_DEBUG, "%s", txt);
+}
+
+
+static int add_extra_attr(struct radius_msg *msg,
+			  struct extra_radius_attr *attr)
+{
+	size_t len;
+	char *pos;
+	u32 val;
+	char buf[128];
+
+	switch (attr->syntax) {
+	case 's':
+		os_snprintf(buf, sizeof(buf), "%s", attr->data);
+		len = os_strlen(buf);
+		break;
+	case 'n':
+		buf[0] = '\0';
+		len = 1;
+		break;
+	case 'x':
+		pos = attr->data;
+		if (pos[0] == '0' && pos[1] == 'x')
+			pos += 2;
+		len = os_strlen(pos);
+		if ((len & 1) || (len / 2) > sizeof(buf)) {
+			printf("Invalid extra attribute hexstring\n");
+			return -1;
+		}
+		len /= 2;
+		if (hexstr2bin(pos, (u8 *) buf, len) < 0) {
+			printf("Invalid extra attribute hexstring\n");
+			return -1;
+		}
+		break;
+	case 'd':
+		val = htonl(atoi(attr->data));
+		os_memcpy(buf, &val, 4);
+		len = 4;
+		break;
+	default:
+		printf("Incorrect extra attribute syntax specification\n");
+		return -1;
+	}
+
+	if (!radius_msg_add_attr(msg, attr->type, (u8 *) buf, len)) {
+		printf("Could not add attribute %d\n", attr->type);
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int add_extra_attrs(struct radius_msg *msg,
+			   struct extra_radius_attr *attrs)
+{
+	struct extra_radius_attr *p;
+	for (p = attrs; p; p = p->next) {
+		if (add_extra_attr(msg, p) < 0)
+			return -1;
+	}
+	return 0;
 }
 
 
@@ -166,22 +235,8 @@
 		goto fail;
 	}
 
-	if (e->cui_flag) {
-		int l = 0;
-		if (e->cui_flag == 1) {
-			l = 1;
-			buf[0] = '\0';
-		} else if (e->cui_flag == 2) {
-			os_snprintf(buf, sizeof(buf), "%s", e->cui_str);
-			l = os_strlen(buf);
-		}
-		if (!radius_msg_add_attr(msg,
-					 RADIUS_ATTR_CHARGEABLE_USER_IDENTITY,
-					 (u8 *) buf, l)) {
-			printf("Could not add Chargeable-User-Identity\n");
-			goto fail;
-		}
-	}
+	if (add_extra_attrs(msg, e->extra_attrs) < 0)
+		goto fail;
 
 	if (eap && !radius_msg_add_eap(msg, eap, len)) {
 		printf("Could not add EAP-Message\n");
@@ -365,6 +420,8 @@
 static void test_eapol_clean(struct eapol_test_data *e,
 			     struct wpa_supplicant *wpa_s)
 {
+	struct extra_radius_attr *p, *prev;
+
 	radius_client_deinit(e->radius);
 	os_free(e->last_eap_radius);
 	if (e->last_recv_radius) {
@@ -387,6 +444,13 @@
 		wpa_s->ctrl_iface = NULL;
 	}
 	wpa_config_free(wpa_s->conf);
+
+	p = e->extra_attrs;
+	while (p) {
+		prev = p;
+		p = p->next;
+		os_free(prev);
+	}
 }
 
 
@@ -560,6 +624,16 @@
 				keys->recv_len;
 			os_memcpy(e->authenticator_pmk, keys->recv,
 				  e->authenticator_pmk_len);
+			if (e->authenticator_pmk_len == 16 && keys->send &&
+			    keys->send_len == 16) {
+				/* MS-CHAP-v2 derives 16 octet keys */
+				wpa_printf(MSG_DEBUG, "Use MS-MPPE-Send-Key "
+					   "to extend PMK to 32 octets");
+				os_memcpy(e->authenticator_pmk +
+					  e->authenticator_pmk_len,
+					  keys->send, keys->send_len);
+				e->authenticator_pmk_len += keys->send_len;
+			}
 		}
 
 		os_free(keys->send);
@@ -879,7 +953,8 @@
 	       "[-s<AS secret>]\\\n"
 	       "           [-r<count>] [-t<timeout>] [-C<Connect-Info>] \\\n"
 	       "           [-M<client MAC address>] \\\n"
-	       "           [-I<CUI>] [-i] [-A<client IP>]\n"
+	       "           [-N<attr spec>] \\\n"
+	       "           [-A<client IP>]\n"
 	       "eapol_test scard\n"
 	       "eapol_test sim <PIN> <num triplets> [debug]\n"
 	       "\n");
@@ -895,7 +970,7 @@
 	       "automatically\n"
 	       "  -r<count> = number of re-authentications\n"
 	       "  -W = wait for a control interface monitor before starting\n"
-	       "  -S = save configuration after authentiation\n"
+	       "  -S = save configuration after authentication\n"
 	       "  -n = no MPPE keys expected\n"
 	       "  -t<timeout> = sets timeout in seconds (default: 30 s)\n"
 	       "  -C<Connect-Info> = RADIUS Connect-Info (default: "
@@ -903,9 +978,18 @@
 	       "  -M<client MAC address> = Set own MAC address "
 	       "(Calling-Station-Id,\n"
 	       "                           default: 02:00:00:00:00:01)\n"
-	       "  -I<CUI> = send Chargeable-User-Identity containing the "
-	       "value of CUI\n"
-	       "  -i = send NUL value in Chargeable-User-Identity\n");
+	       "  -N<attr spec> = send arbitrary attribute specified by:\n"
+	       "                  attr_id:syntax:value or attr_id\n"
+	       "                  attr_id - number id of the attribute\n"
+	       "                  syntax - one of: s, d, x\n"
+	       "                     s = string\n"
+	       "                     d = integer\n"
+	       "                     x = octet string\n"
+	       "                  value - attribute value.\n"
+	       "       When only attr_id is specified, NULL will be used as "
+	       "value.\n"
+	       "       Multiple attributes can be specified by using the "
+	       "option several times.\n");
 }
 
 
@@ -919,6 +1003,8 @@
 	char *cli_addr = NULL;
 	char *conf = NULL;
 	int timeout = 30;
+	char *pos;
+	struct extra_radius_attr *p = NULL, *p1;
 
 	if (os_program_init())
 		return -1;
@@ -933,7 +1019,7 @@
 	wpa_debug_show_keys = 1;
 
 	for (;;) {
-		c = getopt(argc, argv, "a:A:c:C:iI:M:np:r:s:St:W");
+		c = getopt(argc, argv, "a:A:c:C:M:nN:p:r:s:St:W");
 		if (c < 0)
 			break;
 		switch (c) {
@@ -948,13 +1034,6 @@
 			break;
 		case 'C':
 			eapol_test.connect_info = optarg;
-			break;
-		case 'i':
-			eapol_test.cui_flag = 1;
-			break;
-		case 'I':
-			eapol_test.cui_flag = 2;
-			eapol_test.cui_str = optarg;
 			break;
 		case 'M':
 			if (hwaddr_aton(optarg, eapol_test.own_addr)) {
@@ -982,6 +1061,34 @@
 			break;
 		case 'W':
 			wait_for_monitor++;
+			break;
+		case 'N':
+			p1 = os_zalloc(sizeof(p1));
+			if (p1 == NULL)
+				break;
+			if (!p)
+				eapol_test.extra_attrs = p1;
+			else
+				p->next = p1;
+			p = p1;
+
+			p->type = atoi(optarg);
+			pos = os_strchr(optarg, ':');
+			if (pos == NULL) {
+				p->syntax = 'n';
+				p->data = NULL;
+				break;
+			}
+
+			pos++;
+			if (pos[0] == '\0' || pos[1] != ':') {
+				printf("Incorrect format of attribute "
+				       "specification\n");
+				break;
+			}
+
+			p->syntax = pos[0];
+			p->data = pos + 2;
 			break;
 		default:
 			usage();

Modified: wpasupplicant/trunk/wpa_supplicant/events.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/events.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/events.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/events.c Sat Jan 10 09:03:49 2009
@@ -31,6 +31,7 @@
 #include "ieee802_11_defs.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
+#include "wps_supplicant.h"
 
 
 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
@@ -275,6 +276,11 @@
 	struct wpa_ie_data ie;
 	int proto_match = 0;
 	const u8 *rsn_ie, *wpa_ie;
+	int ret;
+
+	ret = wpas_wps_ssid_bss_match(ssid, bss);
+	if (ret >= 0)
+		return ret;
 
 	rsn_ie = wpa_scan_get_ie(bss, WLAN_EID_RSN);
 	while ((ssid->proto & WPA_PROTO_RSN) && rsn_ie) {
@@ -409,13 +415,22 @@
 		}
 
 		for (ssid = group; ssid; ssid = ssid->pnext) {
+			int check_ssid = 1;
+
 			if (ssid->disabled) {
 				wpa_printf(MSG_DEBUG, "   skip - disabled");
 				continue;
 			}
 
-			if (ssid_len != ssid->ssid_len ||
-			    os_memcmp(ssid_, ssid->ssid, ssid_len) != 0) {
+#ifdef CONFIG_WPS
+			if (ssid->ssid_len == 0 &&
+			    wpas_wps_ssid_wildcard_ok(ssid, bss))
+				check_ssid = 0;
+#endif /* CONFIG_WPS */
+
+			if (check_ssid &&
+			    (ssid_len != ssid->ssid_len ||
+			     os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
 				wpa_printf(MSG_DEBUG, "   skip - "
 					   "SSID mismatch");
 				continue;
@@ -485,12 +500,26 @@
 		}
 
 		for (ssid = group; ssid; ssid = ssid->pnext) {
+			int check_ssid = ssid->ssid_len != 0;
+
 			if (ssid->disabled) {
 				wpa_printf(MSG_DEBUG, "   skip - disabled");
 				continue;
 			}
 
-			if (ssid->ssid_len != 0 &&
+#ifdef CONFIG_WPS
+			if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+				/* Only allow wildcard SSID match if an AP
+				 * advertises active WPS operation that matches
+				 * with our mode. */
+				check_ssid = 1;
+				if (ssid->ssid_len == 0 &&
+				    wpas_wps_ssid_wildcard_ok(ssid, bss))
+					check_ssid = 0;
+			}
+#endif /* CONFIG_WPS */
+
+			if (check_ssid &&
 			    (ssid_len != ssid->ssid_len ||
 			     os_memcmp(ssid_, ssid->ssid, ssid_len) != 0)) {
 				wpa_printf(MSG_DEBUG, "   skip - "
@@ -507,6 +536,7 @@
 			}
 			
 			if (!(ssid->key_mgmt & WPA_KEY_MGMT_NONE) &&
+			    !(ssid->key_mgmt & WPA_KEY_MGMT_WPS) &&
 			    !(ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA))
 			{
 				wpa_printf(MSG_DEBUG, "   skip - "
@@ -596,9 +626,11 @@
 	} else {
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_SCAN_RESULTS);
 		wpa_supplicant_dbus_notify_scan_results(wpa_s);
-	}
-
-	if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
+		wpas_wps_notify_scan_results(wpa_s);
+	}
+
+	if ((wpa_s->conf->ap_scan == 2 && !wpas_wps_searching(wpa_s)) ||
+	    wpa_s->disconnected)
 		return;
 
 	while (selected == NULL) {
@@ -619,6 +651,13 @@
 	}
 
 	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

Modified: wpasupplicant/trunk/wpa_supplicant/main.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/main.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/main.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/main.c Sat Jan 10 09:03:49 2009
@@ -19,19 +19,6 @@
 
 #include "common.h"
 #include "wpa_supplicant_i.h"
-
-
-extern const char *wpa_supplicant_version;
-extern const char *wpa_supplicant_license;
-#ifndef CONFIG_NO_STDOUT_DEBUG
-extern const char *wpa_supplicant_full_license1;
-extern const char *wpa_supplicant_full_license2;
-extern const char *wpa_supplicant_full_license3;
-extern const char *wpa_supplicant_full_license4;
-extern const char *wpa_supplicant_full_license5;
-#endif /* CONFIG_NO_STDOUT_DEBUG */
-
-extern struct wpa_driver_ops *wpa_supplicant_drivers[];
 
 
 static void usage(void)

Modified: wpasupplicant/trunk/wpa_supplicant/main_winsvc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/main_winsvc.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/main_winsvc.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/main_winsvc.c Sat Jan 10 09:03:49 2009
@@ -12,7 +12,7 @@
  * See README and COPYING for more details.
  *
  * The root of wpa_supplicant configuration in registry is
- * HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant. This level includes global
+ * HKEY_LOCAL_MACHINE\\SOFTWARE\\%wpa_supplicant. This level includes global
  * parameters and a 'interfaces' subkey with all the interface configuration
  * (adapter to confname mapping). Each such mapping is a subkey that has
  * 'adapter' and 'config' values.
@@ -70,9 +70,10 @@
 	HKEY hk;
 #define TBUFLEN 255
 	TCHAR adapter[TBUFLEN], config[TBUFLEN], ctrl_interface[TBUFLEN];
-	DWORD buflen;
+	DWORD buflen, val;
 	LONG ret;
 	struct wpa_interface iface;
+	int skip_on_error = 0;
 
 	ret = RegOpenKeyEx(_hk, name, 0, KEY_QUERY_VALUE, &hk);
 	if (ret != ERROR_SUCCESS) {
@@ -116,10 +117,21 @@
 		iface.confname = (char *) config;
 	}
 
+	buflen = sizeof(val);
+	ret = RegQueryValueEx(hk, TEXT("skip_on_error"), NULL, NULL,
+			      (LPBYTE) &val, &buflen);
+	if (ret == ERROR_SUCCESS && buflen == sizeof(val))
+		skip_on_error = val;
+
 	RegCloseKey(hk);
 
-	if (wpa_supplicant_add_iface(global, &iface) == NULL)
-		return -1;
+	if (wpa_supplicant_add_iface(global, &iface) == NULL) {
+		if (skip_on_error)
+			wpa_printf(MSG_DEBUG, "Skipped interface '%s' due to "
+				   "initialization failure", iface.ifname);
+		else
+			return -1;
+	}
 
 	return 0;
 }

Modified: wpasupplicant/trunk/wpa_supplicant/mlme.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/mlme.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/mlme.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/mlme.c Sat Jan 10 09:03:49 2009
@@ -1738,9 +1738,9 @@
 
 #ifdef CONFIG_IEEE80211W
 
-/* MLME-PING.response */
-static int ieee80211_sta_send_ping_resp(struct wpa_supplicant *wpa_s,
-					const u8 *addr, const u8 *trans_id)
+/* MLME-SAQuery.response */
+static int ieee80211_sta_send_sa_query_resp(struct wpa_supplicant *wpa_s,
+					    const u8 *addr, const u8 *trans_id)
 {
 	struct ieee80211_mgmt *mgmt;
 	int res;
@@ -1749,7 +1749,7 @@
 	mgmt = os_zalloc(sizeof(*mgmt));
 	if (mgmt == NULL) {
 		wpa_printf(MSG_DEBUG, "MLME: Failed to allocate buffer for "
-			   "ping action frame");
+			   "SA Query action frame");
 		return -1;
 	}
 
@@ -1759,11 +1759,11 @@
 	os_memcpy(mgmt->bssid, wpa_s->bssid, ETH_ALEN);
 	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
 					   WLAN_FC_STYPE_ACTION);
-	mgmt->u.action.category = WLAN_ACTION_PING;
-	mgmt->u.action.u.ping_resp.action = WLAN_PING_RESPONSE;
-	os_memcpy(mgmt->u.action.u.ping_resp.trans_id, trans_id,
-		  WLAN_PING_TRANS_ID_LEN);
-	len += 1 + sizeof(mgmt->u.action.u.ping_resp);
+	mgmt->u.action.category = WLAN_ACTION_SA_QUERY;
+	mgmt->u.action.u.sa_query_resp.action = WLAN_SA_QUERY_RESPONSE;
+	os_memcpy(mgmt->u.action.u.sa_query_resp.trans_id, trans_id,
+		  WLAN_SA_QUERY_TR_ID_LEN);
+	len += 1 + sizeof(mgmt->u.action.u.sa_query_resp);
 
 	res = ieee80211_sta_tx(wpa_s, (u8 *) mgmt, len);
 	os_free(mgmt);
@@ -1772,36 +1772,36 @@
 }
 
 
-static void ieee80211_rx_mgmt_ping_action(
+static void ieee80211_rx_mgmt_sa_query_action(
 	struct wpa_supplicant *wpa_s, struct ieee80211_mgmt *mgmt, size_t len,
 	struct ieee80211_rx_status *rx_status)
 {
-	if (len < 24 + 1 + sizeof(mgmt->u.action.u.ping_req)) {
-		wpa_printf(MSG_DEBUG, "MLME: Too short Ping Action frame");
-		return;
-	}
-
-	if (mgmt->u.action.u.ping_req.action != WLAN_PING_REQUEST) {
-		wpa_printf(MSG_DEBUG, "MLME: Unexpected Ping Action %d",
-			   mgmt->u.action.u.ping_req.action);
+	if (len < 24 + 1 + sizeof(mgmt->u.action.u.sa_query_req)) {
+		wpa_printf(MSG_DEBUG, "MLME: Too short SA Query Action frame");
+		return;
+	}
+
+	if (mgmt->u.action.u.sa_query_req.action != WLAN_SA_QUERY_REQUEST) {
+		wpa_printf(MSG_DEBUG, "MLME: Unexpected SA Query Action %d",
+			   mgmt->u.action.u.sa_query_req.action);
 		return;
 	}
 
 	if (os_memcmp(mgmt->sa, wpa_s->bssid, ETH_ALEN) != 0) {
-		wpa_printf(MSG_DEBUG, "MLME: Ignore ping from unknown source "
-			   MACSTR, MAC2STR(mgmt->sa));
+		wpa_printf(MSG_DEBUG, "MLME: Ignore SA Query from unknown "
+			   "source " MACSTR, MAC2STR(mgmt->sa));
 		return;
 	}
 
 	if (wpa_s->mlme.state == IEEE80211_ASSOCIATE) {
-		wpa_printf(MSG_DEBUG, "MLME: Ignore ping request during "
+		wpa_printf(MSG_DEBUG, "MLME: Ignore SA query request during "
 			   "association process");
 		return;
 	}
 
-	wpa_printf(MSG_DEBUG, "MLME: Replying to ping request");
-	ieee80211_sta_send_ping_resp(wpa_s, mgmt->sa,
-				     mgmt->u.action.u.ping_req.trans_id);
+	wpa_printf(MSG_DEBUG, "MLME: Replying to SA Query request");
+	ieee80211_sta_send_sa_query_resp(wpa_s, mgmt->sa, mgmt->u.action.u.
+					 sa_query_req.trans_id);
 }
 
 #endif /* CONFIG_IEEE80211W */
@@ -1824,8 +1824,8 @@
 		break;
 #endif /* CONFIG_IEEE80211R */
 #ifdef CONFIG_IEEE80211W
-	case WLAN_ACTION_PING:
-		ieee80211_rx_mgmt_ping_action(wpa_s, mgmt, len, rx_status);
+	case WLAN_ACTION_SA_QUERY:
+		ieee80211_rx_mgmt_sa_query_action(wpa_s, mgmt, len, rx_status);
 		break;
 #endif /* CONFIG_IEEE80211W */
 	default:

Modified: wpasupplicant/trunk/wpa_supplicant/scan.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/scan.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/scan.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/scan.c Sat Jan 10 09:03:49 2009
@@ -19,7 +19,7 @@
 #include "config.h"
 #include "wpa_supplicant_i.h"
 #include "mlme.h"
-#include "uuid.h"
+#include "wps_supplicant.h"
 
 
 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
@@ -41,13 +41,42 @@
 }
 
 
+#ifdef CONFIG_WPS
+static int wpas_wps_in_use(struct wpa_config *conf,
+			   enum wps_request_type *req_type)
+{
+	struct wpa_ssid *ssid;
+	int wps = 0;
+
+	for (ssid = conf->ssid; ssid; ssid = ssid->next) {
+		if (!(ssid->key_mgmt & WPA_KEY_MGMT_WPS))
+			continue;
+
+		wps = 1;
+		*req_type = wpas_wps_get_req_type(ssid);
+		if (!ssid->eap.phase1)
+			continue;
+
+		if (os_strstr(ssid->eap.phase1, "pbc=1"))
+			return 2;
+	}
+
+	return wps;
+}
+#endif /* CONFIG_WPS */
+
 static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
 	struct wpa_ssid *ssid;
 	int enabled, scan_req = 0, ret;
+	struct wpabuf *wps_ie = NULL;
 	const u8 *extra_ie = NULL;
 	size_t extra_ie_len = 0;
+	int wps = 0;
+#ifdef CONFIG_WPS
+	enum wps_request_type req_type = WPS_REQ_ENROLLEE_INFO;
+#endif /* CONFIG_WPS */
 
 	if (wpa_s->disconnected && !wpa_s->scan_req)
 		return;
@@ -134,8 +163,12 @@
 	} else
 		wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
 
+#ifdef CONFIG_WPS
+	wps = wpas_wps_in_use(wpa_s->conf, &req_type);
+#endif /* CONFIG_WPS */
+
 	if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
-	    !wpa_s->use_client_mlme) {
+	    !wpa_s->use_client_mlme && wps != 2) {
 		wpa_s->scan_res_tried++;
 		wpa_s->scan_req = scan_req;
 		wpa_printf(MSG_DEBUG, "Trying to get current scan results "
@@ -144,6 +177,17 @@
 		wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL);
 		return;
 	}
+
+#ifdef CONFIG_WPS
+	if (wps) {
+		wps_ie = wps_build_probe_req_ie(wps == 2, &wpa_s->wps->dev,
+						wpa_s->wps->uuid, req_type);
+		if (wps_ie) {
+			extra_ie = wpabuf_head(wps_ie);
+			extra_ie_len = wpabuf_len(wps_ie);
+		}
+	}
+#endif /* CONFIG_WPS */
 
 	if (wpa_s->use_client_mlme) {
 		ieee80211_sta_set_probe_req_ie(wpa_s, extra_ie, extra_ie_len);
@@ -154,6 +198,8 @@
 		ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL,
 				   ssid ? ssid->ssid_len : 0);
 	}
+
+	wpabuf_free(wps_ie);
 
 	if (ret) {
 		wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");

Modified: wpasupplicant/trunk/wpa_supplicant/win_example.reg
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/win_example.reg?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/win_example.reg (original)
+++ wpasupplicant/trunk/wpa_supplicant/win_example.reg Sat Jan 10 09:03:49 2009
@@ -11,6 +11,13 @@
 [HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test]
 "ap_scan"=dword:00000002
 "update_config"=dword:00000001
+"uuid"="12345678-9abc-def0-1234-56789abcdef0"
+"device_name"="Wireless Client"
+"manufacturer"="Company"
+"model_name"="cmodel"
+"serial_number"="12345"
+"device_type"="1-0050F204-1"
+"os_version"="01020300"
 
 [HKEY_LOCAL_MACHINE\SOFTWARE\wpa_supplicant\configs\test\blobs]
 "testblob"=hex:01,02,03,04,05
@@ -31,4 +38,5 @@
 "adapter"="{A7627643-C310-49E5-BD89-7E77709C04AB}"
 "config"="test"
 "ctrl_interface"=""
+"skip_on_error"=dword:00000000
 

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_cli.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_cli.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_cli.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_cli.c Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2008, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2009, 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
@@ -31,7 +31,7 @@
 
 static const char *wpa_cli_version =
 "wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2008, Jouni Malinen <j at w1.fi> and contributors";
+"Copyright (c) 2004-2009, Jouni Malinen <j at w1.fi> and contributors";
 
 
 static const char *wpa_cli_license =
@@ -86,55 +86,6 @@
 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 "\n";
 
-static const char *commands_help =
-"commands:\n"
-"  status [verbose] = get current WPA/EAPOL/EAP status\n"
-"  mib = get MIB variables (dot1x, dot11)\n"
-"  help = show this usage help\n"
-"  interface [ifname] = show interfaces/select interface\n"
-"  level <debug level> = change debug level\n"
-"  license = show full wpa_cli license\n"
-"  logoff = IEEE 802.1X EAPOL state machine logoff\n"
-"  logon = IEEE 802.1X EAPOL state machine logon\n"
-"  set = set variables (shows list of variables when run without arguments)\n"
-"  pmksa = show PMKSA cache\n"
-"  reassociate = force reassociation\n"
-"  reconfigure = force wpa_supplicant to re-read its configuration file\n"
-"  preauthenticate <BSSID> = force preauthentication\n"
-"  identity <network id> <identity> = configure identity for an SSID\n"
-"  password <network id> <password> = configure password for an SSID\n"
-"  new_password <network id> <password> = change password for an SSID\n"
-"  pin <network id> <pin> = configure pin for an SSID\n"
-"  otp <network id> <password> = configure one-time-password for an SSID\n"
-"  passphrase <network id> <passphrase> = configure private key passphrase\n"
-"    for an SSID\n"
-"  bssid <network id> <BSSID> = set preferred BSSID for an SSID\n"
-"  list_networks = list configured networks\n"
-"  select_network <network id> = select a network (disable others)\n"
-"  enable_network <network id> = enable a network\n"
-"  disable_network <network id> = disable a network\n"
-"  add_network = add a network\n"
-"  remove_network <network id> = remove a network\n"
-"  set_network <network id> <variable> <value> = set network variables "
-"(shows\n"
-"    list of variables when run without arguments)\n"
-"  get_network <network id> <variable> = get network variables\n"
-"  save_config = save the current configuration\n"
-"  disconnect = disconnect and wait for reassociate/reconnect command before\n "
-"    connecting\n"
-"  reconnect = like reassociate, but only takes effect if already "
-"disconnected\n"
-"  scan = request new BSS scan\n"
-"  scan_results = get latest scan results\n"
-"  bss <<idx> | <bssid>> = get detailed scan result info\n"
-"  get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
-"get capabilies\n"
-"  ap_scan <value> = set ap_scan parameter\n"
-"  stkstart <addr> = request STK negotiation with <addr>\n"
-"  ft_ds <addr> = request over-the-DS FT with <addr>\n"
-"  terminate = terminate wpa_supplicant\n"
-"  quit = exit wpa_cli\n";
-
 static struct wpa_ctrl *ctrl_conn;
 static int wpa_cli_quit = 0;
 static int wpa_cli_attached = 0;
@@ -144,6 +95,9 @@
 static char *ctrl_ifname = NULL;
 static const char *pid_file = NULL;
 static const char *action_file = NULL;
+
+
+static void print_help();
 
 
 static void usage(void)
@@ -158,9 +112,8 @@
 	       "       wpa_supplicant\n"
 	       "  -B = run a daemon in the background\n"
 	       "  default path: /var/run/wpa_supplicant\n"
-	       "  default interface: first interface found in socket path\n"
-	       "%s",
-	       commands_help);
+	       "  default interface: first interface found in socket path\n");
+	print_help();
 }
 
 
@@ -274,7 +227,7 @@
 
 static int wpa_cli_cmd_help(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
-	printf("%s", commands_help);
+	print_help();
 	return 0;
 }
 
@@ -432,6 +385,80 @@
 	res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
 	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
 		printf("Too long FT_DS command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_wps_pbc(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc == 0) {
+		/* Any BSSID */
+		return wpa_ctrl_command(ctrl, "WPS_PBC");
+	}
+
+	/* Specific BSSID */
+	res = os_snprintf(cmd, sizeof(cmd), "WPS_PBC %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long WPS_PBC command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_wps_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc == 0) {
+		printf("Invalid WPS_PIN command: need one or two arguments:\n"
+		       "- BSSID: use 'any' to select any\n"
+		       "- PIN: optional, used only with devices that have no "
+		       "display\n");
+		return -1;
+	}
+
+	if (argc == 1) {
+		/* Use dynamically generated PIN (returned as reply) */
+		res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s", argv[0]);
+		if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+			printf("Too long WPS_PIN command.\n");
+			return -1;
+		}
+		return wpa_ctrl_command(ctrl, cmd);
+	}
+
+	/* Use hardcoded PIN from a label */
+	res = os_snprintf(cmd, sizeof(cmd), "WPS_PIN %s %s", argv[0], argv[1]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long WPS_PIN command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cli_cmd_wps_reg(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc != 2) {
+		printf("Invalid WPS_REG command: need two arguments:\n"
+		       "- BSSID: use 'any' to select any\n"
+		       "- AP PIN\n");
+		return -1;
+	}
+
+	res = os_snprintf(cmd, sizeof(cmd), "WPS_REG %s %s", argv[0], argv[1]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long WPS_REG command.\n");
 		return -1;
 	}
 	return wpa_ctrl_command(ctrl, cmd);
@@ -1042,57 +1069,228 @@
 }
 
 
+static int wpa_cli_cmd_interface_list(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "INTERFACE_LIST");
+}
+
+
+enum wpa_cli_cmd_flags {
+	cli_cmd_flag_none		= 0x00,
+	cli_cmd_flag_sensitive		= 0x01
+};
+
 struct wpa_cli_cmd {
 	const char *cmd;
 	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
+	enum wpa_cli_cmd_flags flags;
+	const char *usage;
 };
 
 static struct wpa_cli_cmd wpa_cli_commands[] = {
-	{ "status", wpa_cli_cmd_status },
-	{ "ping", wpa_cli_cmd_ping },
-	{ "mib", wpa_cli_cmd_mib },
-	{ "help", wpa_cli_cmd_help },
-	{ "interface", wpa_cli_cmd_interface },
-	{ "level", wpa_cli_cmd_level },
-	{ "license", wpa_cli_cmd_license },
-	{ "quit", wpa_cli_cmd_quit },
-	{ "set", wpa_cli_cmd_set },
-	{ "logon", wpa_cli_cmd_logon },
-	{ "logoff", wpa_cli_cmd_logoff },
-	{ "pmksa", wpa_cli_cmd_pmksa },
-	{ "reassociate", wpa_cli_cmd_reassociate },
-	{ "preauthenticate", wpa_cli_cmd_preauthenticate },
-	{ "identity", wpa_cli_cmd_identity },
-	{ "password", wpa_cli_cmd_password },
-	{ "new_password", wpa_cli_cmd_new_password },
-	{ "pin", wpa_cli_cmd_pin },
-	{ "otp", wpa_cli_cmd_otp },
-	{ "passphrase", wpa_cli_cmd_passphrase },
-	{ "bssid", wpa_cli_cmd_bssid },
-	{ "list_networks", wpa_cli_cmd_list_networks },
-	{ "select_network", wpa_cli_cmd_select_network },
-	{ "enable_network", wpa_cli_cmd_enable_network },
-	{ "disable_network", wpa_cli_cmd_disable_network },
-	{ "add_network", wpa_cli_cmd_add_network },
-	{ "remove_network", wpa_cli_cmd_remove_network },
-	{ "set_network", wpa_cli_cmd_set_network },
-	{ "get_network", wpa_cli_cmd_get_network },
-	{ "save_config", wpa_cli_cmd_save_config },
-	{ "disconnect", wpa_cli_cmd_disconnect },
-	{ "reconnect", wpa_cli_cmd_reconnect },
-	{ "scan", wpa_cli_cmd_scan },
-	{ "scan_results", wpa_cli_cmd_scan_results },
-	{ "bss", wpa_cli_cmd_bss },
-	{ "get_capability", wpa_cli_cmd_get_capability },
-	{ "reconfigure", wpa_cli_cmd_reconfigure },
-	{ "terminate", wpa_cli_cmd_terminate },
-	{ "interface_add", wpa_cli_cmd_interface_add },
-	{ "interface_remove", wpa_cli_cmd_interface_remove },
-	{ "ap_scan", wpa_cli_cmd_ap_scan },
-	{ "stkstart", wpa_cli_cmd_stkstart },
-	{ "ft_ds", wpa_cli_cmd_ft_ds },
-	{ NULL, NULL }
+	{ "status", wpa_cli_cmd_status,
+	  cli_cmd_flag_none,
+	  "[verbose] = get current WPA/EAPOL/EAP status" },
+	{ "ping", wpa_cli_cmd_ping,
+	  cli_cmd_flag_none,
+	  "= pings wpa_supplicant" },
+	{ "mib", wpa_cli_cmd_mib,
+	  cli_cmd_flag_none,
+	  "= get MIB variables (dot1x, dot11)" },
+	{ "help", wpa_cli_cmd_help,
+	  cli_cmd_flag_none,
+	  "= show this usage help" },
+	{ "interface", wpa_cli_cmd_interface,
+	  cli_cmd_flag_none,
+	  "[ifname] = show interfaces/select interface" },
+	{ "level", wpa_cli_cmd_level,
+	  cli_cmd_flag_none,
+	  "<debug level> = change debug level" },
+	{ "license", wpa_cli_cmd_license,
+	  cli_cmd_flag_none,
+	  "= show full wpa_cli license" },
+	{ "quit", wpa_cli_cmd_quit,
+	  cli_cmd_flag_none,
+	  "= exit wpa_cli" },
+	{ "set", wpa_cli_cmd_set,
+	  cli_cmd_flag_none,
+	  "= set variables (shows list of variables when run without "
+	  "arguments)" },
+	{ "logon", wpa_cli_cmd_logon,
+	  cli_cmd_flag_none,
+	  "= IEEE 802.1X EAPOL state machine logon" },
+	{ "logoff", wpa_cli_cmd_logoff,
+	  cli_cmd_flag_none,
+	  "= IEEE 802.1X EAPOL state machine logoff" },
+	{ "pmksa", wpa_cli_cmd_pmksa,
+	  cli_cmd_flag_none,
+	  "= show PMKSA cache" },
+	{ "reassociate", wpa_cli_cmd_reassociate,
+	  cli_cmd_flag_none,
+	  "= force reassociation" },
+	{ "preauthenticate", wpa_cli_cmd_preauthenticate,
+	  cli_cmd_flag_none,
+	  "<BSSID> = force preauthentication" },
+	{ "identity", wpa_cli_cmd_identity,
+	  cli_cmd_flag_none,
+	  "<network id> <identity> = configure identity for an SSID" },
+	{ "password", wpa_cli_cmd_password,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <password> = configure password for an SSID" },
+	{ "new_password", wpa_cli_cmd_new_password,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <password> = change password for an SSID" },
+	{ "pin", wpa_cli_cmd_pin,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <pin> = configure pin for an SSID" },
+	{ "otp", wpa_cli_cmd_otp,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <password> = configure one-time-password for an SSID"
+	},
+	{ "passphrase", wpa_cli_cmd_passphrase,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <passphrase> = configure private key passphrase\n"
+	  "  for an SSID" },
+	{ "bssid", wpa_cli_cmd_bssid,
+	  cli_cmd_flag_none,
+	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
+	{ "list_networks", wpa_cli_cmd_list_networks,
+	  cli_cmd_flag_none,
+	  "= list configured networks" },
+	{ "select_network", wpa_cli_cmd_select_network,
+	  cli_cmd_flag_none,
+	  "<network id> = select a network (disable others)" },
+	{ "enable_network", wpa_cli_cmd_enable_network,
+	  cli_cmd_flag_none,
+	  "<network id> = enable a network" },
+	{ "disable_network", wpa_cli_cmd_disable_network,
+	  cli_cmd_flag_none,
+	  "<network id> = disable a network" },
+	{ "add_network", wpa_cli_cmd_add_network,
+	  cli_cmd_flag_none,
+	  "= add a network" },
+	{ "remove_network", wpa_cli_cmd_remove_network,
+	  cli_cmd_flag_none,
+	  "<network id> = remove a network" },
+	{ "set_network", wpa_cli_cmd_set_network,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <variable> <value> = set network variables (shows\n"
+	  "  list of variables when run without arguments)" },
+	{ "get_network", wpa_cli_cmd_get_network,
+	  cli_cmd_flag_none,
+	  "<network id> <variable> = get network variables" },
+	{ "save_config", wpa_cli_cmd_save_config,
+	  cli_cmd_flag_none,
+	  "= save the current configuration" },
+	{ "disconnect", wpa_cli_cmd_disconnect,
+	  cli_cmd_flag_none,
+	  "= disconnect and wait for reassociate/reconnect command before\n"
+	  "  connecting" },
+	{ "reconnect", wpa_cli_cmd_reconnect,
+	  cli_cmd_flag_none,
+	  "= like reassociate, but only takes effect if already disconnected"
+	},
+	{ "scan", wpa_cli_cmd_scan,
+	  cli_cmd_flag_none,
+	  "= request new BSS scan" },
+	{ "scan_results", wpa_cli_cmd_scan_results,
+	  cli_cmd_flag_none,
+	  "= get latest scan results" },
+	{ "bss", wpa_cli_cmd_bss,
+	  cli_cmd_flag_none,
+	  "<<idx> | <bssid>> = get detailed scan result info" },
+	{ "get_capability", wpa_cli_cmd_get_capability,
+	  cli_cmd_flag_none,
+	  "<eap/pairwise/group/key_mgmt/proto/auth_alg> = get capabilies" },
+	{ "reconfigure", wpa_cli_cmd_reconfigure,
+	  cli_cmd_flag_none,
+	  "= force wpa_supplicant to re-read its configuration file" },
+	{ "terminate", wpa_cli_cmd_terminate,
+	  cli_cmd_flag_none,
+	  "= terminate wpa_supplicant" },
+	{ "interface_add", wpa_cli_cmd_interface_add,
+	  cli_cmd_flag_none,
+	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
+	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
+	  "  are optional" },
+	{ "interface_remove", wpa_cli_cmd_interface_remove,
+	  cli_cmd_flag_none,
+	  "<ifname> = removes the interface" },
+	{ "interface_list", wpa_cli_cmd_interface_list,
+	  cli_cmd_flag_none,
+	  "= list available interfaces" },
+	{ "ap_scan", wpa_cli_cmd_ap_scan,
+	  cli_cmd_flag_none,
+	  "<value> = set ap_scan parameter" },
+	{ "stkstart", wpa_cli_cmd_stkstart,
+	  cli_cmd_flag_none,
+	  "<addr> = request STK negotiation with <addr>" },
+	{ "ft_ds", wpa_cli_cmd_ft_ds,
+	  cli_cmd_flag_none,
+	  "<addr> = request over-the-DS FT with <addr>" },
+	{ "wps_pbc", wpa_cli_cmd_wps_pbc,
+	  cli_cmd_flag_none,
+	  "[BSSID] = start Wi-Fi Protected Setup: Push Button Configuration" },
+	{ "wps_pin", wpa_cli_cmd_wps_pin,
+	  cli_cmd_flag_sensitive,
+	  "<BSSID> [PIN] = start WPS PIN method (returns PIN, if not "
+	  "hardcoded)" },
+	{ "wps_reg", wpa_cli_cmd_wps_reg,
+	  cli_cmd_flag_sensitive,
+	  "<BSSID> <AP PIN> = start WPS Registrar to configure an AP" },
+	{ NULL, NULL, cli_cmd_flag_none, NULL }
 };
+
+
+/*
+ * Prints command usage, lines are padded with the specified string.
+ */
+static void print_cmd_help(struct wpa_cli_cmd *cmd, const char *pad)
+{
+	char c;
+	size_t n;
+
+	printf("%s%s ", pad, cmd->cmd);
+	for (n = 0; (c = cmd->usage[n]); n++) {
+		printf("%c", c);
+		if (c == '\n')
+			printf("%s", pad);
+	}
+	printf("\n");
+}
+
+
+static void print_help(void)
+{
+	int n;
+	printf("commands:\n");
+	for (n = 0; wpa_cli_commands[n].cmd; n++)
+		print_cmd_help(&wpa_cli_commands[n], "  ");
+}
+
+
+#ifdef CONFIG_READLINE
+static int cmd_has_sensitive_data(const char *cmd)
+{
+	const char *c, *delim;
+	int n;
+	size_t len;
+
+	delim = os_strchr(cmd, ' ');
+	if (delim)
+		len = delim - cmd;
+	else
+		len = os_strlen(cmd);
+
+	for (n = 0; (c = wpa_cli_commands[n].cmd); n++) {
+		if (os_strncasecmp(cmd, c, len) == 0 && len == os_strlen(c))
+			return (wpa_cli_commands[n].flags &
+				cli_cmd_flag_sensitive);
+	}
+	return 0;
+}
+#endif /* CONFIG_READLINE */
 
 
 static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
@@ -1430,24 +1628,20 @@
 		 * passwords. */
 		HIST_ENTRY *h;
 		history_set_pos(0);
-		h = next_history();
-		while (h) {
+		while ((h = current_history())) {
 			char *p = h->line;
 			while (*p == ' ' || *p == '\t')
 				p++;
-			if (os_strncasecmp(p, "pa", 2) == 0 ||
-			    os_strncasecmp(p, "o", 1) == 0 ||
-			    os_strncasecmp(p, "n", 1)) {
+			if (cmd_has_sensitive_data(p)) {
 				h = remove_history(where_history());
 				if (h) {
 					os_free(h->line);
 					os_free(h->data);
 					os_free(h);
-				}
-				h = current_history();
-			} else {
-				h = next_history();
-			}
+				} else
+					next_history();
+			} else
+				next_history();
 		}
 		write_history(hfile);
 		os_free(hfile);

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.cpp Sat Jan 10 09:03:49 2009
@@ -44,6 +44,7 @@
 	connect(removeButton, SIGNAL(clicked()), this, SLOT(removeNetwork()));
 	connect(eapSelect, SIGNAL(activated(int)), this,
 		SLOT(eapChanged(int)));
+	connect(useWpsButton, SIGNAL(clicked()), this, SLOT(useWps()));
 
 	wpagui = NULL;
 	new_network = false;
@@ -98,6 +99,10 @@
 	wepEnabled(auth == AUTH_NONE && encr == 1);
 
 	getEapCapa();
+
+	if (flags.indexOf("[WPS") >= 0)
+		useWpsButton->setEnabled(true);
+	bssid = sel->text(1);
 }
 
 
@@ -273,7 +278,7 @@
 		setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
 	}
 	if (pskEdit->isEnabled() &&
-	    strcmp(passwordEdit->text().toAscii().constData(),
+	    strcmp(pskEdit->text().toAscii().constData(),
 		   WPA_GUI_KEY_DATA) != 0)
 		setNetworkParam(id, "psk",
 				pskEdit->text().toAscii().constData(),
@@ -646,7 +651,7 @@
 		if (strncmp(reply, "\"auth=", 6))
 			break;
 		if (strcmp(reply + 6, "GTC auth=MSCHAPV2") == 0) {
-			val = "GTC(auth) + MSCHAPv2(prov)";
+			val = (char *) "GTC(auth) + MSCHAPv2(prov)";
 			break;
 		}
 		val = reply + 2;
@@ -806,3 +811,13 @@
 	QStringList types = res.split(QChar(' '));
 	eapSelect->insertItems(-1, types);
 }
+
+
+void NetworkConfig::useWps()
+{
+	if (wpagui == NULL)
+		return;
+	wpagui->setBssFromScan(bssid);
+	wpagui->wpsDialog();
+	close();
+}

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.h Sat Jan 10 09:03:49 2009
@@ -43,6 +43,7 @@
 	virtual void writeWepKey(int network_id, QLineEdit *edit, int id);
 	virtual void removeNetwork();
 	virtual void eapChanged(int sel);
+	virtual void useWps();
 
 protected slots:
 	virtual void languageChange();
@@ -51,6 +52,7 @@
 	WpaGui *wpagui;
 	int edit_network_id;
 	bool new_network;
+	QString bssid;
 
 	virtual void wepEnabled(bool enabled);
 	virtual void getEapCapa();

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.ui
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.ui?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.ui (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/networkconfig.ui Sat Jan 10 09:03:49 2009
@@ -349,14 +349,14 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1" >
+   <item row="1" column="2" >
     <widget class="QPushButton" name="addButton" >
      <property name="text" >
       <string>Add</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="2" >
+   <item row="1" column="3" >
     <widget class="QPushButton" name="removeButton" >
      <property name="enabled" >
       <bool>false</bool>
@@ -378,6 +378,16 @@
       </size>
      </property>
     </spacer>
+   </item>
+   <item row="1" column="1" >
+    <widget class="QPushButton" name="useWpsButton" >
+     <property name="enabled" >
+      <bool>false</bool>
+     </property>
+     <property name="text" >
+      <string>WPS</string>
+     </property>
+    </widget>
    </item>
   </layout>
  </widget>

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpa_gui.pro Sat Jan 10 09:03:49 2009
@@ -15,6 +15,13 @@
   DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
   SOURCES += ../../src/utils/os_win32.c
   RESOURCES += icons_png.qrc
+} else:win32-x-g++ {
+  # cross compilation to win32
+  LIBS += -lws2_32 -static -mwindows
+  DEFINES += CONFIG_NATIVE_WINDOWS CONFIG_CTRL_IFACE_NAMED_PIPE
+  DEFINES += _X86_
+  SOURCES += ../../src/utils/os_win32.c
+  RESOURCES += icons_png.qrc
 } else {
   DEFINES += CONFIG_CTRL_IFACE_UNIX
   SOURCES += ../../src/utils/os_unix.c
@@ -27,7 +34,8 @@
 	eventhistory.h \
 	scanresults.h \
 	userdatarequest.h \
-	networkconfig.h
+	networkconfig.h \
+	addinterface.h
 
 SOURCES	+= main.cpp \
 	wpagui.cpp \
@@ -35,6 +43,7 @@
 	scanresults.cpp \
 	userdatarequest.cpp \
 	networkconfig.cpp \
+	addinterface.cpp \
 	../../src/common/wpa_ctrl.c
 
 RESOURCES += icons.qrc

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.cpp
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.cpp?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.cpp (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.cpp Sat Jan 10 09:03:49 2009
@@ -17,6 +17,10 @@
 #include <unistd.h>
 #endif
 
+#ifdef CONFIG_NATIVE_WINDOWS
+#include <windows.h>
+#endif /* CONFIG_NATIVE_WINDOWS */
+
 #include <cstdio>
 #include <QMessageBox>
 #include <QCloseEvent>
@@ -42,12 +46,37 @@
 {
 	setupUi(this);
 
+#ifdef CONFIG_NATIVE_WINDOWS
+	fileStopServiceAction = new QAction(this);
+	fileStopServiceAction->setObjectName("Stop Service");
+	fileStopServiceAction->setIconText("Stop Service");
+	fileMenu->insertAction(actionWPS, fileStopServiceAction);
+
+	fileStartServiceAction = new QAction(this);
+	fileStartServiceAction->setObjectName("Start Service");
+	fileStartServiceAction->setIconText("Start Service");
+	fileMenu->insertAction(fileStopServiceAction, fileStartServiceAction);
+
+	connect(fileStartServiceAction, SIGNAL(triggered()), this,
+		SLOT(startService()));
+	connect(fileStopServiceAction, SIGNAL(triggered()), this,
+		SLOT(stopService()));
+
+	addInterfaceAction = new QAction(this);
+	addInterfaceAction->setIconText("Add Interface");
+	fileMenu->insertAction(fileStartServiceAction, addInterfaceAction);
+
+	connect(addInterfaceAction, SIGNAL(triggered()), this,
+		SLOT(addInterface()));
+#endif /* CONFIG_NATIVE_WINDOWS */
+
 	(void) statusBar();
 
 	connect(fileEventHistoryAction, SIGNAL(triggered()), this,
 		SLOT(eventHistory()));
 	connect(fileSaveConfigAction, SIGNAL(triggered()), this,
 		SLOT(saveConfig()));
+	connect(actionWPS, SIGNAL(triggered()), this, SLOT(wpsDialog()));
 	connect(fileExitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
 	connect(networkAddAction, SIGNAL(triggered()), this,
 		SLOT(addNetwork()));
@@ -86,9 +115,17 @@
 	connect(scanNetworkButton, SIGNAL(clicked()), this, SLOT(scan()));
 	connect(networkList, SIGNAL(itemDoubleClicked(QListWidgetItem *)),
 		this, SLOT(editListedNetwork()));
+	connect(wpaguiTab, SIGNAL(currentChanged(int)), this,
+		SLOT(tabChanged(int)));
+	connect(wpsPbcButton, SIGNAL(clicked()), this, SLOT(wpsPbc()));
+	connect(wpsPinButton, SIGNAL(clicked()), this, SLOT(wpsGeneratePin()));
+	connect(wpsApPinEdit, SIGNAL(textChanged(const QString &)), this,
+		SLOT(wpsApPinChanged(const QString &)));
+	connect(wpsApPinButton, SIGNAL(clicked()), this, SLOT(wpsApPin()));
 
 	eh = NULL;
 	scanres = NULL;
+	add_iface = NULL;
 	udr = NULL;
 	tray_icon = NULL;
 	startInTray = false;
@@ -105,6 +142,7 @@
 	else
 		show();
 
+	connectedToService = false;
 	textStatus->setText("connecting to wpa_supplicant");
 	timer = new QTimer(this);
 	connect(timer, SIGNAL(timeout()), SLOT(ping()));
@@ -146,6 +184,12 @@
 		scanres->close();
 		delete scanres;
 		scanres = NULL;
+	}
+
+	if (add_iface) {
+		add_iface->close();
+		delete add_iface;
+		add_iface = NULL;
 	}
 
 	if (udr) {
@@ -250,6 +294,7 @@
 			ret = wpa_ctrl_request(ctrl, "INTERFACES", 10, buf,
 					       &len, NULL);
 			if (ret >= 0) {
+				connectedToService = true;
 				buf[len] = '\0';
 				pos = strchr(buf, '\n');
 				if (pos)
@@ -261,8 +306,22 @@
 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 	}
 
-	if (ctrl_iface == NULL)
+	if (ctrl_iface == NULL) {
+#ifdef CONFIG_NATIVE_WINDOWS
+		static bool first = true;
+		if (first && !serviceRunning()) {
+			first = false;
+			if (QMessageBox::warning(
+				    this, qAppName(),
+				    "wpa_supplicant service is not running.\n"
+				    "Do you want to start it?",
+				    QMessageBox::Yes | QMessageBox::No) ==
+			    QMessageBox::Yes)
+				startService();
+		}
+#endif /* CONFIG_NATIVE_WINDOWS */
 		return -1;
+	}
 
 #ifdef CONFIG_CTRL_IFACE_UNIX
 	flen = strlen(ctrl_iface_dir) + strlen(ctrl_iface) + 2;
@@ -340,6 +399,16 @@
 		}
 	}
 
+	len = sizeof(buf) - 1;
+	if (wpa_ctrl_request(ctrl_conn, "GET_CAPABILITY eap", 18, buf, &len,
+			     NULL) >= 0) {
+		buf[len] = '\0';
+
+		QString res(buf);
+		QStringList types = res.split(QChar(' '));
+		actionWPS->setEnabled(types.contains("WSC"));
+	}
+
 	return 0;
 }
 
@@ -385,6 +454,21 @@
 		textSsid->clear();
 		textBssid->clear();
 		textIpAddress->clear();
+
+#ifdef CONFIG_NATIVE_WINDOWS
+		static bool first = true;
+		if (first && connectedToService &&
+		    (ctrl_iface == NULL || *ctrl_iface == '\0')) {
+			first = false;
+			if (QMessageBox::information(
+				    this, qAppName(),
+				    "No network interfaces in use.\n"
+				    "Would you like to add one?",
+				    QMessageBox::Yes | QMessageBox::No) ==
+			    QMessageBox::Yes)
+				addInterface();
+		}
+#endif /* CONFIG_NATIVE_WINDOWS */
 		return;
 	}
 
@@ -599,6 +683,7 @@
 	char reply[10];
 	size_t reply_len = sizeof(reply);
 	ctrlRequest("DISCONNECT", reply, &reply_len);
+	stopWpsRun(false);
 }
 
 
@@ -679,6 +764,14 @@
 		updateStatus();
 		updateNetworks();
 	}
+
+#ifndef CONFIG_CTRL_IFACE_NAMED_PIPE
+	/* Use less frequent pings and status updates when the main window is
+	 * hidden (running in taskbar). */
+	int interval = isHidden() ? 5000 : 1000;
+	if (timer->interval() != interval)
+		timer->setInterval(interval);
+#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
 }
 
 
@@ -738,6 +831,49 @@
 		showTrayMessage(QSystemTrayIcon::Information, 3,
 				"Connection to network established.");
 		QTimer::singleShot(5 * 1000, this, SLOT(showTrayStatus()));
+		stopWpsRun(true);
+	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PBC)) {
+		showTrayMessage(QSystemTrayIcon::Information, 3,
+				"Wi-Fi Protected Setup (WPS) AP\n"
+				"in active PBC mode found.");
+		wpsStatusText->setText("WPS AP in active PBC mode found");
+		wpaguiTab->setCurrentWidget(wpsTab);
+		wpsInstructions->setText("Press the PBC button on the screen "
+					 "to start registration");
+	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE_PIN)) {
+		showTrayMessage(QSystemTrayIcon::Information, 3,
+				"Wi-Fi Protected Setup (WPS) AP\n"
+				" in active PIN mode found.");
+		wpsStatusText->setText("WPS AP with recently selected "
+				       "registrar");
+		wpaguiTab->setCurrentWidget(wpsTab);
+	} else if (str_match(pos, WPS_EVENT_AP_AVAILABLE)) {
+		showTrayMessage(QSystemTrayIcon::Information, 3,
+				"Wi-Fi Protected Setup (WPS)\n"
+				"AP detected.");
+		wpsStatusText->setText("WPS AP detected");
+		wpaguiTab->setCurrentWidget(wpsTab);
+	} else if (str_match(pos, WPS_EVENT_OVERLAP)) {
+		showTrayMessage(QSystemTrayIcon::Information, 3,
+				"Wi-Fi Protected Setup (WPS)\n"
+				"PBC mode overlap detected.");
+		wpsStatusText->setText("PBC mode overlap detected");
+		wpsInstructions->setText("More than one AP is currently in "
+					 "active WPS PBC mode. Wait couple of "
+					 "minutes and try again");
+		wpaguiTab->setCurrentWidget(wpsTab);
+	} else if (str_match(pos, WPS_EVENT_CRED_RECEIVED)) {
+		wpsStatusText->setText("Network configuration received");
+		wpaguiTab->setCurrentWidget(wpsTab);
+	} else if (str_match(pos, WPA_EVENT_EAP_METHOD)) {
+		if (strstr(pos, "(WSC)"))
+			wpsStatusText->setText("Registration started");
+	} else if (str_match(pos, WPS_EVENT_M2D)) {
+		wpsStatusText->setText("Registrar does not yet know PIN");
+	} else if (str_match(pos, WPS_EVENT_FAIL)) {
+		wpsStatusText->setText("Registration failed");
+	} else if (str_match(pos, WPS_EVENT_SUCCESS)) {
+		wpsStatusText->setText("Registration succeeded");
 	}
 }
 
@@ -804,6 +940,7 @@
 	cmd.prepend("SELECT_NETWORK ");
 	ctrlRequest(cmd.toAscii().constData(), reply, &reply_len);
 	triggerUpdate();
+	stopWpsRun(false);
 }
 
 
@@ -1275,3 +1412,254 @@
 
 	event->accept();
 }
+
+
+void WpaGui::wpsDialog()
+{
+	wpaguiTab->setCurrentWidget(wpsTab);
+}
+
+
+void WpaGui::tabChanged(int index)
+{
+	if (index != 2)
+		return;
+
+	if (wpsRunning)
+		return;
+
+	wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
+	if (bssFromScan.isEmpty())
+		wpsApPinButton->setEnabled(false);
+}
+
+
+void WpaGui::wpsPbc()
+{
+	char reply[20];
+	size_t reply_len = sizeof(reply);
+
+	if (ctrlRequest("WPS_PBC", reply, &reply_len) < 0)
+		return;
+
+	wpsPinEdit->setEnabled(false);
+	if (wpsStatusText->text().compare("WPS AP in active PBC mode found")) {
+		wpsInstructions->setText("Press the push button on the AP to "
+					 "start the PBC mode.");
+	} else {
+		wpsInstructions->setText("If you have not yet done so, press "
+					 "the push button on the AP to start "
+					 "the PBC mode.");
+	}
+	wpsStatusText->setText("Waiting for Registrar");
+	wpsRunning = true;
+}
+
+
+void WpaGui::wpsGeneratePin()
+{
+	char reply[20];
+	size_t reply_len = sizeof(reply) - 1;
+
+	if (ctrlRequest("WPS_PIN any", reply, &reply_len) < 0)
+		return;
+
+	reply[reply_len] = '\0';
+
+	wpsPinEdit->setText(reply);
+	wpsPinEdit->setEnabled(true);
+	wpsInstructions->setText("Enter the generated PIN into the Registrar "
+				 "(either the internal one in the AP or an "
+				 "external one).");
+	wpsStatusText->setText("Waiting for Registrar");
+	wpsRunning = true;
+}
+
+
+void WpaGui::setBssFromScan(const QString &bssid)
+{
+	bssFromScan = bssid;
+	wpsApPinEdit->setEnabled(!bssFromScan.isEmpty());
+	wpsApPinButton->setEnabled(wpsApPinEdit->text().length() == 8);
+	wpsStatusText->setText("WPS AP selected from scan results");
+	wpsInstructions->setText("If you want to use an AP device PIN, e.g., "
+				 "from a label in the device, enter the eight "
+				 "digit AP PIN and click Use AP PIN button.");
+}
+
+
+void WpaGui::wpsApPinChanged(const QString &text)
+{
+	wpsApPinButton->setEnabled(text.length() == 8);
+}
+
+
+void WpaGui::wpsApPin()
+{
+	char reply[20];
+	size_t reply_len = sizeof(reply);
+
+	QString cmd("WPS_REG " + bssFromScan + " " + wpsApPinEdit->text());
+	if (ctrlRequest(cmd.toAscii().constData(), reply, &reply_len) < 0)
+		return;
+
+	wpsStatusText->setText("Waiting for AP/Enrollee");
+	wpsRunning = true;
+}
+
+
+void WpaGui::stopWpsRun(bool success)
+{
+	if (wpsRunning)
+		wpsStatusText->setText(success ? "Connected to the network" :
+				       "Stopped");
+	else
+		wpsStatusText->setText("");
+	wpsPinEdit->setEnabled(false);
+	wpsInstructions->setText("");
+	wpsRunning = false;
+	bssFromScan = "";
+	wpsApPinEdit->setEnabled(false);
+	wpsApPinButton->setEnabled(false);
+}
+
+
+#ifdef CONFIG_NATIVE_WINDOWS
+
+#ifndef WPASVC_NAME
+#define WPASVC_NAME TEXT("wpasvc")
+#endif
+
+class ErrorMsg : public QMessageBox {
+public:
+	ErrorMsg(QWidget *parent, DWORD last_err = GetLastError());
+	void showMsg(QString msg);
+private:
+	DWORD err;
+};
+
+ErrorMsg::ErrorMsg(QWidget *parent, DWORD last_err) :
+	QMessageBox(parent), err(last_err)
+{
+	setWindowTitle("wpa_gui error");
+	setIcon(QMessageBox::Warning);
+}
+
+void ErrorMsg::showMsg(QString msg)
+{
+	LPTSTR buf;
+
+	setText(msg);
+	if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+			  FORMAT_MESSAGE_FROM_SYSTEM,
+			  NULL, err, 0, (LPTSTR) (void *) &buf,
+			  0, NULL) > 0) {
+		QString msg = QString::fromWCharArray(buf);
+		setInformativeText(QString("[%1] %2").arg(err).arg(msg));
+		LocalFree(buf);
+	} else {
+		setInformativeText(QString("[%1]").arg(err));
+	}
+
+	exec();
+}
+
+
+void WpaGui::startService()
+{
+	SC_HANDLE svc, scm;
+
+	scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+	if (!scm) {
+		ErrorMsg(this).showMsg("OpenSCManager failed");
+		return;
+	}
+
+	svc = OpenService(scm, WPASVC_NAME, SERVICE_START);
+	if (!svc) {
+		ErrorMsg(this).showMsg("OpenService failed");
+		CloseServiceHandle(scm);
+		return;
+	}
+
+	if (!StartService(svc, 0, NULL)) {
+		ErrorMsg(this).showMsg("Failed to start wpa_supplicant "
+				       "service");
+	}
+
+	CloseServiceHandle(svc);
+	CloseServiceHandle(scm);
+}
+
+
+void WpaGui::stopService()
+{
+	SC_HANDLE svc, scm;
+	SERVICE_STATUS status;
+
+	scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+	if (!scm) {
+		ErrorMsg(this).showMsg("OpenSCManager failed");
+		return;
+	}
+
+	svc = OpenService(scm, WPASVC_NAME, SERVICE_STOP);
+	if (!svc) {
+		ErrorMsg(this).showMsg("OpenService failed");
+		CloseServiceHandle(scm);
+		return;
+	}
+
+	if (!ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
+		ErrorMsg(this).showMsg("Failed to stop wpa_supplicant "
+				       "service");
+	}
+
+	CloseServiceHandle(svc);
+	CloseServiceHandle(scm);
+}
+
+
+bool WpaGui::serviceRunning()
+{
+	SC_HANDLE svc, scm;
+	SERVICE_STATUS status;
+	bool running = false;
+
+	scm = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
+	if (!scm) {
+		printf("OpenSCManager failed: %d\n", (int) GetLastError());
+		return false;
+	}
+
+	svc = OpenService(scm, WPASVC_NAME, SERVICE_QUERY_STATUS);
+	if (!svc) {
+		printf("OpenService failed: %d\n\n", (int) GetLastError());
+		CloseServiceHandle(scm);
+		return false;
+	}
+
+	if (QueryServiceStatus(svc, &status)) {
+		if (status.dwCurrentState != SERVICE_STOPPED)
+			running = true;
+	}
+
+	CloseServiceHandle(svc);
+	CloseServiceHandle(scm);
+
+	return running;
+}
+
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+
+void WpaGui::addInterface()
+{
+	if (add_iface) {
+		add_iface->close();
+		delete add_iface;
+	}
+	add_iface = new AddInterface(this, this);
+	add_iface->show();
+	add_iface->exec();
+}

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.h Sat Jan 10 09:03:49 2009
@@ -18,6 +18,7 @@
 #include <QSystemTrayIcon>
 #include <QObject>
 #include "ui_wpagui.h"
+#include "addinterface.h"
 
 class UserDataRequest;
 
@@ -38,6 +39,7 @@
 	virtual void enableNetwork(const QString &sel);
 	virtual void disableNetwork(const QString &sel);
 	virtual int getNetworkDisabled(const QString &sel);
+	void setBssFromScan(const QString &bssid);
 
 public slots:
 	virtual void parse_argv();
@@ -71,6 +73,17 @@
 	virtual void showTrayMessage(QSystemTrayIcon::MessageIcon type,
 				     int sec, const QString &msg);
 	virtual void showTrayStatus();
+	virtual void wpsDialog();
+	virtual void tabChanged(int index);
+	virtual void wpsPbc();
+	virtual void wpsGeneratePin();
+	virtual void wpsApPinChanged(const QString &text);
+	virtual void wpsApPin();
+#ifdef CONFIG_NATIVE_WINDOWS
+	virtual void startService();
+	virtual void stopService();
+#endif /* CONFIG_NATIVE_WINDOWS */
+	virtual void addInterface();
 
 protected slots:
 	virtual void languageChange();
@@ -105,6 +118,24 @@
 	bool startInTray;
 
 	int openCtrlConnection(const char *ifname);
+
+	bool wpsRunning;
+
+	QString bssFromScan;
+
+	void stopWpsRun(bool success);
+
+#ifdef CONFIG_NATIVE_WINDOWS
+	QAction *fileStartServiceAction;
+	QAction *fileStopServiceAction;
+
+	bool serviceRunning();
+#endif /* CONFIG_NATIVE_WINDOWS */
+
+	QAction *addInterfaceAction;
+	AddInterface *add_iface;
+
+	bool connectedToService;
 };
 
 #endif /* WPAGUI_H */

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.ui
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.ui?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.ui (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui-qt4/wpagui.ui Sat Jan 10 09:03:49 2009
@@ -289,6 +289,89 @@
         </item>
        </layout>
       </widget>
+      <widget class="QWidget" name="wpsTab" >
+       <attribute name="title" >
+        <string>WPS</string>
+       </attribute>
+       <layout class="QGridLayout" name="gridLayout" >
+        <item row="0" column="0" >
+         <widget class="QLabel" name="label_2" >
+          <property name="text" >
+           <string>Status:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1" colspan="3" >
+         <widget class="QLabel" name="wpsStatusText" >
+          <property name="text" >
+           <string/>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0" colspan="2" >
+         <widget class="QPushButton" name="wpsPbcButton" >
+          <property name="text" >
+           <string>PBC - push button</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0" colspan="2" >
+         <widget class="QPushButton" name="wpsPinButton" >
+          <property name="text" >
+           <string>Generate PIN</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="2" >
+         <widget class="QLabel" name="label" >
+          <property name="text" >
+           <string>PIN:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="3" >
+         <widget class="QLineEdit" name="wpsPinEdit" >
+          <property name="enabled" >
+           <bool>false</bool>
+          </property>
+          <property name="readOnly" >
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="0" colspan="2" >
+         <widget class="QPushButton" name="wpsApPinButton" >
+          <property name="enabled" >
+           <bool>false</bool>
+          </property>
+          <property name="text" >
+           <string>Use AP PIN</string>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="2" >
+         <widget class="QLabel" name="label_3" >
+          <property name="text" >
+           <string>AP PIN:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="3" >
+         <widget class="QLineEdit" name="wpsApPinEdit" >
+          <property name="enabled" >
+           <bool>false</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="0" colspan="4" >
+         <widget class="QTextEdit" name="wpsInstructions" >
+          <property name="readOnly" >
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
      </widget>
     </item>
    </layout>
@@ -308,6 +391,7 @@
     </property>
     <addaction name="fileEventHistoryAction" />
     <addaction name="fileSaveConfigAction" />
+    <addaction name="actionWPS" />
     <addaction name="separator" />
     <addaction name="fileExitAction" />
    </widget>
@@ -408,6 +492,14 @@
     <string>&amp;About</string>
    </property>
   </action>
+  <action name="actionWPS" >
+   <property name="enabled" >
+    <bool>false</bool>
+   </property>
+   <property name="text" >
+    <string>&amp;Wi-Fi Protected Setup</string>
+   </property>
+  </action>
  </widget>
  <layoutdefault spacing="6" margin="11" />
  <pixmapfunction></pixmapfunction>

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_gui/networkconfig.ui.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_gui/networkconfig.ui.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_gui/networkconfig.ui.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_gui/networkconfig.ui.h Sat Jan 10 09:03:49 2009
@@ -179,7 +179,7 @@
 	setNetworkParam(id, "group", "TKIP CCMP WEP104 WEP40", false);
     }
     if (pskEdit->isEnabled() &&
-	strcmp(passwordEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
+	strcmp(pskEdit->text().ascii(), WPA_GUI_KEY_DATA) != 0)
 	setNetworkParam(id, "psk", pskEdit->text().ascii(), psklen != 64);
     if (eapSelect->isEnabled())
 	setNetworkParam(id, "eap", eapSelect->currentText().ascii(), false);

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c Sat Jan 10 09:03:49 2009
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant
- * Copyright (c) 2003-2008, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2003-2009, 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
@@ -38,10 +38,11 @@
 #include "ieee802_11_defs.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
+#include "wps_supplicant.h"
 
 const char *wpa_supplicant_version =
 "wpa_supplicant v" VERSION_STR "\n"
-"Copyright (c) 2003-2008, Jouni Malinen <j at w1.fi> and contributors";
+"Copyright (c) 2003-2009, Jouni Malinen <j at w1.fi> and contributors";
 
 const char *wpa_supplicant_license =
 "This program is free software. You can distribute it and/or modify it\n"
@@ -107,8 +108,6 @@
 "\n";
 #endif /* CONFIG_NO_STDOUT_DEBUG */
 
-extern struct wpa_driver_ops *wpa_supplicant_drivers[];
-
 extern int wpa_debug_level;
 extern int wpa_debug_show_keys;
 extern int wpa_debug_timestamp;
@@ -251,10 +250,9 @@
 	struct eapol_config eapol_conf;
 	struct wpa_ssid *ssid = wpa_s->current_ssid;
 
-	if (wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
-		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
-		eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
-	}
+	eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
+	eapol_sm_notify_eap_fail(wpa_s->eapol, FALSE);
+
 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE ||
 	    wpa_s->key_mgmt == WPA_KEY_MGMT_WPA_NONE)
 		eapol_sm_notify_portControl(wpa_s->eapol, ForceAuthorized);
@@ -282,7 +280,8 @@
 	eapol_conf.workaround = ssid->eap_workaround;
 	eapol_conf.eap_disabled =
 		!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
-		wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA;
+		wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
+		wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
 	eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
 #endif /* IEEE8021X_EAPOL */
 }
@@ -302,7 +301,9 @@
 {
 	int i;
 
-	if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
+	if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
+		wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
+	else if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)
 		wpa_s->key_mgmt = WPA_KEY_MGMT_IEEE8021X_NO_WPA;
 	else
 		wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
@@ -382,6 +383,8 @@
 	wpa_supplicant_cancel_auth_timeout(wpa_s);
 
 	ieee80211_sta_deinit(wpa_s);
+
+	wpas_wps_deinit(wpa_s);
 }
 
 
@@ -635,6 +638,8 @@
 		return KEY_MGMT_802_1X_SHA256;
 	case WPA_KEY_MGMT_PSK_SHA256:
 		return KEY_MGMT_PSK_SHA256;
+	case WPA_KEY_MGMT_WPS:
+		return KEY_MGMT_WPS;
 	case WPA_KEY_MGMT_PSK:
 	default:
 		return KEY_MGMT_PSK;
@@ -927,6 +932,17 @@
 			wpa_ft_prepare_auth_request(wpa_s->wpa);
 		}
 #endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_WPS
+	} else if ((ssid->ssid == NULL || ssid->ssid_len == 0) &&
+		   wpa_s->conf->ap_scan == 2 &&
+		   (ssid->key_mgmt & WPA_KEY_MGMT_WPS)) {
+		/* Use ap_scan==1 style network selection to find the network
+		 */
+		wpa_s->scan_req = 2;
+		wpa_s->reassociate = 1;
+		wpa_supplicant_req_scan(wpa_s, 0, 0);
+		return;
+#endif /* CONFIG_WPS */
 	} else {
 		wpa_msg(wpa_s, MSG_INFO, "Trying to associate with SSID '%s'",
 			wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
@@ -1001,6 +1017,18 @@
 				   "results)");
 			return;
 		}
+#ifdef CONFIG_WPS
+	} else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
+		struct wpabuf *wps_ie;
+		wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
+		if (wps_ie && wpabuf_len(wps_ie) <= sizeof(wpa_ie)) {
+			wpa_ie_len = wpabuf_len(wps_ie);
+			os_memcpy(wpa_ie, wpabuf_head(wps_ie), wpa_ie_len);
+		} else
+			wpa_ie_len = 0;
+		wpabuf_free(wps_ie);
+		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
+#endif /* CONFIG_WPS */
 	} else {
 		wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
 		wpa_ie_len = 0;
@@ -1019,6 +1047,8 @@
 			wep_keys_set = 1;
 		}
 	}
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_WPS)
+		use_crypt = 0;
 
 #ifdef IEEE8021X_EAPOL
 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
@@ -1089,6 +1119,18 @@
 	case IEEE80211W_REQUIRED:
 		params.mgmt_frame_protection = MGMT_FRAME_PROTECTION_REQUIRED;
 		break;
+	}
+	if (ssid->ieee80211w != NO_IEEE80211W && bss) {
+		const u8 *rsn = wpa_scan_get_ie(bss, WLAN_EID_RSN);
+		struct wpa_ie_data ie;
+		if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie) == 0 &&
+		    ie.capabilities &
+		    (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
+			wpa_printf(MSG_DEBUG, "WPA: Selected AP supports MFP: "
+				   "require MFP");
+			params.mgmt_frame_protection =
+				MGMT_FRAME_PROTECTION_REQUIRED;
+		}
 	}
 #endif /* CONFIG_IEEE80211W */
 
@@ -1397,6 +1439,14 @@
 		    (!entry->bssid_set ||
 		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
 			return entry;
+#ifdef CONFIG_WPS
+		if (!entry->disabled &&
+		    (entry->key_mgmt & WPA_KEY_MGMT_WPS) &&
+		    (entry->ssid == NULL || entry->ssid_len == 0) &&
+		    (!entry->bssid_set ||
+		     os_memcmp(bssid, entry->bssid, ETH_ALEN) == 0))
+			return entry;
+#endif /* CONFIG_WPS */
 		entry = entry->next;
 	}
 
@@ -1458,7 +1508,8 @@
 		wpa_supplicant_req_auth_timeout(
 			wpa_s,
 			(wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||
-			 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) ?
+			 wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA ||
+			 wpa_s->key_mgmt == WPA_KEY_MGMT_WPS) ?
 			70 : 10, 0);
 	}
 	wpa_s->eapol_received++;
@@ -1769,7 +1820,16 @@
 	if (wpa_supplicant_driver_init(wpa_s) < 0)
 		return -1;
 
+	if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
+	    wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
+		wpa_printf(MSG_DEBUG, "Failed to set country");
+		return -1;
+	}
+
 	wpa_sm_set_own_addr(wpa_s->wpa, wpa_s->own_addr);
+
+	if (wpas_wps_init(wpa_s))
+		return -1;
 
 	if (wpa_supplicant_init_eapol(wpa_s) < 0)
 		return -1;
@@ -1950,7 +2010,7 @@
 struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
 {
 	struct wpa_global *global;
-	int ret;
+	int ret, i;
 
 	if (params == NULL)
 		return NULL;
@@ -2005,6 +2065,30 @@
 		}
 	}
 
+	for (i = 0; wpa_supplicant_drivers[i]; i++)
+		global->drv_count++;
+	if (global->drv_count == 0) {
+		wpa_printf(MSG_ERROR, "No drivers enabled");
+		wpa_supplicant_deinit(global);
+		return NULL;
+	}
+	global->drv_priv = os_zalloc(global->drv_count * sizeof(void *));
+	if (global->drv_priv == NULL) {
+		wpa_supplicant_deinit(global);
+		return NULL;
+	}
+	for (i = 0; wpa_supplicant_drivers[i]; i++) {
+		if (!wpa_supplicant_drivers[i]->global_init)
+			continue;
+		global->drv_priv[i] = wpa_supplicant_drivers[i]->global_init();
+		if (global->drv_priv[i] == NULL) {
+			wpa_printf(MSG_ERROR, "Failed to initialize driver "
+				   "'%s'", wpa_supplicant_drivers[i]->name);
+			wpa_supplicant_deinit(global);
+			return NULL;
+		}
+	}
+
 	return global;
 }
 
@@ -2051,6 +2135,8 @@
  */
 void wpa_supplicant_deinit(struct wpa_global *global)
 {
+	int i;
+
 	if (global == NULL)
 		return;
 
@@ -2064,6 +2150,13 @@
 
 	eap_peer_unregister_methods();
 
+	for (i = 0; wpa_supplicant_drivers[i]; i++) {
+		if (!global->drv_priv[i])
+			continue;
+		wpa_supplicant_drivers[i]->global_deinit(global->drv_priv[i]);
+	}
+	os_free(global->drv_priv);
+
 	eloop_destroy();
 
 	if (global->params.pid_file) {

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf Sat Jan 10 09:03:49 2009
@@ -135,12 +135,61 @@
 # in most cases.
 #driver_param="field=value"
 
+# Country code
+# The ISO/IEC alpha2 country code for the country in which this device is
+# currently operating.
+#country=US
+
 # Maximum lifetime for PMKSA in seconds; default 43200
 #dot11RSNAConfigPMKLifetime=43200
 # Threshold for reauthentication (percentage of PMK lifetime); default 70
 #dot11RSNAConfigPMKReauthThreshold=70
 # Timeout for security association negotiation in seconds; default 60
 #dot11RSNAConfigSATimeout=60
+
+# Wi-Fi Protected Setup (WPS) parameters
+
+# Universally Unique IDentifier (UUID; see RFC 4122) of the device
+# If not configured, UUID will be generated based on the local MAC address.
+#uuid=12345678-9abc-def0-1234-56789abcdef0
+
+# Device Name
+# User-friendly description of device; up to 32 octets encoded in UTF-8
+#device_name=Wireless Client
+
+# Manufacturer
+# The manufacturer of the device (up to 64 ASCII characters)
+#manufacturer=Company
+
+# Model Name
+# Model of the device (up to 32 ASCII characters)
+#model_name=cmodel
+
+# Model Number
+# Additional device description (up to 32 ASCII characters)
+#model_number=123
+
+# Serial Number
+# Serial number of the device (up to 32 characters)
+#serial_number=12345
+
+# Primary Device Type
+# Used format: <categ>-<OUI>-<subcateg>
+# categ = Category as an integer value
+# OUI = OUI and type octet as a 4-octet hex-encoded value; 0050F204 for
+#       default WPS OUI
+# subcateg = OUI-specific Sub Category as an integer value
+# Examples:
+#   1-0050F204-1 (Computer / PC)
+#   1-0050F204-2 (Computer / Server)
+#   5-0050F204-1 (Storage / NAS)
+#   6-0050F204-1 (Network Infrastructure / AP)
+#device_type=1-0050F204-1
+
+# OS Version
+# 4-octet operating system version number (hex string)
+#os_version=01020300
+
 
 # network block
 #
@@ -397,6 +446,8 @@
 #	 * 0 = do not use cryptobinding (default)
 #	 * 1 = use cryptobinding if server supports it
 #	 * 2 = require cryptobinding
+#	EAP-WSC (WPS) uses following options: pin=<Device Password> or
+#	pbc=1.
 # phase2: Phase2 (inner authentication with TLS tunnel) parameters
 #	(string with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or
 #	"autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS)

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h Sat Jan 10 09:03:49 2009
@@ -17,6 +17,19 @@
 
 #include "drivers/driver.h"
 
+extern const char *wpa_supplicant_version;
+extern const char *wpa_supplicant_license;
+#ifndef CONFIG_NO_STDOUT_DEBUG
+extern const char *wpa_supplicant_full_license1;
+extern const char *wpa_supplicant_full_license2;
+extern const char *wpa_supplicant_full_license3;
+extern const char *wpa_supplicant_full_license4;
+extern const char *wpa_supplicant_full_license5;
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+
+extern struct wpa_driver_ops *wpa_supplicant_drivers[];
+
+
 struct wpa_scan_result;
 struct wpa_sm;
 struct wpa_supplicant;
@@ -156,6 +169,8 @@
 	struct wpa_params params;
 	struct ctrl_iface_global_priv *ctrl_iface;
 	struct ctrl_iface_dbus_priv *dbus_ctrl_iface;
+	void **drv_priv;
+	size_t drv_count;
 };
 
 
@@ -338,6 +353,8 @@
 	int pending_mic_error_report;
 	int pending_mic_error_pairwise;
 	int mic_errors_seen; /* Michael MIC errors with the current PTK */
+
+	struct wps_context *wps;
 };
 
 
@@ -394,6 +411,8 @@
 static inline void * wpa_drv_init(struct wpa_supplicant *wpa_s,
 				  const char *ifname)
 {
+	if (wpa_s->driver->init2)
+		return wpa_s->driver->init2(wpa_s, ifname, wpa_s->global);
 	if (wpa_s->driver->init) {
 		return wpa_s->driver->init(wpa_s, ifname);
 	}
@@ -674,6 +693,14 @@
 	return -1;
 }
 
+static inline int wpa_drv_set_country(struct wpa_supplicant *wpa_s,
+				      const char *alpha2)
+{
+	if (wpa_s->driver->set_country)
+		return wpa_s->driver->set_country(wpa_s->drv_priv, alpha2);
+	return 0;
+}
+
 static inline int wpa_drv_send_mlme(struct wpa_supplicant *wpa_s,
 				    const u8 *data, size_t data_len)
 {

Modified: wpasupplicant/trunk/wpa_supplicant/wpas_glue.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpas_glue.c?rev=1305&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpas_glue.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpas_glue.c Sat Jan 10 09:03:49 2009
@@ -27,6 +27,7 @@
 #include "ieee802_11_defs.h"
 #include "wpa_ctrl.h"
 #include "wpas_glue.h"
+#include "wps_supplicant.h"
 
 
 #ifndef CONFIG_NO_CONFIG_BLOBS
@@ -228,6 +229,9 @@
 	wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully",
 		   success ? "" : "un");
 
+	if (wpas_wps_eapol_cb(wpa_s) > 0)
+		return;
+
 	if (!success) {
 		/*
 		 * Make sure we do not get stuck here waiting for long EAPOL
@@ -554,6 +558,7 @@
 	ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
 	ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
 #endif /* EAP_TLS_OPENSSL */
+	ctx->wps = wpa_s->wps;
 	ctx->eap_param_needed = wpa_supplicant_eap_param_needed;
 	ctx->cb = wpa_supplicant_eapol_cb;
 	ctx->cb_ctx = wpa_s;




More information about the Pkg-wpa-devel mailing list