[pkg-wpa-devel] r909 - in /wpasupplicant/branches/upstream/current: src/common/ src/crypto/ src/drivers/ src/eap_common/ src/eap_peer/ src/eap_server/ src/eapol_supp/ src/radius/ src/rsn_supp/ src/tls/ src/utils/ wpa_supplicant/ wpa_supplicant/doc/docbook/ wpa_supplicant/tests/ wpa_supplicant/vs2005/eapol_test/ wpa_supplicant/vs2005/wpa_supplicant/ wpa_supplicant/vs2005/wpasvc/

kelmo-guest at users.alioth.debian.org kelmo-guest at users.alioth.debian.org
Sun Dec 9 08:34:59 UTC 2007


Author: kelmo-guest
Date: Sun Dec  9 08:34:57 2007
New Revision: 909

URL: http://svn.debian.org/wsvn/?sc=1&rev=909
Log:
[svn-upgrade] Integrating new upstream version, wpasupplicant (0.6.1~git20071209)

Added:
    wpasupplicant/branches/upstream/current/src/common/eapol_common.h
    wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.c
    wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.h
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_wsc.c
    wpasupplicant/branches/upstream/current/src/eapol_supp/
    wpasupplicant/branches/upstream/current/src/eapol_supp/.gitignore
    wpasupplicant/branches/upstream/current/src/eapol_supp/Makefile
    wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c
    wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/config_blob.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/scan.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.h
Removed:
    wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_sm.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_sm.h
Modified:
    wpasupplicant/branches/upstream/current/src/common/version.h
    wpasupplicant/branches/upstream/current/src/common/wpa_common.h
    wpasupplicant/branches/upstream/current/src/crypto/aes.c
    wpasupplicant/branches/upstream/current/src/crypto/aes_wrap.c
    wpasupplicant/branches/upstream/current/src/crypto/crypto_gnutls.c
    wpasupplicant/branches/upstream/current/src/crypto/crypto_openssl.c
    wpasupplicant/branches/upstream/current/src/crypto/sha1.c
    wpasupplicant/branches/upstream/current/src/crypto/tls_openssl.c
    wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.c
    wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.h
    wpasupplicant/branches/upstream/current/src/drivers/driver_ndis.c
    wpasupplicant/branches/upstream/current/src/eap_common/eap_defs.h
    wpasupplicant/branches/upstream/current/src/eap_common/eap_gpsk_common.c
    wpasupplicant/branches/upstream/current/src/eap_common/eap_sim_common.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast_pac.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_gpsk.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_leap.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_methods.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_pax.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_peap.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_psk.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_sake.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_sim.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.h
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_tnc.c
    wpasupplicant/branches/upstream/current/src/eap_peer/eap_ttls.c
    wpasupplicant/branches/upstream/current/src/eap_peer/tncc.c
    wpasupplicant/branches/upstream/current/src/eap_peer/tncc.h
    wpasupplicant/branches/upstream/current/src/eap_server/eap.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap.h
    wpasupplicant/branches/upstream/current/src/eap_server/eap_aka.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_fast.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_gpsk.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_gtc.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_i.h
    wpasupplicant/branches/upstream/current/src/eap_server/eap_identity.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_md5.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.h
    wpasupplicant/branches/upstream/current/src/eap_server/eap_mschapv2.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_pax.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_peap.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_psk.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_sake.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_sim.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_sim_db.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_tls.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_tls_common.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_tlv.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_ttls.c
    wpasupplicant/branches/upstream/current/src/eap_server/eap_vendor_test.c
    wpasupplicant/branches/upstream/current/src/radius/radius_client.c
    wpasupplicant/branches/upstream/current/src/radius/radius_server.c
    wpasupplicant/branches/upstream/current/src/rsn_supp/peerkey.c
    wpasupplicant/branches/upstream/current/src/rsn_supp/pmksa_cache.c
    wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.c
    wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.h
    wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.c
    wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.h
    wpasupplicant/branches/upstream/current/src/rsn_supp/wpa_ft.c
    wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_read.c
    wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_write.c
    wpasupplicant/branches/upstream/current/src/utils/build_config.h
    wpasupplicant/branches/upstream/current/src/utils/common.h
    wpasupplicant/branches/upstream/current/src/utils/os.h
    wpasupplicant/branches/upstream/current/src/utils/os_unix.c
    wpasupplicant/branches/upstream/current/src/utils/os_win32.c
    wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog
    wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile
    wpasupplicant/branches/upstream/current/wpa_supplicant/README
    wpasupplicant/branches/upstream/current/wpa_supplicant/config.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/config.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/config_file.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/config_ssid.h
    wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_named_pipe.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_udp.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_unix.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig
    wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
    wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_test.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/events.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/main.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/nmake.mak
    wpasupplicant/branches/upstream/current/wpa_supplicant/preauth_test.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_wpa.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt
    wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
    wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
    wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c
    wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h

Added: wpasupplicant/branches/upstream/current/src/common/eapol_common.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/common/eapol_common.h?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/common/eapol_common.h (added)
+++ wpasupplicant/branches/upstream/current/src/common/eapol_common.h Sun Dec  9 08:34:57 2007
@@ -1,0 +1,47 @@
+/*
+ * EAPOL definitions shared between hostapd and wpa_supplicant
+ * Copyright (c) 2002-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef EAPOL_COMMON_H
+#define EAPOL_COMMON_H
+
+/* IEEE Std 802.1X-2004 */
+
+#ifdef _MSC_VER
+#pragma pack(push, 1)
+#endif /* _MSC_VER */
+
+struct ieee802_1x_hdr {
+	u8 version;
+	u8 type;
+	be16 length;
+	/* followed by length octets of data */
+} STRUCT_PACKED;
+
+#ifdef _MSC_VER
+#pragma pack(pop)
+#endif /* _MSC_VER */
+
+#define EAPOL_VERSION 2
+
+enum { IEEE802_1X_TYPE_EAP_PACKET = 0,
+       IEEE802_1X_TYPE_EAPOL_START = 1,
+       IEEE802_1X_TYPE_EAPOL_LOGOFF = 2,
+       IEEE802_1X_TYPE_EAPOL_KEY = 3,
+       IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT = 4
+};
+
+enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2,
+       EAPOL_KEY_TYPE_WPA = 254 };
+
+#endif /* EAPOL_COMMON_H */

Modified: wpasupplicant/branches/upstream/current/src/common/version.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/common/version.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/common/version.h (original)
+++ wpasupplicant/branches/upstream/current/src/common/version.h Sun Dec  9 08:34:57 2007
@@ -1,6 +1,6 @@
 #ifndef VERSION_H
 #define VERSION_H
 
-#define VERSION_STR "0.6.0"
+#define VERSION_STR "0.6.1"
 
 #endif /* VERSION_H */

Modified: wpasupplicant/branches/upstream/current/src/common/wpa_common.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/common/wpa_common.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/common/wpa_common.h (original)
+++ wpasupplicant/branches/upstream/current/src/common/wpa_common.h Sun Dec  9 08:34:57 2007
@@ -96,30 +96,9 @@
 #define RSN_NUM_REPLAY_COUNTERS_16 3
 
 
-/* IEEE Std 802.1X-2004 */
-
 #ifdef _MSC_VER
 #pragma pack(push, 1)
 #endif /* _MSC_VER */
-
-struct ieee802_1x_hdr {
-	u8 version;
-	u8 type;
-	be16 length;
-	/* followed by length octets of data */
-} STRUCT_PACKED;
-
-#define EAPOL_VERSION 2
-
-enum { IEEE802_1X_TYPE_EAP_PACKET = 0,
-       IEEE802_1X_TYPE_EAPOL_START = 1,
-       IEEE802_1X_TYPE_EAPOL_LOGOFF = 2,
-       IEEE802_1X_TYPE_EAPOL_KEY = 3,
-       IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT = 4
-};
-
-enum { EAPOL_KEY_TYPE_RC4 = 1, EAPOL_KEY_TYPE_RSN = 2,
-       EAPOL_KEY_TYPE_WPA = 254 };
 
 #ifdef CONFIG_IEEE80211W
 #define WPA_IGTK_LEN 16

Modified: wpasupplicant/branches/upstream/current/src/crypto/aes.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/crypto/aes.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/crypto/aes.c (original)
+++ wpasupplicant/branches/upstream/current/src/crypto/aes.c Sun Dec  9 08:34:57 2007
@@ -893,6 +893,7 @@
 	}
 }
 
+#ifndef CONFIG_NO_AES_DECRYPT
 /**
  * Expand the cipher key into the decryption key schedule.
  *
@@ -924,7 +925,9 @@
 		}
 	}
 }
-
+#endif /* CONFIG_NO_AES_DECRYPT */
+
+#ifndef CONFIG_NO_AES_ENCRYPT
 void rijndaelEncrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16])
 {
 	u32 s0, s1, s2, s3, t0, t1, t2, t3;
@@ -991,6 +994,7 @@
 	s3 = TE41(t3) ^ TE42(t0) ^ TE43(t1) ^ TE44(t2) ^ rk[3];
 	PUTU32(ct + 12, s3);
 }
+#endif /* CONFIG_NO_AES_ENCRYPT */
 
 void rijndaelDecrypt(const u32 rk[/*44*/], const u8 ct[16], u8 pt[16])
 {
@@ -1065,6 +1069,7 @@
 
 #define AES_PRIV_SIZE (4 * 44)
 
+#ifndef CONFIG_NO_AES_ENCRYPT
 void * aes_encrypt_init(const u8 *key, size_t len)
 {
 	u32 *rk;
@@ -1089,8 +1094,10 @@
 	os_memset(ctx, 0, AES_PRIV_SIZE);
 	os_free(ctx);
 }
-
-
+#endif /* CONFIG_NO_AES_ENCRYPT */
+
+
+#ifndef CONFIG_NO_AES_DECRYPT
 void * aes_decrypt_init(const u8 *key, size_t len)
 {
 	u32 *rk;
@@ -1115,5 +1122,6 @@
 	os_memset(ctx, 0, AES_PRIV_SIZE);
 	os_free(ctx);
 }
+#endif /* CONFIG_NO_AES_DECRYPT */
 
 #endif /* INTERNAL_AES */

Modified: wpasupplicant/branches/upstream/current/src/crypto/aes_wrap.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/crypto/aes_wrap.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/crypto/aes_wrap.c (original)
+++ wpasupplicant/branches/upstream/current/src/crypto/aes_wrap.c Sun Dec  9 08:34:57 2007
@@ -257,6 +257,7 @@
 #endif /* CONFIG_NO_AES_OMAC1 */
 
 
+#ifndef CONFIG_NO_AES_ENCRYPT_BLOCK
 /**
  * aes_128_encrypt_block - Perform one AES 128-bit block operation
  * @key: Key for AES
@@ -274,6 +275,7 @@
 	aes_encrypt_deinit(ctx);
 	return 0;
 }
+#endif /* CONFIG_NO_AES_ENCRYPT_BLOCK */
 
 
 #ifndef CONFIG_NO_AES_CTR

Modified: wpasupplicant/branches/upstream/current/src/crypto/crypto_gnutls.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/crypto/crypto_gnutls.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/crypto/crypto_gnutls.c (original)
+++ wpasupplicant/branches/upstream/current/src/crypto/crypto_gnutls.c Sun Dec  9 08:34:57 2007
@@ -92,11 +92,13 @@
 }
 
 
+#ifndef CONFIG_NO_FIPS186_2_PRF
 int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
 {
 	/* FIX: how to do this with libgcrypt? */
 	return -1;
 }
+#endif /* CONFIG_NO_FIPS186_2_PRF */
 
 
 void * aes_encrypt_init(const u8 *key, size_t len)

Modified: wpasupplicant/branches/upstream/current/src/crypto/crypto_openssl.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/crypto/crypto_openssl.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/crypto/crypto_openssl.c (original)
+++ wpasupplicant/branches/upstream/current/src/crypto/crypto_openssl.c Sun Dec  9 08:34:57 2007
@@ -100,6 +100,7 @@
 }
 
 
+#ifndef CONFIG_NO_FIPS186_2_PRF
 int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
 {
 	u8 xkey[64];
@@ -152,6 +153,7 @@
 
 	return 0;
 }
+#endif /* CONFIG_NO_FIPS186_2_PRF */
 
 
 void * aes_encrypt_init(const u8 *key, size_t len)

Modified: wpasupplicant/branches/upstream/current/src/crypto/sha1.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/crypto/sha1.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/crypto/sha1.c (original)
+++ wpasupplicant/branches/upstream/current/src/crypto/sha1.c Sun Dec  9 08:34:57 2007
@@ -155,6 +155,7 @@
 }
 
 
+#ifndef CONFIG_NO_T_PRF
 /**
  * sha1_t_prf - EAP-FAST Pseudo-Random Function (T-PRF)
  * @key: Key for PRF
@@ -207,8 +208,10 @@
 		len[0] = SHA1_MAC_LEN;
 	}
 }
-
-
+#endif /* CONFIG_NO_T_PRF */
+
+
+#ifndef CONFIG_NO_TLS_PRF
 /**
  * tls_prf - Pseudo-Random Function for TLS (TLS-PRF, RFC 2246)
  * @secret: Key for PRF
@@ -289,7 +292,10 @@
 
 	return 0;
 }
-
+#endif /* CONFIG_NO_TLS_PRF */
+
+
+#ifndef CONFIG_NO_PBKDF2
 
 static void pbkdf2_sha1_f(const char *passphrase, const char *ssid,
 			  size_t ssid_len, int iterations, unsigned int count,
@@ -362,6 +368,8 @@
 	}
 }
 
+#endif /* CONFIG_NO_PBKDF2 */
+
 
 #ifdef INTERNAL_SHA1
 
@@ -401,6 +409,7 @@
 }
 
 
+#ifndef CONFIG_NO_FIPS186_2_PRF
 int fips186_2_prf(const u8 *seed, size_t seed_len, u8 *x, size_t xlen)
 {
 	u8 xkey[64];
@@ -453,6 +462,7 @@
 
 	return 0;
 }
+#endif /* CONFIG_NO_FIPS186_2_PRF */
 
 
 /* ===== start - public domain SHA1 implementation ===== */

Modified: wpasupplicant/branches/upstream/current/src/crypto/tls_openssl.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/crypto/tls_openssl.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/crypto/tls_openssl.c (original)
+++ wpasupplicant/branches/upstream/current/src/crypto/tls_openssl.c Sun Dec  9 08:34:57 2007
@@ -1100,6 +1100,18 @@
 				  size_t ca_cert_blob_len, const char *ca_path)
 {
 	SSL_CTX *ssl_ctx = _ssl_ctx;
+
+	/*
+	 * Remove previously configured trusted CA certificates before adding
+	 * new ones.
+	 */
+	X509_STORE_free(ssl_ctx->cert_store);
+	ssl_ctx->cert_store = X509_STORE_new();
+	if (ssl_ctx->cert_store == NULL) {
+		wpa_printf(MSG_DEBUG, "OpenSSL: %s - failed to allocate new "
+			   "certificate store", __func__);
+		return -1;
+	}
 
 	if (ca_cert_blob) {
 		X509 *cert = d2i_X509(NULL, (OPENSSL_d2i_TYPE) &ca_cert_blob,

Modified: wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.c (original)
+++ wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.c Sun Dec  9 08:34:57 2007
@@ -102,35 +102,35 @@
 
 
 static int (*__Apple80211Associate)(Apple80211Ref handle, CFDictionaryRef bss,
-				    CFStringRef arg) = NULL;
+				    CFStringRef password) = NULL;
 
 int Apple80211Associate(Apple80211Ref handle, CFDictionaryRef bss,
-			CFStringRef arg)
+			CFStringRef password)
 {
-	return __Apple80211Associate(handle, bss, arg);
+	return __Apple80211Associate(handle, bss, password);
 }
 
 
 static int (*__Apple80211AssociateAndCopyInfo)(Apple80211Ref handle,
 					       CFDictionaryRef bss,
-					       CFStringRef arg,
+					       CFStringRef password,
 					       CFDictionaryRef *info) =
 	NULL;
 
 int Apple80211AssociateAndCopyInfo(Apple80211Ref handle, CFDictionaryRef bss,
-				   CFStringRef arg, CFDictionaryRef *info)
+				   CFStringRef password, CFDictionaryRef *info)
 {
-	return __Apple80211AssociateAndCopyInfo(handle, bss, arg, info);
+	return __Apple80211AssociateAndCopyInfo(handle, bss, password, info);
 }
 
 
 static int (*__Apple80211CopyValue)(Apple80211Ref handle, int field,
-				    int unused, void *value) = NULL;
+				    CFDictionaryRef arg2, void *value) = NULL;
 
-int Apple80211CopyValue(Apple80211Ref handle, int field, int unused,
+int Apple80211CopyValue(Apple80211Ref handle, int field, CFDictionaryRef arg2,
 			void *value)
 {
-	return __Apple80211CopyValue(handle, field, unused, value);
+	return __Apple80211CopyValue(handle, field, arg2, value);
 }
 
 

Modified: wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.h (original)
+++ wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.h Sun Dec  9 08:34:57 2007
@@ -27,16 +27,17 @@
 		   CFDictionaryRef parameters);
 
 int Apple80211Associate(Apple80211Ref handle, CFDictionaryRef bss,
-			CFStringRef arg);
+			CFStringRef password);
 int Apple80211AssociateAndCopyInfo(Apple80211Ref handle, CFDictionaryRef bss,
-				   CFStringRef arg, CFDictionaryRef *info);
+				   CFStringRef password,
+				   CFDictionaryRef *info);
 
 enum {
 	APPLE80211_VALUE_SSID = 1,
 	APPLE80211_VALUE_BSSID = 9
 };
 
-int Apple80211CopyValue(Apple80211Ref handle, int field, int unused,
+int Apple80211CopyValue(Apple80211Ref handle, int field, CFDictionaryRef arg2,
 			void *value);
 
 #endif /* MOBILEAPPLE80211_H */

Modified: wpasupplicant/branches/upstream/current/src/drivers/driver_ndis.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/drivers/driver_ndis.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/drivers/driver_ndis.c (original)
+++ wpasupplicant/branches/upstream/current/src/drivers/driver_ndis.c Sun Dec  9 08:34:57 2007
@@ -1174,7 +1174,6 @@
 
 	entry = drv->pmkid;
 	prev = NULL;
-	drv->pmkid = NULL;
 	while (entry) {
 		if (os_memcmp(entry->bssid, bssid, ETH_ALEN) == 0 &&
 		    os_memcmp(entry->pmkid, pmkid, 16) == 0) {

Modified: wpasupplicant/branches/upstream/current/src/eap_common/eap_defs.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_common/eap_defs.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_common/eap_defs.h (original)
+++ wpasupplicant/branches/upstream/current/src/eap_common/eap_defs.h Sun Dec  9 08:34:57 2007
@@ -69,7 +69,8 @@
 
 /* SMI Network Management Private Enterprise Code for vendor specific types */
 enum {
-	EAP_VENDOR_IETF = 0
+	EAP_VENDOR_IETF = 0,
+	EAP_VENDOR_WFA = 0x00372A /* Wi-Fi Alliance */
 };
 
 #define EAP_MSK_LEN 64

Modified: wpasupplicant/branches/upstream/current/src/eap_common/eap_gpsk_common.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_common/eap_gpsk_common.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_common/eap_gpsk_common.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_common/eap_gpsk_common.c Sun Dec  9 08:34:57 2007
@@ -120,7 +120,7 @@
 				       u8 *sk, size_t sk_len,
 				       u8 *pk, size_t pk_len)
 {
-	u8 zero[32], mk[32], *pos, *data;
+	u8 mk[32], *pos, *data;
 	size_t data_len, mk_len;
 	int (*gkdf)(const u8 *psk, const u8 *data, size_t data_len,
 		    u8 *buf, size_t len);
@@ -141,7 +141,8 @@
 		return -1;
 	}
 
-	os_memset(zero, 0, sizeof(zero));
+	if (psk_len < mk_len)
+		return -1;
 
 	data_len = 2 + psk_len + 6 + seed_len;
 	data = os_malloc(data_len);
@@ -160,7 +161,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation",
 			data, data_len);
 
-	if (gkdf(zero, data, data_len, mk, mk_len) < 0) {
+	if (gkdf(psk, data, data_len, mk, mk_len) < 0) {
 		os_free(data);
 		return -1;
 	}
@@ -206,12 +207,12 @@
 	 * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
 	 *            (= seed)
 	 * KS = 16, PL = psk_len, CSuite_Sel = 0x00000000 0x0001
-	 * zero = 0x00 || 0x00 || ... || 0x00 (16 times)
-	 * MK = GKDF-16 (zero, PL || PSK || CSuite_Sel || inputString)
+	 * MK = GKDF-16 (PSK[0..15], PL || PSK || CSuite_Sel || inputString)
 	 * MSK = GKDF-160 (MK, inputString)[0..63]
 	 * EMSK = GKDF-160 (MK, inputString)[64..127]
 	 * SK = GKDF-160 (MK, inputString)[128..143]
 	 * PK = GKDF-160 (MK, inputString)[144..159]
+	 * zero = 0x00 || 0x00 || ... || 0x00 (16 times)
 	 * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
 	 *                      CSuite_Sel || inputString)
 	 */
@@ -242,11 +243,11 @@
 	 * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
 	 *            (= seed)
 	 * KS = 32, PL = psk_len, CSuite_Sel = 0x00000000 0x0002
-	 * zero = 0x00 || 0x00 || ... || 0x00 (32 times)
-	 * MK = GKDF-32 (zero, PL || PSK || CSuite_Sel || inputString)
+	 * MK = GKDF-32 (PSK[0..31], PL || PSK || CSuite_Sel || inputString)
 	 * MSK = GKDF-160 (MK, inputString)[0..63]
 	 * EMSK = GKDF-160 (MK, inputString)[64..127]
 	 * SK = GKDF-160 (MK, inputString)[128..159]
+	 * zero = 0x00 || 0x00 || ... || 0x00 (32 times)
 	 * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
 	 *                      CSuite_Sel || inputString)
 	 */

Modified: wpasupplicant/branches/upstream/current/src/eap_common/eap_sim_common.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_common/eap_sim_common.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_common/eap_sim_common.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_common/eap_sim_common.c Sun Dec  9 08:34:57 2007
@@ -747,7 +747,7 @@
 	if (pos == NULL)
 		return -1;
 	msg->iv = (pos - msg->buf) + 4;
-	if (hostapd_get_rand(msg->buf + msg->iv, EAP_SIM_IV_LEN)) {
+	if (os_get_random(msg->buf + msg->iv, EAP_SIM_IV_LEN)) {
 		msg->iv = 0;
 		return -1;
 	}

Added: wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.c (added)
+++ wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,40 @@
+/*
+ * EAP-WSC common routines for Wi-Fi Protected Setup
+ * Copyright (c) 2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eap_defs.h"
+#include "eap_common.h"
+#include "eap_wsc_common.h"
+
+u8 * eap_wsc_build_frag_ack(u8 id, u8 code, size_t *len)
+{
+	struct eap_hdr *msg;
+	u8 *pos;
+
+	msg = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, len, 2, code,
+			    id, &pos);
+	if (msg == NULL) {
+		wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for "
+			   "FRAG_ACK");
+		return NULL;
+	}
+
+	wpa_printf(MSG_DEBUG, "EAP-WSC: Send WSC/FRAG_ACK");
+	*pos++ = WSC_FRAG_ACK; /* Op-Code */
+	*pos = 0; /* Flags */
+
+	return (u8 *) msg;
+}

Added: wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.h?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.h (added)
+++ wpasupplicant/branches/upstream/current/src/eap_common/eap_wsc_common.h Sun Dec  9 08:34:57 2007
@@ -1,0 +1,42 @@
+/*
+ * EAP-WSC definitions for Wi-Fi Protected Setup
+ * Copyright (c) 2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef EAP_WSC_COMMON_H
+#define EAP_WSC_COMMON_H
+
+#define EAP_VENDOR_TYPE_WSC 1
+
+enum wsc_op_code {
+	WSC_Start = 0x01,
+	WSC_ACK = 0x02,
+	WSC_NACK = 0x03,
+	WSC_MSG = 0x04,
+	WSC_Done = 0x05,
+	WSC_FRAG_ACK = 0x06
+};
+
+#define WSC_FLAGS_MF 0x01
+#define WSC_FLAGS_LF 0x02
+
+#define WSC_ID_REGISTRAR "WFA-SimpleConfig-Registrar-1-0"
+#define WSC_ID_REGISTRAR_LEN 30
+#define WSC_ID_ENROLLEE "WFA-SimpleConfig-Enrollee-1-0"
+#define WSC_ID_ENROLLEE_LEN 29
+
+#define WSC_FRAGMENT_SIZE 1400
+
+
+u8 * eap_wsc_build_frag_ack(u8 id, u8 code, size_t *len);
+
+#endif /* EAP_WSC_COMMON_H */

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap.c Sun Dec  9 08:34:57 2007
@@ -94,6 +94,32 @@
 	sm->m->deinit(sm, sm->eap_method_priv);
 	sm->eap_method_priv = NULL;
 	sm->m = NULL;
+}
+
+
+/**
+ * eap_allowed_method - Check whether EAP method is allowed
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+ * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
+ * @method: EAP type
+ * Returns: 1 = allowed EAP method, 0 = not allowed
+ */
+static int eap_allowed_method(struct eap_sm *sm, int vendor, u32 method)
+{
+	struct wpa_ssid *config = eap_get_config(sm);
+	int i;
+	struct eap_method_type *m;
+
+	if (config == NULL || config->eap_methods == NULL)
+		return 1;
+
+	m = config->eap_methods;
+	for (i = 0; m[i].vendor != EAP_VENDOR_IETF ||
+		     m[i].method != EAP_TYPE_NONE; i++) {
+		if (m[i].vendor == vendor && m[i].method == method)
+			return 1;
+	}
+	return 0;
 }
 
 
@@ -719,9 +745,7 @@
 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor,
 				  EapType method)
 {
-	struct wpa_ssid *config = eap_get_config(sm);
-
-	if (!wpa_config_allowed_eap_method(config, vendor, method)) {
+	if (!eap_allowed_method(sm, vendor, method)) {
 		wpa_printf(MSG_DEBUG, "EAP: configuration does not allow: "
 			   "vendor %u method %u", vendor, method);
 		return FALSE;
@@ -738,7 +762,6 @@
 				      const struct eap_method *methods,
 				      size_t count)
 {
-	struct wpa_ssid *config = eap_get_config(sm);
 	struct eap_hdr *resp;
 	u8 *pos;
 	int found = 0;
@@ -765,8 +788,7 @@
 		if (sm->reqVendor == m->vendor &&
 		    sm->reqVendorMethod == m->method)
 			continue; /* do not allow the current method again */
-		if (wpa_config_allowed_eap_method(config, m->vendor,
-						  m->method)) {
+		if (eap_allowed_method(sm, m->vendor, m->method)) {
 			wpa_printf(MSG_DEBUG, "EAP: allowed type: "
 				   "vendor=%u method=%u",
 				   m->vendor, m->method);
@@ -799,7 +821,6 @@
 
 static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len)
 {
-	struct wpa_ssid *config = eap_get_config(sm);
 	struct eap_hdr *resp;
 	u8 *pos;
 	int found = 0, expanded_found = 0;
@@ -829,8 +850,7 @@
 	for (m = methods; m; m = m->next) {
 		if (m->vendor == EAP_VENDOR_IETF && m->method == sm->reqMethod)
 			continue; /* do not allow the current method again */
-		if (wpa_config_allowed_eap_method(config, m->vendor,
-						  m->method)) {
+		if (eap_allowed_method(sm, m->vendor, m->method)) {
 			if (m->vendor != EAP_VENDOR_IETF) {
 				if (expanded_found)
 					continue;
@@ -1993,7 +2013,9 @@
  */
 void eap_set_config_blob(struct eap_sm *sm, struct wpa_config_blob *blob)
 {
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	sm->eapol_cb->set_config_blob(sm->eapol_ctx, blob);
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 }
 
 
@@ -2006,7 +2028,11 @@
 const struct wpa_config_blob * eap_get_config_blob(struct eap_sm *sm,
 						   const char *name)
 {
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	return sm->eapol_cb->get_config_blob(sm->eapol_ctx, name);
+#else /* CONFIG_NO_CONFIG_BLOBS */
+	return NULL;
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 }
 
 

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast.c Sun Dec  9 08:34:57 2007
@@ -1733,8 +1733,7 @@
 
 	if (res == 1) {
 		os_free(resp);
-		return eap_peer_tls_build_ack(&data->ssl, respDataLen, id,
-					      EAP_TYPE_FAST,
+		return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_FAST,
 					      data->fast_version);
 	}
 

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast_pac.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast_pac.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast_pac.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_fast_pac.c Sun Dec  9 08:34:57 2007
@@ -15,7 +15,8 @@
 #include "includes.h"
 
 #include "common.h"
-#include "config.h"
+#include "config_blob.h"
+#include "config_ssid.h"
 #include "eap_i.h"
 #include "eap_fast_pac.h"
 
@@ -280,7 +281,7 @@
 		rc->pos = (char *) blob->data;
 		rc->end = (char *) blob->data + blob->len;
 	} else {
-		rc->f = fopen(pac_file, "r");
+		rc->f = fopen(pac_file, "rb");
 		if (rc->f == NULL) {
 			wpa_printf(MSG_INFO, "EAP-FAST: No PAC file '%s' - "
 				   "assume no PAC entries have been "
@@ -549,7 +550,7 @@
 		eap_set_config_blob(sm, blob);
 	} else {
 		FILE *f;
-		f = fopen(pac_file, "w");
+		f = fopen(pac_file, "wb");
 		if (f == NULL) {
 			wpa_printf(MSG_INFO, "EAP-FAST: Failed to open PAC "
 				   "file '%s' for writing", pac_file);

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_gpsk.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_gpsk.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_gpsk.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_gpsk.c Sun Dec  9 08:34:57 2007
@@ -1,5 +1,5 @@
 /*
- * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-06.txt)
+ * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt)
  * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -429,6 +429,45 @@
 }
 
 
+const u8 * eap_gpsk_validate_id_server(struct eap_gpsk_data *data,
+				       const u8 *pos, const u8 *end)
+{
+	size_t len;
+
+	if (pos == NULL)
+		return NULL;
+
+	if (end - pos < (int) 2) {
+		wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
+			   "length(ID_Server)");
+		return NULL;
+	}
+
+	len = WPA_GET_BE16(pos);
+	pos += 2;
+
+	if (end - pos < (int) len) {
+		wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for "
+			   "ID_Server");
+		return NULL;
+	}
+
+	if (len != data->id_server_len ||
+	    os_memcmp(pos, data->id_server, len) != 0) {
+		wpa_printf(MSG_INFO, "EAP-GPSK: ID_Server did not match with "
+			   "the one used in GPSK-1");
+		wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1",
+				  data->id_server, data->id_server_len);
+		wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-3",
+				  pos, len);
+	}
+
+	pos += len;
+
+	return pos;
+}
+
+
 const u8 * eap_gpsk_validate_csuite(struct eap_gpsk_data *data, const u8 *pos,
 				    const u8 *end)
 {
@@ -540,6 +579,7 @@
 	end = payload + payload_len;
 
 	pos = eap_gpsk_validate_rand(data, payload, end);
+	pos = eap_gpsk_validate_id_server(data, pos, end);
 	pos = eap_gpsk_validate_csuite(data, pos, end);
 	pos = eap_gpsk_validate_pd_payload_2(data, pos, end);
 	pos = eap_gpsk_validate_gpsk_3_mic(data, payload, pos, end);

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_leap.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_leap.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_leap.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_leap.c Sun Dec  9 08:34:57 2007
@@ -174,7 +174,7 @@
 	*pos++ = LEAP_VERSION;
 	*pos++ = 0; /* unused */
 	*pos++ = LEAP_CHALLENGE_LEN;
-	if (hostapd_get_rand(pos, LEAP_CHALLENGE_LEN)) {
+	if (os_get_random(pos, LEAP_CHALLENGE_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-LEAP: Failed to read random data "
 			   "for challenge");
 		os_free(resp);

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_methods.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_methods.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_methods.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_methods.c Sun Dec  9 08:34:57 2007
@@ -455,6 +455,13 @@
 	}
 #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_VENDOR_TEST
 	if (ret == 0) {
 		int eap_peer_vendor_test_register(void);

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_pax.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_pax.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_pax.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_pax.c Sun Dec  9 08:34:57 2007
@@ -187,7 +187,7 @@
 			    pos, left);
 	}
 
-	if (hostapd_get_rand(data->rand.r.y, EAP_PAX_RAND_LEN)) {
+	if (os_get_random(data->rand.r.y, EAP_PAX_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data");
 		ret->ignore = TRUE;
 		return NULL;

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_peap.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_peap.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_peap.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_peap.c Sun Dec  9 08:34:57 2007
@@ -619,8 +619,7 @@
 
 	if (res == 1) {
 		os_free(resp);
-		return eap_peer_tls_build_ack(&data->ssl, respDataLen, id,
-					      EAP_TYPE_PEAP,
+		return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_PEAP,
 					      data->peap_version);
 	}
 

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_psk.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_psk.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_psk.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_psk.c Sun Dec  9 08:34:57 2007
@@ -125,7 +125,7 @@
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_S",
 			  data->id_s, data->id_s_len);
 
-	if (hostapd_get_rand(data->rand_p, EAP_PSK_RAND_LEN)) {
+	if (os_get_random(data->rand_p, EAP_PSK_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
 		ret->ignore = TRUE;
 		return NULL;

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_sake.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_sake.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_sake.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_sake.c Sun Dec  9 08:34:57 2007
@@ -233,7 +233,7 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)",
 		    data->rand_s, EAP_SAKE_RAND_LEN);
 
-	if (hostapd_get_rand(data->rand_p, EAP_SAKE_RAND_LEN)) {
+	if (os_get_random(data->rand_p, EAP_SAKE_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data");
 		return NULL;
 	}

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_sim.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_sim.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_sim.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_sim.c Sun Dec  9 08:34:57 2007
@@ -59,7 +59,7 @@
 	if (data == NULL)
 		return NULL;
 
-	if (hostapd_get_rand(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
+	if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
 			   "for NONCE_MT");
 		os_free(data);
@@ -895,7 +895,7 @@
 static void * eap_sim_init_for_reauth(struct eap_sm *sm, void *priv)
 {
 	struct eap_sim_data *data = priv;
-	if (hostapd_get_rand(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
+	if (os_get_random(data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to get random data "
 			   "for NONCE_MT");
 		os_free(data);

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls.c Sun Dec  9 08:34:57 2007
@@ -109,8 +109,7 @@
 		return resp;
 	}
 
-	return eap_peer_tls_build_ack(&data->ssl, respDataLen, id,
-				      EAP_TYPE_TLS, 0);
+	return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_TLS, 0);
 }
 
 
@@ -178,8 +177,8 @@
 
 	if (res == 1) {
 		os_free(resp);
-		return eap_peer_tls_build_ack(&data->ssl, respDataLen, id,
-					      EAP_TYPE_TLS, 0);
+		return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_TLS,
+					      0);
 	}
 
 	return resp;

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.c Sun Dec  9 08:34:57 2007
@@ -17,10 +17,10 @@
 #include "common.h"
 #include "eap_i.h"
 #include "eap_tls_common.h"
+#include "config_blob.h"
 #include "config_ssid.h"
 #include "sha1.h"
 #include "tls.h"
-#include "config.h"
 
 
 static int eap_tls_check_blob(struct eap_sm *sm, const char **name,
@@ -623,15 +623,14 @@
 
 /**
  * eap_peer_tls_build_ack - Build a TLS ACK frame
- * @data: Data for TLS processing
  * @respDataLen: Buffer for returning the length of the response message
  * @id: EAP identifier for the response
  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
  * @peap_version: Version number for EAP-PEAP/TTLS
  * Returns: Pointer to the allocated ACK frame or %NULL on failure
  */
-u8 * eap_peer_tls_build_ack(struct eap_ssl_data *data, size_t *respDataLen,
-			    u8 id, EapType eap_type, int peap_version)
+u8 * eap_peer_tls_build_ack(size_t *respDataLen, u8 id, EapType eap_type,
+			    int peap_version)
 {
 	struct eap_hdr *resp;
 	u8 *pos;

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.h (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_tls_common.h Sun Dec  9 08:34:57 2007
@@ -109,8 +109,8 @@
 				EapType eap_type, int peap_version,
 				u8 id, const u8 *in_data, size_t in_len,
 				u8 **out_data, size_t *out_len);
-u8 * eap_peer_tls_build_ack(struct eap_ssl_data *data, size_t *respDataLen,
-			    u8 id, EapType eap_type, int peap_version);
+u8 * eap_peer_tls_build_ack(size_t *respDataLen, u8 id, EapType eap_type,
+			    int peap_version);
 int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data);
 int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
 			char *buf, size_t buflen, int verbose);

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_tnc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_tnc.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_tnc.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_tnc.c Sun Dec  9 08:34:57 2007
@@ -76,6 +76,7 @@
 	size_t imc_len;
 	char *start_buf, *end_buf;
 	size_t start_len, end_len;
+	int tncs_done = 0;
 
 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TNC,
 			       reqData, reqDataLen, &len);
@@ -87,7 +88,6 @@
 	}
 
 	req = (const struct eap_hdr *) reqData;
-	wpa_hexdump(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
 
 	if ((*pos & EAP_TNC_VERSION_MASK) != EAP_TNC_VERSION) {
@@ -109,6 +109,8 @@
 
 		data->state = METHOD_MAY_CONT;
 	} else {
+		enum tncc_process_res res;
+
 		if (*pos & EAP_TNC_FLAGS_START) {
 			wpa_printf(MSG_DEBUG, "EAP-TNC: Server used start "
 				   "flag again");
@@ -116,9 +118,31 @@
 			return NULL;
 		}
 
-		if (tncc_process_if_tnccs(data->tncc, pos + 1, len - 1)) {
+		res = tncc_process_if_tnccs(data->tncc, pos + 1, len - 1);
+		switch (res) {
+		case TNCCS_PROCESS_ERROR:
 			ret->ignore = TRUE;
 			return NULL;
+		case TNCCS_PROCESS_OK_NO_RECOMMENDATION:
+		case TNCCS_RECOMMENDATION_ERROR:
+			wpa_printf(MSG_DEBUG, "EAP-TNC: No "
+				   "TNCCS-Recommendation received");
+			break;
+		case TNCCS_RECOMMENDATION_ALLOW:
+			wpa_msg(sm->msg_ctx, MSG_INFO,
+				"TNC: Recommendation = allow");
+			tncs_done = 1;
+			break;
+		case TNCCS_RECOMMENDATION_NONE:
+			wpa_msg(sm->msg_ctx, MSG_INFO,
+				"TNC: Recommendation = none");
+			tncs_done = 1;
+			break;
+		case TNCCS_RECOMMENDATION_ISOLATE:
+			wpa_msg(sm->msg_ctx, MSG_INFO,
+				"TNC: Recommendation = isolate");
+			tncs_done = 1;
+			break;
 		}
 	}
 
@@ -126,6 +150,19 @@
 	ret->methodState = data->state;
 	ret->decision = DECISION_UNCOND_SUCC;
 	ret->allowNotifications = TRUE;
+
+	if (tncs_done) {
+		resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC,
+				     respDataLen, 1, EAP_CODE_RESPONSE,
+				     req->identifier, &rpos);
+		if (resp == NULL)
+			return NULL;
+
+		*rpos = EAP_TNC_VERSION;
+		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS done - reply with an "
+			   "empty ACK message");
+		return (u8 *) resp;
+	}
 
 	imc_len = tncc_total_send_len(data->tncc);
 

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/eap_ttls.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_ttls.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_ttls.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_ttls.c Sun Dec  9 08:34:57 2007
@@ -1626,8 +1626,8 @@
 	    tls_connection_resumed(sm->ssl_ctx, data->ssl.conn)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Session resumption - "
 			   "skip phase 2");
-		*out_data = eap_peer_tls_build_ack(&data->ssl, out_len,
-						   identifier, EAP_TYPE_TTLS,
+		*out_data = eap_peer_tls_build_ack(out_len, identifier,
+						   EAP_TYPE_TTLS,
 						   data->ttls_version);
 		ret->methodState = METHOD_DONE;
 		ret->decision = DECISION_UNCOND_SUCC;
@@ -1910,8 +1910,8 @@
 	 * the other functions and get rid of this res==1 case here. */
 	if (res == 1) {
 		os_free(resp);
-		return eap_peer_tls_build_ack(&data->ssl, respDataLen,
-					      req->identifier, EAP_TYPE_TTLS,
+		return eap_peer_tls_build_ack(respDataLen, req->identifier,
+					      EAP_TYPE_TTLS,
 					      data->ttls_version);
 	}
 	return resp;

Added: wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c (added)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/eap_wsc.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,496 @@
+/*
+ * EAP-WSC peer for Wi-Fi Protected Setup
+ * Copyright (c) 2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eap_i.h"
+#include "eap_common/eap_wsc_common.h"
+
+
+struct wps_data {
+	int registrar;
+	int msg_num;
+};
+
+
+static struct wps_data * wps_init(int registrar)
+{
+	struct wps_data *data = os_zalloc(sizeof(*data));
+	if (data == NULL)
+		return NULL;
+	data->registrar = registrar;
+	data->msg_num = 1;
+	return data;
+}
+
+
+static void wps_deinit(struct wps_data *data)
+{
+	os_free(data);
+}
+
+
+enum wps_process_res {
+	WPS_DONE, WPS_CONTINUE, WPS_FAILURE, WPS_PENDING
+};
+
+static enum wps_process_res wps_process_msg(struct wps_data *wps, u8 op_code,
+					    const u8 *msg, size_t msg_len)
+{
+	/* TODO: proper processing and/or sending to an external process */
+
+	wpa_hexdump(MSG_MSGDUMP, "WPS: Received message", msg, msg_len);
+	if ((wps->registrar && (wps->msg_num & 1) == 0) ||
+	    (!wps->registrar && (wps->msg_num & 1) == 1)) {
+		wpa_printf(MSG_DEBUG, "WPS: Unexpected message number %d",
+			   wps->msg_num);
+		return WPS_FAILURE;
+	}
+
+	if (wps->msg_num <= 8 && op_code == WSC_MSG) {
+		wpa_printf(MSG_DEBUG, "WPS: Process M%d", wps->msg_num);
+	} else if (wps->registrar && wps->msg_num == 9 &&
+		   op_code == WSC_Done) {
+		wpa_printf(MSG_DEBUG, "WPS: Process Done");
+	} else {
+		wpa_printf(MSG_DEBUG, "WPS: Unexpected Op-Code %d "
+			   "(msg_num=%d)", op_code, wps->msg_num);
+		return WPS_FAILURE;
+	}
+
+	wps->msg_num++;
+	return WPS_CONTINUE;
+
+}
+
+
+static u8 * wps_get_msg(struct wps_data *wps, size_t *msg_len, u8 *op_code)
+{
+	u8 *msg;
+
+	/* TODO: proper processing and/or query from an external process */
+
+	if ((wps->registrar && (wps->msg_num & 1) == 1) ||
+	    (!wps->registrar && (wps->msg_num & 1) == 0)) {
+		wpa_printf(MSG_DEBUG, "WPS: Unexpected request for message "
+			   "number %d", wps->msg_num);
+		return NULL;
+	}
+
+	if (wps->msg_num == 7 || wps->msg_num == 8) {
+		msg = os_zalloc(2000);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 2000;
+		*op_code = WSC_MSG;
+		*msg = WSC_MSG;
+		wpa_printf(MSG_DEBUG, "WPS: Send M%d", wps->msg_num);
+	} else if (wps->msg_num <= 6) {
+		msg = os_zalloc(1);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 1;
+		*op_code = WSC_MSG;
+		*msg = WSC_MSG;
+		wpa_printf(MSG_DEBUG, "WPS: Send M%d", wps->msg_num);
+	} else if (!wps->registrar && wps->msg_num == 9) {
+		msg = os_zalloc(1);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 1;
+		*op_code = WSC_Done;
+		*msg = WSC_Done;
+		wpa_printf(MSG_DEBUG, "WPS: Send Done");
+	} else if (wps->registrar && wps->msg_num == 10) {
+		msg = os_zalloc(1);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 1;
+		*op_code = WSC_ACK;
+		*msg = WSC_ACK;
+		wpa_printf(MSG_DEBUG, "WPS: Send ACK");
+	} else
+		return NULL;
+
+	wps->msg_num++;
+	return msg;
+}
+
+
+struct eap_wsc_data {
+	enum { WAIT_START, MSG, FRAG_ACK, WAIT_FRAG_ACK, DONE, FAIL } state;
+	int registrar;
+	u8 *in_buf, *out_buf, in_op_code, out_op_code;
+	size_t in_len, in_used, out_len, out_used;
+	size_t fragment_size;
+	struct wps_data *wps;
+};
+
+
+static const char * eap_wsc_state_txt(int state)
+{
+	switch (state) {
+	case WAIT_START:
+		return "WAIT_START";
+	case MSG:
+		return "MSG";
+	case FRAG_ACK:
+		return "FRAG_ACK";
+	case WAIT_FRAG_ACK:
+		return "WAIT_FRAG_ACK";
+	case DONE:
+		return "DONE";
+	case FAIL:
+		return "FAIL";
+	default:
+		return "?";
+	}
+}
+
+
+static void eap_wsc_state(struct eap_wsc_data *data, int state)
+{
+	wpa_printf(MSG_DEBUG, "EAP-WSC: %s -> %s",
+		   eap_wsc_state_txt(data->state),
+		   eap_wsc_state_txt(state));
+	data->state = state;
+}
+
+
+static void * eap_wsc_init(struct eap_sm *sm)
+{
+	struct eap_wsc_data *data;
+	const u8 *identity;
+	size_t identity_len;
+	int registrar;
+
+	identity = eap_get_config_identity(sm, &identity_len);
+
+	if (identity && identity_len == WSC_ID_REGISTRAR_LEN &&
+	    os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0)
+		registrar = 1; /* Supplicant is Registrar */
+	else if (identity && identity_len == WSC_ID_ENROLLEE_LEN &&
+	    os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0)
+		registrar = 0; /* Supplicant is Enrollee */
+	else {
+		wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity",
+				  identity, identity_len);
+		return NULL;
+	}
+
+	data = os_zalloc(sizeof(*data));
+	if (data == NULL)
+		return NULL;
+	data->state = registrar ? MSG : WAIT_START;
+	data->registrar = registrar;
+	data->wps = wps_init(registrar);
+	if (data->wps == NULL) {
+		os_free(data);
+		return NULL;
+	}
+	data->fragment_size = WSC_FRAGMENT_SIZE;
+
+	return data;
+}
+
+
+static void eap_wsc_deinit(struct eap_sm *sm, void *priv)
+{
+	struct eap_wsc_data *data = priv;
+	os_free(data->in_buf);
+	os_free(data->out_buf);
+	wps_deinit(data->wps);
+	os_free(data);
+}
+
+
+static u8 * eap_wsc_build_msg(struct eap_wsc_data *data,
+			      struct eap_method_ret *ret, u8 id,
+			      size_t *respDataLen)
+{
+	struct eap_hdr *resp;
+	u8 *pos, flags;
+	size_t send_len, plen;
+
+	ret->ignore = FALSE;
+	wpa_printf(MSG_DEBUG, "EAP-WSC: Generating Response");
+	ret->allowNotifications = TRUE;
+
+	flags = 0;
+	send_len = data->out_len - data->out_used;
+	if (2 + send_len > data->fragment_size) {
+		send_len = data->fragment_size - 2;
+		flags |= WSC_FLAGS_MF;
+		if (data->out_used == 0) {
+			flags |= WSC_FLAGS_LF;
+			send_len -= 2;
+		}
+	}
+	plen = 2 + send_len;
+	if (flags & WSC_FLAGS_LF)
+		plen += 2;
+	resp = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, respDataLen,
+			     plen, EAP_CODE_RESPONSE, id, &pos);
+	if (resp == NULL)
+		return NULL;
+
+	*pos++ = data->out_op_code; /* Op-Code */
+	*pos++ = flags; /* Flags */
+	if (flags & WSC_FLAGS_LF) {
+		WPA_PUT_BE16(pos, data->out_len);
+		pos += 2;
+	}
+
+	os_memcpy(pos, data->out_buf + data->out_used, send_len);
+	data->out_used += send_len;
+
+	ret->methodState = METHOD_MAY_CONT;
+	ret->decision = DECISION_FAIL;
+
+	if (data->out_used == data->out_len) {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %u bytes "
+			   "(message sent completely)", send_len);
+		os_free(data->out_buf);
+		data->out_buf = NULL;
+		data->out_len = data->out_used = 0;
+		if ((data->state == FAIL && data->out_op_code == WSC_ACK) ||
+		    data->out_op_code == WSC_NACK ||
+		    data->out_op_code == WSC_Done) {
+			eap_wsc_state(data, FAIL);
+			ret->methodState = METHOD_DONE;
+		} else
+			eap_wsc_state(data, MSG);
+	} else {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %u bytes "
+			   "(%u more to send)", send_len,
+			   data->out_len - data->out_used);
+		eap_wsc_state(data, WAIT_FRAG_ACK);
+	}
+
+	return (u8 *) resp;
+}
+
+
+static u8 * eap_wsc_process(struct eap_sm *sm, void *priv,
+			    struct eap_method_ret *ret,
+			    const u8 *reqData, size_t reqDataLen,
+			    size_t *respDataLen)
+{
+	struct eap_wsc_data *data = priv;
+	const struct eap_hdr *req;
+	const u8 *start, *pos, *end;
+	size_t len;
+	u8 op_code, flags, id;
+	u16 message_length = 0;
+	const u8 *msg;
+	size_t msg_len;
+	enum wps_process_res res;
+
+	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
+			       reqData, reqDataLen, &len);
+	if (pos == NULL || len < 2) {
+		ret->ignore = TRUE;
+		return NULL;
+	}
+
+	req = (const struct eap_hdr *) reqData;
+	id = req->identifier;
+
+	start = pos;
+	end = start + len;
+
+	op_code = *pos++;
+	flags = *pos++;
+	if (flags & WSC_FLAGS_LF) {
+		if (end - pos < 2) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Message underflow");
+			ret->ignore = TRUE;
+			return NULL;
+		}
+		message_length = WPA_GET_BE16(pos);
+		pos += 2;
+
+		if (message_length < end - pos) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Invalid Message "
+				   "Length");
+			ret->ignore = TRUE;
+			return NULL;
+		}
+	}
+
+	wpa_printf(MSG_DEBUG, "EAP-WSC: Received packet: Op-Code %d "
+		   "Flags 0x%x Message Length %d",
+		   op_code, flags, message_length);
+
+	if (data->state == WAIT_FRAG_ACK) {
+		if (op_code != WSC_FRAG_ACK) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
+				   "in WAIT_FRAG_ACK state", op_code);
+			ret->ignore = TRUE;
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment acknowledged");
+		eap_wsc_state(data, MSG);
+		return eap_wsc_build_msg(data, ret, id, respDataLen);
+	}
+
+	if (op_code != WSC_ACK && op_code != WSC_NACK && op_code != WSC_MSG &&
+	    op_code != WSC_Done && op_code != WSC_Start) {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
+			   op_code);
+		ret->ignore = TRUE;
+		return NULL;
+	}
+
+	if (data->state == WAIT_START) {
+		if (op_code != WSC_Start) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
+				   "in WAIT_START state", op_code);
+			ret->ignore = TRUE;
+			return NULL;
+		}
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Received start");
+		eap_wsc_state(data, MSG);
+		/* Start message has empty payload, skip processing */
+		goto send_msg;
+	} else if (op_code == WSC_Start) {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
+			   op_code);
+		ret->ignore = TRUE;
+		return NULL;
+	}
+
+	if (data->in_buf) {
+		/* Process continuation of a pending message */
+		if (op_code != data->in_op_code) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
+				   "in fragment (expected %d)",
+				   op_code, data->in_op_code);
+			ret->ignore = TRUE;
+			return NULL;
+		}
+
+		if (data->in_used + (end - pos) > data->in_len) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment overflow");
+			ret->ignore = TRUE;
+			return NULL;
+		}
+
+		os_memcpy(data->in_buf + data->in_used, pos, end - pos);
+		data->in_used += end - pos;
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Received %u bytes, waiting "
+			   "for %u bytes more", end - pos,
+			   data->in_len - data->in_used);
+	}
+
+	if (flags & WSC_FLAGS_MF) {
+		if (data->in_buf == NULL && !(flags & WSC_FLAGS_LF)) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: No Message Length "
+				   "field in a fragmented packet");
+			ret->ignore = TRUE;
+			return NULL;
+		}
+
+		if (data->in_buf == NULL) {
+			/* First fragment of the message */
+			data->in_buf = os_malloc(message_length);
+			if (data->in_buf == NULL) {
+				wpa_printf(MSG_DEBUG, "EAP-WSC: No memory for "
+					   "message");
+				ret->ignore = TRUE;
+				return NULL;
+			}
+			data->in_len = message_length;
+			data->in_used = end - pos;
+			data->in_op_code = op_code;
+			os_memcpy(data->in_buf, pos, data->in_used);
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Received %u bytes in "
+				   "first fragment, waiting for %u bytes more",
+				   data->in_used,
+				   data->in_len - data->in_used);
+		}
+
+		return eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE,
+					      respDataLen);
+	}
+
+	if (data->in_buf) {
+		msg = data->in_buf;
+		msg_len = data->in_len;
+	} else {
+		msg = pos;
+		msg_len = end - pos;
+	}
+
+	res = wps_process_msg(data->wps, op_code, msg, msg_len);
+	switch (res) {
+	case WPS_DONE:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing completed "
+			   "successfully - report EAP failure");
+		eap_wsc_state(data, FAIL);
+		break;
+	case WPS_CONTINUE:
+		eap_wsc_state(data, MSG);
+		break;
+	case WPS_FAILURE:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing failed");
+		eap_wsc_state(data, FAIL);
+		break;
+	case WPS_PENDING:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing pending");
+		ret->ignore = TRUE;
+		return NULL;
+	}
+
+	os_free(data->in_buf);
+	data->in_buf = NULL;
+	data->in_len = data->in_used = 0;
+
+send_msg:
+	if (data->out_buf == NULL) {
+		data->out_buf = wps_get_msg(data->wps, &data->out_len,
+					    &data->out_op_code);
+		if (data->out_buf == NULL) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to receive "
+				   "message from WPS");
+			return NULL;
+		}
+	}
+
+	eap_wsc_state(data, MSG);
+	return eap_wsc_build_msg(data, ret, id, respDataLen);
+}
+
+
+int eap_peer_wsc_register(void)
+{
+	struct eap_method *eap;
+	int ret;
+
+	eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
+				    EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
+				    "WSC");
+	if (eap == NULL)
+		return -1;
+
+	eap->init = eap_wsc_init;
+	eap->deinit = eap_wsc_deinit;
+	eap->process = eap_wsc_process;
+
+	ret = eap_peer_method_register(eap);
+	if (ret)
+		eap_peer_method_free(eap);
+	return ret;
+}

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/tncc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/tncc.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/tncc.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/tncc.c Sun Dec  9 08:34:57 2007
@@ -84,6 +84,12 @@
 
 #define TNC_VENDORID_ANY ((TNC_VendorID) 0xffffff)
 #define TNC_SUBTYPE_ANY ((TNC_MessageSubtype) 0xff)
+
+/* TNCC-TNCS Message Types */
+#define TNC_TNCCS_RECOMMENDATION		0x00000001
+#define TNC_TNCCS_ERROR				0x00000002
+#define TNC_TNCCS_PREFERREDLANGUAGE		0x00000003
+#define TNC_TNCCS_REASONSTRINGS			0x00000004
 
 
 struct tnc_if_imc {
@@ -611,16 +617,125 @@
 }
 
 
-int tncc_process_if_tnccs(struct tncc_data *tncc, const u8 *msg, size_t len)
-{
-	char *buf, *start, *end, *pos, *pos2;
+static void tncc_notify_recommendation(struct tncc_data *tncc,
+				       enum tncc_process_res res)
+{
+	TNC_ConnectionState state;
+	struct tnc_if_imc *imc;
+
+	switch (res) {
+	case TNCCS_RECOMMENDATION_ALLOW:
+		state = TNC_CONNECTION_STATE_ACCESS_ALLOWED;
+		break;
+	case TNCCS_RECOMMENDATION_NONE:
+		state = TNC_CONNECTION_STATE_ACCESS_NONE;
+		break;
+	case TNCCS_RECOMMENDATION_ISOLATE:
+		state = TNC_CONNECTION_STATE_ACCESS_ISOLATED;
+		break;
+	default:
+		state = TNC_CONNECTION_STATE_ACCESS_NONE;
+		break;
+	}
+
+	for (imc = tncc->imc; imc; imc = imc->next)
+		tncc_imc_notify_connection_change(imc, state);
+}
+
+
+static int tncc_get_type(char *start, unsigned int *type)
+{
+	char *pos = os_strstr(start, "<Type>");
+	if (pos == NULL)
+		return -1;
+	pos += 6;
+	*type = strtoul(pos, NULL, 16);
+	return 0;
+}
+
+
+static unsigned char * tncc_get_base64(char *start, size_t *decoded_len)
+{
+	char *pos, *pos2;
+	unsigned char *decoded;
+
+	pos = os_strstr(start, "<Base64>");
+	if (pos == NULL)
+		return NULL;
+
+	pos += 8;
+	pos2 = os_strstr(pos, "</Base64>");
+	if (pos2 == NULL)
+		return NULL;
+	*pos2 = '\0';
+
+	decoded = base64_decode((unsigned char *) pos, os_strlen(pos),
+				decoded_len);
+	*pos2 = '<';
+	if (decoded == NULL) {
+		wpa_printf(MSG_DEBUG, "TNC: Failed to decode Base64 data");
+	}
+
+	return decoded;
+}
+
+
+static enum tncc_process_res tncc_get_recommendation(char *start)
+{
+	char *pos, *pos2, saved;
+	int recom;
+
+	pos = os_strstr(start, "<TNCCS-Recommendation ");
+	if (pos == NULL)
+		return TNCCS_RECOMMENDATION_ERROR;
+
+	pos += 21;
+	pos = os_strstr(pos, " type=");
+	if (pos == NULL)
+		return TNCCS_RECOMMENDATION_ERROR;
+	pos += 6;
+
+	if (*pos == '"')
+		pos++;
+
+	pos2 = pos;
+	while (*pos2 != '\0' && *pos2 != '"' && *pos2 != '>')
+		pos2++;
+
+	if (*pos2 == '\0')
+		return TNCCS_RECOMMENDATION_ERROR;
+
+	saved = *pos2;
+	*pos2 = '\0';
+	wpa_printf(MSG_DEBUG, "TNC: TNCCS-Recommendation: '%s'", pos);
+
+	recom = TNCCS_RECOMMENDATION_ERROR;
+	if (os_strcmp(pos, "allow") == 0)
+		recom = TNCCS_RECOMMENDATION_ALLOW;
+	else if (os_strcmp(pos, "none") == 0)
+		recom = TNCCS_RECOMMENDATION_NONE;
+	else if (os_strcmp(pos, "isolate") == 0)
+		recom = TNCCS_RECOMMENDATION_ISOLATE;
+
+	*pos2 = saved;
+
+	return recom;
+}
+
+
+enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
+					    const u8 *msg, size_t len)
+{
+	char *buf, *start, *end, *pos, *pos2, *payload;
 	unsigned int batch_id;
 	unsigned char *decoded;
 	size_t decoded_len;
+	enum tncc_process_res res = TNCCS_PROCESS_OK_NO_RECOMMENDATION;
+	int recommendation_msg = 0;
 
 	buf = os_malloc(len + 1);
 	if (buf == NULL)
-		return -1;
+		return TNCCS_PROCESS_ERROR;
 
 	os_memcpy(buf, msg, len);
 	buf[len] = '\0';
@@ -628,7 +743,7 @@
 	end = os_strstr(buf, "</TNCCS-Batch>");
 	if (start == NULL || end == NULL || start > end) {
 		os_free(buf);
-		return -1;
+		return TNCCS_PROCESS_ERROR;
 	}
 
 	start += 13;
@@ -639,7 +754,7 @@
 	pos = os_strstr(start, "BatchId=");
 	if (pos == NULL) {
 		os_free(buf);
-		return -1;
+		return TNCCS_PROCESS_ERROR;
 	}
 
 	pos += 8;
@@ -653,9 +768,18 @@
 			   "%u (expected %u)",
 			   batch_id, tncc->last_batchid + 1);
 		os_free(buf);
-		return -1;
+		return TNCCS_PROCESS_ERROR;
 	}
 	tncc->last_batchid = batch_id;
+
+	while (*pos != '\0' && *pos != '>')
+		pos++;
+	if (*pos == '\0') {
+		os_free(buf);
+		return TNCCS_PROCESS_ERROR;
+	}
+	pos++;
+	payload = start;
 
 	/*
 	 * <IMC-IMV-Message>
@@ -665,6 +789,7 @@
 	 */
 
 	while (*start) {
+		char *endpos;
 		unsigned int type;
 
 		pos = os_strstr(start, "<IMC-IMV-Message>");
@@ -675,51 +800,120 @@
 		if (end == NULL)
 			break;
 		*end = '\0';
+		endpos = end;
 		end += 18;
 
-		pos = os_strstr(start, "<Type>");
-		if (pos == NULL) {
+		if (tncc_get_type(start, &type) < 0) {
+			*endpos = '<';
 			start = end;
 			continue;
 		}
-
-		pos += 6;
-		type = strtoul(pos, NULL, 16);
 		wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type);
 
-		pos = os_strstr(start, "<Base64>");
-		if (pos == NULL) {
+		decoded = tncc_get_base64(start, &decoded_len);
+		if (decoded == NULL) {
+			*endpos = '<';
 			start = end;
 			continue;
 		}
-		pos += 8;
-
-		pos2 = os_strstr(pos, "</Base64>");
-		if (pos2 == NULL) {
+
+		tncc_send_to_imcs(tncc, type, decoded, decoded_len);
+
+		os_free(decoded);
+
+		start = end;
+	}
+
+	/*
+	 * <TNCC-TNCS-Message>
+	 * <Type>01234567</Type>
+	 * <XML><TNCCS-Foo type="foo"></TNCCS-Foo></XML>
+	 * <Base64>foo==</Base64>
+	 * </TNCC-TNCS-Message>
+	 */
+
+	start = payload;
+	while (*start) {
+		unsigned int type;
+		char *xml, *xmlend, *endpos;
+
+		pos = os_strstr(start, "<TNCC-TNCS-Message>");
+		if (pos == NULL)
+			break;
+		start = pos + 19;
+		end = os_strstr(start, "</TNCC-TNCS-Message>");
+		if (end == NULL)
+			break;
+		*end = '\0';
+		endpos = end;
+		end += 20;
+
+		if (tncc_get_type(start, &type) < 0) {
+			*endpos = '<';
 			start = end;
 			continue;
 		}
-		*pos2 = '\0';
-
-		decoded = base64_decode((unsigned char *) pos, os_strlen(pos),
-					&decoded_len);
-		if (decoded == NULL) {
-			wpa_printf(MSG_DEBUG, "TNC: Failed to decode "
-				   "IMC-IMV-Message Base64 data");
-			start = end;
-			continue;
-		}
-
-		tncc_send_to_imcs(tncc, type, decoded, decoded_len);
-
-		os_free(decoded);
+		wpa_printf(MSG_DEBUG, "TNC: TNCC-TNCS-Message Type 0x%x",
+			   type);
+
+		/* Base64 OR XML */
+		decoded = NULL;
+		xml = NULL;
+		xmlend = NULL;
+		pos = os_strstr(start, "<XML>");
+		if (pos) {
+			pos += 5;
+			pos2 = os_strstr(pos, "</XML>");
+			if (pos2 == NULL) {
+				*endpos = '<';
+				start = end;
+				continue;
+			}
+			xmlend = pos2;
+			xml = pos;
+		} else {
+			decoded = tncc_get_base64(start, &decoded_len);
+			if (decoded == NULL) {
+				*endpos = '<';
+				start = end;
+				continue;
+			}
+		}
+
+		if (decoded) {
+			wpa_hexdump_ascii(MSG_MSGDUMP,
+					  "TNC: TNCC-TNCS-Message Base64",
+					  decoded, decoded_len);
+			os_free(decoded);
+		}
+
+		if (xml) {
+			wpa_hexdump_ascii(MSG_MSGDUMP,
+					  "TNC: TNCC-TNCS-Message XML",
+					  (unsigned char *) xml,
+					  xmlend - xml);
+		}
+
+		if (type == TNC_TNCCS_RECOMMENDATION && xml) {
+			/*
+			 * <TNCCS-Recommendation type="allow">
+			 * </TNCCS-Recommendation>
+			 */
+			*xmlend = '\0';
+			res = tncc_get_recommendation(xml);
+			*xmlend = '<';
+			recommendation_msg = 1;
+		}
 
 		start = end;
 	}
 
 	os_free(buf);
 
-	return 0;
+	if (recommendation_msg)
+		tncc_notify_recommendation(tncc, res);
+
+	return res;
 }
 
 

Modified: wpasupplicant/branches/upstream/current/src/eap_peer/tncc.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_peer/tncc.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_peer/tncc.h (original)
+++ wpasupplicant/branches/upstream/current/src/eap_peer/tncc.h Sun Dec  9 08:34:57 2007
@@ -24,6 +24,17 @@
 u8 * tncc_copy_send_buf(struct tncc_data *tncc, u8 *pos);
 char * tncc_if_tnccs_start(struct tncc_data *tncc);
 char * tncc_if_tnccs_end(void);
-int tncc_process_if_tnccs(struct tncc_data *tncc, const u8 *msg, size_t len);
+
+enum tncc_process_res {
+	TNCCS_PROCESS_ERROR = -1,
+	TNCCS_PROCESS_OK_NO_RECOMMENDATION = 0,
+	TNCCS_RECOMMENDATION_ERROR,
+	TNCCS_RECOMMENDATION_ALLOW,
+	TNCCS_RECOMMENDATION_NONE,
+	TNCCS_RECOMMENDATION_ISOLATE
+};
+
+enum tncc_process_res tncc_process_if_tnccs(struct tncc_data *tncc,
+					    const u8 *msg, size_t len);
 
 #endif /* TNCC_H */

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap.c Sun Dec  9 08:34:57 2007
@@ -1,5 +1,5 @@
 /*
- * hostapd / EAP Standalone Authenticator state machine (RFC 4137)
+ * hostapd / EAP Full Authenticator state machine (RFC 4137)
  * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -10,6 +10,12 @@
  * license.
  *
  * See README and COPYING for more details.
+ *
+ * This state machine is based on the full authenticator state machine defined
+ * in RFC 4137. However, to support backend authentication in RADIUS
+ * authentication server functionality, parts of backend authenticator (also
+ * from RFC 4137) are mixed in. This functionality is enabled by setting
+ * backend_auth configuration variable to TRUE.
  */
 
 #include "includes.h"
@@ -32,6 +38,7 @@
 				   int eapSRTT, int eapRTTVAR,
 				   int methodTimeout);
 static void eap_sm_parseEapResp(struct eap_sm *sm, u8 *resp, size_t len);
+static int eap_sm_getId(const u8 *data, size_t len);
 static u8 * eap_sm_buildSuccess(struct eap_sm *sm, int id, size_t *len);
 static u8 * eap_sm_buildFailure(struct eap_sm *sm, int id, size_t *len);
 static int eap_sm_nextId(struct eap_sm *sm, int id);
@@ -41,35 +48,26 @@
 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method);
 
 
-static Boolean eapol_get_bool(struct eap_sm *sm, enum eapol_bool_var var)
-{
-	return sm->eapol_cb->get_bool(sm->eapol_ctx, var);
-}
-
-
-static void eapol_set_bool(struct eap_sm *sm, enum eapol_bool_var var,
-			   Boolean value)
-{
-	sm->eapol_cb->set_bool(sm->eapol_ctx, var, value);
-}
-
-
-static void eapol_set_eapReqData(struct eap_sm *sm,
-				 const u8 *eapReqData, size_t eapReqDataLen)
-{
-	wpa_hexdump(MSG_MSGDUMP, "EAP: eapReqData -> EAPOL",
-		    sm->eapReqData, sm->eapReqDataLen);
-	sm->eapol_cb->set_eapReqData(sm->eapol_ctx, eapReqData, eapReqDataLen);
-}
-
-
-static void eapol_set_eapKeyData(struct eap_sm *sm,
-				 const u8 *eapKeyData, size_t eapKeyDataLen)
-{
-	wpa_hexdump(MSG_MSGDUMP, "EAP: eapKeyData -> EAPOL",
-		    sm->eapKeyData, sm->eapKeyDataLen);
-	sm->eapol_cb->set_eapKeyData(sm->eapol_ctx, eapKeyData, eapKeyDataLen);
-}
+static int eap_copy_data(u8 **dst, size_t *dst_len,
+			 const u8 *src, size_t src_len)
+{
+	if (src == NULL)
+		return -1;
+
+	os_free(*dst);
+	*dst = os_malloc(src_len);
+	if (*dst) {
+		os_memcpy(*dst, src, src_len);
+		*dst_len = src_len;
+		return 0;
+	} else {
+		*dst_len = 0;
+		return -1;
+	}
+}
+
+#define EAP_COPY(dst, src) \
+	eap_copy_data((dst), (dst ## Len), (src), (src ## Len))
 
 
 /**
@@ -126,14 +124,14 @@
 	SM_ENTRY(EAP, INITIALIZE);
 
 	sm->currentId = -1;
-	eapol_set_bool(sm, EAPOL_eapSuccess, FALSE);
-	eapol_set_bool(sm, EAPOL_eapFail, FALSE);
-	eapol_set_bool(sm, EAPOL_eapTimeout, FALSE);
-	free(sm->eapKeyData);
-	sm->eapKeyData = NULL;
-	sm->eapKeyDataLen = 0;
-	/* eapKeyAvailable = FALSE */
-	eapol_set_bool(sm, EAPOL_eapRestart, FALSE);
+	sm->eap_if.eapSuccess = FALSE;
+	sm->eap_if.eapFail = FALSE;
+	sm->eap_if.eapTimeout = FALSE;
+	os_free(sm->eap_if.eapKeyData);
+	sm->eap_if.eapKeyData = NULL;
+	sm->eap_if.eapKeyDataLen = 0;
+	sm->eap_if.eapKeyAvailable = FALSE;
+	sm->eap_if.eapRestart = FALSE;
 
 	/*
 	 * This is not defined in RFC 4137, but method state needs to be
@@ -150,7 +148,8 @@
 	if (sm->backend_auth) {
 		sm->currentMethod = EAP_TYPE_NONE;
 		/* parse rxResp, respId, respMethod */
-		eap_sm_parseEapResp(sm, sm->eapRespData, sm->eapRespDataLen);
+		eap_sm_parseEapResp(sm, sm->eap_if.eapRespData,
+				    sm->eap_if.eapRespDataLen);
 		if (sm->rxResp) {
 			sm->currentId = sm->respId;
 		}
@@ -193,9 +192,9 @@
 {
 	SM_ENTRY(EAP, IDLE);
 
-	sm->retransWhile = eap_sm_calculateTimeout(sm, sm->retransCount,
-						   sm->eapSRTT, sm->eapRTTVAR,
-						   sm->methodTimeout);
+	sm->eap_if.retransWhile = eap_sm_calculateTimeout(
+		sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
+		sm->methodTimeout);
 }
 
 
@@ -203,8 +202,11 @@
 {
 	SM_ENTRY(EAP, RETRANSMIT);
 
-	/* TODO: Is this needed since EAPOL state machines take care of
-	 * retransmit? */
+	sm->retransCount++;
+	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
+		if (EAP_COPY(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
+			sm->eap_if.eapReq = TRUE;
+	}
 }
 
 
@@ -213,7 +215,8 @@
 	SM_ENTRY(EAP, RECEIVED);
 
 	/* parse rxResp, respId, respMethod */
-	eap_sm_parseEapResp(sm, sm->eapRespData, sm->eapRespDataLen);
+	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData,
+			    sm->eap_if.eapRespDataLen);
 	sm->num_rounds++;
 }
 
@@ -221,8 +224,8 @@
 SM_STATE(EAP, DISCARD)
 {
 	SM_ENTRY(EAP, DISCARD);
-	eapol_set_bool(sm, EAPOL_eapResp, FALSE);
-	eapol_set_bool(sm, EAPOL_eapNoReq, TRUE);
+	sm->eap_if.eapResp = FALSE;
+	sm->eap_if.eapNoReq = TRUE;
 }
 
 
@@ -231,20 +234,19 @@
 	SM_ENTRY(EAP, SEND_REQUEST);
 
 	sm->retransCount = 0;
-	if (sm->eapReqData) {
-		eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen);
-		free(sm->lastReqData);
-		sm->lastReqData = sm->eapReqData;
-		sm->lastReqDataLen = sm->eapReqDataLen;
-		sm->eapReqData = NULL;
-		sm->eapReqDataLen = 0;
-		eapol_set_bool(sm, EAPOL_eapResp, FALSE);
-		eapol_set_bool(sm, EAPOL_eapReq, TRUE);
+	if (sm->eap_if.eapReqData) {
+		if (EAP_COPY(&sm->lastReqData, sm->eap_if.eapReqData) == 0) {
+			sm->eap_if.eapResp = FALSE;
+			sm->eap_if.eapReq = TRUE;
+		} else {
+			sm->eap_if.eapResp = FALSE;
+			sm->eap_if.eapReq = FALSE;
+		}
 	} else {
 		wpa_printf(MSG_INFO, "EAP: SEND_REQUEST - no eapReqData");
-		eapol_set_bool(sm, EAPOL_eapResp, FALSE);
-		eapol_set_bool(sm, EAPOL_eapReq, FALSE);
-		eapol_set_bool(sm, EAPOL_eapNoReq, TRUE);
+		sm->eap_if.eapResp = FALSE;
+		sm->eap_if.eapReq = FALSE;
+		sm->eap_if.eapNoReq = TRUE;
 	}
 }
 
@@ -255,7 +257,8 @@
 
 	if (sm->m->check) {
 		sm->ignore = sm->m->check(sm, sm->eap_method_priv,
-					  sm->eapRespData, sm->eapRespDataLen);
+					  sm->eap_if.eapRespData,
+					  sm->eap_if.eapRespDataLen);
 	}
 }
 
@@ -273,9 +276,10 @@
 	wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d",
 		   sm->currentId);
 	sm->lastId = sm->currentId;
-	free(sm->eapReqData);
-	sm->eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,
-					 sm->currentId, &sm->eapReqDataLen);
+	os_free(sm->eap_if.eapReqData);
+	sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,
+						sm->currentId,
+						&sm->eap_if.eapReqDataLen);
 	if (sm->m->getTimeout)
 		sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv);
 	else
@@ -287,17 +291,18 @@
 {
 	SM_ENTRY(EAP, METHOD_RESPONSE);
 
-	sm->m->process(sm, sm->eap_method_priv, sm->eapRespData,
-		       sm->eapRespDataLen);
+	sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData,
+		       sm->eap_if.eapRespDataLen);
 	if (sm->m->isDone(sm, sm->eap_method_priv)) {
 		eap_sm_Policy_update(sm, NULL, 0);
-		free(sm->eapKeyData);
+		os_free(sm->eap_if.eapKeyData);
 		if (sm->m->getKey) {
-			sm->eapKeyData = sm->m->getKey(sm, sm->eap_method_priv,
-						       &sm->eapKeyDataLen);
+			sm->eap_if.eapKeyData = sm->m->getKey(
+				sm, sm->eap_method_priv,
+				&sm->eap_if.eapKeyDataLen);
 		} else {
-			sm->eapKeyData = NULL;
-			sm->eapKeyDataLen = 0;
+			sm->eap_if.eapKeyData = NULL;
+			sm->eap_if.eapKeyDataLen = 0;
 		}
 		sm->methodState = METHOD_END;
 	} else {
@@ -354,11 +359,11 @@
 	}
 	sm->m = NULL;
 
-	nak = (struct eap_hdr *) sm->eapRespData;
-	if (nak && sm->eapRespDataLen > sizeof(*nak)) {
+	nak = (struct eap_hdr *) sm->eap_if.eapRespData;
+	if (nak && sm->eap_if.eapRespDataLen > sizeof(*nak)) {
 		len = be_to_host16(nak->length);
-		if (len > sm->eapRespDataLen)
-			len = sm->eapRespDataLen;
+		if (len > sm->eap_if.eapRespDataLen)
+			len = sm->eap_if.eapRespDataLen;
 		pos = (u8 *) (nak + 1);
 		len -= sizeof(*nak);
 		if (*pos == EAP_TYPE_NAK) {
@@ -383,7 +388,7 @@
 {
 	SM_ENTRY(EAP, TIMEOUT_FAILURE);
 
-	eapol_set_bool(sm, EAPOL_eapTimeout, TRUE);
+	sm->eap_if.eapTimeout = TRUE;
 }
 
 
@@ -391,19 +396,13 @@
 {
 	SM_ENTRY(EAP, FAILURE);
 
-	free(sm->eapReqData);
-	sm->eapReqData = eap_sm_buildFailure(sm, sm->currentId,
-					     &sm->eapReqDataLen);
-	if (sm->eapReqData) {
-		eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen);
-		free(sm->eapReqData);
-		sm->eapReqData = NULL;
-		sm->eapReqDataLen = 0;
-	}
-	free(sm->lastReqData);
+	os_free(sm->eap_if.eapReqData);
+	sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId,
+						    &sm->eap_if.eapReqDataLen);
+	os_free(sm->lastReqData);
 	sm->lastReqData = NULL;
 	sm->lastReqDataLen = 0;
-	eapol_set_bool(sm, EAPOL_eapFail, TRUE);
+	sm->eap_if.eapFail = TRUE;
 }
 
 
@@ -411,31 +410,174 @@
 {
 	SM_ENTRY(EAP, SUCCESS);
 
-	free(sm->eapReqData);
-	sm->eapReqData = eap_sm_buildSuccess(sm, sm->currentId,
-					     &sm->eapReqDataLen);
-	if (sm->eapReqData) {
-		eapol_set_eapReqData(sm, sm->eapReqData, sm->eapReqDataLen);
-		free(sm->eapReqData);
-		sm->eapReqData = NULL;
-		sm->eapReqDataLen = 0;
-	}
-	free(sm->lastReqData);
+	os_free(sm->eap_if.eapReqData);
+	sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId,
+						    &sm->eap_if.eapReqDataLen);
+	os_free(sm->lastReqData);
 	sm->lastReqData = NULL;
 	sm->lastReqDataLen = 0;
-	if (sm->eapKeyData) {
-		eapol_set_eapKeyData(sm, sm->eapKeyData, sm->eapKeyDataLen);
-	}
-	eapol_set_bool(sm, EAPOL_eapSuccess, TRUE);
+	if (sm->eap_if.eapKeyData)
+		sm->eap_if.eapKeyAvailable = TRUE;
+	sm->eap_if.eapSuccess = TRUE;
+}
+
+
+SM_STATE(EAP, INITIALIZE_PASSTHROUGH)
+{
+	SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);
+
+	os_free(sm->eap_if.aaaEapRespData);
+	sm->eap_if.aaaEapRespData = NULL;
+	sm->eap_if.aaaEapRespDataLen = 0;
+}
+
+
+SM_STATE(EAP, IDLE2)
+{
+	SM_ENTRY(EAP, IDLE2);
+
+	sm->eap_if.retransWhile = eap_sm_calculateTimeout(
+		sm, sm->retransCount, sm->eap_if.eapSRTT, sm->eap_if.eapRTTVAR,
+		sm->methodTimeout);
+}
+
+
+SM_STATE(EAP, RETRANSMIT2)
+{
+	SM_ENTRY(EAP, RETRANSMIT2);
+
+	sm->retransCount++;
+	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
+		if (EAP_COPY(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
+			sm->eap_if.eapReq = TRUE;
+	}
+}
+
+
+SM_STATE(EAP, RECEIVED2)
+{
+	SM_ENTRY(EAP, RECEIVED2);
+
+	/* parse rxResp, respId, respMethod */
+	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData,
+			    sm->eap_if.eapRespDataLen);
+}
+
+
+SM_STATE(EAP, DISCARD2)
+{
+	SM_ENTRY(EAP, DISCARD2);
+	sm->eap_if.eapResp = FALSE;
+	sm->eap_if.eapNoReq = TRUE;
+}
+
+
+SM_STATE(EAP, SEND_REQUEST2)
+{
+	SM_ENTRY(EAP, SEND_REQUEST2);
+
+	sm->retransCount = 0;
+	if (sm->eap_if.eapReqData) {
+		if (EAP_COPY(&sm->lastReqData, sm->eap_if.eapReqData) == 0) {
+			sm->eap_if.eapResp = FALSE;
+			sm->eap_if.eapReq = TRUE;
+		} else {
+			sm->eap_if.eapResp = FALSE;
+			sm->eap_if.eapReq = FALSE;
+		}
+	} else {
+		wpa_printf(MSG_INFO, "EAP: SEND_REQUEST2 - no eapReqData");
+		sm->eap_if.eapResp = FALSE;
+		sm->eap_if.eapReq = FALSE;
+		sm->eap_if.eapNoReq = TRUE;
+	}
+}
+
+
+SM_STATE(EAP, AAA_REQUEST)
+{
+	SM_ENTRY(EAP, AAA_REQUEST);
+
+	if (sm->eap_if.eapRespData == NULL) {
+		wpa_printf(MSG_INFO, "EAP: AAA_REQUEST - no eapRespData");
+		return;
+	}
+
+	/*
+	 * if (respMethod == IDENTITY)
+	 *	aaaIdentity = eapRespData
+	 * This is already taken care of by the EAP-Identity method which
+	 * stores the identity into sm->identity.
+	 */
+
+	EAP_COPY(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);
+}
+
+
+SM_STATE(EAP, AAA_RESPONSE)
+{
+	SM_ENTRY(EAP, AAA_RESPONSE);
+
+	EAP_COPY(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
+	sm->currentId =
+		eap_sm_getId(sm->eap_if.eapReqData, sm->eap_if.eapReqDataLen);
+	sm->methodTimeout = sm->eap_if.aaaMethodTimeout;
+}
+
+
+SM_STATE(EAP, AAA_IDLE)
+{
+	SM_ENTRY(EAP, AAA_IDLE);
+
+	sm->eap_if.aaaFail = FALSE;
+	sm->eap_if.aaaSuccess = FALSE;
+	sm->eap_if.aaaEapReq = FALSE;
+	sm->eap_if.aaaEapNoReq = FALSE;
+	sm->eap_if.aaaEapResp = TRUE;
+}
+
+
+SM_STATE(EAP, TIMEOUT_FAILURE2)
+{
+	SM_ENTRY(EAP, TIMEOUT_FAILURE2);
+
+	sm->eap_if.eapTimeout = TRUE;
+}
+
+
+SM_STATE(EAP, FAILURE2)
+{
+	SM_ENTRY(EAP, FAILURE2);
+
+	EAP_COPY(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
+	sm->eap_if.eapFail = TRUE;
+}
+
+
+SM_STATE(EAP, SUCCESS2)
+{
+	SM_ENTRY(EAP, SUCCESS2);
+
+	EAP_COPY(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
+
+	sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable;
+	if (sm->eap_if.aaaEapKeyAvailable) {
+		EAP_COPY(&sm->eap_if.eapKeyData, sm->eap_if.aaaEapKeyData);
+	} else {
+		os_free(sm->eap_if.eapKeyData);
+		sm->eap_if.eapKeyData = NULL;
+		sm->eap_if.eapKeyDataLen = 0;
+	}
+
+	sm->eap_if.eapSuccess = TRUE;
 }
 
 
 SM_STEP(EAP)
 {
-	if (eapol_get_bool(sm, EAPOL_eapRestart) &&
-	    eapol_get_bool(sm, EAPOL_portEnabled))
+	if (sm->eap_if.eapRestart && sm->eap_if.portEnabled)
 		SM_ENTER_GLOBAL(EAP, INITIALIZE);
-	else if (!eapol_get_bool(sm, EAPOL_portEnabled))
+	else if (!sm->eap_if.portEnabled)
 		SM_ENTER_GLOBAL(EAP, DISABLED);
 	else if (sm->num_rounds > EAP_MAX_AUTH_ROUNDS) {
 		if (sm->num_rounds == EAP_MAX_AUTH_ROUNDS + 1) {
@@ -470,13 +612,13 @@
 		}
 		break;
 	case EAP_DISABLED:
-		if (eapol_get_bool(sm, EAPOL_portEnabled))
+		if (sm->eap_if.portEnabled)
 			SM_ENTER(EAP, INITIALIZE);
 		break;
 	case EAP_IDLE:
-		if (sm->retransWhile == 0)
+		if (sm->eap_if.retransWhile == 0)
 			SM_ENTER(EAP, RETRANSMIT);
-		else if (eapol_get_bool(sm, EAPOL_eapResp))
+		else if (sm->eap_if.eapResp)
 			SM_ENTER(EAP, RECEIVED);
 		break;
 	case EAP_RETRANSMIT:
@@ -575,6 +717,8 @@
 			SM_ENTER(EAP, FAILURE);
 		else if (sm->decision == DECISION_SUCCESS)
 			SM_ENTER(EAP, SUCCESS);
+		else if (sm->decision == DECISION_PASSTHROUGH)
+			SM_ENTER(EAP, INITIALIZE_PASSTHROUGH);
 		else
 			SM_ENTER(EAP, PROPOSE_METHOD);
 		break;
@@ -583,6 +727,59 @@
 	case EAP_FAILURE:
 		break;
 	case EAP_SUCCESS:
+		break;
+
+	case EAP_INITIALIZE_PASSTHROUGH:
+		if (sm->currentId == -1)
+			SM_ENTER(EAP, AAA_IDLE);
+		else
+			SM_ENTER(EAP, AAA_REQUEST);
+		break;
+	case EAP_IDLE2:
+		if (sm->eap_if.eapResp)
+			SM_ENTER(EAP, RECEIVED2);
+		else if (sm->eap_if.retransWhile == 0)
+			SM_ENTER(EAP, RETRANSMIT2);
+		break;
+	case EAP_RETRANSMIT2:
+		if (sm->retransCount > sm->MaxRetrans)
+			SM_ENTER(EAP, TIMEOUT_FAILURE2);
+		else
+			SM_ENTER(EAP, IDLE2);
+		break;
+	case EAP_RECEIVED2:
+		if (sm->rxResp && (sm->respId == sm->currentId))
+			SM_ENTER(EAP, AAA_REQUEST);
+		else
+			SM_ENTER(EAP, DISCARD2);
+		break;
+	case EAP_DISCARD2:
+		SM_ENTER(EAP, IDLE2);
+		break;
+	case EAP_SEND_REQUEST2:
+		SM_ENTER(EAP, IDLE2);
+		break;
+	case EAP_AAA_REQUEST:
+		SM_ENTER(EAP, AAA_IDLE);
+		break;
+	case EAP_AAA_RESPONSE:
+		SM_ENTER(EAP, SEND_REQUEST2);
+		break;
+	case EAP_AAA_IDLE:
+		if (sm->eap_if.aaaFail)
+			SM_ENTER(EAP, FAILURE2);
+		else if (sm->eap_if.aaaSuccess)
+			SM_ENTER(EAP, SUCCESS2);
+		else if (sm->eap_if.aaaEapReq)
+			SM_ENTER(EAP, AAA_RESPONSE);
+		else if (sm->eap_if.aaaTimeout)
+			SM_ENTER(EAP, TIMEOUT_FAILURE2);
+		break;
+	case EAP_TIMEOUT_FAILURE2:
+		break;
+	case EAP_FAILURE2:
+		break;
+	case EAP_SUCCESS2:
 		break;
 	}
 }
@@ -611,8 +808,11 @@
 	sm->respVendor = EAP_VENDOR_IETF;
 	sm->respVendorMethod = EAP_TYPE_NONE;
 
-	if (resp == NULL || len < sizeof(*hdr))
+	if (resp == NULL || len < sizeof(*hdr)) {
+		wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p "
+			   "len=%lu", resp, (unsigned long) len);
 		return;
+	}
 
 	hdr = (struct eap_hdr *) resp;
 	plen = be_to_host16(hdr->length);
@@ -651,13 +851,26 @@
 }
 
 
+static int eap_sm_getId(const u8 *data, size_t len)
+{
+	const struct eap_hdr *hdr;
+
+	if (data == NULL || len < sizeof(*hdr))
+		return -1;
+
+	hdr = (const struct eap_hdr *) data;
+	wpa_printf(MSG_DEBUG, "EAP: getId: id=%d", hdr->identifier);
+	return hdr->identifier;
+}
+
+
 static u8 * eap_sm_buildSuccess(struct eap_sm *sm, int id, size_t *len)
 {
 	struct eap_hdr *resp;
 	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);
 
 	*len = sizeof(*resp);
-	resp = malloc(*len);
+	resp = os_malloc(*len);
 	if (resp == NULL)
 		return NULL;
 	resp->code = EAP_CODE_SUCCESS;
@@ -674,7 +887,7 @@
 	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);
 
 	*len = sizeof(*resp);
-	resp = malloc(*len);
+	resp = os_malloc(*len);
 	if (resp == NULL)
 		return NULL;
 	resp->code = EAP_CODE_FAILURE;
@@ -744,9 +957,9 @@
 
 	not_found:
 		/* not found - remove from the list */
-		memmove(&sm->user->methods[i], &sm->user->methods[i + 1],
-			(EAP_MAX_METHODS - i - 1) *
-			sizeof(sm->user->methods[0]));
+		os_memmove(&sm->user->methods[i], &sm->user->methods[i + 1],
+			   (EAP_MAX_METHODS - i - 1) *
+			   sizeof(sm->user->methods[0]));
 		sm->user->methods[EAP_MAX_METHODS - 1].vendor =
 			EAP_VENDOR_IETF;
 		sm->user->methods[EAP_MAX_METHODS - 1].method = EAP_TYPE_NONE;
@@ -808,6 +1021,11 @@
 
 static int eap_sm_Policy_getDecision(struct eap_sm *sm)
 {
+	if (!sm->eap_server && sm->identity) {
+		wpa_printf(MSG_DEBUG, "EAP: getDecision: -> PASSTHROUGH");
+		return DECISION_PASSTHROUGH;
+	}
+
 	if (sm->m && sm->currentMethod != EAP_TYPE_IDENTITY &&
 	    sm->m->isSuccess(sm, sm->eap_method_priv)) {
 		wpa_printf(MSG_DEBUG, "EAP: getDecision: method succeeded -> "
@@ -883,37 +1101,13 @@
 }
 
 
-/**
- * eap_set_eapRespData - Set EAP response (eapRespData)
- * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
- * @eapRespData: EAP-Response payload from the supplicant
- * @eapRespDataLen: Length of eapRespData in bytes
- *
- * This function is called when an EAP-Response is received from a supplicant.
- */
-void eap_set_eapRespData(struct eap_sm *sm, const u8 *eapRespData,
-			 size_t eapRespDataLen)
-{
-	if (sm == NULL)
-		return;
-	free(sm->eapRespData);
-	sm->eapRespData = malloc(eapRespDataLen);
-	if (sm->eapRespData == NULL)
-		return;
-	memcpy(sm->eapRespData, eapRespData, eapRespDataLen);
-	sm->eapRespDataLen = eapRespDataLen;
-	wpa_hexdump(MSG_MSGDUMP, "EAP: EAP-Response received",
-		    eapRespData, eapRespDataLen);
-}
-
-
 static void eap_user_free(struct eap_user *user)
 {
 	if (user == NULL)
 		return;
-	free(user->password);
+	os_free(user->password);
 	user->password = NULL;
-	free(user);
+	os_free(user);
 }
 
 
@@ -941,6 +1135,7 @@
 	sm->ssl_ctx = conf->ssl_ctx;
 	sm->eap_sim_db_priv = conf->eap_sim_db_priv;
 	sm->backend_auth = conf->backend_auth;
+	sm->eap_server = conf->eap_server;
 	if (conf->pac_opaque_encr_key) {
 		sm->pac_opaque_encr_key = os_malloc(16);
 		if (sm->pac_opaque_encr_key) {
@@ -949,7 +1144,7 @@
 		}
 	}
 	if (conf->eap_fast_a_id)
-		sm->eap_fast_a_id = strdup(conf->eap_fast_a_id);
+		sm->eap_fast_a_id = os_strdup(conf->eap_fast_a_id);
 
 	wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
 
@@ -971,15 +1166,18 @@
 	wpa_printf(MSG_DEBUG, "EAP: Server state machine removed");
 	if (sm->m && sm->eap_method_priv)
 		sm->m->reset(sm, sm->eap_method_priv);
-	free(sm->eapReqData);
-	free(sm->eapKeyData);
-	free(sm->lastReqData);
-	free(sm->eapRespData);
-	free(sm->identity);
-	free(sm->pac_opaque_encr_key);
-	free(sm->eap_fast_a_id);
+	os_free(sm->eap_if.eapReqData);
+	os_free(sm->eap_if.eapKeyData);
+	os_free(sm->lastReqData);
+	os_free(sm->eap_if.eapRespData);
+	os_free(sm->identity);
+	os_free(sm->pac_opaque_encr_key);
+	os_free(sm->eap_fast_a_id);
+	os_free(sm->eap_if.aaaEapReqData);
+	os_free(sm->eap_if.aaaEapRespData);
+	os_free(sm->eap_if.aaaEapKeyData);
 	eap_user_free(sm->user);
-	free(sm);
+	os_free(sm);
 }
 
 
@@ -1026,3 +1224,27 @@
 		return 0;
 	return sm->method_pending == METHOD_PENDING_WAIT;
 }
+
+
+/**
+ * eap_get_identity - Get the user identity (from EAP-Response/Identity)
+ * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
+ * @len: Buffer for returning identity length
+ * Returns: Pointer to the user identity or %NULL if not available
+ */
+const u8 * eap_get_identity(struct eap_sm *sm, size_t *len)
+{
+	*len = sm->identity_len;
+	return sm->identity;
+}
+
+
+/**
+ * eap_get_interface - Get pointer to EAP-EAPOL interface data
+ * @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
+ * Returns: Pointer to the EAP-EAPOL interface data
+ */
+struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm)
+{
+	return &sm->eap_if;
+}

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap.h (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap.h Sun Dec  9 08:34:57 2007
@@ -1,5 +1,5 @@
 /*
- * hostapd / EAP Standalone Authenticator state machine (RFC 4137)
+ * hostapd / EAP Full Authenticator state machine (RFC 4137)
  * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -35,19 +35,50 @@
 	int force_version;
 };
 
-enum eapol_bool_var {
-	EAPOL_eapSuccess, EAPOL_eapRestart, EAPOL_eapFail, EAPOL_eapResp,
-	EAPOL_eapReq, EAPOL_eapNoReq, EAPOL_portEnabled, EAPOL_eapTimeout
+struct eap_eapol_interface {
+	/* Lower layer to full authenticator variables */
+	Boolean eapResp; /* shared with EAPOL Backend Authentication */
+	u8 *eapRespData;
+	size_t eapRespDataLen;
+	Boolean portEnabled;
+	int retransWhile;
+	Boolean eapRestart; /* shared with EAPOL Authenticator PAE */
+	int eapSRTT;
+	int eapRTTVAR;
+
+	/* Full authenticator to lower layer variables */
+	Boolean eapReq; /* shared with EAPOL Backend Authentication */
+	Boolean eapNoReq; /* shared with EAPOL Backend Authentication */
+	Boolean eapSuccess;
+	Boolean eapFail;
+	Boolean eapTimeout;
+	u8 *eapReqData;
+	size_t eapReqDataLen;
+	u8 *eapKeyData;
+	size_t eapKeyDataLen;
+	Boolean eapKeyAvailable; /* called keyAvailable in IEEE 802.1X-2004 */
+
+	/* AAA interface to full authenticator variables */
+	Boolean aaaEapReq;
+	Boolean aaaEapNoReq;
+	Boolean aaaSuccess;
+	Boolean aaaFail;
+	u8 *aaaEapReqData;
+	size_t aaaEapReqDataLen;
+	u8 *aaaEapKeyData;
+	size_t aaaEapKeyDataLen;
+	Boolean aaaEapKeyAvailable;
+	int aaaMethodTimeout;
+
+	/* Full authenticator to AAA interface variables */
+	Boolean aaaEapResp;
+	u8 *aaaEapRespData;
+	size_t aaaEapRespDataLen;
+	/* aaaIdentity -> eap_get_identity() */
+	Boolean aaaTimeout;
 };
 
 struct eapol_callbacks {
-	Boolean (*get_bool)(void *ctx, enum eapol_bool_var variable);
-	void (*set_bool)(void *ctx, enum eapol_bool_var variable,
-			 Boolean value);
-	void (*set_eapReqData)(void *ctx, const u8 *eapReqData,
-			       size_t eapReqDataLen);
-	void (*set_eapKeyData)(void *ctx, const u8 *eapKeyData,
-			       size_t eapKeyDataLen);
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);
 	const char * (*get_eap_req_id_text)(void *ctx, size_t *len);
@@ -57,63 +88,21 @@
 	void *ssl_ctx;
 	void *eap_sim_db_priv;
 	Boolean backend_auth;
+	int eap_server;
 	u8 *pac_opaque_encr_key;
 	char *eap_fast_a_id;
 };
 
-
-#ifdef EAP_SERVER
 
 struct eap_sm * eap_server_sm_init(void *eapol_ctx,
 				   struct eapol_callbacks *eapol_cb,
 				   struct eap_config *eap_conf);
 void eap_server_sm_deinit(struct eap_sm *sm);
 int eap_server_sm_step(struct eap_sm *sm);
-void eap_set_eapRespData(struct eap_sm *sm, const u8 *eapRespData,
-			 size_t eapRespDataLen);
 void eap_sm_notify_cached(struct eap_sm *sm);
 void eap_sm_pending_cb(struct eap_sm *sm);
 int eap_sm_method_pending(struct eap_sm *sm);
-
-#else /* EAP_SERVER */
-
-static inline struct eap_sm *
-eap_server_sm_init(void *eapol_ctx,
-		   struct eapol_callbacks *eapol_cb,
-		   struct eap_config *eap_conf)
-{
-	return NULL;
-}
-
-static inline void eap_server_sm_deinit(struct eap_sm *sm)
-{
-}
-
-static inline int eap_server_sm_step(struct eap_sm *sm)
-{
-	return 0;
-}
-
-
-static inline void eap_set_eapRespData(struct eap_sm *sm,
-				       const u8 *eapRespData,
-				       size_t eapRespDataLen)
-{
-}
-
-static inline void eap_sm_notify_cached(struct eap_sm *sm)
-{
-}
-
-static inline void eap_sm_pending_cb(struct eap_sm *sm)
-{
-}
-
-static inline int eap_sm_method_pending(struct eap_sm *sm)
-{
-	return 0;
-}
-
-#endif /* EAP_SERVER */
+const u8 * eap_get_identity(struct eap_sm *sm, size_t *len);
+struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm);
 
 #endif /* EAP_H */

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_aka.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_aka.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_aka.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_aka.c Sun Dec  9 08:34:57 2007
@@ -103,9 +103,9 @@
 static void eap_aka_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_aka_data *data = priv;
-	free(data->next_pseudonym);
-	free(data->next_reauth_id);
-	free(data);
+	os_free(data->next_pseudonym);
+	os_free(data->next_reauth_id);
+	os_free(data);
 }
 
 
@@ -131,10 +131,10 @@
 			      struct eap_sim_msg *msg, u16 counter,
 			      const u8 *nonce_s)
 {
-	free(data->next_pseudonym);
+	os_free(data->next_pseudonym);
 	data->next_pseudonym =
 		eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 1);
-	free(data->next_reauth_id);
+	os_free(data->next_reauth_id);
 	if (data->counter <= EAP_AKA_MAX_FAST_REAUTHS) {
 		data->next_reauth_id =
 			eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 1);
@@ -167,18 +167,18 @@
 		wpa_printf(MSG_DEBUG, "   *AT_NEXT_PSEUDONYM (%s)",
 			   data->next_pseudonym);
 		eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_PSEUDONYM,
-				strlen(data->next_pseudonym),
+				os_strlen(data->next_pseudonym),
 				(u8 *) data->next_pseudonym,
-				strlen(data->next_pseudonym));
+				os_strlen(data->next_pseudonym));
 	}
 
 	if (data->next_reauth_id) {
 		wpa_printf(MSG_DEBUG, "   *AT_NEXT_REAUTH_ID (%s)",
 			   data->next_reauth_id);
 		eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_REAUTH_ID,
-				strlen(data->next_reauth_id),
+				os_strlen(data->next_reauth_id),
 				(u8 *) data->next_reauth_id,
-				strlen(data->next_reauth_id));
+				os_strlen(data->next_reauth_id));
 	}
 
 	if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
@@ -223,7 +223,7 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Re-authentication");
 
-	if (hostapd_get_rand(data->nonce_s, EAP_SIM_NONCE_S_LEN))
+	if (os_get_random(data->nonce_s, EAP_SIM_NONCE_S_LEN))
 		return NULL;
 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-AKA: NONCE_S",
 			data->nonce_s, EAP_SIM_NONCE_S_LEN);
@@ -291,13 +291,12 @@
 static Boolean eap_aka_check(struct eap_sm *sm, void *priv,
 			     u8 *respData, size_t respDataLen)
 {
-	struct eap_hdr *resp;
-	u8 *pos;
-
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	if (respDataLen < sizeof(*resp) + 4 || *pos != EAP_TYPE_AKA ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA,
+			       respData, respDataLen, &len);
+	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-AKA: Invalid frame");
 		return TRUE;
 	}
@@ -385,8 +384,8 @@
 				identity = data->reauth->identity;
 				identity_len = data->reauth->identity_len;
 				data->counter = data->reauth->counter;
-				memcpy(data->mk, data->reauth->mk,
-				       EAP_SIM_MK_LEN);
+				os_memcpy(data->mk, data->reauth->mk,
+					  EAP_SIM_MK_LEN);
 			}
 		}
 	}
@@ -471,11 +470,11 @@
 	}
 
 	if (attr->identity) {
-		free(sm->identity);
-		sm->identity = malloc(attr->identity_len);
+		os_free(sm->identity);
+		sm->identity = os_malloc(attr->identity_len);
 		if (sm->identity) {
-			memcpy(sm->identity, attr->identity,
-			       attr->identity_len);
+			os_memcpy(sm->identity, attr->identity,
+				  attr->identity_len);
 			sm->identity_len = attr->identity_len;
 		}
 	}
@@ -505,7 +504,7 @@
 	}
 
 	if (attr->res == NULL || attr->res_len != data->res_len ||
-	    memcmp(attr->res, data->res, data->res_len) != 0) {
+	    os_memcmp(attr->res, data->res, data->res_len) != 0) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message did not "
 			   "include valid AT_RES");
 		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
@@ -615,7 +614,7 @@
 			   eattr.counter, data->counter);
 		goto fail;
 	}
-	free(decrypted);
+	os_free(decrypted);
 	decrypted = NULL;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Re-authentication response includes "
@@ -668,7 +667,7 @@
 	eap_aka_state(data, NOTIFICATION);
 	eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
 	data->reauth = NULL;
-	free(decrypted);
+	os_free(decrypted);
 }
 
 
@@ -786,10 +785,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_SIM_KEYING_DATA_LEN);
+	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
+	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
 	*len = EAP_SIM_KEYING_DATA_LEN;
 	return key;
 }
@@ -803,10 +802,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_EMSK_LEN);
+	key = os_malloc(EAP_EMSK_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->emsk, EAP_EMSK_LEN);
+	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
 	*len = EAP_EMSK_LEN;
 	return key;
 }

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_fast.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_fast.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_fast.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_fast.c Sun Dec  9 08:34:57 2007
@@ -513,8 +513,8 @@
 	if (data->phase2_priv && data->phase2_method)
 		data->phase2_method->reset(sm, data->phase2_priv);
 	eap_server_tls_ssl_deinit(sm, &data->ssl);
-	free(data->srv_id);
-	free(data);
+	os_free(data->srv_id);
+	os_free(data);
 }
 
 
@@ -527,7 +527,7 @@
 	size_t srv_id_len = os_strlen(data->srv_id);
 
 	*reqDataLen = sizeof(*req) + 2 + sizeof(*a_id) + srv_id_len;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for"
 			   " request");
@@ -614,7 +614,7 @@
 
 	/* TODO: add support for fragmentation, if needed. This will need to
 	 * add TLS Message Length field, if the frame is fragmented. */
-	req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
+	req = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
 	if (req == NULL)
 		return NULL;
 
@@ -631,7 +631,7 @@
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt Phase 2 "
 			   "data");
-		free(req);
+		os_free(req);
 		return NULL;
 	}
 
@@ -919,7 +919,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
 			(u8 *) req, req_len);
 	encr = eap_fast_encrypt(sm, data, id, req, req_len, reqDataLen);
-	free(req);
+	os_free(req);
 
 	return encr;
 }
@@ -1483,9 +1483,9 @@
 	buf_len = in_len;
 	if (data->ssl.tls_in_total > buf_len)
 		buf_len = data->ssl.tls_in_total;
-	in_decrypted = malloc(buf_len);
+	in_decrypted = os_malloc(buf_len);
 	if (in_decrypted == NULL) {
-		free(data->ssl.tls_in);
+		os_free(data->ssl.tls_in);
 		data->ssl.tls_in = NULL;
 		data->ssl.tls_in_len = 0;
 		wpa_printf(MSG_WARNING, "EAP-FAST: Failed to allocate memory "
@@ -1496,13 +1496,13 @@
 	len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
 					       in_data, in_len,
 					       in_decrypted, buf_len);
-	free(data->ssl.tls_in);
+	os_free(data->ssl.tls_in);
 	data->ssl.tls_in = NULL;
 	data->ssl.tls_in_len = 0;
 	if (len_decrypted < 0) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Failed to decrypt Phase 2 "
 			   "data");
-		free(in_decrypted);
+		os_free(in_decrypted);
 		eap_fast_state(data, FAILURE);
 		return;
 	}
@@ -1512,7 +1512,7 @@
 
 	eap_fast_process_phase2_tlvs(sm, data, in_decrypted, len_decrypted);
 
-	free(in_decrypted);
+	os_free(in_decrypted);
 }
 
 
@@ -1560,7 +1560,7 @@
 		if (data->ssl.tls_in_left == 0) {
 			data->ssl.tls_in_total = tls_msg_len;
 			data->ssl.tls_in_left = tls_msg_len;
-			free(data->ssl.tls_in);
+			os_free(data->ssl.tls_in);
 			data->ssl.tls_in = NULL;
 			data->ssl.tls_in_len = 0;
 		}

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_gpsk.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_gpsk.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_gpsk.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_gpsk.c Sun Dec  9 08:34:57 2007
@@ -1,5 +1,5 @@
 /*
- * hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-06.txt) server
+ * hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-08.txt) server
  * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -77,9 +77,9 @@
 	data->state = GPSK_1;
 
 	/* TODO: add support for configuring ID_Server */
-	data->id_server = (u8 *) strdup("hostapd");
+	data->id_server = (u8 *) os_strdup("hostapd");
 	if (data->id_server)
-		data->id_server_len = strlen((char *) data->id_server);
+		data->id_server_len = os_strlen((char *) data->id_server);
 
 	data->csuite_count = 0;
 	if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
@@ -106,9 +106,9 @@
 static void eap_gpsk_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_gpsk_data *data = priv;
-	free(data->id_server);
-	free(data->id_peer);
-	free(data);
+	os_free(data->id_server);
+	os_free(data->id_peer);
+	os_free(data);
 }
 
 
@@ -122,7 +122,7 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-1");
 
-	if (hostapd_get_rand(data->rand_server, EAP_GPSK_RAND_LEN)) {
+	if (os_get_random(data->rand_server, EAP_GPSK_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to get random data");
 		eap_gpsk_state(data, FAILURE);
 		return NULL;
@@ -146,16 +146,16 @@
 	WPA_PUT_BE16(pos, data->id_server_len);
 	pos += 2;
 	if (data->id_server)
-		memcpy(pos, data->id_server, data->id_server_len);
+		os_memcpy(pos, data->id_server, data->id_server_len);
 	pos += data->id_server_len;
 
-	memcpy(pos, data->rand_server, EAP_GPSK_RAND_LEN);
+	os_memcpy(pos, data->rand_server, EAP_GPSK_RAND_LEN);
 	pos += EAP_GPSK_RAND_LEN;
 
 	WPA_PUT_BE16(pos, data->csuite_count * sizeof(struct eap_gpsk_csuite));
 	pos += 2;
-	memcpy(pos, data->csuite_list,
-	       data->csuite_count * sizeof(struct eap_gpsk_csuite));
+	os_memcpy(pos, data->csuite_list,
+		  data->csuite_count * sizeof(struct eap_gpsk_csuite));
 
 	return (u8 *) req;
 }
@@ -173,8 +173,8 @@
 	wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-3");
 
 	miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
-	len = 1 + 2 * EAP_GPSK_RAND_LEN + sizeof(struct eap_gpsk_csuite) + 2 +
-		miclen;
+	len = 1 + 2 * EAP_GPSK_RAND_LEN + 2 + data->id_server_len +
+		sizeof(struct eap_gpsk_csuite) + 2 + miclen;
 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqDataLen,
 			    len, EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL) {
@@ -187,10 +187,15 @@
 	*pos++ = EAP_GPSK_OPCODE_GPSK_3;
 	start = pos;
 
-	memcpy(pos, data->rand_peer, EAP_GPSK_RAND_LEN);
+	os_memcpy(pos, data->rand_peer, EAP_GPSK_RAND_LEN);
 	pos += EAP_GPSK_RAND_LEN;
-	memcpy(pos, data->rand_server, EAP_GPSK_RAND_LEN);
+	os_memcpy(pos, data->rand_server, EAP_GPSK_RAND_LEN);
 	pos += EAP_GPSK_RAND_LEN;
+	WPA_PUT_BE16(pos, data->id_server_len);
+	pos += 2;
+	if (data->id_server)
+		os_memcpy(pos, data->id_server, data->id_server_len);
+	pos += data->id_server_len;
 	csuite = (struct eap_gpsk_csuite *) pos;
 	WPA_PUT_BE32(csuite->vendor, data->vendor);
 	WPA_PUT_BE16(csuite->specifier, data->specifier);
@@ -203,7 +208,7 @@
 	if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
 				 data->specifier, start, pos - start, pos) < 0)
 	{
-		free(req);
+		os_free(req);
 		eap_gpsk_state(data, FAILURE);
 		return NULL;
 	}
@@ -293,14 +298,14 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	free(data->id_peer);
-	data->id_peer = malloc(alen);
+	os_free(data->id_peer);
+	data->id_peer = os_malloc(alen);
 	if (data->id_peer == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Not enough memory to store "
 			   "%d-octet ID_Peer", alen);
 		return;
 	}
-	memcpy(data->id_peer, pos, alen);
+	os_memcpy(data->id_peer, pos, alen);
 	data->id_peer_len = alen;
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
 			  data->id_peer, data->id_peer_len);
@@ -321,7 +326,7 @@
 		return;
 	}
 	if (alen != data->id_server_len ||
-	    memcmp(pos, data->id_server, alen) != 0) {
+	    os_memcmp(pos, data->id_server, alen) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1 and "
 			   "GPSK-2 did not match");
 		eap_gpsk_state(data, FAILURE);
@@ -335,7 +340,7 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	memcpy(data->rand_peer, pos, EAP_GPSK_RAND_LEN);
+	os_memcpy(data->rand_peer, pos, EAP_GPSK_RAND_LEN);
 	wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
 		    data->rand_peer, EAP_GPSK_RAND_LEN);
 	pos += EAP_GPSK_RAND_LEN;
@@ -346,7 +351,7 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	if (memcmp(data->rand_server, pos, EAP_GPSK_RAND_LEN) != 0) {
+	if (os_memcmp(data->rand_server, pos, EAP_GPSK_RAND_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1 and "
 			   "GPSK-2 did not match");
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1",
@@ -373,7 +378,7 @@
 		return;
 	}
 	if (alen != data->csuite_count * sizeof(struct eap_gpsk_csuite) ||
-	    memcmp(pos, data->csuite_list, alen) != 0) {
+	    os_memcmp(pos, data->csuite_list, alen) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List in GPSK-1 and "
 			   "GPSK-2 did not match");
 		eap_gpsk_state(data, FAILURE);
@@ -389,8 +394,8 @@
 	}
 	csuite = (const struct eap_gpsk_csuite *) pos;
 	for (i = 0; i < data->csuite_count; i++) {
-		if (memcmp(csuite, &data->csuite_list[i], sizeof(*csuite)) ==
-		    0)
+		if (os_memcmp(csuite, &data->csuite_list[i], sizeof(*csuite))
+		    == 0)
 			break;
 	}
 	if (i == data->csuite_count) {
@@ -458,7 +463,7 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	if (memcmp(mic, pos, miclen) != 0) {
+	if (os_memcmp(mic, pos, miclen) != 0) {
 		wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-2");
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
@@ -525,7 +530,7 @@
 		eap_gpsk_state(data, FAILURE);
 		return;
 	}
-	if (memcmp(mic, pos, miclen) != 0) {
+	if (os_memcmp(mic, pos, miclen) != 0) {
 		wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-4");
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
 		wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
@@ -583,10 +588,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_MSK_LEN);
+	key = os_malloc(EAP_MSK_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->msk, EAP_MSK_LEN);
+	os_memcpy(key, data->msk, EAP_MSK_LEN);
 	*len = EAP_MSK_LEN;
 
 	return key;
@@ -601,10 +606,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_EMSK_LEN);
+	key = os_malloc(EAP_EMSK_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->emsk, EAP_EMSK_LEN);
+	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
 	*len = EAP_EMSK_LEN;
 
 	return key;

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_gtc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_gtc.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_gtc.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_gtc.c Sun Dec  9 08:34:57 2007
@@ -49,7 +49,7 @@
 static void eap_gtc_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_gtc_data *data = priv;
-	free(data);
+	os_free(data);
 }
 
 
@@ -64,7 +64,7 @@
 
 	msg = data->prefix ? "CHALLENGE=Password" : "Password";
 
-	msg_len = strlen(msg);
+	msg_len = os_strlen(msg);
 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqDataLen,
 			    msg_len, EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL) {
@@ -74,7 +74,7 @@
 		return NULL;
 	}
 
-	memcpy(pos, msg, msg_len);
+	os_memcpy(pos, msg, msg_len);
 
 	data->state = CONTINUE;
 
@@ -173,7 +173,7 @@
 	}
 
 	if (rlen != sm->user->password_len ||
-	    memcmp(pos, sm->user->password, rlen) != 0) {
+	    os_memcmp(pos, sm->user->password, rlen) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure");
 		data->state = FAILURE;
 	} else {

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_i.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_i.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_i.h (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_i.h Sun Dec  9 08:34:57 2007
@@ -105,34 +105,19 @@
 		EAP_INTEGRITY_CHECK, EAP_METHOD_RESPONSE, EAP_METHOD_REQUEST,
 		EAP_PROPOSE_METHOD, EAP_SELECT_ACTION, EAP_SEND_REQUEST,
 		EAP_DISCARD, EAP_NAK, EAP_RETRANSMIT, EAP_SUCCESS, EAP_FAILURE,
-		EAP_TIMEOUT_FAILURE, EAP_PICK_UP_METHOD
+		EAP_TIMEOUT_FAILURE, EAP_PICK_UP_METHOD,
+		EAP_INITIALIZE_PASSTHROUGH, EAP_IDLE2, EAP_RETRANSMIT2,
+		EAP_RECEIVED2, EAP_DISCARD2, EAP_SEND_REQUEST2,
+		EAP_AAA_REQUEST, EAP_AAA_RESPONSE, EAP_AAA_IDLE,
+		EAP_TIMEOUT_FAILURE2, EAP_FAILURE2, EAP_SUCCESS2
 	} EAP_state;
 
 	/* Constants */
 	int MaxRetrans;
 
-	/* Lower layer to standalone authenticator variables */
-	/* eapResp: eapol_sm->be_auth.eapResp */
-	/* portEnabled: eapol_sm->portEnabled */
-	/* eapRestart: eapol_sm->auth_pae.eapRestart */
-	u8 *eapRespData;
-	size_t eapRespDataLen;
-	int retransWhile;
-	int eapSRTT;
-	int eapRTTVAR;
+	struct eap_eapol_interface eap_if;
 
-	/* Standalone authenticator to lower layer variables */
-	/* eapReq: eapol_sm->be_auth.eapReq */
-	/* eapNoReq: eapol_sm->be_auth.eapNoReq */
-	/* eapSuccess: eapol_sm->eapSuccess */
-	/* eapFail: eapol_sm->eapFail */
-	/* eapTimeout: eapol_sm->eapTimeout */
-	u8 *eapReqData;
-	size_t eapReqDataLen;
-	u8 *eapKeyData; /* also eapKeyAvailable (boolean) */
-	size_t eapKeyDataLen;
-
-	/* Standalone authenticator state machine local variables */
+	/* Full authenticator state machine local variables */
 
 	/* Long-term (maintained betwen packets) */
 	EapType currentMethod;
@@ -153,12 +138,13 @@
 	u32 respVendorMethod;
 	Boolean ignore;
 	enum {
-		DECISION_SUCCESS, DECISION_FAILURE, DECISION_CONTINUE
+		DECISION_SUCCESS, DECISION_FAILURE, DECISION_CONTINUE,
+		DECISION_PASSTHROUGH
 	} decision;
 
 	/* Miscellaneous variables */
 	const struct eap_method *m; /* selected EAP method */
-	/* not defined in draft-ietf-eap-statemachine-02 */
+	/* not defined in RFC 4137 */
 	Boolean changed;
 	void *eapol_ctx, *msg_ctx;
 	struct eapol_callbacks *eapol_cb;
@@ -174,6 +160,7 @@
 	void *eap_sim_db_priv;
 	Boolean backend_auth;
 	Boolean update_user;
+	int eap_server;
 
 	int num_rounds;
 	enum {

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_identity.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_identity.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_identity.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_identity.c Sun Dec  9 08:34:57 2007
@@ -51,7 +51,7 @@
 static void eap_identity_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_identity_data *data = priv;
-	free(data);
+	os_free(data);
 }
 
 
@@ -81,7 +81,7 @@
 	}
 
 	if (req_data)
-		memcpy(pos, req_data, req_data_len);
+		os_memcpy(pos, req_data, req_data_len);
 
 	return (u8 *) req;
 }
@@ -127,12 +127,12 @@
 		return; /* Should not happen - frame already validated */
 
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len);
-	free(sm->identity);
-	sm->identity = malloc(len);
+	os_free(sm->identity);
+	sm->identity = os_malloc(len ? len : 1);
 	if (sm->identity == NULL) {
 		data->state = FAILURE;
 	} else {
-		memcpy(sm->identity, pos, len);
+		os_memcpy(sm->identity, pos, len);
 		sm->identity_len = len;
 		data->state = SUCCESS;
 	}

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_md5.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_md5.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_md5.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_md5.c Sun Dec  9 08:34:57 2007
@@ -44,7 +44,7 @@
 static void eap_md5_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_md5_data *data = priv;
-	free(data);
+	os_free(data);
 }
 
 
@@ -55,7 +55,7 @@
 	struct eap_hdr *req;
 	u8 *pos;
 
-	if (hostapd_get_rand(data->challenge, CHALLENGE_LEN)) {
+	if (os_get_random(data->challenge, CHALLENGE_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data");
 		data->state = FAILURE;
 		return NULL;
@@ -71,7 +71,7 @@
 	}
 
 	*pos++ = CHALLENGE_LEN;
-	memcpy(pos, data->challenge, CHALLENGE_LEN);
+	os_memcpy(pos, data->challenge, CHALLENGE_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", pos, CHALLENGE_LEN);
 
 	data->state = CONTINUE;
@@ -138,7 +138,7 @@
 	len[2] = CHALLENGE_LEN;
 	md5_vector(3, addr, len, hash);
 
-	if (memcmp(hash, pos, MD5_MAC_LEN) == 0) {
+	if (os_memcmp(hash, pos, MD5_MAC_LEN) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success");
 		data->state = SUCCESS;
 	} else {

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.c Sun Dec  9 08:34:57 2007
@@ -52,7 +52,7 @@
 {
 	struct eap_method *m;
 	for (m = eap_methods; m; m = m->next) {
-		if (strcmp(m->name, name) == 0) {
+		if (os_strcmp(m->name, name) == 0) {
 			*vendor = m->vendor;
 			return m->method;
 		}
@@ -95,7 +95,7 @@
  */
 void eap_server_method_free(struct eap_method *method)
 {
-	free(method);
+	os_free(method);
 }
 
 
@@ -119,7 +119,7 @@
 	for (m = eap_methods; m; m = m->next) {
 		if ((m->vendor == method->vendor &&
 		     m->method == method->method) ||
-		    strcmp(m->name, method->name) == 0)
+		    os_strcmp(m->name, method->name) == 0)
 			return -2;
 		last = m;
 	}
@@ -254,6 +254,13 @@
 	}
 #endif /* EAP_FAST */
 
+#ifdef EAP_WSC
+	if (ret == 0) {
+		int eap_server_wsc_register(void);
+		ret = eap_server_wsc_register();
+	}
+#endif /* EAP_WSC */
+
 	return ret;
 }
 

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.h (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_methods.h Sun Dec  9 08:34:57 2007
@@ -22,29 +22,8 @@
 void eap_server_method_free(struct eap_method *method);
 int eap_server_method_register(struct eap_method *method);
 
-#ifdef EAP_SERVER
-
 EapType eap_server_get_type(const char *name, int *vendor);
 int eap_server_register_methods(void);
 void eap_server_unregister_methods(void);
 
-#else /* EAP_SERVER */
-
-static inline EapType eap_server_get_type(const char *name, int *vendor)
-{
-	*vendor = EAP_VENDOR_IETF;
-	return EAP_TYPE_NONE;
-}
-
-static inline int eap_server_register_methods(void)
-{
-	return 0;
-}
-
-static inline void eap_server_unregister_methods(void)
-{
-}
-
-#endif /* EAP_SERVER */
-
 #endif /* EAP_METHODS_H */

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_mschapv2.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_mschapv2.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_mschapv2.c Sun Dec  9 08:34:57 2007
@@ -95,8 +95,8 @@
 	if (data == NULL)
 		return;
 
-	free(data->peer_challenge);
-	free(data);
+	os_free(data->peer_challenge);
+	os_free(data);
 }
 
 
@@ -111,14 +111,14 @@
 	size_t ms_len;
 
 	if (!data->auth_challenge_from_tls &&
-	    hostapd_get_rand(data->auth_challenge, CHALLENGE_LEN)) {
+	    os_get_random(data->auth_challenge, CHALLENGE_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to get random "
 			   "data");
 		data->state = FAILURE;
 		return NULL;
 	}
 
-	ms_len = sizeof(*ms) + 1 + CHALLENGE_LEN + strlen(name);
+	ms_len = sizeof(*ms) + 1 + CHALLENGE_LEN + os_strlen(name);
 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqDataLen,
 			    ms_len, EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL) {
@@ -136,11 +136,11 @@
 	pos = (u8 *) (ms + 1);
 	*pos++ = CHALLENGE_LEN;
 	if (!data->auth_challenge_from_tls)
-		memcpy(pos, data->auth_challenge, CHALLENGE_LEN);
+		os_memcpy(pos, data->auth_challenge, CHALLENGE_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge", pos,
 		    CHALLENGE_LEN);
 	pos += CHALLENGE_LEN;
-	memcpy(pos, name, strlen(name));
+	os_memcpy(pos, name, os_strlen(name));
 
 	return (u8 *) req;
 }
@@ -157,7 +157,7 @@
 	size_t ms_len;
 
 	ms_len = sizeof(*ms) + 2 + 2 * sizeof(data->auth_response) + 1 + 2 +
-		strlen(message);
+		os_strlen(message);
 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqDataLen,
 			    ms_len, EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL) {
@@ -182,7 +182,7 @@
 	*pos++ = ' ';
 	*pos++ = 'M';
 	*pos++ = '=';
-	memcpy(pos, message, strlen(message));
+	os_memcpy(pos, message, os_strlen(message));
 
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Success Request Message",
 			  msg, ms_len - sizeof(*ms));
@@ -202,7 +202,7 @@
 		"M=FAILED";
 	size_t ms_len;
 
-	ms_len = sizeof(*ms) + strlen(message);
+	ms_len = sizeof(*ms) + os_strlen(message);
 	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqDataLen,
 			    ms_len, EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL) {
@@ -217,10 +217,10 @@
 	ms->mschapv2_id = data->resp_mschapv2_id;
 	WPA_PUT_BE16(ms->ms_length, ms_len);
 
-	memcpy((u8 *) (ms + 1), message, strlen(message));
+	os_memcpy((u8 *) (ms + 1), message, os_strlen(message));
 
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Failure Request Message",
-			  (u8 *) message, strlen(message));
+			  (u8 *) message, os_strlen(message));
 
 	return (u8 *) req;
 }
@@ -365,7 +365,7 @@
 	}
 
 	if (username_len != user_len ||
-	    memcmp(username, user, username_len) != 0) {
+	    os_memcmp(username, user, username_len) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Mismatch in user names");
 		wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Expected user "
 				  "name", username, username_len);
@@ -392,7 +392,7 @@
 				     expected);
 	}
 
-	if (memcmp(nt_response, expected, 24) == 0) {
+	if (os_memcmp(nt_response, expected, 24) == 0) {
 		const u8 *pw_hash;
 		u8 pw_hash_buf[16], pw_hash_hash[16];
 
@@ -537,7 +537,7 @@
 		return NULL;
 
 	*len = 2 * MSCHAPV2_KEY_LEN;
-	key = malloc(*len);
+	key = os_malloc(*len);
 	if (key == NULL)
 		return NULL;
 	get_asymetric_start_key(data->master_key, key, MSCHAPV2_KEY_LEN, 0, 0);

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_pax.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_pax.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_pax.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_pax.c Sun Dec  9 08:34:57 2007
@@ -68,8 +68,8 @@
 static void eap_pax_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_pax_data *data = priv;
-	free(data->cid);
-	free(data);
+	os_free(data->cid);
+	os_free(data);
 }
 
 
@@ -82,14 +82,14 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (sending)");
 
-	if (hostapd_get_rand(data->rand.r.x, EAP_PAX_RAND_LEN)) {
+	if (os_get_random(data->rand.r.x, EAP_PAX_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to get random data");
 		data->state = FAILURE;
 		return NULL;
 	}
 
 	*reqDataLen = sizeof(*req) + 2 + EAP_PAX_RAND_LEN + EAP_PAX_ICV_LEN;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory "
 			   "request");
@@ -109,7 +109,7 @@
 	pos = (u8 *) (req + 1);
 	*pos++ = 0;
 	*pos++ = EAP_PAX_RAND_LEN;
-	memcpy(pos, data->rand.r.x, EAP_PAX_RAND_LEN);
+	os_memcpy(pos, data->rand.r.x, EAP_PAX_RAND_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: A = X (server rand)",
 		    pos, EAP_PAX_RAND_LEN);
 	pos += EAP_PAX_RAND_LEN;
@@ -134,7 +134,7 @@
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-3 (sending)");
 
 	*reqDataLen = sizeof(*req) + 2 + EAP_PAX_MAC_LEN + EAP_PAX_ICV_LEN;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory "
 			   "request");
@@ -277,7 +277,7 @@
 		eap_pax_mac(data->mac_id, data->ick, EAP_PAX_ICK_LEN,
 			    respData, len - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0,
 			    icvbuf);
-		if (memcmp(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) {
+		if (os_memcmp(icvbuf, icv, EAP_PAX_ICV_LEN) != 0) {
 			wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV");
 			wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV",
 				    icvbuf, EAP_PAX_ICV_LEN);
@@ -315,7 +315,7 @@
 	}
 	pos += 2;
 	left -= 2;
-	memcpy(data->rand.r.y, pos, EAP_PAX_RAND_LEN);
+	os_memcpy(data->rand.r.y, pos, EAP_PAX_RAND_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Y (client rand)",
 		    data->rand.r.y, EAP_PAX_RAND_LEN);
 	pos += EAP_PAX_RAND_LEN;
@@ -326,14 +326,14 @@
 		return;
 	}
 	data->cid_len = WPA_GET_BE16(pos);
-	free(data->cid);
-	data->cid = malloc(data->cid_len);
+	os_free(data->cid);
+	data->cid = os_malloc(data->cid_len);
 	if (data->cid == NULL) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Failed to allocate memory for "
 			   "CID");
 		return;
 	}
-	memcpy(data->cid, pos + 2, data->cid_len);
+	os_memcpy(data->cid, pos + 2, data->cid_len);
 	pos += 2 + data->cid_len;
 	left -= 2 + data->cid_len;
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PAX: CID",
@@ -384,7 +384,7 @@
 		data->state = FAILURE;
 		return;
 	}
-	memcpy(data->ak, sm->user->password, EAP_PAX_AK_LEN);
+	os_memcpy(data->ak, sm->user->password, EAP_PAX_AK_LEN);
 
 	if (eap_pax_initial_key_derivation(data->mac_id, data->ak,
 					   data->rand.e, data->mk, data->ck,
@@ -400,7 +400,7 @@
 		    data->rand.r.x, EAP_PAX_RAND_LEN,
 		    data->rand.r.y, EAP_PAX_RAND_LEN,
 		    (u8 *) data->cid, data->cid_len, mac);
-	if (memcmp(mac, pos, EAP_PAX_MAC_LEN) != 0) {
+	if (os_memcmp(mac, pos, EAP_PAX_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Invalid MAC_CK(A, B, CID) in "
 			   "PAX_STD-2");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected MAC_CK(A, B, CID)",
@@ -420,7 +420,7 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN);
 	eap_pax_mac(data->mac_id, data->ick, EAP_PAX_ICK_LEN,
 		    respData, len - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0, icvbuf);
-	if (memcmp(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) {
+	if (os_memcmp(icvbuf, pos, EAP_PAX_ICV_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Invalid ICV in PAX_STD-2");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: Expected ICV",
 			    icvbuf, EAP_PAX_ICV_LEN);
@@ -492,7 +492,7 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_MSK_LEN);
+	key = os_malloc(EAP_MSK_LEN);
 	if (key == NULL)
 		return NULL;
 
@@ -513,7 +513,7 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_EMSK_LEN);
+	key = os_malloc(EAP_EMSK_LEN);
 	if (key == NULL)
 		return NULL;
 

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_peap.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_peap.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_peap.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_peap.c Sun Dec  9 08:34:57 2007
@@ -159,7 +159,7 @@
 	if (data->phase2_priv && data->phase2_method)
 		data->phase2_method->reset(sm, data->phase2_priv);
 	eap_server_tls_ssl_deinit(sm, &data->ssl);
-	free(data);
+	os_free(data);
 }
 
 
@@ -170,7 +170,7 @@
 	u8 *pos;
 
 	*reqDataLen = sizeof(*req) + 2;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PEAP: Failed to allocate memory for"
 			   " request");
@@ -224,7 +224,7 @@
 
 	/* TODO: add support for fragmentation, if needed. This will need to
 	 * add TLS Message Length field, if the frame is fragmented. */
-	req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
+	req = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
 	if (req == NULL)
 		return NULL;
 
@@ -241,7 +241,7 @@
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt Phase 2 "
 			   "data");
-		free(req);
+		os_free(req);
 		return NULL;
 	}
 
@@ -273,7 +273,7 @@
 	}
 
 	encr_req = eap_peap_encrypt(sm, data, id, req, req_len, reqDataLen);
-	free(buf);
+	os_free(buf);
 
 	return encr_req;
 }
@@ -301,7 +301,7 @@
 
 	encr_req = eap_peap_encrypt(sm, data, id, (u8 *) hdr, req_len,
 				    reqDataLen);
-	free(hdr);
+	os_free(hdr);
 
 	return encr_req;
 }
@@ -488,9 +488,9 @@
 	buf_len = in_len;
 	if (data->ssl.tls_in_total > buf_len)
 		buf_len = data->ssl.tls_in_total;
-	in_decrypted = malloc(buf_len);
+	in_decrypted = os_malloc(buf_len);
 	if (in_decrypted == NULL) {
-		free(data->ssl.tls_in);
+		os_free(data->ssl.tls_in);
 		data->ssl.tls_in = NULL;
 		data->ssl.tls_in_len = 0;
 		wpa_printf(MSG_WARNING, "EAP-PEAP: failed to allocate memory "
@@ -501,13 +501,13 @@
 	len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
 					       in_data, in_len,
 					       in_decrypted, buf_len);
-	free(data->ssl.tls_in);
+	os_free(data->ssl.tls_in);
 	data->ssl.tls_in = NULL;
 	data->ssl.tls_in_len = 0;
 	if (len_decrypted < 0) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Failed to decrypt Phase 2 "
 			   "data");
-		free(in_decrypted);
+		os_free(in_decrypted);
 		eap_peap_state(data, FAILURE);
 		return;
 	}
@@ -518,14 +518,14 @@
 	hdr = (struct eap_hdr *) in_decrypted;
 
 	if (data->peap_version == 0 && data->state != PHASE2_TLV) {
-		struct eap_hdr *nhdr = malloc(sizeof(struct eap_hdr) +
-					      len_decrypted);
+		struct eap_hdr *nhdr = os_malloc(sizeof(struct eap_hdr) +
+						 len_decrypted);
 		if (nhdr == NULL) {
-			free(in_decrypted);
+			os_free(in_decrypted);
 			return;
 		}
-		memcpy((u8 *) (nhdr + 1), in_decrypted, len_decrypted);
-		free(in_decrypted);
+		os_memcpy((u8 *) (nhdr + 1), in_decrypted, len_decrypted);
+		os_free(in_decrypted);
 		nhdr->code = resp->code;
 		nhdr->identifier = resp->identifier;
 		nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
@@ -536,7 +536,7 @@
 	}
 	hdr = (struct eap_hdr *) in_decrypted;
 	if (len_decrypted < (int) sizeof(*hdr)) {
-		free(in_decrypted);
+		os_free(in_decrypted);
 		wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
 			   "EAP frame (len=%d)", len_decrypted);
 		eap_peap_req_failure(sm, data);
@@ -544,7 +544,7 @@
 	}
 	len = be_to_host16(hdr->length);
 	if (len > len_decrypted) {
-		free(in_decrypted);
+		os_free(in_decrypted);
 		wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in "
 			   "Phase 2 EAP frame (len=%d hdr->length=%d)",
 			   len_decrypted, len);
@@ -573,7 +573,7 @@
 		break;
 	}
 
-	free(in_decrypted);
+	os_free(in_decrypted);
  }
 
 
@@ -621,7 +621,7 @@
 		if (data->ssl.tls_in_left == 0) {
 			data->ssl.tls_in_total = tls_msg_len;
 			data->ssl.tls_in_left = tls_msg_len;
-			free(data->ssl.tls_in);
+			os_free(data->ssl.tls_in);
 			data->ssl.tls_in = NULL;
 			data->ssl.tls_in_len = 0;
 		}

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_psk.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_psk.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_psk.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_psk.c Sun Dec  9 08:34:57 2007
@@ -53,8 +53,8 @@
 static void eap_psk_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_psk_data *data = priv;
-	free(data->id_p);
-	free(data);
+	os_free(data->id_p);
+	os_free(data);
 }
 
 
@@ -65,7 +65,7 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)");
 
-	if (hostapd_get_rand(data->rand_s, EAP_PSK_RAND_LEN)) {
+	if (os_get_random(data->rand_s, EAP_PSK_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
 		data->state = FAILURE;
 		return NULL;
@@ -74,7 +74,7 @@
 		    data->rand_s, EAP_PSK_RAND_LEN);
 
 	*reqDataLen = sizeof(*req) + data->id_s_len;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
 			   "request");
@@ -87,8 +87,8 @@
 	req->length = host_to_be16(*reqDataLen);
 	req->type = EAP_TYPE_PSK;
 	req->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */
-	memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
-	memcpy((u8 *) (req + 1), data->id_s, data->id_s_len);
+	os_memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
+	os_memcpy((u8 *) (req + 1), data->id_s, data->id_s_len);
 
 	return (u8 *) req;
 }
@@ -104,7 +104,7 @@
 	wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-3 (sending)");
 
 	*reqDataLen = sizeof(*req) + 4 + 16 + 1;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
 			   "request");
@@ -117,20 +117,20 @@
 	req->length = host_to_be16(*reqDataLen);
 	req->type = EAP_TYPE_PSK;
 	req->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */
-	memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
+	os_memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
 
 	/* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
 	buflen = data->id_s_len + EAP_PSK_RAND_LEN;
-	buf = malloc(buflen);
+	buf = os_malloc(buflen);
 	if (buf == NULL) {
-		free(req);
-		data->state = FAILURE;
-		return NULL;
-	}
-	memcpy(buf, data->id_s, data->id_s_len);
-	memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
+		os_free(req);
+		data->state = FAILURE;
+		return NULL;
+	}
+	os_memcpy(buf, data->id_s, data->id_s_len);
+	os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
 	omac1_aes_128(data->ak, buf, buflen, req->mac_s);
-	free(buf);
+	os_free(buf);
 
 	eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk,
 			    data->emsk);
@@ -138,10 +138,10 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN);
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN);
 
-	memset(nonce, 0, sizeof(nonce));
+	os_memset(nonce, 0, sizeof(nonce));
 	pchannel = (u8 *) (req + 1);
-	memcpy(pchannel, nonce + 12, 4);
-	memset(pchannel + 4, 0, 16); /* Tag */
+	os_memcpy(pchannel, nonce + 12, 4);
+	os_memset(pchannel + 4, 0, 16); /* Tag */
 	pchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6;
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (plaintext)",
 		    pchannel, 4 + 16 + 1);
@@ -233,14 +233,14 @@
 	pos = (u8 *) (resp + 1);
 	left = len - sizeof(*resp);
 
-	free(data->id_p);
-	data->id_p = malloc(left);
+	os_free(data->id_p);
+	data->id_p = os_malloc(left);
 	if (data->id_p == NULL) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Failed to allocate memory for "
 			   "ID_P");
 		return;
 	}
-	memcpy(data->id_p, pos, left);
+	os_memcpy(data->id_p, pos, left);
 	data->id_p_len = left;
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P",
 			  data->id_p, data->id_p_len);
@@ -286,26 +286,26 @@
 
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_P (client rand)",
 		    resp->rand_p, EAP_PSK_RAND_LEN);
-	memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN);
+	os_memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN);
 
 	/* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
 	buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
-	buf = malloc(buflen);
+	buf = os_malloc(buflen);
 	if (buf == NULL) {
 		data->state = FAILURE;
 		return;
 	}
-	memcpy(buf, data->id_p, data->id_p_len);
+	os_memcpy(buf, data->id_p, data->id_p_len);
 	pos = buf + data->id_p_len;
-	memcpy(pos, data->id_s, data->id_s_len);
+	os_memcpy(pos, data->id_s, data->id_s_len);
 	pos += data->id_s_len;
-	memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN);
+	os_memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN);
 	pos += EAP_PSK_RAND_LEN;
-	memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
+	os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
 	omac1_aes_128(data->ak, buf, buflen, mac);
-	free(buf);
+	os_free(buf);
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN);
-	if (memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
+	if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P");
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P",
 			    mac, EAP_PSK_MAC_LEN);
@@ -348,23 +348,23 @@
 		return;
 	}
 
-	memset(nonce, 0, 12);
-	memcpy(nonce + 12, pos, 4);
+	os_memset(nonce, 0, 12);
+	os_memcpy(nonce + 12, pos, 4);
 	pos += 4;
 	left -= 4;
 	tag = pos;
 	pos += 16;
 	left -= 16;
 
-	decrypted = malloc(left);
+	decrypted = os_malloc(left);
 	if (decrypted == NULL)
 		return;
-	memcpy(decrypted, pos, left);
+	os_memcpy(decrypted, pos, left);
 
 	if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
 				respData, 22, decrypted, left, tag)) {
 		wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
-		free(decrypted);
+		os_free(decrypted);
 		data->state = FAILURE;
 		return;
 	}
@@ -386,7 +386,7 @@
 		data->state = FAILURE;
 		break;
 	}
-	free(decrypted);
+	os_free(decrypted);
 }
 
 
@@ -431,10 +431,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_MSK_LEN);
+	key = os_malloc(EAP_MSK_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->msk, EAP_MSK_LEN);
+	os_memcpy(key, data->msk, EAP_MSK_LEN);
 	*len = EAP_MSK_LEN;
 
 	return key;
@@ -449,10 +449,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_EMSK_LEN);
+	key = os_malloc(EAP_EMSK_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->emsk, EAP_EMSK_LEN);
+	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
 	*len = EAP_EMSK_LEN;
 
 	return key;

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_sake.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_sake.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_sake.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_sake.c Sun Dec  9 08:34:57 2007
@@ -74,7 +74,7 @@
 		return NULL;
 	data->state = CHALLENGE;
 
-	if (hostapd_get_rand(&data->session_id, 1)) {
+	if (os_get_random(&data->session_id, 1)) {
 		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data");
 		os_free(data);
 		return NULL;
@@ -83,9 +83,9 @@
 		   data->session_id);
 
 	/* TODO: add support for configuring SERVERID */
-	data->serverid = (u8 *) strdup("hostapd");
+	data->serverid = (u8 *) os_strdup("hostapd");
 	if (data->serverid)
-		data->serverid_len = strlen((char *) data->serverid);
+		data->serverid_len = os_strlen((char *) data->serverid);
 
 	return data;
 }
@@ -172,7 +172,7 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge");
 
-	if (hostapd_get_rand(data->rand_s, EAP_SAKE_RAND_LEN)) {
+	if (os_get_random(data->rand_s, EAP_SAKE_RAND_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data");
 		data->state = FAILURE;
 		return NULL;

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_sim.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_sim.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_sim.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_sim.c Sun Dec  9 08:34:57 2007
@@ -89,9 +89,9 @@
 static void eap_sim_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_sim_data *data = priv;
-	free(data->next_pseudonym);
-	free(data->next_reauth_id);
-	free(data);
+	os_free(data->next_pseudonym);
+	os_free(data->next_reauth_id);
+	os_free(data);
 }
 
 
@@ -122,10 +122,10 @@
 			      struct eap_sim_msg *msg, u16 counter,
 			      const u8 *nonce_s)
 {
-	free(data->next_pseudonym);
+	os_free(data->next_pseudonym);
 	data->next_pseudonym =
 		eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 0);
-	free(data->next_reauth_id);
+	os_free(data->next_reauth_id);
 	if (data->counter <= EAP_SIM_MAX_FAST_REAUTHS) {
 		data->next_reauth_id =
 			eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 0);
@@ -158,18 +158,18 @@
 		wpa_printf(MSG_DEBUG, "   *AT_NEXT_PSEUDONYM (%s)",
 			   data->next_pseudonym);
 		eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_PSEUDONYM,
-				strlen(data->next_pseudonym),
+				os_strlen(data->next_pseudonym),
 				(u8 *) data->next_pseudonym,
-				strlen(data->next_pseudonym));
+				os_strlen(data->next_pseudonym));
 	}
 
 	if (data->next_reauth_id) {
 		wpa_printf(MSG_DEBUG, "   *AT_NEXT_REAUTH_ID (%s)",
 			   data->next_reauth_id);
 		eap_sim_msg_add(msg, EAP_SIM_AT_NEXT_REAUTH_ID,
-				strlen(data->next_reauth_id),
+				os_strlen(data->next_reauth_id),
 				(u8 *) data->next_reauth_id,
-				strlen(data->next_reauth_id));
+				os_strlen(data->next_reauth_id));
 	}
 
 	if (eap_sim_msg_add_encr_end(msg, data->k_encr, EAP_SIM_AT_PADDING)) {
@@ -215,7 +215,7 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Re-authentication");
 
-	if (hostapd_get_rand(data->nonce_s, EAP_SIM_NONCE_S_LEN))
+	if (os_get_random(data->nonce_s, EAP_SIM_NONCE_S_LEN))
 		return NULL;
 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: NONCE_S",
 			data->nonce_s, EAP_SIM_NONCE_S_LEN);
@@ -265,17 +265,17 @@
 			     u8 *respData, size_t respDataLen)
 {
 	struct eap_sim_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, subtype;
-
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	if (respDataLen < sizeof(*resp) + 4 || *pos != EAP_TYPE_SIM ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+	const u8 *pos;
+	size_t len;
+	u8 subtype;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM,
+			       respData, respDataLen, &len);
+	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Invalid frame");
 		return TRUE;
 	}
-	subtype = pos[1];
+	subtype = *pos;
 
 	if (subtype == EAP_SIM_SUBTYPE_CLIENT_ERROR)
 		return FALSE;
@@ -344,11 +344,11 @@
 	}
 
 	if (attr->identity) {
-		free(sm->identity);
-		sm->identity = malloc(attr->identity_len);
+		os_free(sm->identity);
+		sm->identity = os_malloc(attr->identity_len);
 		if (sm->identity) {
-			memcpy(sm->identity, attr->identity,
-			       attr->identity_len);
+			os_memcpy(sm->identity, attr->identity,
+				  attr->identity_len);
 			sm->identity_len = attr->identity_len;
 		}
 	}
@@ -375,8 +375,8 @@
 				identity = data->reauth->identity;
 				identity_len = data->reauth->identity_len;
 				data->counter = data->reauth->counter;
-				memcpy(data->mk, data->reauth->mk,
-				       EAP_SIM_MK_LEN);
+				os_memcpy(data->mk, data->reauth->mk,
+					  EAP_SIM_MK_LEN);
 			}
 		}
 	}
@@ -419,7 +419,7 @@
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Identity for MK derivation",
 			  sm->identity, sm->identity_len);
 
-	memcpy(data->nonce_mt, attr->nonce_mt, EAP_SIM_NONCE_MT_LEN);
+	os_memcpy(data->nonce_mt, attr->nonce_mt, EAP_SIM_NONCE_MT_LEN);
 	WPA_PUT_BE16(ver_list, EAP_SIM_VERSION);
 	eap_sim_derive_mk(sm->identity, sm->identity_len, attr->nonce_mt,
 			  attr->selected_version, ver_list, sizeof(ver_list),
@@ -515,7 +515,7 @@
 			   eattr.counter, data->counter);
 		goto fail;
 	}
-	free(decrypted);
+	os_free(decrypted);
 	decrypted = NULL;
 
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Re-authentication response includes "
@@ -558,7 +558,7 @@
 	eap_sim_state(data, FAILURE);
 	eap_sim_db_remove_reauth(sm->eap_sim_db_priv, data->reauth);
 	data->reauth = NULL;
-	free(decrypted);
+	os_free(decrypted);
 }
 
 
@@ -632,10 +632,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_SIM_KEYING_DATA_LEN);
+	key = os_malloc(EAP_SIM_KEYING_DATA_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
+	os_memcpy(key, data->msk, EAP_SIM_KEYING_DATA_LEN);
 	*len = EAP_SIM_KEYING_DATA_LEN;
 	return key;
 }
@@ -649,10 +649,10 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(EAP_EMSK_LEN);
+	key = os_malloc(EAP_EMSK_LEN);
 	if (key == NULL)
 		return NULL;
-	memcpy(key, data->emsk, EAP_EMSK_LEN);
+	os_memcpy(key, data->emsk, EAP_EMSK_LEN);
 	*len = EAP_EMSK_LEN;
 	return key;
 }

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_sim_db.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_sim_db.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_sim_db.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_sim_db.c Sun Dec  9 08:34:57 2007
@@ -83,7 +83,7 @@
 	entry = data->pending;
 	while (entry) {
 		if (entry->aka == aka && entry->imsi_len == imsi_len &&
-		    memcmp(entry->imsi, imsi, imsi_len) == 0) {
+		    os_memcmp(entry->imsi, imsi, imsi_len) == 0) {
 			if (prev)
 				prev->next = entry->next;
 			else
@@ -118,7 +118,7 @@
 	 * (IMSI = ASCII string, Kc/SRES/RAND = hex string)
 	 */
 
-	entry = eap_sim_db_get_pending(data, (u8 *) imsi, strlen(imsi), 0);
+	entry = eap_sim_db_get_pending(data, (u8 *) imsi, os_strlen(imsi), 0);
 	if (entry == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the "
 			   "received message found");
@@ -126,7 +126,7 @@
 	}
 
 	start = buf;
-	if (strncmp(start, "FAILURE", 7) == 0) {
+	if (os_strncmp(start, "FAILURE", 7) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported "
 			   "failure");
 		entry->state = FAILURE;
@@ -137,11 +137,11 @@
 
 	num_chal = 0;
 	while (num_chal < EAP_SIM_MAX_CHAL) {
-		end = strchr(start, ' ');
+		end = os_strchr(start, ' ');
 		if (end)
 			*end = '\0';
 
-		pos = strchr(start, ':');
+		pos = os_strchr(start, ':');
 		if (pos == NULL)
 			goto parse_fail;
 		*pos = '\0';
@@ -150,7 +150,7 @@
 			goto parse_fail;
 
 		start = pos + 1;
-		pos = strchr(start, ':');
+		pos = os_strchr(start, ':');
 		if (pos == NULL)
 			goto parse_fail;
 		*pos = '\0';
@@ -180,7 +180,7 @@
 
 parse_fail:
 	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
-	free(entry);
+	os_free(entry);
 }
 
 
@@ -196,7 +196,7 @@
 	 * (IMSI = ASCII string, RAND/AUTN/IK/CK/RES = hex string)
 	 */
 
-	entry = eap_sim_db_get_pending(data, (u8 *) imsi, strlen(imsi), 1);
+	entry = eap_sim_db_get_pending(data, (u8 *) imsi, os_strlen(imsi), 1);
 	if (entry == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: No pending entry for the "
 			   "received message found");
@@ -204,7 +204,7 @@
 	}
 
 	start = buf;
-	if (strncmp(start, "FAILURE", 7) == 0) {
+	if (os_strncmp(start, "FAILURE", 7) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: External server reported "
 			   "failure");
 		entry->state = FAILURE;
@@ -213,7 +213,7 @@
 		return;
 	}
 
-	end = strchr(start, ' ');
+	end = os_strchr(start, ' ');
 	if (end == NULL)
 		goto parse_fail;
 	*end = '\0';
@@ -221,7 +221,7 @@
 		goto parse_fail;
 
 	start = end + 1;
-	end = strchr(start, ' ');
+	end = os_strchr(start, ' ');
 	if (end == NULL)
 		goto parse_fail;
 	*end = '\0';
@@ -229,7 +229,7 @@
 		goto parse_fail;
 
 	start = end + 1;
-	end = strchr(start, ' ');
+	end = os_strchr(start, ' ');
 	if (end == NULL)
 		goto parse_fail;
 	*end = '\0';
@@ -237,7 +237,7 @@
 		goto parse_fail;
 
 	start = end + 1;
-	end = strchr(start, ' ');
+	end = os_strchr(start, ' ');
 	if (end == NULL)
 		goto parse_fail;
 	*end = '\0';
@@ -245,7 +245,7 @@
 		goto parse_fail;
 
 	start = end + 1;
-	end = strchr(start, ' ');
+	end = os_strchr(start, ' ');
 	if (end)
 		*end = '\0';
 	else {
@@ -271,7 +271,7 @@
 
 parse_fail:
 	wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failed to parse response string");
-	free(entry);
+	os_free(entry);
 }
 
 
@@ -301,21 +301,21 @@
 	/* <cmd> <IMSI> ... */
 
 	cmd = buf;
-	pos = strchr(cmd, ' ');
+	pos = os_strchr(cmd, ' ');
 	if (pos == NULL)
 		goto parse_fail;
 	*pos = '\0';
 	imsi = pos + 1;
-	pos = strchr(imsi, ' ');
+	pos = os_strchr(imsi, ' ');
 	if (pos == NULL)
 		goto parse_fail;
 	*pos = '\0';
 	wpa_printf(MSG_DEBUG, "EAP-SIM DB: External response=%s for IMSI %s",
 		   cmd, imsi);
 
-	if (strcmp(cmd, "SIM-RESP-AUTH") == 0)
+	if (os_strcmp(cmd, "SIM-RESP-AUTH") == 0)
 		eap_sim_db_sim_resp_auth(data, imsi, pos + 1);
-	else if (strcmp(cmd, "AKA-RESP-AUTH") == 0)
+	else if (os_strcmp(cmd, "AKA-RESP-AUTH") == 0)
 		eap_sim_db_aka_resp_auth(data, imsi, pos + 1);
 	else
 		wpa_printf(MSG_INFO, "EAP-SIM DB: Unknown external response "
@@ -332,7 +332,7 @@
 	struct sockaddr_un addr;
 	static int counter = 0;
 
-	if (strncmp(data->fname, "unix:", 5) != 0)
+	if (os_strncmp(data->fname, "unix:", 5) != 0)
 		return -1;
 
 	data->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
@@ -341,11 +341,11 @@
 		return -1;
 	}
 
-	memset(&addr, 0, sizeof(addr));
+	os_memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
-	snprintf(addr.sun_path, sizeof(addr.sun_path),
-		 "/tmp/eap_sim_db_%d-%d", getpid(), counter++);
-	data->local_sock = strdup(addr.sun_path);
+	os_snprintf(addr.sun_path, sizeof(addr.sun_path),
+		    "/tmp/eap_sim_db_%d-%d", getpid(), counter++);
+	data->local_sock = os_strdup(addr.sun_path);
 	if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 		perror("bind(eap_sim_db)");
 		close(data->sock);
@@ -353,13 +353,14 @@
 		return -1;
 	}
 
-	memset(&addr, 0, sizeof(addr));
+	os_memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
 	os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path));
 	if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 		perror("connect(eap_sim_db)");
 		wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket",
-				  (u8 *) addr.sun_path, strlen(addr.sun_path));
+				  (u8 *) addr.sun_path,
+				  os_strlen(addr.sun_path));
 		close(data->sock);
 		data->sock = -1;
 		return -1;
@@ -380,7 +381,7 @@
 	}
 	if (data->local_sock) {
 		unlink(data->local_sock);
-		free(data->local_sock);
+		os_free(data->local_sock);
 		data->local_sock = NULL;
 	}
 }
@@ -406,11 +407,11 @@
 	data->sock = -1;
 	data->get_complete_cb = get_complete_cb;
 	data->ctx = ctx;
-	data->fname = strdup(config);
+	data->fname = os_strdup(config);
 	if (data->fname == NULL)
 		goto fail;
 
-	if (strncmp(data->fname, "unix:", 5) == 0) {
+	if (os_strncmp(data->fname, "unix:", 5) == 0) {
 		if (eap_sim_db_open_socket(data))
 			goto fail;
 	}
@@ -419,25 +420,25 @@
 
 fail:
 	eap_sim_db_close_socket(data);
-	free(data->fname);
-	free(data);
+	os_free(data->fname);
+	os_free(data);
 	return NULL;
 }
 
 
 static void eap_sim_db_free_pseudonym(struct eap_sim_pseudonym *p)
 {
-	free(p->identity);
-	free(p->pseudonym);
-	free(p);
+	os_free(p->identity);
+	os_free(p->pseudonym);
+	os_free(p);
 }
 
 
 static void eap_sim_db_free_reauth(struct eap_sim_reauth *r)
 {
-	free(r->identity);
-	free(r->reauth_id);
-	free(r);
+	os_free(r->identity);
+	os_free(r->reauth_id);
+	os_free(r);
 }
 
 
@@ -453,7 +454,7 @@
 	struct eap_sim_db_pending *pending, *prev_pending;
 
 	eap_sim_db_close_socket(data);
-	free(data->fname);
+	os_free(data->fname);
 
 	p = data->pseudonyms;
 	while (p) {
@@ -473,10 +474,10 @@
 	while (pending) {
 		prev_pending = pending;
 		pending = pending->next;
-		free(prev_pending);
-	}
-
-	free(data);
+		os_free(prev_pending);
+	}
+
+	os_free(data);
 }
 
 
@@ -577,7 +578,7 @@
 		if (entry->state == FAILURE) {
 			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> "
 				   "failure");
-			free(entry);
+			os_free(entry);
 			return EAP_SIM_DB_FAILURE;
 		}
 
@@ -593,10 +594,11 @@
 		num_chal = entry->u.sim.num_chal;
 		if (num_chal > max_chal)
 			num_chal = max_chal;
-		memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN);
-		memcpy(sres, entry->u.sim.sres, num_chal * EAP_SIM_SRES_LEN);
-		memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
-		free(entry);
+		os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN);
+		os_memcpy(sres, entry->u.sim.sres,
+			  num_chal * EAP_SIM_SRES_LEN);
+		os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN);
+		os_free(entry);
 		return num_chal;
 	}
 
@@ -605,12 +607,12 @@
 			return EAP_SIM_DB_FAILURE;
 	}
 
-	len = snprintf(msg, sizeof(msg), "SIM-REQ-AUTH ");
+	len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH ");
 	if (len < 0 || len + identity_len >= sizeof(msg))
 		return EAP_SIM_DB_FAILURE;
-	memcpy(msg + len, identity, identity_len);
+	os_memcpy(msg + len, identity, identity_len);
 	len += identity_len;
-	ret = snprintf(msg + len, sizeof(msg) - len, " %d", max_chal);
+	ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal);
 	if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
 		return EAP_SIM_DB_FAILURE;
 	len += ret;
@@ -625,7 +627,7 @@
 		return EAP_SIM_DB_FAILURE;
 
 	os_get_time(&entry->timestamp);
-	memcpy(entry->imsi, identity, identity_len);
+	os_memcpy(entry->imsi, identity, identity_len);
 	entry->imsi_len = identity_len;
 	entry->cb_session_ctx = cb_session_ctx;
 	entry->state = PENDING;
@@ -657,20 +659,20 @@
 		len++;
 	}
 
-	pseudonym = malloc(len + 1);
+	pseudonym = os_malloc(len + 1);
 	if (pseudonym == NULL)
 		return NULL;
-	memcpy(pseudonym, identity, len);
+	os_memcpy(pseudonym, identity, len);
 	pseudonym[len] = '\0';
 
 	p = data->pseudonyms;
 	while (p) {
-		if (strcmp(p->pseudonym, pseudonym) == 0)
+		if (os_strcmp(p->pseudonym, pseudonym) == 0)
 			break;
 		p = p->next;
 	}
 
-	free(pseudonym);
+	os_free(pseudonym);
 
 	return p;
 }
@@ -690,7 +692,7 @@
 	p = data->pseudonyms;
 	while (p) {
 		if (identity_len == p->identity_len &&
-		    memcmp(p->identity, identity, identity_len) == 0)
+		    os_memcmp(p->identity, identity, identity_len) == 0)
 			break;
 		p = p->next;
 	}
@@ -720,20 +722,20 @@
 		len++;
 	}
 
-	reauth_id = malloc(len + 1);
+	reauth_id = os_malloc(len + 1);
 	if (reauth_id == NULL)
 		return NULL;
-	memcpy(reauth_id, identity, len);
+	os_memcpy(reauth_id, identity, len);
 	reauth_id[len] = '\0';
 
 	r = data->reauths;
 	while (r) {
-		if (strcmp(r->reauth_id, reauth_id) == 0)
+		if (os_strcmp(r->reauth_id, reauth_id) == 0)
 			break;
 		r = r->next;
 	}
 
-	free(reauth_id);
+	os_free(reauth_id);
 
 	return r;
 }
@@ -760,7 +762,7 @@
 	r = data->reauths;
 	while (r) {
 		if (identity_len == r->identity_len &&
-		    memcmp(r->identity, identity, identity_len) == 0)
+		    os_memcmp(r->identity, identity, identity_len) == 0)
 			break;
 		r = r->next;
 	}
@@ -824,9 +826,9 @@
 	char *id, *pos, *end;
 	u8 buf[10];
 
-	if (hostapd_get_rand(buf, sizeof(buf)))
+	if (os_get_random(buf, sizeof(buf)))
 		return NULL;
-	id = malloc(sizeof(buf) * 2 + 2);
+	id = os_malloc(sizeof(buf) * 2 + 2);
 	if (id == NULL)
 		return NULL;
 
@@ -908,25 +910,25 @@
 	if (p) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous "
 			   "pseudonym: %s", p->pseudonym);
-		free(p->pseudonym);
+		os_free(p->pseudonym);
 		p->pseudonym = pseudonym;
 		return 0;
 	}
 
 	p = os_zalloc(sizeof(*p));
 	if (p == NULL) {
-		free(pseudonym);
+		os_free(pseudonym);
 		return -1;
 	}
 
 	p->next = data->pseudonyms;
-	p->identity = malloc(identity_len);
+	p->identity = os_malloc(identity_len);
 	if (p->identity == NULL) {
-		free(p);
-		free(pseudonym);
+		os_free(p);
+		os_free(pseudonym);
 		return -1;
 	}
-	memcpy(p->identity, identity, identity_len);
+	os_memcpy(p->identity, identity, identity_len);
 	p->identity_len = identity_len;
 	p->pseudonym = pseudonym;
 	data->pseudonyms = p;
@@ -968,23 +970,23 @@
 	if (r) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Replacing previous "
 			   "reauth_id: %s", r->reauth_id);
-		free(r->reauth_id);
+		os_free(r->reauth_id);
 		r->reauth_id = reauth_id;
 	} else {
 		r = os_zalloc(sizeof(*r));
 		if (r == NULL) {
-			free(reauth_id);
+			os_free(reauth_id);
 			return -1;
 		}
 
 		r->next = data->reauths;
-		r->identity = malloc(identity_len);
+		r->identity = os_malloc(identity_len);
 		if (r->identity == NULL) {
-			free(r);
-			free(reauth_id);
+			os_free(r);
+			os_free(reauth_id);
 			return -1;
 		}
-		memcpy(r->identity, identity, identity_len);
+		os_memcpy(r->identity, identity, identity_len);
 		r->identity_len = identity_len;
 		r->reauth_id = reauth_id;
 		data->reauths = r;
@@ -992,7 +994,7 @@
 	}
 
 	r->counter = counter;
-	memcpy(r->mk, mk, EAP_SIM_MK_LEN);
+	os_memcpy(r->mk, mk, EAP_SIM_MK_LEN);
 
 	return 0;
 }
@@ -1137,7 +1139,7 @@
 	entry = eap_sim_db_get_pending(data, identity, identity_len, 1);
 	if (entry) {
 		if (entry->state == FAILURE) {
-			free(entry);
+			os_free(entry);
 			wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure");
 			return EAP_SIM_DB_FAILURE;
 		}
@@ -1150,13 +1152,13 @@
 
 		wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully "
 			   "received authentication data");
-		memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN);
-		memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN);
-		memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN);
-		memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
-		memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
+		os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN);
+		os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN);
+		os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN);
+		os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN);
+		os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN);
 		*res_len = entry->u.aka.res_len;
-		free(entry);
+		os_free(entry);
 		return 0;
 	}
 
@@ -1165,10 +1167,10 @@
 			return EAP_SIM_DB_FAILURE;
 	}
 
-	len = snprintf(msg, sizeof(msg), "AKA-REQ-AUTH ");
+	len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH ");
 	if (len < 0 || len + identity_len >= sizeof(msg))
 		return EAP_SIM_DB_FAILURE;
-	memcpy(msg + len, identity, identity_len);
+	os_memcpy(msg + len, identity, identity_len);
 	len += identity_len;
 
 	wpa_hexdump(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication "
@@ -1182,7 +1184,7 @@
 
 	os_get_time(&entry->timestamp);
 	entry->aka = 1;
-	memcpy(entry->imsi, identity, identity_len);
+	os_memcpy(entry->imsi, identity, identity_len);
 	entry->imsi_len = identity_len;
 	entry->cb_session_ctx = cb_session_ctx;
 	entry->state = PENDING;
@@ -1225,19 +1227,19 @@
 		char msg[100];
 		int len, ret;
 
-		len = snprintf(msg, sizeof(msg), "AKA-AUTS ");
+		len = os_snprintf(msg, sizeof(msg), "AKA-AUTS ");
 		if (len < 0 || len + identity_len - 1 >= sizeof(msg))
 			return -1;
-		memcpy(msg + len, identity + 1, identity_len - 1);
+		os_memcpy(msg + len, identity + 1, identity_len - 1);
 		len += identity_len - 1;
 
-		ret = snprintf(msg + len, sizeof(msg) - len, " ");
+		ret = os_snprintf(msg + len, sizeof(msg) - len, " ");
 		if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
 			return -1;
 		len += ret;
 		len += wpa_snprintf_hex(msg + len, sizeof(msg) - len,
 					auts, EAP_AKA_AUTS_LEN);
-		ret = snprintf(msg + len, sizeof(msg) - len, " ");
+		ret = os_snprintf(msg + len, sizeof(msg) - len, " ");
 		if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
 			return -1;
 		len += ret;

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_tls.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_tls.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_tls.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_tls.c Sun Dec  9 08:34:57 2007
@@ -54,7 +54,7 @@
 	if (data == NULL)
 		return;
 	eap_server_tls_ssl_deinit(sm, &data->ssl);
-	free(data);
+	os_free(data);
 }
 
 
@@ -65,7 +65,7 @@
 	u8 *pos;
 
 	*reqDataLen = sizeof(*req) + 2;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-TLS: Failed to allocate memory for "
 			   "request");
@@ -172,7 +172,7 @@
 		if (data->ssl.tls_in_left == 0) {
 			data->ssl.tls_in_total = tls_msg_len;
 			data->ssl.tls_in_left = tls_msg_len;
-			free(data->ssl.tls_in);
+			os_free(data->ssl.tls_in);
 			data->ssl.tls_in = NULL;
 			data->ssl.tls_in_len = 0;
 		}
@@ -237,11 +237,11 @@
 					       "client EAP encryption",
 					       EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
 	if (eapKeyData) {
-		emsk = malloc(EAP_EMSK_LEN);
+		emsk = os_malloc(EAP_EMSK_LEN);
 		if (emsk)
-			memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN,
-			       EAP_EMSK_LEN);
-		free(eapKeyData);
+			os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN,
+				  EAP_EMSK_LEN);
+		os_free(eapKeyData);
 	} else
 		emsk = NULL;
 

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_tls_common.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_tls_common.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_tls_common.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_tls_common.c Sun Dec  9 08:34:57 2007
@@ -58,8 +58,8 @@
 void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
 {
 	tls_connection_deinit(sm->ssl_ctx, data->conn);
-	free(data->tls_in);
-	free(data->tls_out);
+	os_free(data->tls_in);
+	os_free(data->tls_out);
 }
 
 
@@ -69,7 +69,7 @@
 	struct tls_keys keys;
 	u8 *rnd = NULL, *out;
 
-	out = malloc(len);
+	out = os_malloc(len);
 	if (out == NULL)
 		return NULL;
 
@@ -84,24 +84,24 @@
 	    keys.master_key == NULL)
 		goto fail;
 
-	rnd = malloc(keys.client_random_len + keys.server_random_len);
+	rnd = os_malloc(keys.client_random_len + keys.server_random_len);
 	if (rnd == NULL)
 		goto fail;
-	memcpy(rnd, keys.client_random, keys.client_random_len);
-	memcpy(rnd + keys.client_random_len, keys.server_random,
-	       keys.server_random_len);
+	os_memcpy(rnd, keys.client_random, keys.client_random_len);
+	os_memcpy(rnd + keys.client_random_len, keys.server_random,
+		  keys.server_random_len);
 
 	if (tls_prf(keys.master_key, keys.master_key_len,
 		    label, rnd, keys.client_random_len +
 		    keys.server_random_len, out, len))
 		goto fail;
 
-	free(rnd);
+	os_free(rnd);
 	return out;
 
 fail:
-	free(out);
-	free(rnd);
+	os_free(out);
+	os_free(rnd);
 	return NULL;
 }
 
@@ -112,27 +112,32 @@
 {
 	u8 *buf;
 
+	if (*in_len == 0) {
+		wpa_printf(MSG_INFO, "SSL: Empty fragment when trying to "
+			   "reassemble");
+		return -1;
+	}
 	if (data->tls_in_left > *in_len || data->tls_in) {
 		if (data->tls_in_len + *in_len > 65536) {
 			/* Limit length to avoid rogue peers from causing large
 			 * memory allocations. */
-			free(data->tls_in);
+			os_free(data->tls_in);
 			data->tls_in = NULL;
 			data->tls_in_len = 0;
 			wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size"
 				   " over 64 kB)");
 			return -1;
 		}
-		buf = realloc(data->tls_in, data->tls_in_len + *in_len);
+		buf = os_realloc(data->tls_in, data->tls_in_len + *in_len);
 		if (buf == NULL) {
-			free(data->tls_in);
+			os_free(data->tls_in);
 			data->tls_in = NULL;
 			data->tls_in_len = 0;
 			wpa_printf(MSG_INFO, "SSL: Could not allocate memory "
 				   "for TLS data");
 			return -1;
 		}
-		memcpy(buf + data->tls_in_len, *in_data, *in_len);
+		os_memcpy(buf + data->tls_in_len, *in_data, *in_len);
 		data->tls_in = buf;
 		data->tls_in_len += *in_len;
 		if (*in_len > data->tls_in_left) {
@@ -178,7 +183,7 @@
 			wpa_printf(MSG_INFO, "SSL: eap_tls_process_helper - "
 				   "pending tls_out data even though "
 				   "tls_out_len = 0");
-			free(data->tls_out);
+			os_free(data->tls_out);
 			WPA_ASSERT(data->tls_out == NULL);
 		}
 		data->tls_out = tls_connection_server_handshake(
@@ -187,7 +192,7 @@
 
 		/* Clear reassembled input data (if the buffer was needed). */
 		data->tls_in_left = data->tls_in_total = data->tls_in_len = 0;
-		free(data->tls_in);
+		os_free(data->tls_in);
 		data->tls_in = NULL;
 	}
 
@@ -201,7 +206,7 @@
 		 * needing more that should have been catched above based on
 		 * the TLS Message Length field. */
 		wpa_printf(MSG_DEBUG, "SSL: No data to be sent out");
-		free(data->tls_out);
+		os_free(data->tls_out);
 		data->tls_out = NULL;
 
 		if (tls_connection_get_read_alerts(sm->ssl_ctx, data->conn)) {
@@ -233,7 +238,7 @@
 
 	*out_len = 0;
 
-	req = malloc(sizeof(struct eap_hdr) + 2 + 4 + data->tls_out_limit);
+	req = os_malloc(sizeof(struct eap_hdr) + 2 + 4 + data->tls_out_limit);
 	if (req == NULL) {
 		*out_data = NULL;
 		return -1;
@@ -258,7 +263,7 @@
 		wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
 			   "will follow", (unsigned long) len);
 	}
-	memcpy(pos, &data->tls_out[data->tls_out_pos], len);
+	os_memcpy(pos, &data->tls_out[data->tls_out_pos], len);
 	data->tls_out_pos += len;
 	*out_len = (pos - (u8 *) req) + len;
 	req->length = host_to_be16(*out_len);
@@ -267,7 +272,7 @@
 	if (!(*flags & EAP_TLS_FLAGS_MORE_FRAGMENTS)) {
 		data->tls_out_len = 0;
 		data->tls_out_pos = 0;
-		free(data->tls_out);
+		os_free(data->tls_out);
 		data->tls_out = NULL;
 	}
 
@@ -281,16 +286,11 @@
 	struct eap_hdr *req;
 	u8 *pos;
 
-	*reqDataLen = sizeof(struct eap_hdr) + 2;
-	req = malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, reqDataLen, 1,
+			    EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL)
 		return NULL;
 	wpa_printf(MSG_DEBUG, "SSL: Building ACK");
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = eap_type; /* Type */
 	*pos = peap_version; /* Flags */
 	return (u8 *) req;
 }

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_tlv.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_tlv.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_tlv.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_tlv.c Sun Dec  9 08:34:57 2007
@@ -40,7 +40,7 @@
 static void eap_tlv_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_tlv_data *data = priv;
-	free(data);
+	os_free(data);
 }
 
 
@@ -57,16 +57,11 @@
 		status = EAP_TLV_RESULT_FAILURE;
 	}
 
-	*reqDataLen = sizeof(struct eap_hdr) + 1 + 6;
-	req = malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, reqDataLen, 6,
+			    EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL)
 		return NULL;
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_TLV;
 	*pos++ = 0x80; /* Mandatory */
 	*pos++ = EAP_TLV_RESULT_TLV;
 	/* Length */

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_ttls.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_ttls.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_ttls.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_ttls.c Sun Dec  9 08:34:57 2007
@@ -121,18 +121,18 @@
 {
 	u8 *avp, *pos;
 
-	avp = malloc(sizeof(struct ttls_avp) + *resp_len + 4);
+	avp = os_malloc(sizeof(struct ttls_avp) + *resp_len + 4);
 	if (avp == NULL) {
-		free(*resp);
+		os_free(*resp);
 		*resp_len = 0;
 		return -1;
 	}
 
 	pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
-	memcpy(pos, *resp, *resp_len);
+	os_memcpy(pos, *resp, *resp_len);
 	pos += *resp_len;
 	AVP_PAD(avp, pos);
-	free(*resp);
+	os_free(*resp);
 	*resp = avp;
 	*resp_len = pos - avp;
 	return 0;
@@ -170,7 +170,7 @@
 
 	pos = buf;
 	left = len;
-	memset(parse, 0, sizeof(*parse));
+	os_memset(parse, 0, sizeof(*parse));
 
 	while (left > 0) {
 		u32 avp_code, avp_length, vendor_id = 0;
@@ -215,25 +215,25 @@
 		if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
 			wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
 			if (parse->eap == NULL) {
-				parse->eap = malloc(dlen);
+				parse->eap = os_malloc(dlen);
 				if (parse->eap == NULL) {
 					wpa_printf(MSG_WARNING, "EAP-TTLS: "
 						   "failed to allocate memory "
 						   "for Phase 2 EAP data");
 					goto fail;
 				}
-				memcpy(parse->eap, dpos, dlen);
+				os_memcpy(parse->eap, dpos, dlen);
 				parse->eap_len = dlen;
 			} else {
-				u8 *neweap = realloc(parse->eap,
-						     parse->eap_len + dlen);
+				u8 *neweap = os_realloc(parse->eap,
+							parse->eap_len + dlen);
 				if (neweap == NULL) {
 					wpa_printf(MSG_WARNING, "EAP-TTLS: "
 						   "failed to allocate memory "
 						   "for Phase 2 EAP data");
 					goto fail;
 				}
-				memcpy(neweap + parse->eap_len, dpos, dlen);
+				os_memcpy(neweap + parse->eap_len, dpos, dlen);
 				parse->eap = neweap;
 				parse->eap_len += dlen;
 			}
@@ -310,7 +310,7 @@
 	return 0;
 
 fail:
-	free(parse->eap);
+	os_free(parse->eap);
 	parse->eap = NULL;
 	return -1;
 }
@@ -327,7 +327,7 @@
 						 "ttls challenge", len);
 	}
 
-	memset(&keys, 0, sizeof(keys));
+	os_memset(&keys, 0, sizeof(keys));
 	if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
 	    keys.client_random == NULL || keys.server_random == NULL ||
 	    keys.inner_secret == NULL) {
@@ -337,18 +337,18 @@
 		return NULL;
 	}
 
-	rnd = malloc(keys.client_random_len + keys.server_random_len);
-	challenge = malloc(len);
+	rnd = os_malloc(keys.client_random_len + keys.server_random_len);
+	challenge = os_malloc(len);
 	if (rnd == NULL || challenge == NULL) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: No memory for implicit "
 			   "challenge derivation");
-		free(rnd);
-		free(challenge);
-		return NULL;
-	}
-	memcpy(rnd, keys.server_random, keys.server_random_len);
-	memcpy(rnd + keys.server_random_len, keys.client_random,
-	       keys.client_random_len);
+		os_free(rnd);
+		os_free(challenge);
+		return NULL;
+	}
+	os_memcpy(rnd, keys.server_random, keys.server_random_len);
+	os_memcpy(rnd + keys.server_random_len, keys.client_random,
+		  keys.client_random_len);
 
 	if (tls_prf(keys.inner_secret, keys.inner_secret_len,
 		    "inner application challenge", rnd,
@@ -356,12 +356,12 @@
 		    challenge, len)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive implicit "
 			   "challenge");
-		free(rnd);
-		free(challenge);
-		return NULL;
-	}
-
-	free(rnd);
+		os_free(rnd);
+		os_free(challenge);
+		return NULL;
+	}
+
+	os_free(rnd);
 
 	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived implicit challenge",
 			challenge, len);
@@ -417,7 +417,7 @@
 	if (data->phase2_priv && data->phase2_method)
 		data->phase2_method->reset(sm, data->phase2_priv);
 	eap_server_tls_ssl_deinit(sm, &data->ssl);
-	free(data);
+	os_free(data);
 }
 
 
@@ -428,7 +428,7 @@
 	u8 *pos;
 
 	*reqDataLen = sizeof(*req) + 2;
-	req = malloc(*reqDataLen);
+	req = os_malloc(*reqDataLen);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
 			   " request");
@@ -482,7 +482,7 @@
 
 	/* TODO: add support for fragmentation, if needed. This will need to
 	 * add TLS Message Length field, if the frame is fragmented. */
-	req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
+	req = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
 	if (req == NULL)
 		return NULL;
 
@@ -499,7 +499,7 @@
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
 			   "data");
-		free(req);
+		os_free(req);
 		return NULL;
 	}
 
@@ -536,7 +536,7 @@
 			"2 data", req, req_len);
 
 	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
-	free(req);
+	os_free(req);
 
 	return encr_req;
 }
@@ -550,7 +550,7 @@
 	int ret;
 	size_t req_len;
 
-	pos = req = malloc(100);
+	pos = req = os_malloc(100);
 	if (req == NULL)
 		return NULL;
 	end = req + 100;
@@ -559,7 +559,7 @@
 		pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
 				       RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
 		*pos++ = data->mschapv2_ident;
-		ret = snprintf((char *) pos, end - pos, "S=");
+		ret = os_snprintf((char *) pos, end - pos, "S=");
 		if (ret >= 0 && ret < end - pos)
 			pos += ret;
 		pos += wpa_snprintf_hex_uppercase(
@@ -568,7 +568,7 @@
 	} else {
 		pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
 				       RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
-		memcpy(pos, "Failed", 6);
+		os_memcpy(pos, "Failed", 6);
 		pos += 6;
 		AVP_PAD(req, pos);
 	}
@@ -578,7 +578,7 @@
 			"data", req, req_len);
 
 	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
-	free(req);
+	os_free(req);
 
 	return encr_req;
 }
@@ -595,7 +595,7 @@
 	const int max_len = 300;
 
 	len = sizeof(struct eap_hdr) + 2 + max_len;
-	req = malloc(len);
+	req = os_malloc(len);
 	if (req == NULL)
 		return NULL;
 
@@ -610,7 +610,7 @@
 						    data->ssl.conn,
 						    final, pos, max_len);
 	if (len < 0) {
-		free(req);
+		os_free(req);
 		return NULL;
 	}
 
@@ -675,11 +675,11 @@
 
 	if (key) {
 		buf_len = 2 + key_len;
-		buf = malloc(buf_len);
+		buf = os_malloc(buf_len);
 		if (buf == NULL)
 			return -1;
 		WPA_PUT_BE16(buf, key_len);
-		memcpy(buf + 2, key, key_len);
+		os_memcpy(buf + 2, key, key_len);
 	} else {
 		buf = NULL;
 		buf_len = 0;
@@ -690,7 +690,7 @@
 	ret = tls_connection_ia_permute_inner_secret(sm->ssl_ctx,
 						     data->ssl.conn,
 						     buf, buf_len);
-	free(buf);
+	os_free(buf);
 
 	return ret;
 }
@@ -711,8 +711,8 @@
 	}
 
 	if (sm->user->password_len != user_password_len ||
-	    memcmp(sm->user->password, user_password, user_password_len) != 0)
-	{
+	    os_memcmp(sm->user->password, user_password, user_password_len) !=
+	    0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
 		eap_ttls_state(data, FAILURE);
 		return;
@@ -764,14 +764,14 @@
 		return;
 	}
 
-	if (memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
+	if (os_memcmp(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN) != 0 ||
 	    password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
-		free(chal);
-		eap_ttls_state(data, FAILURE);
-		return;
-	}
-	free(chal);
+		os_free(chal);
+		eap_ttls_state(data, FAILURE);
+		return;
+	}
+	os_free(chal);
 
 	/* MD5(Ident + Password + Challenge) */
 	addr[0] = password;
@@ -782,7 +782,7 @@
 	len[2] = challenge_len;
 	md5_vector(3, addr, len, hash);
 
-	if (memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
+	if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
 		eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
 			       SUCCESS);
@@ -829,14 +829,14 @@
 		return;
 	}
 
-	if (memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
+	if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN) != 0 ||
 	    response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
-		free(chal);
-		eap_ttls_state(data, FAILURE);
-		return;
-	}
-	free(chal);
+		os_free(chal);
+		eap_ttls_state(data, FAILURE);
+		return;
+	}
+	os_free(chal);
 
 	if (sm->user->password_hash)
 		challenge_response(challenge, sm->user->password, nt_response);
@@ -844,7 +844,7 @@
 		nt_challenge_response(challenge, sm->user->password,
 				      sm->user->password_len, nt_response);
 
-	if (memcmp(nt_response, response + 2 + 24, 24) == 0) {
+	if (os_memcmp(nt_response, response + 2 + 24, 24) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
 		eap_ttls_state(data, data->ttls_version > 0 ? PHASE_FINISHED :
 			       SUCCESS);
@@ -911,14 +911,14 @@
 		return;
 	}
 
-	if (memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
+	if (os_memcmp(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN) != 0 ||
 	    response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
-		free(chal);
-		eap_ttls_state(data, FAILURE);
-		return;
-	}
-	free(chal);
+		os_free(chal);
+		eap_ttls_state(data, FAILURE);
+		return;
+	}
+	os_free(chal);
 
 	auth_challenge = challenge;
 	peer_challenge = response + 2;
@@ -944,7 +944,7 @@
 	}
 
 	rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
-	if (memcmp(nt_response, rx_resp, 24) == 0) {
+	if (os_memcmp(nt_response, rx_resp, 24) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
 			   "NT-Response");
 		data->mschapv2_resp_ok = 1;
@@ -1187,9 +1187,9 @@
 	buf_len = in_len;
 	if (data->ssl.tls_in_total > buf_len)
 		buf_len = data->ssl.tls_in_total;
-	in_decrypted = malloc(buf_len);
+	in_decrypted = os_malloc(buf_len);
 	if (in_decrypted == NULL) {
-		free(data->ssl.tls_in);
+		os_free(data->ssl.tls_in);
 		data->ssl.tls_in = NULL;
 		data->ssl.tls_in_len = 0;
 		wpa_printf(MSG_WARNING, "EAP-TTLS: failed to allocate memory "
@@ -1200,13 +1200,13 @@
 	len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
 					       in_data, in_len,
 					       in_decrypted, buf_len);
-	free(data->ssl.tls_in);
+	os_free(data->ssl.tls_in);
 	data->ssl.tls_in = NULL;
 	data->ssl.tls_in_len = 0;
 	if (len_decrypted < 0) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
 			   "data");
-		free(in_decrypted);
+		os_free(in_decrypted);
 		eap_ttls_state(data, FAILURE);
 		return;
 	}
@@ -1224,7 +1224,7 @@
 			eap_ttls_state(data, FAILURE);
 		}
 
-		free(in_decrypted);
+		os_free(in_decrypted);
 		return;
 	}
 
@@ -1233,17 +1233,17 @@
 
 	if (eap_ttls_avp_parse(in_decrypted, len_decrypted, &parse) < 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
-		free(in_decrypted);
+		os_free(in_decrypted);
 		eap_ttls_state(data, FAILURE);
 		return;
 	}
 
 	if (parse.user_name) {
-		free(sm->identity);
-		sm->identity = malloc(parse.user_name_len);
+		os_free(sm->identity);
+		sm->identity = os_malloc(parse.user_name_len);
 		if (sm->identity) {
-			memcpy(sm->identity, parse.user_name,
-			       parse.user_name_len);
+			os_memcpy(sm->identity, parse.user_name,
+				  parse.user_name_len);
 			sm->identity_len = parse.user_name_len;
 		}
 		if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
@@ -1282,8 +1282,8 @@
 	}
 
 done:
-	free(in_decrypted);
-	free(parse.eap);
+	os_free(in_decrypted);
+	os_free(parse.eap);
  }
 
 
@@ -1335,7 +1335,7 @@
 		if (data->ssl.tls_in_left == 0) {
 			data->ssl.tls_in_total = tls_msg_len;
 			data->ssl.tls_in_left = tls_msg_len;
-			free(data->ssl.tls_in);
+			os_free(data->ssl.tls_in);
 			data->ssl.tls_in = NULL;
 			data->ssl.tls_in_len = 0;
 		}
@@ -1401,7 +1401,7 @@
 	struct tls_keys keys;
 	u8 *rnd, *key;
 
-	memset(&keys, 0, sizeof(keys));
+	os_memset(&keys, 0, sizeof(keys));
 	if (tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
 	    keys.client_random == NULL || keys.server_random == NULL ||
 	    keys.inner_secret == NULL) {
@@ -1411,24 +1411,24 @@
 		return NULL;
 	}
 
-	rnd = malloc(keys.client_random_len + keys.server_random_len);
-	key = malloc(EAP_TLS_KEY_LEN);
+	rnd = os_malloc(keys.client_random_len + keys.server_random_len);
+	key = os_malloc(EAP_TLS_KEY_LEN);
 	if (rnd == NULL || key == NULL) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: No memory for key derivation");
-		free(rnd);
-		free(key);
-		return NULL;
-	}
-	memcpy(rnd, keys.client_random, keys.client_random_len);
-	memcpy(rnd + keys.client_random_len, keys.server_random,
-	       keys.server_random_len);
+		os_free(rnd);
+		os_free(key);
+		return NULL;
+	}
+	os_memcpy(rnd, keys.client_random, keys.client_random_len);
+	os_memcpy(rnd + keys.client_random_len, keys.server_random,
+		  keys.server_random_len);
 
 	if (tls_prf(keys.inner_secret, keys.inner_secret_len,
 		    "ttls v1 keying material", rnd, keys.client_random_len +
 		    keys.server_random_len, key, EAP_TLS_KEY_LEN)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
-		free(rnd);
-		free(key);
+		os_free(rnd);
+		os_free(key);
 		return NULL;
 	}
 
@@ -1437,7 +1437,7 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: TLS/IA inner secret",
 			keys.inner_secret, keys.inner_secret_len);
 
-	free(rnd);
+	os_free(rnd);
 
 	return key;
 }

Modified: wpasupplicant/branches/upstream/current/src/eap_server/eap_vendor_test.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_vendor_test.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_vendor_test.c (original)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_vendor_test.c Sun Dec  9 08:34:57 2007
@@ -70,7 +70,7 @@
 static void eap_vendor_test_reset(struct eap_sm *sm, void *priv)
 {
 	struct eap_vendor_test_data *data = priv;
-	free(data);
+	os_free(data);
 }
 
 
@@ -81,23 +81,14 @@
 	struct eap_hdr *req;
 	u8 *pos;
 
-	*reqDataLen = sizeof(*req) + 8 + 1;
-	req = malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, reqDataLen, 1,
+			    EAP_CODE_REQUEST, id, &pos);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate "
 			   "memory for request");
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_EXPANDED;
-	WPA_PUT_BE24(pos, EAP_VENDOR_ID);
-	pos += 3;
-	WPA_PUT_BE32(pos, EAP_VENDOR_TYPE);
-	pos += 4;
 	*pos = data->state == INIT ? 1 : 3;
 
 	return (u8 *) req;
@@ -181,12 +172,12 @@
 	if (data->state != SUCCESS)
 		return NULL;
 
-	key = malloc(key_len);
+	key = os_malloc(key_len);
 	if (key == NULL)
 		return NULL;
 
-	memset(key, 0x11, key_len / 2);
-	memset(key + key_len / 2, 0x22, key_len / 2);
+	os_memset(key, 0x11, key_len / 2);
+	os_memset(key + key_len / 2, 0x22, key_len / 2);
 	*len = key_len;
 
 	return key;

Added: wpasupplicant/branches/upstream/current/src/eap_server/eap_wsc.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eap_server/eap_wsc.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eap_server/eap_wsc.c (added)
+++ wpasupplicant/branches/upstream/current/src/eap_server/eap_wsc.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,541 @@
+/*
+ * EAP-WSC server for Wi-Fi Protected Setup
+ * Copyright (c) 2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eap_i.h"
+#include "eap_common/eap_wsc_common.h"
+
+
+struct wps_data {
+	int registrar;
+	int msg_num;
+};
+
+
+static struct wps_data * wps_init(int registrar)
+{
+	struct wps_data *data = os_zalloc(sizeof(*data));
+	if (data == NULL)
+		return NULL;
+	data->registrar = registrar;
+	data->msg_num = 1;
+	return data;
+}
+
+
+static void wps_deinit(struct wps_data *data)
+{
+	os_free(data);
+}
+
+
+enum wps_process_res {
+	WPS_DONE, WPS_CONTINUE, WPS_FAILURE, WPS_PENDING
+};
+
+static enum wps_process_res wps_process_msg(struct wps_data *wps, u8 op_code,
+					    const u8 *msg, size_t msg_len)
+{
+	/* TODO: proper processing and/or sending to an external process */
+
+	wpa_hexdump(MSG_MSGDUMP, "WPS: Received message", msg, msg_len);
+	if ((wps->registrar && (wps->msg_num & 1) == 0) ||
+	    (!wps->registrar && (wps->msg_num & 1) == 1)) {
+		wpa_printf(MSG_DEBUG, "WPS: Unexpected message number %d",
+			   wps->msg_num);
+		return WPS_FAILURE;
+	}
+
+	if (wps->msg_num <= 8 && op_code == WSC_MSG) {
+		wpa_printf(MSG_DEBUG, "WPS: Process M%d", wps->msg_num);
+	} else if (wps->registrar && wps->msg_num == 3 &&
+		   op_code == WSC_ACK) {
+		wpa_printf(MSG_DEBUG, "WPS: Process ACK to M2/M2D");
+		/* could send out next M2/M2D */
+		return WPS_DONE;
+	} else if (wps->registrar && wps->msg_num == 3 &&
+		   op_code == WSC_Done) {
+		wpa_printf(MSG_DEBUG, "WPS: Process Done to M2/M2D");
+		return WPS_DONE;
+	} else if (wps->msg_num <= 8 && op_code == WSC_Done) {
+		wpa_printf(MSG_DEBUG, "WPS: Process Done prior to completion");
+		return WPS_DONE;
+	} else if (wps->msg_num <= 8 && op_code == WSC_ACK) {
+		wpa_printf(MSG_DEBUG, "WPS: Process ACK prior to completion");
+		return WPS_DONE;
+	} else if (wps->msg_num <= 8 && op_code == WSC_NACK) {
+		wpa_printf(MSG_DEBUG, "WPS: Process NACK prior to completion");
+		return WPS_DONE;
+	} else if (wps->registrar && wps->msg_num == 9 &&
+		   op_code == WSC_Done) {
+		wpa_printf(MSG_DEBUG, "WPS: Process Done");
+		return WPS_DONE;
+	} else if (!wps->registrar && wps->msg_num == 10 &&
+		   op_code == WSC_ACK) {
+		wpa_printf(MSG_DEBUG, "WPS: Process ACK");
+		return WPS_DONE;
+	} else {
+		wpa_printf(MSG_DEBUG, "WPS: Unexpected Op-Code %d "
+			   "(msg_num=%d)", op_code, wps->msg_num);
+		return WPS_FAILURE;
+	}
+
+	wps->msg_num++;
+	return WPS_CONTINUE;
+}
+
+
+static u8 * wps_get_msg(struct wps_data *wps, size_t *msg_len, u8 *op_code)
+{
+	u8 *msg;
+
+	/* TODO: proper processing and/or query from an external process */
+
+	if ((wps->registrar && (wps->msg_num & 1) == 1) ||
+	    (!wps->registrar && (wps->msg_num & 1) == 0)) {
+		wpa_printf(MSG_DEBUG, "WPS: Unexpected request for message "
+			   "number %d", wps->msg_num);
+		return NULL;
+	}
+
+	if (wps->msg_num == 7 || wps->msg_num == 8) {
+		msg = os_zalloc(2000);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 2000;
+		*op_code = WSC_MSG;
+		*msg = WSC_MSG;
+		wpa_printf(MSG_DEBUG, "WPS: Send M%d", wps->msg_num);
+	} else if (wps->msg_num <= 6) {
+		msg = os_zalloc(1);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 1;
+		*op_code = WSC_MSG;
+		*msg = WSC_MSG;
+		wpa_printf(MSG_DEBUG, "WPS: Send M%d", wps->msg_num);
+	} else if (!wps->registrar && wps->msg_num == 9) {
+		msg = os_zalloc(1);
+		if (msg == NULL)
+			return NULL;
+		*msg_len = 1;
+		*op_code = WSC_Done;
+		*msg = WSC_Done;
+		wpa_printf(MSG_DEBUG, "WPS: Send Done");
+	} else
+		return NULL;
+
+	wps->msg_num++;
+	return msg;
+}
+
+
+struct eap_wsc_data {
+	enum { START, MSG, FRAG_ACK, WAIT_FRAG_ACK, DONE, FAIL } state;
+	int registrar;
+	u8 *in_buf, *out_buf, in_op_code, out_op_code;
+	size_t in_len, in_used, out_len, out_used;
+	size_t fragment_size;
+	struct wps_data *wps;
+};
+
+
+static const char * eap_wsc_state_txt(int state)
+{
+	switch (state) {
+	case START:
+		return "START";
+	case MSG:
+		return "MSG";
+	case FRAG_ACK:
+		return "FRAG_ACK";
+	case WAIT_FRAG_ACK:
+		return "WAIT_FRAG_ACK";
+	case DONE:
+		return "DONE";
+	case FAIL:
+		return "FAIL";
+	default:
+		return "?";
+	}
+}
+
+
+static void eap_wsc_state(struct eap_wsc_data *data, int state)
+{
+	wpa_printf(MSG_DEBUG, "EAP-WSC: %s -> %s",
+		   eap_wsc_state_txt(data->state),
+		   eap_wsc_state_txt(state));
+	data->state = state;
+}
+
+
+static void * eap_wsc_init(struct eap_sm *sm)
+{
+	struct eap_wsc_data *data;
+	int registrar;
+
+	if (sm->identity && sm->identity_len == WSC_ID_REGISTRAR_LEN &&
+	    os_memcmp(sm->identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) ==
+	    0)
+		registrar = 0; /* Supplicant is Registrar */
+	else if (sm->identity && sm->identity_len == WSC_ID_ENROLLEE_LEN &&
+		 os_memcmp(sm->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN)
+		 == 0)
+		registrar = 1; /* Supplicant is Enrollee */
+	else {
+		wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity",
+				  sm->identity, sm->identity_len);
+		return NULL;
+	}
+
+	data = os_zalloc(sizeof(*data));
+	if (data == NULL)
+		return NULL;
+	data->state = registrar ? START : MSG;
+	data->registrar = registrar;
+	data->wps = wps_init(registrar);
+	if (data->wps == NULL) {
+		os_free(data);
+		return NULL;
+	}
+	data->fragment_size = WSC_FRAGMENT_SIZE;
+
+	return data;
+}
+
+
+static void eap_wsc_reset(struct eap_sm *sm, void *priv)
+{
+	struct eap_wsc_data *data = priv;
+	os_free(data->in_buf);
+	os_free(data->out_buf);
+	wps_deinit(data->wps);
+	os_free(data);
+}
+
+
+static u8 * eap_wsc_build_start(struct eap_sm *sm, struct eap_wsc_data *data,
+				int id, size_t *reqDataLen)
+{
+	struct eap_hdr *req;
+	u8 *pos;
+
+	req = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, reqDataLen, 2,
+			    EAP_CODE_REQUEST, id, &pos);
+	if (req == NULL) {
+		wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for "
+			   "request");
+		return NULL;
+	}
+
+	wpa_printf(MSG_DEBUG, "EAP-WSC: Send WSC/Start");
+	*pos++ = WSC_Start; /* Op-Code */
+	*pos = 0; /* Flags */
+
+	return (u8 *) req;
+}
+
+
+static u8 * eap_wsc_build_msg(struct eap_sm *sm, struct eap_wsc_data *data,
+			      int id, size_t *reqDataLen)
+{
+	struct eap_hdr *req;
+	u8 *pos, flags;
+	size_t send_len, plen;
+
+	if (data->out_buf == NULL) {
+		data->out_buf = wps_get_msg(data->wps, &data->out_len,
+					    &data->out_op_code);
+		if (data->out_buf == NULL) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to receive "
+				   "message from WPS");
+			return NULL;
+		}
+	}
+
+	flags = 0;
+	send_len = data->out_len - data->out_used;
+	if (2 + send_len > data->fragment_size) {
+		send_len = data->fragment_size - 2;
+		flags |= WSC_FLAGS_MF;
+		if (data->out_used == 0) {
+			flags |= WSC_FLAGS_LF;
+			send_len -= 2;
+		}
+	}
+	plen = 2 + send_len;
+	if (flags & WSC_FLAGS_LF)
+		plen += 2;
+	req = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, reqDataLen,
+			    plen, EAP_CODE_REQUEST, id, &pos);
+	if (req == NULL) {
+		wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for "
+			   "request");
+		return NULL;
+	}
+
+	*pos++ = data->out_op_code; /* Op-Code */
+	*pos++ = flags; /* Flags */
+	if (flags & WSC_FLAGS_LF) {
+		WPA_PUT_BE16(pos, data->out_len);
+		pos += 2;
+	}
+
+	os_memcpy(pos, data->out_buf + data->out_used, send_len);
+	data->out_used += send_len;
+
+	if (data->out_used == data->out_len) {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %u bytes "
+			   "(message sent completely)", send_len);
+		os_free(data->out_buf);
+		data->out_buf = NULL;
+		data->out_len = data->out_used = 0;
+		eap_wsc_state(data, MSG);
+	} else {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Sending out %u bytes "
+			   "(%u more to send)", send_len,
+			   data->out_len - data->out_used);
+		eap_wsc_state(data, WAIT_FRAG_ACK);
+	}
+
+	return (u8 *) req;
+}
+
+
+static u8 * eap_wsc_buildReq(struct eap_sm *sm, void *priv, int id,
+			     size_t *reqDataLen)
+{
+	struct eap_wsc_data *data = priv;
+
+	switch (data->state) {
+	case START:
+		return eap_wsc_build_start(sm, data, id, reqDataLen);
+	case FRAG_ACK:
+		return eap_wsc_build_frag_ack(id, EAP_CODE_REQUEST,
+					      reqDataLen);
+	case MSG:
+		return eap_wsc_build_msg(sm, data, id, reqDataLen);
+	default:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected state %d in "
+			   "buildReq", data->state);
+		return NULL;
+	}
+}
+
+
+static Boolean eap_wsc_check(struct eap_sm *sm, void *priv,
+			     u8 *respData, size_t respDataLen)
+{
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
+			       respData, respDataLen, &len);
+	if (pos == NULL || len < 2) {
+		wpa_printf(MSG_INFO, "EAP-WSC: Invalid frame");
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+
+static void eap_wsc_process(struct eap_sm *sm, void *priv,
+			    u8 *respData, size_t respDataLen)
+{
+	struct eap_wsc_data *data = priv;
+	const u8 *start, *pos, *end;
+	size_t len;
+	u8 op_code, flags;
+	u16 message_length = 0;
+	const u8 *msg;
+	size_t msg_len;
+	enum wps_process_res res;
+
+	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
+			       respData, respDataLen, &len);
+	if (pos == NULL || len < 2)
+		return; /* Should not happen; message already verified */
+
+	start = pos;
+	end = start + len;
+
+	op_code = *pos++;
+	flags = *pos++;
+	if (flags & WSC_FLAGS_LF) {
+		if (end - pos < 2) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Message underflow");
+			return;
+		}
+		message_length = WPA_GET_BE16(pos);
+		pos += 2;
+
+		if (message_length < end - pos) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Invalid Message "
+				   "Length");
+			return;
+		}
+	}
+
+	wpa_printf(MSG_DEBUG, "EAP-WSC: Received packet: Op-Code %d "
+		   "Flags 0x%x Message Length %d",
+		   op_code, flags, message_length);
+
+	if (data->state == WAIT_FRAG_ACK) {
+		if (op_code != WSC_FRAG_ACK) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
+				   "in WAIT_FRAG_ACK state", op_code);
+			eap_wsc_state(data, FAIL);
+			return;
+		}
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment acknowledged");
+		eap_wsc_state(data, MSG);
+		return;
+	}
+
+	if (op_code != WSC_ACK && op_code != WSC_NACK && op_code != WSC_MSG &&
+	    op_code != WSC_Done) {
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
+			   op_code);
+		eap_wsc_state(data, FAIL);
+		return;
+	}
+
+	if (data->in_buf) {
+		/* Process continuation of a pending message */
+		if (op_code != data->in_op_code) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
+				   "in fragment (expected %d)",
+				   op_code, data->in_op_code);
+			eap_wsc_state(data, FAIL);
+			return;
+		}
+
+		if (data->in_used + (end - pos) > data->in_len) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment overflow");
+			eap_wsc_state(data, FAIL);
+			return;
+		}
+
+		os_memcpy(data->in_buf + data->in_used, pos, end - pos);
+		data->in_used += end - pos;
+		wpa_printf(MSG_DEBUG, "EAP-WSC: Received %u bytes, waiting "
+			   "for %u bytes more", end - pos,
+			   data->in_len - data->in_used);
+	}
+
+	if (flags & WSC_FLAGS_MF) {
+		if (data->in_buf == NULL && !(flags & WSC_FLAGS_LF)) {
+			wpa_printf(MSG_DEBUG, "EAP-WSC: No Message Length "
+				   "field in a fragmented packet");
+			return;
+		}
+
+		if (data->in_buf == NULL) {
+			/* First fragment of the message */
+			data->in_buf = os_malloc(message_length);
+			if (data->in_buf == NULL) {
+				wpa_printf(MSG_DEBUG, "EAP-WSC: No memory for "
+					   "message");
+				return;
+			}
+			data->in_len = message_length;
+			data->in_used = end - pos;
+			data->in_op_code = op_code;
+			os_memcpy(data->in_buf, pos, data->in_used);
+			wpa_printf(MSG_DEBUG, "EAP-WSC: Received %u bytes in "
+				   "first fragment, waiting for %u bytes more",
+				   data->in_used,
+				   data->in_len - data->in_used);
+		}
+
+		eap_wsc_state(data, FRAG_ACK);
+		return;
+	}
+
+	if (data->in_buf) {
+		msg = data->in_buf;
+		msg_len = data->in_len;
+	} else {
+		msg = pos;
+		msg_len = end - pos;
+	}
+
+	res = wps_process_msg(data->wps, op_code, msg, msg_len);
+	switch (res) {
+	case WPS_DONE:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing completed "
+			   "successfully - report EAP failure");
+		eap_wsc_state(data, FAIL);
+		break;
+	case WPS_CONTINUE:
+		eap_wsc_state(data, MSG);
+		break;
+	case WPS_FAILURE:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing failed");
+		eap_wsc_state(data, FAIL);
+		break;
+	case WPS_PENDING:
+		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing pending");
+		sm->method_pending = METHOD_PENDING_WAIT;
+		break;
+	}
+
+	os_free(data->in_buf);
+	data->in_buf = NULL;
+	data->in_len = data->in_used = 0;
+}
+
+
+static Boolean eap_wsc_isDone(struct eap_sm *sm, void *priv)
+{
+	struct eap_wsc_data *data = priv;
+	return data->state == FAIL;
+}
+
+
+static Boolean eap_wsc_isSuccess(struct eap_sm *sm, void *priv)
+{
+	/* EAP-WSC will always result in EAP-Failure */
+	return FALSE;
+}
+
+
+int eap_server_wsc_register(void)
+{
+	struct eap_method *eap;
+	int ret;
+
+	eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
+				      EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
+				      "WSC");
+	if (eap == NULL)
+		return -1;
+
+	eap->init = eap_wsc_init;
+	eap->reset = eap_wsc_reset;
+	eap->buildReq = eap_wsc_buildReq;
+	eap->check = eap_wsc_check;
+	eap->process = eap_wsc_process;
+	eap->isDone = eap_wsc_isDone;
+	eap->isSuccess = eap_wsc_isSuccess;
+
+	ret = eap_server_method_register(eap);
+	if (ret)
+		eap_server_method_free(eap);
+	return ret;
+}

Added: wpasupplicant/branches/upstream/current/src/eapol_supp/.gitignore
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eapol_supp/.gitignore?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eapol_supp/.gitignore (added)
+++ wpasupplicant/branches/upstream/current/src/eapol_supp/.gitignore Sun Dec  9 08:34:57 2007
@@ -1,0 +1,1 @@
+*.d

Added: wpasupplicant/branches/upstream/current/src/eapol_supp/Makefile
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eapol_supp/Makefile?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eapol_supp/Makefile (added)
+++ wpasupplicant/branches/upstream/current/src/eapol_supp/Makefile Sun Dec  9 08:34:57 2007
@@ -1,0 +1,6 @@
+all:
+	@echo Nothing to be made.
+
+clean:
+	for d in $(SUBDIRS); do make -C $$d clean; done
+	rm -f *~ *.o *.d

Added: wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c (added)
+++ wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,1793 @@
+/*
+ * EAPOL supplicant state machines
+ * Copyright (c) 2004-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eapol_supp_sm.h"
+#include "eap_peer/eap.h"
+#include "eloop.h"
+#include "eapol_common.h"
+#include "md5.h"
+#include "rc4.h"
+#include "state_machine.h"
+
+#define STATE_MACHINE_DATA struct eapol_sm
+#define STATE_MACHINE_DEBUG_PREFIX "EAPOL"
+
+
+/* IEEE 802.1X-2004 - Supplicant - EAPOL state machines */
+
+/**
+ * struct eapol_sm - Internal data for EAPOL state machines
+ */
+struct eapol_sm {
+	/* Timers */
+	unsigned int authWhile;
+	unsigned int heldWhile;
+	unsigned int startWhen;
+	unsigned int idleWhile; /* for EAP state machine */
+
+	/* Global variables */
+	Boolean eapFail;
+	Boolean eapolEap;
+	Boolean eapSuccess;
+	Boolean initialize;
+	Boolean keyDone;
+	Boolean keyRun;
+	PortControl portControl;
+	Boolean portEnabled;
+	PortStatus suppPortStatus;  /* dot1xSuppControlledPortStatus */
+	Boolean portValid;
+	Boolean suppAbort;
+	Boolean suppFail;
+	Boolean suppStart;
+	Boolean suppSuccess;
+	Boolean suppTimeout;
+
+	/* Supplicant PAE state machine */
+	enum {
+		SUPP_PAE_UNKNOWN = 0,
+		SUPP_PAE_DISCONNECTED = 1,
+		SUPP_PAE_LOGOFF = 2,
+		SUPP_PAE_CONNECTING = 3,
+		SUPP_PAE_AUTHENTICATING = 4,
+		SUPP_PAE_AUTHENTICATED = 5,
+		/* unused(6) */
+		SUPP_PAE_HELD = 7,
+		SUPP_PAE_RESTART = 8,
+		SUPP_PAE_S_FORCE_AUTH = 9,
+		SUPP_PAE_S_FORCE_UNAUTH = 10
+	} SUPP_PAE_state; /* dot1xSuppPaeState */
+	/* Variables */
+	Boolean userLogoff;
+	Boolean logoffSent;
+	unsigned int startCount;
+	Boolean eapRestart;
+	PortControl sPortMode;
+	/* Constants */
+	unsigned int heldPeriod; /* dot1xSuppHeldPeriod */
+	unsigned int startPeriod; /* dot1xSuppStartPeriod */
+	unsigned int maxStart; /* dot1xSuppMaxStart */
+
+	/* Key Receive state machine */
+	enum {
+		KEY_RX_UNKNOWN = 0,
+		KEY_RX_NO_KEY_RECEIVE, KEY_RX_KEY_RECEIVE
+	} KEY_RX_state;
+	/* Variables */
+	Boolean rxKey;
+
+	/* Supplicant Backend state machine */
+	enum {
+		SUPP_BE_UNKNOWN = 0,
+		SUPP_BE_INITIALIZE = 1,
+		SUPP_BE_IDLE = 2,
+		SUPP_BE_REQUEST = 3,
+		SUPP_BE_RECEIVE = 4,
+		SUPP_BE_RESPONSE = 5,
+		SUPP_BE_FAIL = 6,
+		SUPP_BE_TIMEOUT = 7, 
+		SUPP_BE_SUCCESS = 8
+	} SUPP_BE_state; /* dot1xSuppBackendPaeState */
+	/* Variables */
+	Boolean eapNoResp;
+	Boolean eapReq;
+	Boolean eapResp;
+	/* Constants */
+	unsigned int authPeriod; /* dot1xSuppAuthPeriod */
+
+	/* Statistics */
+	unsigned int dot1xSuppEapolFramesRx;
+	unsigned int dot1xSuppEapolFramesTx;
+	unsigned int dot1xSuppEapolStartFramesTx;
+	unsigned int dot1xSuppEapolLogoffFramesTx;
+	unsigned int dot1xSuppEapolRespFramesTx;
+	unsigned int dot1xSuppEapolReqIdFramesRx;
+	unsigned int dot1xSuppEapolReqFramesRx;
+	unsigned int dot1xSuppInvalidEapolFramesRx;
+	unsigned int dot1xSuppEapLengthErrorFramesRx;
+	unsigned int dot1xSuppLastEapolFrameVersion;
+	unsigned char dot1xSuppLastEapolFrameSource[6];
+
+	/* Miscellaneous variables (not defined in IEEE 802.1X-2004) */
+	Boolean changed;
+	struct eap_sm *eap;
+	struct wpa_ssid *config;
+	Boolean initial_req;
+	u8 *last_rx_key;
+	size_t last_rx_key_len;
+	u8 *eapReqData; /* for EAP */
+	size_t eapReqDataLen; /* for EAP */
+	Boolean altAccept; /* for EAP */
+	Boolean altReject; /* for EAP */
+	Boolean replay_counter_valid;
+	u8 last_replay_counter[16];
+	struct eapol_config conf;
+	struct eapol_ctx *ctx;
+	enum { EAPOL_CB_IN_PROGRESS = 0, EAPOL_CB_SUCCESS, EAPOL_CB_FAILURE }
+		cb_status;
+	Boolean cached_pmk;
+
+	Boolean unicast_key_received, broadcast_key_received;
+};
+
+
+#define IEEE8021X_REPLAY_COUNTER_LEN 8
+#define IEEE8021X_KEY_SIGN_LEN 16
+#define IEEE8021X_KEY_IV_LEN 16
+
+#define IEEE8021X_KEY_INDEX_FLAG 0x80
+#define IEEE8021X_KEY_INDEX_MASK 0x03
+
+#ifdef _MSC_VER
+#pragma pack(push, 1)
+#endif /* _MSC_VER */
+
+struct ieee802_1x_eapol_key {
+	u8 type;
+	/* Note: key_length is unaligned */
+	u8 key_length[2];
+	/* does not repeat within the life of the keying material used to
+	 * encrypt the Key field; 64-bit NTP timestamp MAY be used here */
+	u8 replay_counter[IEEE8021X_REPLAY_COUNTER_LEN];
+	u8 key_iv[IEEE8021X_KEY_IV_LEN]; /* cryptographically random number */
+	u8 key_index; /* key flag in the most significant bit:
+		       * 0 = broadcast (default key),
+		       * 1 = unicast (key mapping key); key index is in the
+		       * 7 least significant bits */
+	/* HMAC-MD5 message integrity check computed with MS-MPPE-Send-Key as
+	 * the key */
+	u8 key_signature[IEEE8021X_KEY_SIGN_LEN];
+
+	/* followed by key: if packet body length = 44 + key length, then the
+	 * key field (of key_length bytes) contains the key in encrypted form;
+	 * if packet body length = 44, key field is absent and key_length
+	 * represents the number of least significant octets from
+	 * MS-MPPE-Send-Key attribute to be used as the keying material;
+	 * RC4 key used in encryption = Key-IV + MS-MPPE-Recv-Key */
+} STRUCT_PACKED;
+
+#ifdef _MSC_VER
+#pragma pack(pop)
+#endif /* _MSC_VER */
+
+
+static void eapol_sm_txLogoff(struct eapol_sm *sm);
+static void eapol_sm_txStart(struct eapol_sm *sm);
+static void eapol_sm_processKey(struct eapol_sm *sm);
+static void eapol_sm_getSuppRsp(struct eapol_sm *sm);
+static void eapol_sm_txSuppRsp(struct eapol_sm *sm);
+static void eapol_sm_abortSupp(struct eapol_sm *sm);
+static void eapol_sm_abort_cached(struct eapol_sm *sm);
+static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx);
+
+
+/* Port Timers state machine - implemented as a function that will be called
+ * once a second as a registered event loop timeout */
+static void eapol_port_timers_tick(void *eloop_ctx, void *timeout_ctx)
+{
+	struct eapol_sm *sm = timeout_ctx;
+
+	if (sm->authWhile > 0) {
+		sm->authWhile--;
+		if (sm->authWhile == 0)
+			wpa_printf(MSG_DEBUG, "EAPOL: authWhile --> 0");
+	}
+	if (sm->heldWhile > 0) {
+		sm->heldWhile--;
+		if (sm->heldWhile == 0)
+			wpa_printf(MSG_DEBUG, "EAPOL: heldWhile --> 0");
+	}
+	if (sm->startWhen > 0) {
+		sm->startWhen--;
+		if (sm->startWhen == 0)
+			wpa_printf(MSG_DEBUG, "EAPOL: startWhen --> 0");
+	}
+	if (sm->idleWhile > 0) {
+		sm->idleWhile--;
+		if (sm->idleWhile == 0)
+			wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0");
+	}
+
+	eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, sm);
+	eapol_sm_step(sm);
+}
+
+
+SM_STATE(SUPP_PAE, LOGOFF)
+{
+	SM_ENTRY(SUPP_PAE, LOGOFF);
+	eapol_sm_txLogoff(sm);
+	sm->logoffSent = TRUE;
+	sm->suppPortStatus = Unauthorized;
+}
+
+
+SM_STATE(SUPP_PAE, DISCONNECTED)
+{
+	SM_ENTRY(SUPP_PAE, DISCONNECTED);
+	sm->sPortMode = Auto;
+	sm->startCount = 0;
+	sm->logoffSent = FALSE;
+	sm->suppPortStatus = Unauthorized;
+	sm->suppAbort = TRUE;
+
+	sm->unicast_key_received = FALSE;
+	sm->broadcast_key_received = FALSE;
+}
+
+
+SM_STATE(SUPP_PAE, CONNECTING)
+{
+	int send_start = sm->SUPP_PAE_state == SUPP_PAE_CONNECTING;
+	SM_ENTRY(SUPP_PAE, CONNECTING);
+	if (send_start) {
+		sm->startWhen = sm->startPeriod;
+		sm->startCount++;
+	} else {
+		/*
+		 * Do not send EAPOL-Start immediately since in most cases,
+		 * Authenticator is going to start authentication immediately
+		 * after association and an extra EAPOL-Start is just going to
+		 * delay authentication. Use a short timeout to send the first
+		 * EAPOL-Start if Authenticator does not start authentication.
+		 */
+		sm->startWhen = 3;
+	}
+	sm->eapolEap = FALSE;
+	if (send_start)
+		eapol_sm_txStart(sm);
+}
+
+
+SM_STATE(SUPP_PAE, AUTHENTICATING)
+{
+	SM_ENTRY(SUPP_PAE, AUTHENTICATING);
+	sm->startCount = 0;
+	sm->suppSuccess = FALSE;
+	sm->suppFail = FALSE;
+	sm->suppTimeout = FALSE;
+	sm->keyRun = FALSE;
+	sm->keyDone = FALSE;
+	sm->suppStart = TRUE;
+}
+
+
+SM_STATE(SUPP_PAE, HELD)
+{
+	SM_ENTRY(SUPP_PAE, HELD);
+	sm->heldWhile = sm->heldPeriod;
+	sm->suppPortStatus = Unauthorized;
+	sm->cb_status = EAPOL_CB_FAILURE;
+}
+
+
+SM_STATE(SUPP_PAE, AUTHENTICATED)
+{
+	SM_ENTRY(SUPP_PAE, AUTHENTICATED);
+	sm->suppPortStatus = Authorized;
+	sm->cb_status = EAPOL_CB_SUCCESS;
+}
+
+
+SM_STATE(SUPP_PAE, RESTART)
+{
+	SM_ENTRY(SUPP_PAE, RESTART);
+	sm->eapRestart = TRUE;
+}
+
+
+SM_STATE(SUPP_PAE, S_FORCE_AUTH)
+{
+	SM_ENTRY(SUPP_PAE, S_FORCE_AUTH);
+	sm->suppPortStatus = Authorized;
+	sm->sPortMode = ForceAuthorized;
+}
+
+
+SM_STATE(SUPP_PAE, S_FORCE_UNAUTH)
+{
+	SM_ENTRY(SUPP_PAE, S_FORCE_UNAUTH);
+	sm->suppPortStatus = Unauthorized;
+	sm->sPortMode = ForceUnauthorized;
+	eapol_sm_txLogoff(sm);
+}
+
+
+SM_STEP(SUPP_PAE)
+{
+	if ((sm->userLogoff && !sm->logoffSent) &&
+	    !(sm->initialize || !sm->portEnabled))
+		SM_ENTER_GLOBAL(SUPP_PAE, LOGOFF);
+	else if (((sm->portControl == Auto) &&
+		  (sm->sPortMode != sm->portControl)) ||
+		 sm->initialize || !sm->portEnabled)
+		SM_ENTER_GLOBAL(SUPP_PAE, DISCONNECTED);
+	else if ((sm->portControl == ForceAuthorized) &&
+		 (sm->sPortMode != sm->portControl) &&
+		 !(sm->initialize || !sm->portEnabled))
+		SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_AUTH);
+	else if ((sm->portControl == ForceUnauthorized) &&
+		 (sm->sPortMode != sm->portControl) &&
+		 !(sm->initialize || !sm->portEnabled))
+		SM_ENTER_GLOBAL(SUPP_PAE, S_FORCE_UNAUTH);
+	else switch (sm->SUPP_PAE_state) {
+	case SUPP_PAE_UNKNOWN:
+		break;
+	case SUPP_PAE_LOGOFF:
+		if (!sm->userLogoff)
+			SM_ENTER(SUPP_PAE, DISCONNECTED);
+		break;
+	case SUPP_PAE_DISCONNECTED:
+		SM_ENTER(SUPP_PAE, CONNECTING);
+		break;
+	case SUPP_PAE_CONNECTING:
+		if (sm->startWhen == 0 && sm->startCount < sm->maxStart)
+			SM_ENTER(SUPP_PAE, CONNECTING);
+		else if (sm->startWhen == 0 &&
+			 sm->startCount >= sm->maxStart &&
+			 sm->portValid)
+			SM_ENTER(SUPP_PAE, AUTHENTICATED);
+		else if (sm->eapSuccess || sm->eapFail)
+			SM_ENTER(SUPP_PAE, AUTHENTICATING);
+		else if (sm->eapolEap)
+			SM_ENTER(SUPP_PAE, RESTART);
+		else if (sm->startWhen == 0 &&
+			 sm->startCount >= sm->maxStart &&
+			 !sm->portValid)
+			SM_ENTER(SUPP_PAE, HELD);
+		break;
+	case SUPP_PAE_AUTHENTICATING:
+		if (sm->eapSuccess && !sm->portValid &&
+		    sm->conf.accept_802_1x_keys &&
+		    sm->conf.required_keys == 0) {
+			wpa_printf(MSG_DEBUG, "EAPOL: IEEE 802.1X for "
+				   "plaintext connection; no EAPOL-Key frames "
+				   "required");
+			sm->portValid = TRUE;
+			if (sm->ctx->eapol_done_cb)
+				sm->ctx->eapol_done_cb(sm->ctx->ctx);
+		}
+		if (sm->eapSuccess && sm->portValid)
+			SM_ENTER(SUPP_PAE, AUTHENTICATED);
+		else if (sm->eapFail || (sm->keyDone && !sm->portValid))
+			SM_ENTER(SUPP_PAE, HELD);
+		else if (sm->suppTimeout)
+			SM_ENTER(SUPP_PAE, CONNECTING);
+		break;
+	case SUPP_PAE_HELD:
+		if (sm->heldWhile == 0)
+			SM_ENTER(SUPP_PAE, CONNECTING);
+		else if (sm->eapolEap)
+			SM_ENTER(SUPP_PAE, RESTART);
+		break;
+	case SUPP_PAE_AUTHENTICATED:
+		if (sm->eapolEap && sm->portValid)
+			SM_ENTER(SUPP_PAE, RESTART);
+		else if (!sm->portValid)
+			SM_ENTER(SUPP_PAE, DISCONNECTED);
+		break;
+	case SUPP_PAE_RESTART:
+		if (!sm->eapRestart)
+			SM_ENTER(SUPP_PAE, AUTHENTICATING);
+		break;
+	case SUPP_PAE_S_FORCE_AUTH:
+		break;
+	case SUPP_PAE_S_FORCE_UNAUTH:
+		break;
+	}
+}
+
+
+SM_STATE(KEY_RX, NO_KEY_RECEIVE)
+{
+	SM_ENTRY(KEY_RX, NO_KEY_RECEIVE);
+}
+
+
+SM_STATE(KEY_RX, KEY_RECEIVE)
+{
+	SM_ENTRY(KEY_RX, KEY_RECEIVE);
+	eapol_sm_processKey(sm);
+	sm->rxKey = FALSE;
+}
+
+
+SM_STEP(KEY_RX)
+{
+	if (sm->initialize || !sm->portEnabled)
+		SM_ENTER_GLOBAL(KEY_RX, NO_KEY_RECEIVE);
+	switch (sm->KEY_RX_state) {
+	case KEY_RX_UNKNOWN:
+		break;
+	case KEY_RX_NO_KEY_RECEIVE:
+		if (sm->rxKey)
+			SM_ENTER(KEY_RX, KEY_RECEIVE);
+		break;
+	case KEY_RX_KEY_RECEIVE:
+		if (sm->rxKey)
+			SM_ENTER(KEY_RX, KEY_RECEIVE);
+		break;
+	}
+}
+
+
+SM_STATE(SUPP_BE, REQUEST)
+{
+	SM_ENTRY(SUPP_BE, REQUEST);
+	sm->authWhile = 0;
+	sm->eapReq = TRUE;
+	eapol_sm_getSuppRsp(sm);
+}
+
+
+SM_STATE(SUPP_BE, RESPONSE)
+{
+	SM_ENTRY(SUPP_BE, RESPONSE);
+	eapol_sm_txSuppRsp(sm);
+	sm->eapResp = FALSE;
+}
+
+
+SM_STATE(SUPP_BE, SUCCESS)
+{
+	SM_ENTRY(SUPP_BE, SUCCESS);
+	sm->keyRun = TRUE;
+	sm->suppSuccess = TRUE;
+
+	if (eap_key_available(sm->eap)) {
+		/* New key received - clear IEEE 802.1X EAPOL-Key replay
+		 * counter */
+		sm->replay_counter_valid = FALSE;
+	}
+}
+
+
+SM_STATE(SUPP_BE, FAIL)
+{
+	SM_ENTRY(SUPP_BE, FAIL);
+	sm->suppFail = TRUE;
+}
+
+
+SM_STATE(SUPP_BE, TIMEOUT)
+{
+	SM_ENTRY(SUPP_BE, TIMEOUT);
+	sm->suppTimeout = TRUE;
+}
+
+
+SM_STATE(SUPP_BE, IDLE)
+{
+	SM_ENTRY(SUPP_BE, IDLE);
+	sm->suppStart = FALSE;
+	sm->initial_req = TRUE;
+}
+
+
+SM_STATE(SUPP_BE, INITIALIZE)
+{
+	SM_ENTRY(SUPP_BE, INITIALIZE);
+	eapol_sm_abortSupp(sm);
+	sm->suppAbort = FALSE;
+}
+
+
+SM_STATE(SUPP_BE, RECEIVE)
+{
+	SM_ENTRY(SUPP_BE, RECEIVE);
+	sm->authWhile = sm->authPeriod;
+	sm->eapolEap = FALSE;
+	sm->eapNoResp = FALSE;
+	sm->initial_req = FALSE;
+}
+
+
+SM_STEP(SUPP_BE)
+{
+	if (sm->initialize || sm->suppAbort)
+		SM_ENTER_GLOBAL(SUPP_BE, INITIALIZE);
+	else switch (sm->SUPP_BE_state) {
+	case SUPP_BE_UNKNOWN:
+		break;
+	case SUPP_BE_REQUEST:
+		/*
+		 * IEEE Std 802.1X-2004 has transitions from REQUEST to FAIL
+		 * and SUCCESS based on eapFail and eapSuccess, respectively.
+		 * However, IEEE Std 802.1X-2004 is also specifying that
+		 * eapNoResp should be set in conjuction with eapSuccess and
+		 * eapFail which would mean that more than one of the
+		 * transitions here would be activated at the same time.
+		 * Skipping RESPONSE and/or RECEIVE states in these cases can
+		 * cause problems and the direct transitions to do not seem
+		 * correct. Because of this, the conditions for these
+		 * transitions are verified only after eapNoResp. They are
+		 * unlikely to be used since eapNoResp should always be set if
+		 * either of eapSuccess or eapFail is set.
+		 */
+		if (sm->eapResp && sm->eapNoResp) {
+			wpa_printf(MSG_DEBUG, "EAPOL: SUPP_BE REQUEST: both "
+				   "eapResp and eapNoResp set?!");
+		}
+		if (sm->eapResp)
+			SM_ENTER(SUPP_BE, RESPONSE);
+		else if (sm->eapNoResp)
+			SM_ENTER(SUPP_BE, RECEIVE);
+		else if (sm->eapFail)
+			SM_ENTER(SUPP_BE, FAIL);
+		else if (sm->eapSuccess)
+			SM_ENTER(SUPP_BE, SUCCESS);
+		break;
+	case SUPP_BE_RESPONSE:
+		SM_ENTER(SUPP_BE, RECEIVE);
+		break;
+	case SUPP_BE_SUCCESS:
+		SM_ENTER(SUPP_BE, IDLE);
+		break;
+	case SUPP_BE_FAIL:
+		SM_ENTER(SUPP_BE, IDLE);
+		break;
+	case SUPP_BE_TIMEOUT:
+		SM_ENTER(SUPP_BE, IDLE);
+		break;
+	case SUPP_BE_IDLE:
+		if (sm->eapFail && sm->suppStart)
+			SM_ENTER(SUPP_BE, FAIL);
+		else if (sm->eapolEap && sm->suppStart)
+			SM_ENTER(SUPP_BE, REQUEST);
+		else if (sm->eapSuccess && sm->suppStart)
+			SM_ENTER(SUPP_BE, SUCCESS);
+		break;
+	case SUPP_BE_INITIALIZE:
+		SM_ENTER(SUPP_BE, IDLE);
+		break;
+	case SUPP_BE_RECEIVE:
+		if (sm->eapolEap)
+			SM_ENTER(SUPP_BE, REQUEST);
+		else if (sm->eapFail)
+			SM_ENTER(SUPP_BE, FAIL);
+		else if (sm->authWhile == 0)
+			SM_ENTER(SUPP_BE, TIMEOUT);
+		else if (sm->eapSuccess)
+			SM_ENTER(SUPP_BE, SUCCESS);
+		break;
+	}
+}
+
+
+static void eapol_sm_txLogoff(struct eapol_sm *sm)
+{
+	wpa_printf(MSG_DEBUG, "EAPOL: txLogoff");
+	sm->ctx->eapol_send(sm->ctx->eapol_send_ctx,
+			    IEEE802_1X_TYPE_EAPOL_LOGOFF, (u8 *) "", 0);
+	sm->dot1xSuppEapolLogoffFramesTx++;
+	sm->dot1xSuppEapolFramesTx++;
+}
+
+
+static void eapol_sm_txStart(struct eapol_sm *sm)
+{
+	wpa_printf(MSG_DEBUG, "EAPOL: txStart");
+	sm->ctx->eapol_send(sm->ctx->eapol_send_ctx,
+			    IEEE802_1X_TYPE_EAPOL_START, (u8 *) "", 0);
+	sm->dot1xSuppEapolStartFramesTx++;
+	sm->dot1xSuppEapolFramesTx++;
+}
+
+
+#define IEEE8021X_ENCR_KEY_LEN 32
+#define IEEE8021X_SIGN_KEY_LEN 32
+
+struct eap_key_data {
+	u8 encr_key[IEEE8021X_ENCR_KEY_LEN];
+	u8 sign_key[IEEE8021X_SIGN_KEY_LEN];
+};
+
+
+static void eapol_sm_processKey(struct eapol_sm *sm)
+{
+	struct ieee802_1x_hdr *hdr;
+	struct ieee802_1x_eapol_key *key;
+	struct eap_key_data keydata;
+	u8 orig_key_sign[IEEE8021X_KEY_SIGN_LEN], datakey[32];
+	u8 ekey[IEEE8021X_KEY_IV_LEN + IEEE8021X_ENCR_KEY_LEN];
+	int key_len, res, sign_key_len, encr_key_len;
+	u16 rx_key_length;
+
+	wpa_printf(MSG_DEBUG, "EAPOL: processKey");
+	if (sm->last_rx_key == NULL)
+		return;
+
+	if (!sm->conf.accept_802_1x_keys) {
+		wpa_printf(MSG_WARNING, "EAPOL: Received IEEE 802.1X EAPOL-Key"
+			   " even though this was not accepted - "
+			   "ignoring this packet");
+		return;
+	}
+
+	hdr = (struct ieee802_1x_hdr *) sm->last_rx_key;
+	key = (struct ieee802_1x_eapol_key *) (hdr + 1);
+	if (sizeof(*hdr) + be_to_host16(hdr->length) > sm->last_rx_key_len) {
+		wpa_printf(MSG_WARNING, "EAPOL: Too short EAPOL-Key frame");
+		return;
+	}
+	rx_key_length = WPA_GET_BE16(key->key_length);
+	wpa_printf(MSG_DEBUG, "EAPOL: RX IEEE 802.1X ver=%d type=%d len=%d "
+		   "EAPOL-Key: type=%d key_length=%d key_index=0x%x",
+		   hdr->version, hdr->type, be_to_host16(hdr->length),
+		   key->type, rx_key_length, key->key_index);
+
+	eapol_sm_notify_lower_layer_success(sm);
+	sign_key_len = IEEE8021X_SIGN_KEY_LEN;
+	encr_key_len = IEEE8021X_ENCR_KEY_LEN;
+	res = eapol_sm_get_key(sm, (u8 *) &keydata, sizeof(keydata));
+	if (res < 0) {
+		wpa_printf(MSG_DEBUG, "EAPOL: Could not get master key for "
+			   "decrypting EAPOL-Key keys");
+		return;
+	}
+	if (res == 16) {
+		/* LEAP derives only 16 bytes of keying material. */
+		res = eapol_sm_get_key(sm, (u8 *) &keydata, 16);
+		if (res) {
+			wpa_printf(MSG_DEBUG, "EAPOL: Could not get LEAP "
+				   "master key for decrypting EAPOL-Key keys");
+			return;
+		}
+		sign_key_len = 16;
+		encr_key_len = 16;
+		os_memcpy(keydata.sign_key, keydata.encr_key, 16);
+	} else if (res) {
+		wpa_printf(MSG_DEBUG, "EAPOL: Could not get enough master key "
+			   "data for decrypting EAPOL-Key keys (res=%d)", res);
+		return;
+	}
+
+	/* The key replay_counter must increase when same master key */
+	if (sm->replay_counter_valid &&
+	    os_memcmp(sm->last_replay_counter, key->replay_counter,
+		      IEEE8021X_REPLAY_COUNTER_LEN) >= 0) {
+		wpa_printf(MSG_WARNING, "EAPOL: EAPOL-Key replay counter did "
+			   "not increase - ignoring key");
+		wpa_hexdump(MSG_DEBUG, "EAPOL: last replay counter",
+			    sm->last_replay_counter,
+			    IEEE8021X_REPLAY_COUNTER_LEN);
+		wpa_hexdump(MSG_DEBUG, "EAPOL: received replay counter",
+			    key->replay_counter, IEEE8021X_REPLAY_COUNTER_LEN);
+		return;
+	}
+
+	/* Verify key signature (HMAC-MD5) */
+	os_memcpy(orig_key_sign, key->key_signature, IEEE8021X_KEY_SIGN_LEN);
+	os_memset(key->key_signature, 0, IEEE8021X_KEY_SIGN_LEN);
+	hmac_md5(keydata.sign_key, sign_key_len,
+		 sm->last_rx_key, sizeof(*hdr) + be_to_host16(hdr->length),
+		 key->key_signature);
+	if (os_memcmp(orig_key_sign, key->key_signature,
+		      IEEE8021X_KEY_SIGN_LEN) != 0) {
+		wpa_printf(MSG_DEBUG, "EAPOL: Invalid key signature in "
+			   "EAPOL-Key packet");
+		os_memcpy(key->key_signature, orig_key_sign,
+			  IEEE8021X_KEY_SIGN_LEN);
+		return;
+	}
+	wpa_printf(MSG_DEBUG, "EAPOL: EAPOL-Key key signature verified");
+
+	key_len = be_to_host16(hdr->length) - sizeof(*key);
+	if (key_len > 32 || rx_key_length > 32) {
+		wpa_printf(MSG_WARNING, "EAPOL: Too long key data length %d",
+			   key_len ? key_len : rx_key_length);
+		return;
+	}
+	if (key_len == rx_key_length) {
+		os_memcpy(ekey, key->key_iv, IEEE8021X_KEY_IV_LEN);
+		os_memcpy(ekey + IEEE8021X_KEY_IV_LEN, keydata.encr_key,
+			  encr_key_len);
+		os_memcpy(datakey, key + 1, key_len);
+		rc4(datakey, key_len, ekey,
+		    IEEE8021X_KEY_IV_LEN + encr_key_len);
+		wpa_hexdump_key(MSG_DEBUG, "EAPOL: Decrypted(RC4) key",
+				datakey, key_len);
+	} else if (key_len == 0) {
+		/*
+		 * IEEE 802.1X-2004 specifies that least significant Key Length
+		 * octets from MS-MPPE-Send-Key are used as the key if the key
+		 * data is not present. This seems to be meaning the beginning
+		 * of the MS-MPPE-Send-Key. In addition, MS-MPPE-Send-Key in
+		 * Supplicant corresponds to MS-MPPE-Recv-Key in Authenticator.
+		 * Anyway, taking the beginning of the keying material from EAP
+		 * seems to interoperate with Authenticators.
+		 */
+		key_len = rx_key_length;
+		os_memcpy(datakey, keydata.encr_key, key_len);
+		wpa_hexdump_key(MSG_DEBUG, "EAPOL: using part of EAP keying "
+				"material data encryption key",
+				datakey, key_len);
+	} else {
+		wpa_printf(MSG_DEBUG, "EAPOL: Invalid key data length %d "
+			   "(key_length=%d)", key_len, rx_key_length);
+		return;
+	}
+
+	sm->replay_counter_valid = TRUE;
+	os_memcpy(sm->last_replay_counter, key->replay_counter,
+		  IEEE8021X_REPLAY_COUNTER_LEN);
+
+	wpa_printf(MSG_DEBUG, "EAPOL: Setting dynamic WEP key: %s keyidx %d "
+		   "len %d",
+		   key->key_index & IEEE8021X_KEY_INDEX_FLAG ?
+		   "unicast" : "broadcast",
+		   key->key_index & IEEE8021X_KEY_INDEX_MASK, key_len);
+
+	if (sm->ctx->set_wep_key &&
+	    sm->ctx->set_wep_key(sm->ctx->ctx,
+				 key->key_index & IEEE8021X_KEY_INDEX_FLAG,
+				 key->key_index & IEEE8021X_KEY_INDEX_MASK,
+				 datakey, key_len) < 0) {
+		wpa_printf(MSG_WARNING, "EAPOL: Failed to set WEP key to the "
+			   " driver.");
+	} else {
+		if (key->key_index & IEEE8021X_KEY_INDEX_FLAG)
+			sm->unicast_key_received = TRUE;
+		else
+			sm->broadcast_key_received = TRUE;
+
+		if ((sm->unicast_key_received ||
+		     !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_UNICAST)) &&
+		    (sm->broadcast_key_received ||
+		     !(sm->conf.required_keys & EAPOL_REQUIRE_KEY_BROADCAST)))
+		{
+			wpa_printf(MSG_DEBUG, "EAPOL: all required EAPOL-Key "
+				   "frames received");
+			sm->portValid = TRUE;
+			if (sm->ctx->eapol_done_cb)
+				sm->ctx->eapol_done_cb(sm->ctx->ctx);
+		}
+	}
+}
+
+
+static void eapol_sm_getSuppRsp(struct eapol_sm *sm)
+{
+	wpa_printf(MSG_DEBUG, "EAPOL: getSuppRsp");
+	/* EAP layer processing; no special code is needed, since Supplicant
+	 * Backend state machine is waiting for eapNoResp or eapResp to be set
+	 * and these are only set in the EAP state machine when the processing
+	 * has finished. */
+}
+
+
+static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
+{
+	u8 *resp;
+	size_t resp_len;
+
+	wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp");
+	resp = eap_get_eapRespData(sm->eap, &resp_len);
+	if (resp == NULL) {
+		wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data "
+			   "not available");
+		return;
+	}
+
+	/* Send EAP-Packet from the EAP layer to the Authenticator */
+	sm->ctx->eapol_send(sm->ctx->eapol_send_ctx,
+			    IEEE802_1X_TYPE_EAP_PACKET, resp, resp_len);
+
+	/* eapRespData is not used anymore, so free it here */
+	os_free(resp);
+
+	if (sm->initial_req)
+		sm->dot1xSuppEapolReqIdFramesRx++;
+	else
+		sm->dot1xSuppEapolReqFramesRx++;
+	sm->dot1xSuppEapolRespFramesTx++;
+	sm->dot1xSuppEapolFramesTx++;
+}
+
+
+static void eapol_sm_abortSupp(struct eapol_sm *sm)
+{
+	/* release system resources that may have been allocated for the
+	 * authentication session */
+	os_free(sm->last_rx_key);
+	sm->last_rx_key = NULL;
+	os_free(sm->eapReqData);
+	sm->eapReqData = NULL;
+	eap_sm_abort(sm->eap);
+}
+
+
+static void eapol_sm_step_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	eapol_sm_step(timeout_ctx);
+}
+
+
+/**
+ * eapol_sm_step - EAPOL state machine step function
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * This function is called to notify the state machine about changed external
+ * variables. It will step through the EAPOL state machines in loop to process
+ * all triggered state changes.
+ */
+void eapol_sm_step(struct eapol_sm *sm)
+{
+	int i;
+
+	/* In theory, it should be ok to run this in loop until !changed.
+	 * However, it is better to use a limit on number of iterations to
+	 * allow events (e.g., SIGTERM) to stop the program cleanly if the
+	 * state machine were to generate a busy loop. */
+	for (i = 0; i < 100; i++) {
+		sm->changed = FALSE;
+		SM_STEP_RUN(SUPP_PAE);
+		SM_STEP_RUN(KEY_RX);
+		SM_STEP_RUN(SUPP_BE);
+		if (eap_peer_sm_step(sm->eap))
+			sm->changed = TRUE;
+		if (!sm->changed)
+			break;
+	}
+
+	if (sm->changed) {
+		/* restart EAPOL state machine step from timeout call in order
+		 * to allow other events to be processed. */
+		eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm);
+		eloop_register_timeout(0, 0, eapol_sm_step_timeout, NULL, sm);
+	}
+
+	if (sm->ctx->cb && sm->cb_status != EAPOL_CB_IN_PROGRESS) {
+		int success = sm->cb_status == EAPOL_CB_SUCCESS ? 1 : 0;
+		sm->cb_status = EAPOL_CB_IN_PROGRESS;
+		sm->ctx->cb(sm, success, sm->ctx->cb_ctx);
+	}
+}
+
+
+#ifdef CONFIG_CTRL_IFACE
+static const char *eapol_supp_pae_state(int state)
+{
+	switch (state) {
+	case SUPP_PAE_LOGOFF:
+		return "LOGOFF";
+	case SUPP_PAE_DISCONNECTED:
+		return "DISCONNECTED";
+	case SUPP_PAE_CONNECTING:
+		return "CONNECTING";
+	case SUPP_PAE_AUTHENTICATING:
+		return "AUTHENTICATING";
+	case SUPP_PAE_HELD:
+		return "HELD";
+	case SUPP_PAE_AUTHENTICATED:
+		return "AUTHENTICATED";
+	case SUPP_PAE_RESTART:
+		return "RESTART";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+
+static const char *eapol_supp_be_state(int state)
+{
+	switch (state) {
+	case SUPP_BE_REQUEST:
+		return "REQUEST";
+	case SUPP_BE_RESPONSE:
+		return "RESPONSE";
+	case SUPP_BE_SUCCESS:
+		return "SUCCESS";
+	case SUPP_BE_FAIL:
+		return "FAIL";
+	case SUPP_BE_TIMEOUT:
+		return "TIMEOUT";
+	case SUPP_BE_IDLE:
+		return "IDLE";
+	case SUPP_BE_INITIALIZE:
+		return "INITIALIZE";
+	case SUPP_BE_RECEIVE:
+		return "RECEIVE";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+
+static const char * eapol_port_status(PortStatus status)
+{
+	if (status == Authorized)
+		return "Authorized";
+	else
+		return "Unauthorized";
+}
+#endif /* CONFIG_CTRL_IFACE */
+
+
+#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
+static const char * eapol_port_control(PortControl ctrl)
+{
+	switch (ctrl) {
+	case Auto:
+		return "Auto";
+	case ForceUnauthorized:
+		return "ForceUnauthorized";
+	case ForceAuthorized:
+		return "ForceAuthorized";
+	default:
+		return "Unknown";
+	}
+}
+#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
+
+
+/**
+ * eapol_sm_configure - Set EAPOL variables
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @heldPeriod: dot1xSuppHeldPeriod
+ * @authPeriod: dot1xSuppAuthPeriod
+ * @startPeriod: dot1xSuppStartPeriod
+ * @maxStart: dot1xSuppMaxStart
+ *
+ * Set configurable EAPOL state machine variables. Each variable can be set to
+ * the given value or ignored if set to -1 (to set only some of the variables).
+ */
+void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod,
+			int startPeriod, int maxStart)
+{
+	if (sm == NULL)
+		return;
+	if (heldPeriod >= 0)
+		sm->heldPeriod = heldPeriod;
+	if (authPeriod >= 0)
+		sm->authPeriod = authPeriod;
+	if (startPeriod >= 0)
+		sm->startPeriod = startPeriod;
+	if (maxStart >= 0)
+		sm->maxStart = maxStart;
+}
+
+
+#ifdef CONFIG_CTRL_IFACE
+/**
+ * eapol_sm_get_status - Get EAPOL state machine status
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @buf: Buffer for status information
+ * @buflen: Maximum buffer length
+ * @verbose: Whether to include verbose status information
+ * Returns: Number of bytes written to buf.
+ *
+ * Query EAPOL state machine for status information. This function fills in a
+ * text area with current status information from the EAPOL state machine. If
+ * the buffer (buf) is not large enough, status information will be truncated
+ * to fit the buffer.
+ */
+int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
+			int verbose)
+{
+	int len, ret;
+	if (sm == NULL)
+		return 0;
+
+	len = os_snprintf(buf, buflen,
+			  "Supplicant PAE state=%s\n"
+			  "suppPortStatus=%s\n",
+			  eapol_supp_pae_state(sm->SUPP_PAE_state),
+			  eapol_port_status(sm->suppPortStatus));
+	if (len < 0 || (size_t) len >= buflen)
+		return 0;
+
+	if (verbose) {
+		ret = os_snprintf(buf + len, buflen - len,
+				  "heldPeriod=%u\n"
+				  "authPeriod=%u\n"
+				  "startPeriod=%u\n"
+				  "maxStart=%u\n"
+				  "portControl=%s\n"
+				  "Supplicant Backend state=%s\n",
+				  sm->heldPeriod,
+				  sm->authPeriod,
+				  sm->startPeriod,
+				  sm->maxStart,
+				  eapol_port_control(sm->portControl),
+				  eapol_supp_be_state(sm->SUPP_BE_state));
+		if (ret < 0 || (size_t) ret >= buflen - len)
+			return len;
+		len += ret;
+	}
+
+	len += eap_sm_get_status(sm->eap, buf + len, buflen - len, verbose);
+
+	return len;
+}
+
+
+/**
+ * eapol_sm_get_mib - Get EAPOL state machine MIBs
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @buf: Buffer for MIB information
+ * @buflen: Maximum buffer length
+ * Returns: Number of bytes written to buf.
+ *
+ * Query EAPOL state machine for MIB information. This function fills in a
+ * text area with current MIB information from the EAPOL state machine. If
+ * the buffer (buf) is not large enough, MIB information will be truncated to
+ * fit the buffer.
+ */
+int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen)
+{
+	size_t len;
+	int ret;
+
+	if (sm == NULL)
+		return 0;
+	ret = os_snprintf(buf, buflen,
+			  "dot1xSuppPaeState=%d\n"
+			  "dot1xSuppHeldPeriod=%u\n"
+			  "dot1xSuppAuthPeriod=%u\n"
+			  "dot1xSuppStartPeriod=%u\n"
+			  "dot1xSuppMaxStart=%u\n"
+			  "dot1xSuppSuppControlledPortStatus=%s\n"
+			  "dot1xSuppBackendPaeState=%d\n",
+			  sm->SUPP_PAE_state,
+			  sm->heldPeriod,
+			  sm->authPeriod,
+			  sm->startPeriod,
+			  sm->maxStart,
+			  sm->suppPortStatus == Authorized ?
+			  "Authorized" : "Unauthorized",
+			  sm->SUPP_BE_state);
+
+	if (ret < 0 || (size_t) ret >= buflen)
+		return 0;
+	len = ret;
+
+	ret = os_snprintf(buf + len, buflen - len,
+			  "dot1xSuppEapolFramesRx=%u\n"
+			  "dot1xSuppEapolFramesTx=%u\n"
+			  "dot1xSuppEapolStartFramesTx=%u\n"
+			  "dot1xSuppEapolLogoffFramesTx=%u\n"
+			  "dot1xSuppEapolRespFramesTx=%u\n"
+			  "dot1xSuppEapolReqIdFramesRx=%u\n"
+			  "dot1xSuppEapolReqFramesRx=%u\n"
+			  "dot1xSuppInvalidEapolFramesRx=%u\n"
+			  "dot1xSuppEapLengthErrorFramesRx=%u\n"
+			  "dot1xSuppLastEapolFrameVersion=%u\n"
+			  "dot1xSuppLastEapolFrameSource=" MACSTR "\n",
+			  sm->dot1xSuppEapolFramesRx,
+			  sm->dot1xSuppEapolFramesTx,
+			  sm->dot1xSuppEapolStartFramesTx,
+			  sm->dot1xSuppEapolLogoffFramesTx,
+			  sm->dot1xSuppEapolRespFramesTx,
+			  sm->dot1xSuppEapolReqIdFramesRx,
+			  sm->dot1xSuppEapolReqFramesRx,
+			  sm->dot1xSuppInvalidEapolFramesRx,
+			  sm->dot1xSuppEapLengthErrorFramesRx,
+			  sm->dot1xSuppLastEapolFrameVersion,
+			  MAC2STR(sm->dot1xSuppLastEapolFrameSource));
+
+	if (ret < 0 || (size_t) ret >= buflen - len)
+		return len;
+	len += ret;
+
+	return len;
+}
+#endif /* CONFIG_CTRL_IFACE */
+
+
+/**
+ * eapol_sm_rx_eapol - Process received EAPOL frames
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @src: Source MAC address of the EAPOL packet
+ * @buf: Pointer to the beginning of the EAPOL data (EAPOL header)
+ * @len: Length of the EAPOL frame
+ * Returns: 1 = EAPOL frame processed, 0 = not for EAPOL state machine,
+ * -1 failure
+ */
+int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
+		      size_t len)
+{
+	const struct ieee802_1x_hdr *hdr;
+	const struct ieee802_1x_eapol_key *key;
+	int data_len;
+	int res = 1;
+	size_t plen;
+
+	if (sm == NULL)
+		return 0;
+	sm->dot1xSuppEapolFramesRx++;
+	if (len < sizeof(*hdr)) {
+		sm->dot1xSuppInvalidEapolFramesRx++;
+		return 0;
+	}
+	hdr = (const struct ieee802_1x_hdr *) buf;
+	sm->dot1xSuppLastEapolFrameVersion = hdr->version;
+	os_memcpy(sm->dot1xSuppLastEapolFrameSource, src, ETH_ALEN);
+	if (hdr->version < EAPOL_VERSION) {
+		/* TODO: backwards compatibility */
+	}
+	plen = be_to_host16(hdr->length);
+	if (plen > len - sizeof(*hdr)) {
+		sm->dot1xSuppEapLengthErrorFramesRx++;
+		return 0;
+	}
+	data_len = plen + sizeof(*hdr);
+
+	switch (hdr->type) {
+	case IEEE802_1X_TYPE_EAP_PACKET:
+		if (sm->cached_pmk) {
+			/* Trying to use PMKSA caching, but Authenticator did
+			 * not seem to have a matching entry. Need to restart
+			 * EAPOL state machines.
+			 */
+			eapol_sm_abort_cached(sm);
+		}
+		os_free(sm->eapReqData);
+		sm->eapReqDataLen = plen;
+		sm->eapReqData = os_malloc(sm->eapReqDataLen);
+		if (sm->eapReqData) {
+			wpa_printf(MSG_DEBUG, "EAPOL: Received EAP-Packet "
+				   "frame");
+			os_memcpy(sm->eapReqData, (u8 *) (hdr + 1),
+				  sm->eapReqDataLen);
+			sm->eapolEap = TRUE;
+			eapol_sm_step(sm);
+		}
+		break;
+	case IEEE802_1X_TYPE_EAPOL_KEY:
+		if (plen < sizeof(*key)) {
+			wpa_printf(MSG_DEBUG, "EAPOL: Too short EAPOL-Key "
+				   "frame received");
+			break;
+		}
+		key = (const struct ieee802_1x_eapol_key *) (hdr + 1);
+		if (key->type == EAPOL_KEY_TYPE_WPA ||
+		    key->type == EAPOL_KEY_TYPE_RSN) {
+			/* WPA Supplicant takes care of this frame. */
+			wpa_printf(MSG_DEBUG, "EAPOL: Ignoring WPA EAPOL-Key "
+				   "frame in EAPOL state machines");
+			res = 0;
+			break;
+		}
+		if (key->type != EAPOL_KEY_TYPE_RC4) {
+			wpa_printf(MSG_DEBUG, "EAPOL: Ignored unknown "
+				   "EAPOL-Key type %d", key->type);
+			break;
+		}
+		os_free(sm->last_rx_key);
+		sm->last_rx_key = os_malloc(data_len);
+		if (sm->last_rx_key) {
+			wpa_printf(MSG_DEBUG, "EAPOL: Received EAPOL-Key "
+				   "frame");
+			os_memcpy(sm->last_rx_key, buf, data_len);
+			sm->last_rx_key_len = data_len;
+			sm->rxKey = TRUE;
+			eapol_sm_step(sm);
+		}
+		break;
+	default:
+		wpa_printf(MSG_DEBUG, "EAPOL: Received unknown EAPOL type %d",
+			   hdr->type);
+		sm->dot1xSuppInvalidEapolFramesRx++;
+		break;
+	}
+
+	return res;
+}
+
+
+/**
+ * eapol_sm_notify_tx_eapol_key - Notification about transmitted EAPOL packet
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * Notify EAPOL station machine about transmitted EAPOL packet from an external
+ * component, e.g., WPA. This will update the statistics.
+ */
+void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
+{
+	if (sm)
+		sm->dot1xSuppEapolFramesTx++;
+}
+
+
+/**
+ * eapol_sm_notify_portEnabled - Notification about portEnabled change
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @enabled: New portEnabled value
+ *
+ * Notify EAPOL station machine about new portEnabled value.
+ */
+void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled)
+{
+	if (sm == NULL)
+		return;
+	wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
+		   "portEnabled=%d", enabled);
+	sm->portEnabled = enabled;
+	eapol_sm_step(sm);
+}
+
+
+/**
+ * eapol_sm_notify_portValid - Notification about portValid change
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @valid: New portValid value
+ *
+ * Notify EAPOL station machine about new portValid value.
+ */
+void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid)
+{
+	if (sm == NULL)
+		return;
+	wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
+		   "portValid=%d", valid);
+	sm->portValid = valid;
+	eapol_sm_step(sm);
+}
+
+
+/**
+ * eapol_sm_notify_eap_success - Notification of external EAP success trigger
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @success: %TRUE = set success, %FALSE = clear success
+ *
+ * Notify the EAPOL state machine that external event has forced EAP state to
+ * success (success = %TRUE). This can be cleared by setting success = %FALSE.
+ *
+ * This function is called to update EAP state when WPA-PSK key handshake has
+ * been completed successfully since WPA-PSK does not use EAP state machine.
+ */
+void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success)
+{
+	if (sm == NULL)
+		return;
+	wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
+		   "EAP success=%d", success);
+	sm->eapSuccess = success;
+	sm->altAccept = success;
+	if (success)
+		eap_notify_success(sm->eap);
+	eapol_sm_step(sm);
+}
+
+
+/**
+ * eapol_sm_notify_eap_fail - Notification of external EAP failure trigger
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @fail: %TRUE = set failure, %FALSE = clear failure
+ *
+ * Notify EAPOL station machine that external event has forced EAP state to
+ * failure (fail = %TRUE). This can be cleared by setting fail = %FALSE.
+ */
+void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
+{
+	if (sm == NULL)
+		return;
+	wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
+		   "EAP fail=%d", fail);
+	sm->eapFail = fail;
+	sm->altReject = fail;
+	eapol_sm_step(sm);
+}
+
+
+/**
+ * eapol_sm_notify_config - Notification of EAPOL configuration change
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @config: Pointer to current network configuration
+ * @conf: Pointer to EAPOL configuration data
+ *
+ * Notify EAPOL station machine that configuration has changed. config will be
+ * stored as a backpointer to network configuration. This can be %NULL to clear
+ * the stored pointed. conf will be copied to local EAPOL/EAP configuration
+ * data. If conf is %NULL, this part of the configuration change will be
+ * skipped.
+ */
+void eapol_sm_notify_config(struct eapol_sm *sm, struct wpa_ssid *config,
+			    const struct eapol_config *conf)
+{
+	if (sm == NULL)
+		return;
+
+	sm->config = config;
+
+	if (conf == NULL)
+		return;
+
+	sm->conf.accept_802_1x_keys = conf->accept_802_1x_keys;
+	sm->conf.required_keys = conf->required_keys;
+	sm->conf.fast_reauth = conf->fast_reauth;
+	if (sm->eap) {
+		eap_set_fast_reauth(sm->eap, conf->fast_reauth);
+		eap_set_workaround(sm->eap, conf->workaround);
+		eap_set_force_disabled(sm->eap, conf->eap_disabled);
+	}
+}
+
+
+/**
+ * eapol_sm_get_key - Get master session key (MSK) from EAP
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @key: Pointer for key buffer
+ * @len: Number of bytes to copy to key
+ * Returns: 0 on success (len of key available), maximum available key len
+ * (>0) if key is available but it is shorter than len, or -1 on failure.
+ *
+ * Fetch EAP keying material (MSK, eapKeyData) from EAP state machine. The key
+ * is available only after a successful authentication.
+ */
+int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
+{
+	const u8 *eap_key;
+	size_t eap_len;
+
+	if (sm == NULL || !eap_key_available(sm->eap))
+		return -1;
+	eap_key = eap_get_eapKeyData(sm->eap, &eap_len);
+	if (eap_key == NULL)
+		return -1;
+	if (len > eap_len)
+		return eap_len;
+	os_memcpy(key, eap_key, len);
+	return 0;
+}
+
+
+/**
+ * eapol_sm_notify_logoff - Notification of logon/logoff commands
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @logoff: Whether command was logoff
+ *
+ * Notify EAPOL state machines that user requested logon/logoff.
+ */
+void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff)
+{
+	if (sm) {
+		sm->userLogoff = logoff;
+		eapol_sm_step(sm);
+	}
+}
+
+
+/**
+ * eapol_sm_notify_pmkid_attempt - Notification of successful PMKSA caching
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * Notify EAPOL state machines that PMKSA caching was successful. This is used
+ * to move EAPOL and EAP state machines into authenticated/successful state.
+ */
+void eapol_sm_notify_cached(struct eapol_sm *sm)
+{
+	if (sm == NULL)
+		return;
+	sm->SUPP_PAE_state = SUPP_PAE_AUTHENTICATED;
+	sm->suppPortStatus = Authorized;
+	eap_notify_success(sm->eap);
+}
+
+
+/**
+ * eapol_sm_notify_pmkid_attempt - Notification of PMKSA caching
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @attempt: Whether PMKSA caching is tried
+ *
+ * Notify EAPOL state machines whether PMKSA caching is used.
+ */
+void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm, int attempt)
+{
+	if (sm == NULL)
+		return;
+	if (attempt) {
+		wpa_printf(MSG_DEBUG, "RSN: Trying to use cached PMKSA");
+		sm->cached_pmk = TRUE;
+	} else {
+		wpa_printf(MSG_DEBUG, "RSN: Do not try to use cached PMKSA");
+		sm->cached_pmk = FALSE;
+	}
+}
+
+
+static void eapol_sm_abort_cached(struct eapol_sm *sm)
+{
+	wpa_printf(MSG_DEBUG, "RSN: Authenticator did not accept PMKID, "
+		   "doing full EAP authentication");
+	if (sm == NULL)
+		return;
+	sm->cached_pmk = FALSE;
+	sm->SUPP_PAE_state = SUPP_PAE_CONNECTING;
+	sm->suppPortStatus = Unauthorized;
+
+	/* Make sure we do not start sending EAPOL-Start frames first, but
+	 * instead move to RESTART state to start EAPOL authentication. */
+	sm->startWhen = 3;
+
+	if (sm->ctx->aborted_cached)
+		sm->ctx->aborted_cached(sm->ctx->ctx);
+}
+
+
+/**
+ * eapol_sm_register_scard_ctx - Notification of smart card context
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @ctx: Context data for smart card operations
+ *
+ * Notify EAPOL state machines of context data for smart card operations. This
+ * context data will be used as a parameter for scard_*() functions.
+ */
+void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx)
+{
+	if (sm) {
+		sm->ctx->scard_ctx = ctx;
+		eap_register_scard_ctx(sm->eap, ctx);
+	}
+}
+
+
+/**
+ * eapol_sm_notify_portControl - Notification of portControl changes
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ * @portControl: New value for portControl variable
+ *
+ * Notify EAPOL state machines that portControl variable has changed.
+ */
+void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl)
+{
+	if (sm == NULL)
+		return;
+	wpa_printf(MSG_DEBUG, "EAPOL: External notification - "
+		   "portControl=%s", eapol_port_control(portControl));
+	sm->portControl = portControl;
+	eapol_sm_step(sm);
+}
+
+
+/**
+ * eapol_sm_notify_ctrl_attached - Notification of attached monitor
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * Notify EAPOL state machines that a monitor was attached to the control
+ * interface to trigger re-sending of pending requests for user input.
+ */
+void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm)
+{
+	if (sm == NULL)
+		return;
+	eap_sm_notify_ctrl_attached(sm->eap);
+}
+
+
+/**
+ * eapol_sm_notify_ctrl_response - Notification of received user input
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * Notify EAPOL state machines that a control response, i.e., user
+ * input, was received in order to trigger retrying of a pending EAP request.
+ */
+void eapol_sm_notify_ctrl_response(struct eapol_sm *sm)
+{
+	if (sm == NULL)
+		return;
+	if (sm->eapReqData && !sm->eapReq) {
+		wpa_printf(MSG_DEBUG, "EAPOL: received control response (user "
+			   "input) notification - retrying pending EAP "
+			   "Request");
+		sm->eapolEap = TRUE;
+		sm->eapReq = TRUE;
+		eapol_sm_step(sm);
+	}
+}
+
+
+/**
+ * eapol_sm_request_reauth - Request reauthentication
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * This function can be used to request EAPOL reauthentication, e.g., when the
+ * current PMKSA entry is nearing expiration.
+ */
+void eapol_sm_request_reauth(struct eapol_sm *sm)
+{
+	if (sm == NULL || sm->SUPP_PAE_state != SUPP_PAE_AUTHENTICATED)
+		return;
+	eapol_sm_txStart(sm);
+}
+
+
+/**
+ * eapol_sm_notify_lower_layer_success - Notification of lower layer success
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * Notify EAPOL (and EAP) state machines that a lower layer has detected a
+ * successful authentication. This is used to recover from dropped EAP-Success
+ * messages.
+ */
+void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm)
+{
+	if (sm == NULL)
+		return;
+	eap_notify_lower_layer_success(sm->eap);
+}
+
+
+/**
+ * eapol_sm_invalidate_cached_session - Mark cached EAP session data invalid
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ */
+void eapol_sm_invalidate_cached_session(struct eapol_sm *sm)
+{
+	if (sm)
+		eap_invalidate_cached_session(sm->eap);
+}
+
+
+static struct wpa_ssid * eapol_sm_get_config(void *ctx)
+{
+	struct eapol_sm *sm = ctx;
+	return sm ? sm->config : NULL;
+}
+
+
+static u8 * eapol_sm_get_eapReqData(void *ctx, size_t *len)
+{
+	struct eapol_sm *sm = ctx;
+	if (sm == NULL || sm->eapReqData == NULL) {
+		*len = 0;
+		return NULL;
+	}
+
+	*len = sm->eapReqDataLen;
+	return sm->eapReqData;
+}
+
+
+static Boolean eapol_sm_get_bool(void *ctx, enum eapol_bool_var variable)
+{
+	struct eapol_sm *sm = ctx;
+	if (sm == NULL)
+		return FALSE;
+	switch (variable) {
+	case EAPOL_eapSuccess:
+		return sm->eapSuccess;
+	case EAPOL_eapRestart:
+		return sm->eapRestart;
+	case EAPOL_eapFail:
+		return sm->eapFail;
+	case EAPOL_eapResp:
+		return sm->eapResp;
+	case EAPOL_eapNoResp:
+		return sm->eapNoResp;
+	case EAPOL_eapReq:
+		return sm->eapReq;
+	case EAPOL_portEnabled:
+		return sm->portEnabled;
+	case EAPOL_altAccept:
+		return sm->altAccept;
+	case EAPOL_altReject:
+		return sm->altReject;
+	}
+	return FALSE;
+}
+
+
+static void eapol_sm_set_bool(void *ctx, enum eapol_bool_var variable,
+			      Boolean value)
+{
+	struct eapol_sm *sm = ctx;
+	if (sm == NULL)
+		return;
+	switch (variable) {
+	case EAPOL_eapSuccess:
+		sm->eapSuccess = value;
+		break;
+	case EAPOL_eapRestart:
+		sm->eapRestart = value;
+		break;
+	case EAPOL_eapFail:
+		sm->eapFail = value;
+		break;
+	case EAPOL_eapResp:
+		sm->eapResp = value;
+		break;
+	case EAPOL_eapNoResp:
+		sm->eapNoResp = value;
+		break;
+	case EAPOL_eapReq:
+		sm->eapReq = value;
+		break;
+	case EAPOL_portEnabled:
+		sm->portEnabled = value;
+		break;
+	case EAPOL_altAccept:
+		sm->altAccept = value;
+		break;
+	case EAPOL_altReject:
+		sm->altReject = value;
+		break;
+	}
+}
+
+
+static unsigned int eapol_sm_get_int(void *ctx, enum eapol_int_var variable)
+{
+	struct eapol_sm *sm = ctx;
+	if (sm == NULL)
+		return 0;
+	switch (variable) {
+	case EAPOL_idleWhile:
+		return sm->idleWhile;
+	}
+	return 0;
+}
+
+
+static void eapol_sm_set_int(void *ctx, enum eapol_int_var variable,
+			     unsigned int value)
+{
+	struct eapol_sm *sm = ctx;
+	if (sm == NULL)
+		return;
+	switch (variable) {
+	case EAPOL_idleWhile:
+		sm->idleWhile = value;
+		break;
+	}
+}
+
+
+static void eapol_sm_set_config_blob(void *ctx, struct wpa_config_blob *blob)
+{
+#ifndef CONFIG_NO_CONFIG_BLOBS
+	struct eapol_sm *sm = ctx;
+	if (sm && sm->ctx && sm->ctx->set_config_blob)
+		sm->ctx->set_config_blob(sm->ctx->ctx, blob);
+#endif /* CONFIG_NO_CONFIG_BLOBS */
+}
+
+
+static const struct wpa_config_blob *
+eapol_sm_get_config_blob(void *ctx, const char *name)
+{
+#ifndef CONFIG_NO_CONFIG_BLOBS
+	struct eapol_sm *sm = ctx;
+	if (sm && sm->ctx && sm->ctx->get_config_blob)
+		return sm->ctx->get_config_blob(sm->ctx->ctx, name);
+	else
+		return NULL;
+#else /* CONFIG_NO_CONFIG_BLOBS */
+	return NULL;
+#endif /* CONFIG_NO_CONFIG_BLOBS */
+}
+
+
+static void eapol_sm_notify_pending(void *ctx)
+{
+	struct eapol_sm *sm = ctx;
+	if (sm == NULL)
+		return;
+	if (sm->eapReqData && !sm->eapReq) {
+		wpa_printf(MSG_DEBUG, "EAPOL: received notification from EAP "
+			   "state machine - retrying pending EAP Request");
+		sm->eapolEap = TRUE;
+		sm->eapReq = TRUE;
+		eapol_sm_step(sm);
+	}
+}
+
+
+static struct eapol_callbacks eapol_cb =
+{
+	eapol_sm_get_config,
+	eapol_sm_get_bool,
+	eapol_sm_set_bool,
+	eapol_sm_get_int,
+	eapol_sm_set_int,
+	eapol_sm_get_eapReqData,
+	eapol_sm_set_config_blob,
+	eapol_sm_get_config_blob,
+	eapol_sm_notify_pending
+};
+
+
+/**
+ * eapol_sm_init - Initialize EAPOL state machine
+ * @ctx: Pointer to EAPOL context data; this needs to be an allocated buffer
+ * and EAPOL state machine will free it in eapol_sm_deinit()
+ * Returns: Pointer to the allocated EAPOL state machine or %NULL on failure
+ *
+ * Allocate and initialize an EAPOL state machine.
+ */
+struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
+{
+	struct eapol_sm *sm;
+	struct eap_config conf;
+	sm = os_zalloc(sizeof(*sm));
+	if (sm == NULL)
+		return NULL;
+	sm->ctx = ctx;
+
+	sm->portControl = Auto;
+
+	/* Supplicant PAE state machine */
+	sm->heldPeriod = 60;
+	sm->startPeriod = 30;
+	sm->maxStart = 3;
+
+	/* Supplicant Backend state machine */
+	sm->authPeriod = 30;
+
+	os_memset(&conf, 0, sizeof(conf));
+#ifdef EAP_TLS_OPENSSL
+	conf.opensc_engine_path = ctx->opensc_engine_path;
+	conf.pkcs11_engine_path = ctx->pkcs11_engine_path;
+	conf.pkcs11_module_path = ctx->pkcs11_module_path;
+#endif /* EAP_TLS_OPENSSL */
+
+	sm->eap = eap_peer_sm_init(sm, &eapol_cb, sm->ctx->msg_ctx, &conf);
+	if (sm->eap == NULL) {
+		os_free(sm);
+		return NULL;
+	}
+
+	/* Initialize EAPOL state machines */
+	sm->initialize = TRUE;
+	eapol_sm_step(sm);
+	sm->initialize = FALSE;
+	eapol_sm_step(sm);
+
+	eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
+
+	return sm;
+}
+
+
+/**
+ * eapol_sm_deinit - Deinitialize EAPOL state machine
+ * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
+ *
+ * Deinitialize and free EAPOL state machine.
+ */
+void eapol_sm_deinit(struct eapol_sm *sm)
+{
+	if (sm == NULL)
+		return;
+	eloop_cancel_timeout(eapol_sm_step_timeout, NULL, sm);
+	eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
+	eap_peer_sm_deinit(sm->eap);
+	os_free(sm->last_rx_key);
+	os_free(sm->eapReqData);
+	os_free(sm->ctx);
+	os_free(sm);
+}

Added: wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.h?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.h (added)
+++ wpasupplicant/branches/upstream/current/src/eapol_supp/eapol_supp_sm.h Sun Dec  9 08:34:57 2007
@@ -1,0 +1,324 @@
+/*
+ * EAPOL supplicant state machines
+ * Copyright (c) 2004-2005, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef EAPOL_SUPP_SM_H
+#define EAPOL_SUPP_SM_H
+
+#include "defs.h"
+
+typedef enum { Unauthorized, Authorized } PortStatus;
+typedef enum { Auto, ForceUnauthorized, ForceAuthorized } PortControl;
+
+/**
+ * struct eapol_config - Per network configuration for EAPOL state machines
+ */
+struct eapol_config {
+	/**
+	 * accept_802_1x_keys - Accept IEEE 802.1X (non-WPA) EAPOL-Key frames
+	 *
+	 * This variable should be set to 1 when using EAPOL state machines
+	 * with non-WPA security policy to generate dynamic WEP keys. When
+	 * using WPA, this should be set to 0 so that WPA state machine can
+	 * process the EAPOL-Key frames.
+	 */
+	int accept_802_1x_keys;
+
+#define EAPOL_REQUIRE_KEY_UNICAST BIT(0)
+#define EAPOL_REQUIRE_KEY_BROADCAST BIT(1)
+	/**
+	 * required_keys - Which EAPOL-Key packets are required
+	 *
+	 * This variable determines which EAPOL-Key packets are required before
+	 * marking connection authenticated. This is a bit field of
+	 * EAPOL_REQUIRE_KEY_UNICAST and EAPOL_REQUIRE_KEY_BROADCAST flags.
+	 */
+	int required_keys;
+
+	/**
+	 * fast_reauth - Whether fast EAP reauthentication is enabled
+	 */
+	int fast_reauth;
+
+	/**
+	 * workaround - Whether EAP workarounds are enabled
+	 */
+	unsigned int workaround;
+
+	/**
+	 * eap_disabled - Whether EAP is disabled
+	 */
+	int eap_disabled;
+};
+
+struct eapol_sm;
+struct wpa_config_blob;
+
+/**
+ * struct eapol_ctx - Global (for all networks) EAPOL state machine context
+ */
+struct eapol_ctx {
+	/**
+	 * ctx - Pointer to arbitrary upper level context
+	 */
+	void *ctx;
+
+	/**
+	 * preauth - IEEE 802.11i/RSN pre-authentication
+	 *
+	 * This EAPOL state machine is used for IEEE 802.11i/RSN
+	 * pre-authentication
+	 */
+	int preauth;
+
+	/**
+	 * cb - Function to be called when EAPOL negotiation has been completed
+	 * @eapol: Pointer to EAPOL state machine data
+	 * @success: Whether the authentication was completed successfully
+	 * @ctx: Pointer to context data (cb_ctx)
+	 *
+	 * This optional callback function will be called when the EAPOL
+	 * authentication has been completed. This allows the owner of the
+	 * EAPOL state machine to process the key and terminate the EAPOL state
+	 * machine. Currently, this is used only in RSN pre-authentication.
+	 */
+	void (*cb)(struct eapol_sm *eapol, int success, void *ctx);
+
+	/**
+	 * cb_ctx - Callback context for cb()
+	 */
+	void *cb_ctx;
+
+	/**
+	 * msg_ctx - Callback context for wpa_msg() calls
+	 */
+	void *msg_ctx;
+
+	/**
+	 * scard_ctx - Callback context for PC/SC scard_*() function calls
+	 *
+	 * This context can be updated with eapol_sm_register_scard_ctx().
+	 */
+	void *scard_ctx;
+
+	/**
+	 * eapol_send_ctx - Callback context for eapol_send() calls
+	 */
+	void *eapol_send_ctx;
+
+	/**
+	 * eapol_done_cb - Function to be called at successful completion
+	 * @ctx: Callback context (ctx)
+	 *
+	 * This function is called at the successful completion of EAPOL
+	 * authentication. If dynamic WEP keys are used, this is called only
+	 * after all the expected keys have been received.
+	 */
+	void (*eapol_done_cb)(void *ctx);
+
+	/**
+	 * eapol_send - Send EAPOL packets
+	 * @ctx: Callback context (eapol_send_ctx)
+	 * @type: EAPOL type (IEEE802_1X_TYPE_*)
+	 * @buf: Pointer to EAPOL payload
+	 * @len: Length of the EAPOL payload
+	 * Returns: 0 on success, -1 on failure
+	 */
+	int (*eapol_send)(void *ctx, int type, const u8 *buf, size_t len);
+
+	/**
+	 * set_wep_key - Configure WEP keys
+	 * @ctx: Callback context (ctx)
+	 * @unicast: Non-zero = unicast, 0 = multicast/broadcast key
+	 * @keyidx: Key index (0..3)
+	 * @key: WEP key
+	 * @keylen: Length of the WEP key
+	 * Returns: 0 on success, -1 on failure
+	 */
+	int (*set_wep_key)(void *ctx, int unicast, int keyidx,
+			   const u8 *key, size_t keylen);
+
+	/**
+	 * set_config_blob - Set or add a named configuration blob
+	 * @ctx: Callback context (ctx)
+	 * @blob: New value for the blob
+	 *
+	 * Adds a new configuration blob or replaces the current value of an
+	 * existing blob.
+	 */
+	void (*set_config_blob)(void *ctx, struct wpa_config_blob *blob);
+
+	/**
+	 * get_config_blob - Get a named configuration blob
+	 * @ctx: Callback context (ctx)
+	 * @name: Name of the blob
+	 * Returns: Pointer to blob data or %NULL if not found
+	 */
+	const struct wpa_config_blob * (*get_config_blob)(void *ctx,
+							  const char *name);
+
+	/**
+	 * aborted_cached - Notify that cached PMK attempt was aborted
+	 * @ctx: Callback context (ctx)
+	 */
+	void (*aborted_cached)(void *ctx);
+
+#ifdef EAP_TLS_OPENSSL
+	/**
+	 * opensc_engine_path - Path to the OpenSSL engine for opensc
+	 *
+	 * This is an OpenSSL specific configuration option for loading OpenSC
+	 * engine (engine_opensc.so); if %NULL, this engine is not loaded.
+	 */
+	const char *opensc_engine_path;
+
+	/**
+	 * pkcs11_engine_path - Path to the OpenSSL engine for PKCS#11
+	 *
+	 * This is an OpenSSL specific configuration option for loading PKCS#11
+	 * engine (engine_pkcs11.so); if %NULL, this engine is not loaded.
+	 */
+	const char *pkcs11_engine_path;
+
+	/**
+	 * pkcs11_module_path - Path to the OpenSSL OpenSC/PKCS#11 module
+	 *
+	 * This is an OpenSSL specific configuration option for configuring
+	 * path to OpenSC/PKCS#11 engine (opensc-pkcs11.so); if %NULL, this
+	 * module is not loaded.
+	 */
+	const char *pkcs11_module_path;
+#endif /* EAP_TLS_OPENSSL */
+};
+
+
+struct wpa_ssid;
+
+#ifdef IEEE8021X_EAPOL
+struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx);
+void eapol_sm_deinit(struct eapol_sm *sm);
+void eapol_sm_step(struct eapol_sm *sm);
+int eapol_sm_get_status(struct eapol_sm *sm, char *buf, size_t buflen,
+			int verbose);
+int eapol_sm_get_mib(struct eapol_sm *sm, char *buf, size_t buflen);
+void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod, int authPeriod,
+			int startPeriod, int maxStart);
+int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src, const u8 *buf,
+		      size_t len);
+void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm);
+void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled);
+void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid);
+void eapol_sm_notify_eap_success(struct eapol_sm *sm, Boolean success);
+void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail);
+void eapol_sm_notify_config(struct eapol_sm *sm, struct wpa_ssid *config,
+			    const struct eapol_config *conf);
+int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len);
+void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff);
+void eapol_sm_notify_cached(struct eapol_sm *sm);
+void eapol_sm_notify_pmkid_attempt(struct eapol_sm *sm, int attempt);
+void eapol_sm_register_scard_ctx(struct eapol_sm *sm, void *ctx);
+void eapol_sm_notify_portControl(struct eapol_sm *sm, PortControl portControl);
+void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm);
+void eapol_sm_notify_ctrl_response(struct eapol_sm *sm);
+void eapol_sm_request_reauth(struct eapol_sm *sm);
+void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm);
+void eapol_sm_invalidate_cached_session(struct eapol_sm *sm);
+#else /* IEEE8021X_EAPOL */
+static inline struct eapol_sm *eapol_sm_init(struct eapol_ctx *ctx)
+{
+	free(ctx);
+	return (struct eapol_sm *) 1;
+}
+static inline void eapol_sm_deinit(struct eapol_sm *sm)
+{
+}
+static inline void eapol_sm_step(struct eapol_sm *sm)
+{
+}
+static inline int eapol_sm_get_status(struct eapol_sm *sm, char *buf,
+				      size_t buflen, int verbose)
+{
+	return 0;
+}
+static inline int eapol_sm_get_mib(struct eapol_sm *sm, char *buf,
+				   size_t buflen)
+{
+	return 0;
+}
+static inline void eapol_sm_configure(struct eapol_sm *sm, int heldPeriod,
+				      int authPeriod, int startPeriod,
+				      int maxStart)
+{
+}
+static inline int eapol_sm_rx_eapol(struct eapol_sm *sm, const u8 *src,
+				    const u8 *buf, size_t len)
+{
+	return 0;
+}
+static inline void eapol_sm_notify_tx_eapol_key(struct eapol_sm *sm)
+{
+}
+static inline void eapol_sm_notify_portEnabled(struct eapol_sm *sm,
+					       Boolean enabled)
+{
+}
+static inline void eapol_sm_notify_portValid(struct eapol_sm *sm,
+					     Boolean valid)
+{
+}
+static inline void eapol_sm_notify_eap_success(struct eapol_sm *sm,
+					       Boolean success)
+{
+}
+static inline void eapol_sm_notify_eap_fail(struct eapol_sm *sm, Boolean fail)
+{
+}
+static inline void eapol_sm_notify_config(struct eapol_sm *sm,
+					  struct wpa_ssid *config,
+					  struct eapol_config *conf)
+{
+}
+static inline int eapol_sm_get_key(struct eapol_sm *sm, u8 *key, size_t len)
+{
+	return -1;
+}
+static inline void eapol_sm_notify_logoff(struct eapol_sm *sm, Boolean logoff)
+{
+}
+static inline void eapol_sm_notify_cached(struct eapol_sm *sm)
+{
+}
+#define eapol_sm_notify_pmkid_attempt(sm, attempt) do { } while (0)
+#define eapol_sm_register_scard_ctx(sm, ctx) do { } while (0)
+static inline void eapol_sm_notify_portControl(struct eapol_sm *sm,
+					       PortControl portControl)
+{
+}
+static inline void eapol_sm_notify_ctrl_attached(struct eapol_sm *sm)
+{
+}
+static inline void eapol_sm_notify_ctrl_response(struct eapol_sm *sm)
+{
+}
+static inline void eapol_sm_request_reauth(struct eapol_sm *sm)
+{
+}
+static inline void eapol_sm_notify_lower_layer_success(struct eapol_sm *sm)
+{
+}
+static inline void eapol_sm_invalidate_cached_session(struct eapol_sm *sm)
+{
+}
+#endif /* IEEE8021X_EAPOL */
+
+#endif /* EAPOL_SUPP_SM_H */

Modified: wpasupplicant/branches/upstream/current/src/radius/radius_client.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/radius/radius_client.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/radius/radius_client.c (original)
+++ wpasupplicant/branches/upstream/current/src/radius/radius_client.c Sun Dec  9 08:34:57 2007
@@ -1170,8 +1170,8 @@
 		if (hostapd_ip_diff(&nserv[i].addr, &oserv[i].addr) ||
 		    nserv[i].port != oserv[i].port ||
 		    nserv[i].shared_secret_len != oserv[i].shared_secret_len ||
-		    memcmp(nserv[i].shared_secret, oserv[i].shared_secret,
-			   nserv[i].shared_secret_len) != 0)
+		    os_memcmp(nserv[i].shared_secret, oserv[i].shared_secret,
+			      nserv[i].shared_secret_len) != 0)
 			return 1;
 	}
 

Modified: wpasupplicant/branches/upstream/current/src/radius/radius_server.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/radius/radius_server.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/radius/radius_server.c (original)
+++ wpasupplicant/branches/upstream/current/src/radius/radius_server.c Sun Dec  9 08:34:57 2007
@@ -50,10 +50,7 @@
 	struct radius_server_data *server;
 	unsigned int sess_id;
 	struct eap_sm *eap;
-	u8 *eapKeyData, *eapReqData;
-	size_t eapKeyDataLen, eapReqDataLen;
-	Boolean eapSuccess, eapRestart, eapFail, eapResp, eapReq, eapNoReq;
-	Boolean portEnabled, eapTimeout;
+	struct eap_eapol_interface *eap_if;
 
 	struct radius_msg *last_msg;
 	char *last_from_addr;
@@ -172,19 +169,17 @@
 				       struct radius_session *sess)
 {
 	eloop_cancel_timeout(radius_server_session_timeout, data, sess);
-	free(sess->eapKeyData);
-	free(sess->eapReqData);
 	eap_server_sm_deinit(sess->eap);
 	if (sess->last_msg) {
 		radius_msg_free(sess->last_msg);
-		free(sess->last_msg);
-	}
-	free(sess->last_from_addr);
+		os_free(sess->last_msg);
+	}
+	os_free(sess->last_from_addr);
 	if (sess->last_reply) {
 		radius_msg_free(sess->last_reply);
-		free(sess->last_reply);
-	}
-	free(sess);
+		os_free(sess->last_reply);
+	}
+	os_free(sess);
 	data->num_sess--;
 }
 
@@ -279,21 +274,21 @@
 
 	RADIUS_DEBUG("Creating a new session");
 
-	user = malloc(256);
+	user = os_malloc(256);
 	if (user == NULL) {
 		return NULL;
 	}
 	res = radius_msg_get_attr(msg, RADIUS_ATTR_USER_NAME, user, 256);
 	if (res < 0 || res > 256) {
 		RADIUS_DEBUG("Could not get User-Name");
-		free(user);
+		os_free(user);
 		return NULL;
 	}
 	user_len = res;
 	RADIUS_DUMP_ASCII("User-Name", user, user_len);
 
 	res = data->get_eap_user(data->conf_ctx, user, user_len, 0, NULL);
-	free(user);
+	os_free(user);
 
 	if (res == 0) {
 		RADIUS_DEBUG("Matching user entry found");
@@ -307,10 +302,11 @@
 		return NULL;
 	}
 
-	memset(&eap_conf, 0, sizeof(eap_conf));
+	os_memset(&eap_conf, 0, sizeof(eap_conf));
 	eap_conf.ssl_ctx = data->ssl_ctx;
 	eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
 	eap_conf.backend_auth = TRUE;
+	eap_conf.eap_server = 1;
 	eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
 	eap_conf.eap_fast_a_id = data->eap_fast_a_id;
 	sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
@@ -321,8 +317,9 @@
 		radius_server_session_free(data, sess);
 		return NULL;
 	}
-	sess->eapRestart = TRUE;
-	sess->portEnabled = TRUE;
+	sess->eap_if = eap_get_interface(sess->eap);
+	sess->eap_if->eapRestart = TRUE;
+	sess->eap_if->portEnabled = TRUE;
 
 	RADIUS_DEBUG("New session 0x%x initialized", sess->sess_id);
 
@@ -340,11 +337,14 @@
 	int code;
 	unsigned int sess_id;
 
-	if (sess->eapFail) {
+	if (sess->eap_if->eapFail) {
+		sess->eap_if->eapFail = FALSE;
 		code = RADIUS_CODE_ACCESS_REJECT;
-	} else if (sess->eapSuccess) {
+	} else if (sess->eap_if->eapSuccess) {
+		sess->eap_if->eapSuccess = FALSE;
 		code = RADIUS_CODE_ACCESS_ACCEPT;
 	} else {
+		sess->eap_if->eapReq = FALSE;
 		code = RADIUS_CODE_ACCESS_CHALLENGE;
 	}
 
@@ -361,23 +361,25 @@
 		RADIUS_DEBUG("Failed to add State attribute");
 	}
 
-	if (sess->eapReqData &&
-	    !radius_msg_add_eap(msg, sess->eapReqData, sess->eapReqDataLen)) {
+	if (sess->eap_if->eapReqData &&
+	    !radius_msg_add_eap(msg, sess->eap_if->eapReqData,
+				sess->eap_if->eapReqDataLen)) {
 		RADIUS_DEBUG("Failed to add EAP-Message attribute");
 	}
 
-	if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eapKeyData) {
+	if (code == RADIUS_CODE_ACCESS_ACCEPT && sess->eap_if->eapKeyData) {
 		int len;
-		if (sess->eapKeyDataLen > 64) {
+		if (sess->eap_if->eapKeyDataLen > 64) {
 			len = 32;
 		} else {
-			len = sess->eapKeyDataLen / 2;
+			len = sess->eap_if->eapKeyDataLen / 2;
 		}
 		if (!radius_msg_add_mppe_keys(msg, request->hdr->authenticator,
 					      (u8 *) client->shared_secret,
 					      client->shared_secret_len,
-					      sess->eapKeyData + len, len,
-					      sess->eapKeyData, len)) {
+					      sess->eap_if->eapKeyData + len,
+					      len, sess->eap_if->eapKeyData,
+					      len)) {
 			RADIUS_DEBUG("Failed to add MPPE key attributes");
 		}
 	}
@@ -411,7 +413,7 @@
 		return -1;
 	}
 
-	memset(&eapfail, 0, sizeof(eapfail));
+	os_memset(&eapfail, 0, sizeof(eapfail));
 	eapfail.code = EAP_CODE_FAILURE;
 	eapfail.identifier = 0;
 	eapfail.length = host_to_be16(sizeof(eapfail));
@@ -440,7 +442,7 @@
 	}
 
 	radius_msg_free(msg);
-	free(msg);
+	os_free(msg);
 
 	return ret;
 }
@@ -540,36 +542,32 @@
 	 * If code is not 1-4, discard the packet silently.
 	 * Or is this already done by the EAP state machine? */
 
-	eap_set_eapRespData(sess->eap, eap, eap_len);
-	free(eap);
+	os_free(sess->eap_if->eapRespData);
+	sess->eap_if->eapRespData = eap;
+	sess->eap_if->eapRespDataLen = eap_len;
 	eap = NULL;
-	sess->eapResp = TRUE;
+	sess->eap_if->eapResp = TRUE;
 	eap_server_sm_step(sess->eap);
 
-	if (sess->eapReqData) {
+	if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
+	     sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
 		RADIUS_DUMP("EAP data from the state machine",
-			    sess->eapReqData, sess->eapReqDataLen);
-	} else if (sess->eapFail) {
+			    sess->eap_if->eapReqData,
+			    sess->eap_if->eapReqDataLen);
+	} else if (sess->eap_if->eapFail) {
 		RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
-			     "set - generate EAP-Failure");
-		hdr = os_zalloc(sizeof(*hdr));
-		if (hdr) {
-			hdr->identifier = resp_id;
-			hdr->length = host_to_be16(sizeof(*hdr));
-			sess->eapReqData = (u8 *) hdr;
-			sess->eapReqDataLen = sizeof(*hdr);
-		}
+			     "set");
 	} else if (eap_sm_method_pending(sess->eap)) {
 		if (sess->last_msg) {
 			radius_msg_free(sess->last_msg);
-			free(sess->last_msg);
+			os_free(sess->last_msg);
 		}
 		sess->last_msg = msg;
 		sess->last_from_port = from_port;
-		free(sess->last_from_addr);
-		sess->last_from_addr = strdup(from_addr);
+		os_free(sess->last_from_addr);
+		sess->last_from_addr = os_strdup(from_addr);
 		sess->last_fromlen = fromlen;
-		memcpy(&sess->last_from, from, fromlen);
+		os_memcpy(&sess->last_from, from, fromlen);
 		return -2;
 	} else {
 		RADIUS_DEBUG("No EAP data from the state machine - ignore this"
@@ -581,10 +579,6 @@
 	}
 
 	reply = radius_server_encapsulate_eap(data, client, sess, msg);
-
-	free(sess->eapReqData);
-	sess->eapReqData = NULL;
-	sess->eapReqDataLen = 0;
 
 	if (reply) {
 		RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
@@ -613,7 +607,7 @@
 		}
 		if (sess->last_reply) {
 			radius_msg_free(sess->last_reply);
-			free(sess->last_reply);
+			os_free(sess->last_reply);
 		}
 		sess->last_reply = reply;
 		sess->last_from_port = from_port;
@@ -625,7 +619,7 @@
 		client->counters.packets_dropped++;
 	}
 
-	if (sess->eapSuccess || sess->eapFail) {
+	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail) {
 		RADIUS_DEBUG("Removing completed session 0x%x after timeout",
 			     sess->sess_id);
 		eloop_cancel_timeout(radius_server_session_remove_timeout,
@@ -652,7 +646,7 @@
 	char abuf[50];
 	int from_port = 0;
 
-	buf = malloc(RADIUS_MAX_MSG_LEN);
+	buf = os_malloc(RADIUS_MAX_MSG_LEN);
 	if (buf == NULL) {
 		goto fail;
 	}
@@ -707,7 +701,7 @@
 		goto fail;
 	}
 
-	free(buf);
+	os_free(buf);
 	buf = NULL;
 
 	if (wpa_debug_level <= MSG_MSGDUMP) {
@@ -740,9 +734,9 @@
 fail:
 	if (msg) {
 		radius_msg_free(msg);
-		free(msg);
-	}
-	free(buf);
+		os_free(msg);
+	}
+	os_free(buf);
 }
 
 
@@ -757,7 +751,7 @@
 		return -1;
 	}
 
-	memset(&addr, 0, sizeof(addr));
+	os_memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(port);
 	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
@@ -782,9 +776,9 @@
 		return -1;
 	}
 
-	memset(&addr, 0, sizeof(addr));
+	os_memset(&addr, 0, sizeof(addr));
 	addr.sin6_family = AF_INET6;
-	memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
+	os_memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
 	addr.sin6_port = htons(port);
 	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 		perror("bind");
@@ -822,8 +816,8 @@
 		client = client->next;
 
 		radius_server_free_sessions(data, prev->sessions);
-		free(prev->shared_secret);
-		free(prev);
+		os_free(prev->shared_secret);
+		os_free(prev);
 	}
 }
 
@@ -848,7 +842,7 @@
 		return NULL;
 	}
 
-	buf = malloc(buf_size);
+	buf = os_malloc(buf_size);
 	if (buf == NULL) {
 		fclose(f);
 		return NULL;
@@ -911,10 +905,11 @@
 			/* Convert IPv4 address to IPv6 */
 			if (mask <= 32)
 				mask += (128 - 32);
-			memset(addr6.s6_addr, 0, 10);
+			os_memset(addr6.s6_addr, 0, 10);
 			addr6.s6_addr[10] = 0xff;
 			addr6.s6_addr[11] = 0xff;
-			memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr, 4);
+			os_memcpy(addr6.s6_addr + 12, (char *) &addr.s_addr,
+				  4);
 		}
 #endif /* CONFIG_IPV6 */
 
@@ -932,13 +927,13 @@
 			failed = 1;
 			break;
 		}
-		entry->shared_secret = strdup(pos);
+		entry->shared_secret = os_strdup(pos);
 		if (entry->shared_secret == NULL) {
 			failed = 1;
-			free(entry);
+			os_free(entry);
 			break;
 		}
-		entry->shared_secret_len = strlen(entry->shared_secret);
+		entry->shared_secret_len = os_strlen(entry->shared_secret);
 		entry->addr.s_addr = addr.s_addr;
 		if (!ipv6) {
 			val = 0;
@@ -950,8 +945,8 @@
 		if (ipv6) {
 			int offset = mask / 8;
 
-			memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
-			memset(entry->mask6.s6_addr, 0xff, offset);
+			os_memcpy(entry->addr6.s6_addr, addr6.s6_addr, 16);
+			os_memset(entry->mask6.s6_addr, 0xff, offset);
 			val = 0;
 			for (i = 0; i < (mask % 8); i++)
 				val |= 1 << (7 - i);
@@ -974,7 +969,7 @@
 		clients = NULL;
 	}
 
-	free(buf);
+	os_free(buf);
 	fclose(f);
 
 	return clients;
@@ -1055,7 +1050,7 @@
 
 	radius_server_free_clients(data, data->clients);
 
-	free(data);
+	os_free(data);
 }
 
 
@@ -1079,40 +1074,40 @@
 	os_get_time(&now);
 	uptime = (now.sec - data->start_time.sec) * 100 +
 		((now.usec - data->start_time.usec) / 10000) % 100;
-	ret = snprintf(pos, end - pos,
-		       "RADIUS-AUTH-SERVER-MIB\n"
-		       "radiusAuthServIdent=hostapd\n"
-		       "radiusAuthServUpTime=%d\n"
-		       "radiusAuthServResetTime=0\n"
-		       "radiusAuthServConfigReset=4\n",
-		       uptime);
+	ret = os_snprintf(pos, end - pos,
+			  "RADIUS-AUTH-SERVER-MIB\n"
+			  "radiusAuthServIdent=hostapd\n"
+			  "radiusAuthServUpTime=%d\n"
+			  "radiusAuthServResetTime=0\n"
+			  "radiusAuthServConfigReset=4\n",
+			  uptime);
 	if (ret < 0 || ret >= end - pos) {
 		*pos = '\0';
 		return pos - buf;
 	}
 	pos += ret;
 
-	ret = snprintf(pos, end - pos,
-		       "radiusAuthServTotalAccessRequests=%u\n"
-		       "radiusAuthServTotalInvalidRequests=%u\n"
-		       "radiusAuthServTotalDupAccessRequests=%u\n"
-		       "radiusAuthServTotalAccessAccepts=%u\n"
-		       "radiusAuthServTotalAccessRejects=%u\n"
-		       "radiusAuthServTotalAccessChallenges=%u\n"
-		       "radiusAuthServTotalMalformedAccessRequests=%u\n"
-		       "radiusAuthServTotalBadAuthenticators=%u\n"
-		       "radiusAuthServTotalPacketsDropped=%u\n"
-		       "radiusAuthServTotalUnknownTypes=%u\n",
-		       data->counters.access_requests,
-		       data->counters.invalid_requests,
-		       data->counters.dup_access_requests,
-		       data->counters.access_accepts,
-		       data->counters.access_rejects,
-		       data->counters.access_challenges,
-		       data->counters.malformed_access_requests,
-		       data->counters.bad_authenticators,
-		       data->counters.packets_dropped,
-		       data->counters.unknown_types);
+	ret = os_snprintf(pos, end - pos,
+			  "radiusAuthServTotalAccessRequests=%u\n"
+			  "radiusAuthServTotalInvalidRequests=%u\n"
+			  "radiusAuthServTotalDupAccessRequests=%u\n"
+			  "radiusAuthServTotalAccessAccepts=%u\n"
+			  "radiusAuthServTotalAccessRejects=%u\n"
+			  "radiusAuthServTotalAccessChallenges=%u\n"
+			  "radiusAuthServTotalMalformedAccessRequests=%u\n"
+			  "radiusAuthServTotalBadAuthenticators=%u\n"
+			  "radiusAuthServTotalPacketsDropped=%u\n"
+			  "radiusAuthServTotalUnknownTypes=%u\n",
+			  data->counters.access_requests,
+			  data->counters.invalid_requests,
+			  data->counters.dup_access_requests,
+			  data->counters.access_accepts,
+			  data->counters.access_rejects,
+			  data->counters.access_challenges,
+			  data->counters.malformed_access_requests,
+			  data->counters.bad_authenticators,
+			  data->counters.packets_dropped,
+			  data->counters.unknown_types);
 	if (ret < 0 || ret >= end - pos) {
 		*pos = '\0';
 		return pos - buf;
@@ -1136,29 +1131,29 @@
 			os_strlcpy(mbuf, inet_ntoa(cli->mask), sizeof(mbuf));
 		}
 
-		ret = snprintf(pos, end - pos,
-			       "radiusAuthClientIndex=%u\n"
-			       "radiusAuthClientAddress=%s/%s\n"
-			       "radiusAuthServAccessRequests=%u\n"
-			       "radiusAuthServDupAccessRequests=%u\n"
-			       "radiusAuthServAccessAccepts=%u\n"
-			       "radiusAuthServAccessRejects=%u\n"
-			       "radiusAuthServAccessChallenges=%u\n"
-			       "radiusAuthServMalformedAccessRequests=%u\n"
-			       "radiusAuthServBadAuthenticators=%u\n"
-			       "radiusAuthServPacketsDropped=%u\n"
-			       "radiusAuthServUnknownTypes=%u\n",
-			       idx,
-			       abuf, mbuf,
-			       cli->counters.access_requests,
-			       cli->counters.dup_access_requests,
-			       cli->counters.access_accepts,
-			       cli->counters.access_rejects,
-			       cli->counters.access_challenges,
-			       cli->counters.malformed_access_requests,
-			       cli->counters.bad_authenticators,
-			       cli->counters.packets_dropped,
-			       cli->counters.unknown_types);
+		ret = os_snprintf(pos, end - pos,
+				  "radiusAuthClientIndex=%u\n"
+				  "radiusAuthClientAddress=%s/%s\n"
+				  "radiusAuthServAccessRequests=%u\n"
+				  "radiusAuthServDupAccessRequests=%u\n"
+				  "radiusAuthServAccessAccepts=%u\n"
+				  "radiusAuthServAccessRejects=%u\n"
+				  "radiusAuthServAccessChallenges=%u\n"
+				  "radiusAuthServMalformedAccessRequests=%u\n"
+				  "radiusAuthServBadAuthenticators=%u\n"
+				  "radiusAuthServPacketsDropped=%u\n"
+				  "radiusAuthServUnknownTypes=%u\n",
+				  idx,
+				  abuf, mbuf,
+				  cli->counters.access_requests,
+				  cli->counters.dup_access_requests,
+				  cli->counters.access_accepts,
+				  cli->counters.access_rejects,
+				  cli->counters.access_challenges,
+				  cli->counters.malformed_access_requests,
+				  cli->counters.bad_authenticators,
+				  cli->counters.packets_dropped,
+				  cli->counters.unknown_types);
 		if (ret < 0 || ret >= end - pos) {
 			*pos = '\0';
 			return pos - buf;
@@ -1170,110 +1165,6 @@
 }
 
 
-static Boolean radius_server_get_bool(void *ctx, enum eapol_bool_var variable)
-{
-	struct radius_session *sess = ctx;
-	if (sess == NULL)
-		return FALSE;
-	switch (variable) {
-	case EAPOL_eapSuccess:
-		return sess->eapSuccess;
-	case EAPOL_eapRestart:
-		return sess->eapRestart;
-	case EAPOL_eapFail:
-		return sess->eapFail;
-	case EAPOL_eapResp:
-		return sess->eapResp;
-	case EAPOL_eapReq:
-		return sess->eapReq;
-	case EAPOL_eapNoReq:
-		return sess->eapNoReq;
-	case EAPOL_portEnabled:
-		return sess->portEnabled;
-	case EAPOL_eapTimeout:
-		return sess->eapTimeout;
-	}
-	return FALSE;
-}
-
-
-static void radius_server_set_bool(void *ctx, enum eapol_bool_var variable,
-			      Boolean value)
-{
-	struct radius_session *sess = ctx;
-	if (sess == NULL)
-		return;
-	switch (variable) {
-	case EAPOL_eapSuccess:
-		sess->eapSuccess = value;
-		break;
-	case EAPOL_eapRestart:
-		sess->eapRestart = value;
-		break;
-	case EAPOL_eapFail:
-		sess->eapFail = value;
-		break;
-	case EAPOL_eapResp:
-		sess->eapResp = value;
-		break;
-	case EAPOL_eapReq:
-		sess->eapReq = value;
-		break;
-	case EAPOL_eapNoReq:
-		sess->eapNoReq = value;
-		break;
-	case EAPOL_portEnabled:
-		sess->portEnabled = value;
-		break;
-	case EAPOL_eapTimeout:
-		sess->eapTimeout = value;
-		break;
-	}
-}
-
-
-static void radius_server_set_eapReqData(void *ctx, const u8 *eapReqData,
-				    size_t eapReqDataLen)
-{
-	struct radius_session *sess = ctx;
-	if (sess == NULL)
-		return;
-
-	free(sess->eapReqData);
-	sess->eapReqData = malloc(eapReqDataLen);
-	if (sess->eapReqData) {
-		memcpy(sess->eapReqData, eapReqData, eapReqDataLen);
-		sess->eapReqDataLen = eapReqDataLen;
-	} else {
-		sess->eapReqDataLen = 0;
-	}
-}
-
-
-static void radius_server_set_eapKeyData(void *ctx, const u8 *eapKeyData,
-				    size_t eapKeyDataLen)
-{
-	struct radius_session *sess = ctx;
-
-	if (sess == NULL)
-		return;
-
-	free(sess->eapKeyData);
-	if (eapKeyData) {
-		sess->eapKeyData = malloc(eapKeyDataLen);
-		if (sess->eapKeyData) {
-			memcpy(sess->eapKeyData, eapKeyData, eapKeyDataLen);
-			sess->eapKeyDataLen = eapKeyDataLen;
-		} else {
-			sess->eapKeyDataLen = 0;
-		}
-	} else {
-		sess->eapKeyData = NULL;
-		sess->eapKeyDataLen = 0;
-	}
-}
-
-
 static int radius_server_get_eap_user(void *ctx, const u8 *identity,
 				      size_t identity_len, int phase2,
 				      struct eap_user *user)
@@ -1288,10 +1179,6 @@
 
 static struct eapol_callbacks radius_server_eapol_cb =
 {
-	.get_bool = radius_server_get_bool,
-	.set_bool = radius_server_set_bool,
-	.set_eapReqData = radius_server_set_eapReqData,
-	.set_eapKeyData = radius_server_set_eapKeyData,
 	.get_eap_user = radius_server_get_eap_user,
 };
 
@@ -1334,5 +1221,5 @@
 		return; /* msg was stored with the session */
 
 	radius_msg_free(msg);
-	free(msg);
-}
+	os_free(msg);
+}

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/peerkey.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/peerkey.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/peerkey.c (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/peerkey.c Sun Dec  9 08:34:57 2007
@@ -251,7 +251,7 @@
 	peerkey->rsnie_i_len = kde.rsn_ie_len;
 	peerkey->cipher = cipher;
 
-	if (hostapd_get_rand(peerkey->pnonce, WPA_NONCE_LEN)) {
+	if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {
 		wpa_msg(sm->ctx->ctx, MSG_WARNING,
 			"WPA: Failed to get random data for PNonce");
 		wpa_supplicant_peerkey_free(sm, peerkey);
@@ -360,7 +360,7 @@
 	wpa_add_kde((u8 *) (msg + 1), RSN_KEY_DATA_PMKID,
 		    peerkey->smkid, PMKID_LEN);
 
-	if (hostapd_get_rand(peerkey->inonce, WPA_NONCE_LEN)) {
+	if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) {
 		wpa_msg(sm->ctx->ctx, MSG_WARNING,
 			"RSN: Failed to get random data for INonce (STK)");
 		os_free(mbuf);
@@ -686,7 +686,7 @@
 		return;
 	}
 
-	if (hostapd_get_rand(peerkey->pnonce, WPA_NONCE_LEN)) {
+	if (os_get_random(peerkey->pnonce, WPA_NONCE_LEN)) {
 		wpa_msg(sm->ctx->ctx, MSG_WARNING,
 			"RSN: Failed to get random data for PNonce");
 		return;
@@ -1083,7 +1083,7 @@
 		  WPA_REPLAY_COUNTER_LEN);
 	inc_byte_array(sm->request_counter, WPA_REPLAY_COUNTER_LEN);
 
-	if (hostapd_get_rand(peerkey->inonce, WPA_NONCE_LEN)) {
+	if (os_get_random(peerkey->inonce, WPA_NONCE_LEN)) {
 		wpa_msg(sm->ctx->ctx, MSG_WARNING,
 			"WPA: Failed to get random data for INonce");
 		os_free(rbuf);

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/pmksa_cache.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/pmksa_cache.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/pmksa_cache.c (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/pmksa_cache.c Sun Dec  9 08:34:57 2007
@@ -20,7 +20,7 @@
 #include "config_ssid.h"
 #include "sha1.h"
 #include "wpa_i.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "pmksa_cache.h"
 
 #if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.c (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.c Sun Dec  9 08:34:57 2007
@@ -20,11 +20,13 @@
 #include "eloop.h"
 #include "config_ssid.h"
 #include "l2_packet/l2_packet.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "preauth.h"
 #include "pmksa_cache.h"
 #include "wpa_i.h"
 
+
+#if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)
 
 #define PMKID_CANDIDATE_PRIO_SCAN 1000
 
@@ -56,8 +58,6 @@
 	}
 }
 
-
-#if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)
 
 static void rsn_preauth_receive(void *ctx, const u8 *src_addr,
 				const u8 *buf, size_t len)

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.h (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/preauth.h Sun Dec  9 08:34:57 2007
@@ -17,21 +17,9 @@
 
 struct wpa_scan_result;
 
-#ifndef CONFIG_NO_WPA
+#if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)
 
 void pmksa_candidate_free(struct wpa_sm *sm);
-
-#else /* CONFIG_NO_WPA */
-
-static inline void pmksa_candidate_free(struct wpa_sm *sm)
-{
-}
-
-#endif /* CONFIG_NO_WPA */
-
-
-#if defined(IEEE8021X_EAPOL) && !defined(CONFIG_NO_WPA2)
-
 int rsn_preauth_init(struct wpa_sm *sm, const u8 *dst,
 		     struct wpa_ssid *config);
 void rsn_preauth_deinit(struct wpa_sm *sm);
@@ -45,6 +33,10 @@
 int rsn_preauth_in_progress(struct wpa_sm *sm);
 
 #else /* IEEE8021X_EAPOL and !CONFIG_NO_WPA2 */
+
+static inline void pmksa_candidate_free(struct wpa_sm *sm)
+{
+}
 
 static inline void rsn_preauth_candidate_process(struct wpa_sm *sm)
 {

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.c (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.c Sun Dec  9 08:34:57 2007
@@ -20,7 +20,7 @@
 #include "wpa.h"
 #include "eloop.h"
 #include "config_ssid.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "preauth.h"
 #include "pmksa_cache.h"
 #include "wpa_i.h"
@@ -411,7 +411,7 @@
 		return;
 
 	if (sm->renew_snonce) {
-		if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) {
+		if (os_get_random(sm->snonce, WPA_NONCE_LEN)) {
 			wpa_msg(sm->ctx->ctx, MSG_WARNING,
 				"WPA: Failed to get random data for SNonce");
 			return;

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.h (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/wpa.h Sun Dec  9 08:34:57 2007
@@ -16,6 +16,7 @@
 #define WPA_H
 
 #include "defs.h"
+#include "eapol_common.h"
 #include "wpa_common.h"
 
 #ifndef ETH_P_EAPOL

Modified: wpasupplicant/branches/upstream/current/src/rsn_supp/wpa_ft.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/rsn_supp/wpa_ft.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/rsn_supp/wpa_ft.c (original)
+++ wpasupplicant/branches/upstream/current/src/rsn_supp/wpa_ft.c Sun Dec  9 08:34:57 2007
@@ -432,7 +432,7 @@
 	size_t ft_ies_len;
 
 	/* Generate a new SNonce */
-	if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) {
+	if (os_get_random(sm->snonce, WPA_NONCE_LEN)) {
 		wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce");
 		return -1;
 	}
@@ -779,7 +779,7 @@
 		   MAC2STR(target_ap));
 
 	/* Generate a new SNonce */
-	if (hostapd_get_rand(sm->snonce, WPA_NONCE_LEN)) {
+	if (os_get_random(sm->snonce, WPA_NONCE_LEN)) {
 		wpa_printf(MSG_INFO, "FT: Failed to generate a new SNonce");
 		return -1;
 	}

Modified: wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_read.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_read.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_read.c (original)
+++ wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_read.c Sun Dec  9 08:34:57 2007
@@ -571,6 +571,7 @@
 static int tls_process_client_key_exchange_dh_anon(
 	struct tlsv1_server *conn, const u8 *pos, const u8 *end)
 {
+#ifdef EAP_FAST
 	const u8 *dh_yc;
 	u16 dh_yc_len;
 	u8 *shared;
@@ -662,6 +663,9 @@
 	}
 
 	return 0;
+#else /* EAP_FAST */
+	return -1;
+#endif /* EAP_FAST */
 }
 
 

Modified: wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_write.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_write.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_write.c (original)
+++ wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_write.c Sun Dec  9 08:34:57 2007
@@ -247,10 +247,12 @@
 {
 	tls_key_exchange keyx;
 	const struct tls_cipher_suite *suite;
+#ifdef EAP_FAST
 	u8 *pos, *rhdr, *hs_start, *hs_length;
 	size_t rlen;
 	u8 *dh_ys;
 	size_t dh_ys_len;
+#endif /* EAP_FAST */
 
 	suite = tls_get_cipher_suite(conn->rl.cipher_suite);
 	if (suite == NULL)
@@ -270,6 +272,7 @@
 		return -1;
 	}
 
+#ifdef EAP_FAST
 	if (conn->cred == NULL || conn->cred->dh_p == NULL ||
 	    conn->cred->dh_g == NULL) {
 		wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available for "
@@ -425,6 +428,9 @@
 	*msgpos = pos;
 
 	return 0;
+#else /* EAP_FAST */
+	return -1;
+#endif /* EAP_FAST */
 }
 
 

Modified: wpasupplicant/branches/upstream/current/src/utils/build_config.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/build_config.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/build_config.h (original)
+++ wpasupplicant/branches/upstream/current/src/utils/build_config.h Sun Dec  9 08:34:57 2007
@@ -46,6 +46,20 @@
 #define EAP_LEAP
 #define EAP_TNC
 #define _CRT_SECURE_NO_DEPRECATE
+
+#ifdef USE_INTERNAL_CRYPTO
+#define CONFIG_TLS_INTERNAL
+#define CONFIG_TLS_INTERNAL_CLIENT
+#define CONFIG_INTERNAL_LIBTOMMATH
+#define INTERNAL_AES
+#define INTERNAL_SHA1
+#define INTERNAL_SHA256
+#define INTERNAL_MD5
+#define INTERNAL_MD4
+#define INTERNAL_DES
+#define CONFIG_INTERNAL_X509
+#define CONFIG_CRYPTO_INTERNAL
+#endif /* USE_INTERNAL_CRYPTO */
 #endif /* CONFIG_WIN32_DEFAULTS */
 
 #ifdef __SYMBIAN32__

Modified: wpasupplicant/branches/upstream/current/src/utils/common.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/common.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/common.h (original)
+++ wpasupplicant/branches/upstream/current/src/utils/common.h Sun Dec  9 08:34:57 2007
@@ -410,7 +410,6 @@
 typedef u64 __bitwise __le64;
 
 
-#define hostapd_get_rand os_get_random
 int hwaddr_aton(const char *txt, u8 *addr);
 int hexstr2bin(const char *hex, u8 *buf, size_t len);
 void inc_byte_array(u8 *counter, size_t len);

Modified: wpasupplicant/branches/upstream/current/src/utils/os.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/os.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/os.h (original)
+++ wpasupplicant/branches/upstream/current/src/utils/os.h Sun Dec  9 08:34:57 2007
@@ -63,6 +63,9 @@
  * @t: Buffer for returning calendar time representation (seconds since
  * 1970-01-01 00:00:00)
  * Returns: 0 on success, -1 on failure
+ *
+ * Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
+ * which is used by POSIX mktime().
  */
 int os_mktime(int year, int month, int day, int hour, int min, int sec,
 	      os_time_t *t);

Modified: wpasupplicant/branches/upstream/current/src/utils/os_unix.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/os_unix.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/os_unix.c (original)
+++ wpasupplicant/branches/upstream/current/src/utils/os_unix.c Sun Dec  9 08:34:57 2007
@@ -39,7 +39,9 @@
 int os_mktime(int year, int month, int day, int hour, int min, int sec,
 	      os_time_t *t)
 {
-	struct tm tm;
+	struct tm tm, *tm1;
+	time_t t_local, t1, t2;
+	os_time_t tz_offset;
 
 	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
 	    hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
@@ -54,7 +56,22 @@
 	tm.tm_min = min;
 	tm.tm_sec = sec;
 
-	*t = (os_time_t) mktime(&tm);
+	t_local = mktime(&tm);
+
+	/* figure out offset to UTC */
+	tm1 = localtime(&t_local);
+	if (tm1) {
+		t1 = mktime(tm1);
+		tm1 = gmtime(&t_local);
+		if (tm1) {
+			t2 = mktime(tm1);
+			tz_offset = t2 - t1;
+		} else
+			tz_offset = 0;
+	} else
+		tz_offset = 0;
+
+	*t = (os_time_t) t_local - tz_offset;
 	return 0;
 }
 

Modified: wpasupplicant/branches/upstream/current/src/utils/os_win32.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/os_win32.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/os_win32.c (original)
+++ wpasupplicant/branches/upstream/current/src/utils/os_win32.c Sun Dec  9 08:34:57 2007
@@ -55,7 +55,9 @@
 int os_mktime(int year, int month, int day, int hour, int min, int sec,
 	      os_time_t *t)
 {
-	struct tm tm;
+	struct tm tm, *tm1;
+	time_t t_local, t1, t2;
+	os_time_t tz_offset;
 
 	if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
 	    hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
@@ -70,7 +72,22 @@
 	tm.tm_min = min;
 	tm.tm_sec = sec;
 
-	*t = (os_time_t) mktime(&tm);
+	t_local = mktime(&tm);
+
+	/* figure out offset to UTC */
+	tm1 = localtime(&t_local);
+	if (tm1) {
+		t1 = mktime(tm1);
+		tm1 = gmtime(&t_local);
+		if (tm1) {
+			t2 = mktime(tm1);
+			tz_offset = t2 - t1;
+		} else
+			tz_offset = 0;
+	} else
+		tz_offset = 0;
+
+	*t = (os_time_t) t_local - tz_offset;
 	return 0;
 }
 

Modified: wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c (original)
+++ wpasupplicant/branches/upstream/current/src/utils/wpa_debug.c Sun Dec  9 08:34:57 2007
@@ -242,6 +242,10 @@
 		    count++);
 #endif /* _WIN32 */
 	out_file = fopen(fname, "w");
+#ifndef _WIN32
+	if (out_file)
+		setvbuf(out_file, NULL, _IOLBF, 0);
+#endif /* _WIN32 */
 	return out_file == NULL ? -1 : 0;
 #else /* CONFIG_DEBUG_FILE */
 	return 0;

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/ChangeLog Sun Dec  9 08:34:57 2007
@@ -1,13 +1,17 @@
 ChangeLog for wpa_supplicant
 
-????-??-?? - v0.6.1
+????-??-?? - v0.6.2
+	* added support for Makefile builds to include debug-log-to-a-file
+	  functionality (CONFIG_DEBUG_FILE=y and -f on command line)
+
+2007-11-24 - v0.6.1
 	* added support for configuring password as NtPasswordHash
 	  (16-byte MD4 hash of password) in hash:<32 hex digits> format
 	* added support for fallback from abbreviated TLS handshake to
 	  full handshake when using EAP-FAST (e.g., due to an expired
 	  PAC-Opaque)
 	* updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
-	  draft (draft-ietf-emu-eap-gpsk-06.txt)
+	  draft (draft-ietf-emu-eap-gpsk-07.txt)
 	* added support for drivers that take care of RSN 4-way handshake
 	  internally (WPA_DRIVER_FLAGS_4WAY_HANDSHAKE in get_capa flags and
 	  WPA_ALG_PMK in set_key)
@@ -24,6 +28,8 @@
 	* fixed a race condition with -W option (wait for a control interface
 	  monitor before starting) that could have caused the first messages to
 	  be lost
+	* added support for processing TNCC-TNCS-Messages to report
+	  recommendation (allow/none/isolate) when using TNC [Bug 243]
 
 2007-05-28 - v0.6.0
 	* added network configuration parameter 'frequency' for setting

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/Makefile Sun Dec  9 08:34:57 2007
@@ -90,7 +90,9 @@
 
 ifeq ($(CONFIG_BACKEND), file)
 OBJS += config_file.o
+ifndef CONFIG_NO_CONFIG_BLOBS
 NEED_BASE64=y
+endif
 CFLAGS += -DCONFIG_BACKEND_FILE
 endif
 
@@ -100,6 +102,18 @@
 
 ifeq ($(CONFIG_BACKEND), none)
 OBJS += config_none.o
+endif
+
+ifdef CONFIG_NO_CONFIG_WRITE
+CFLAGS += -DCONFIG_NO_CONFIG_WRITE
+endif
+
+ifdef CONFIG_NO_CONFIG_BLOBS
+CFLAGS += -DCONFIG_NO_CONFIG_BLOBS
+endif
+
+ifdef CONFIG_NO_SCAN_PROCESSING
+CFLAGS += -DCONFIG_NO_SCAN_PROCESSING
 endif
 
 ifdef CONFIG_DRIVER_HOSTAP
@@ -390,6 +404,7 @@
 OBJS += ../src/eap_common/eap_sim_common.o
 OBJS_h += ../src/eap_server/eap_sim_db.o
 NEED_AES=y
+NEED_FIPS186_2_PRF=y
 endif
 
 ifdef CONFIG_EAP_TLV
@@ -410,6 +425,7 @@
 OBJS_h += ../src/eap_server/eap_fast.o
 endif
 TLS_FUNCS=y
+NEED_T_PRF=y
 endif
 
 ifdef CONFIG_EAP_PAX
@@ -453,6 +469,19 @@
 CFLAGS += -DEAP_GPSK_SHA256
 endif
 NEED_SHA256=y
+endif
+
+ifdef CONFIG_EAP_WSC
+# EAP-WSC
+ifeq ($(CONFIG_EAP_WSC), dyn)
+CFLAGS += -DEAP_WSC_DYNAMIC
+EAPDYN += ../src/eap_peer/eap_wsc.so
+else
+CFLAGS += -DEAP_WSC
+OBJS += ../src/eap_peer/eap_wsc.o ../src/eap_common/eap_wsc_common.o
+OBJS_h += ../src/eap_server/eap_wsc.o
+endif
+CONFIG_IEEE8021X_EAPOL=y
 endif
 
 ifdef CONFIG_EAP_VENDOR_TEST
@@ -478,7 +507,7 @@
 ifdef CONFIG_IEEE8021X_EAPOL
 # IEEE 802.1X/EAPOL state machines (e.g., for RADIUS authentication)
 CFLAGS += -DIEEE8021X_EAPOL
-OBJS += eapol_sm.o ../src/eap_peer/eap.o ../src/eap_common/eap_common.o ../src/eap_peer/eap_methods.o
+OBJS += ../src/eapol_supp/eapol_supp_sm.o ../src/eap_peer/eap.o ../src/eap_common/eap_common.o ../src/eap_peer/eap_methods.o
 ifdef CONFIG_DYNAMIC_EAP_METHODS
 CFLAGS += -DCONFIG_DYNAMIC_EAP_METHODS
 LIBS += -ldl -rdynamic
@@ -550,6 +579,7 @@
 CFLAGS += -DEAP_TLS_FUNCS
 OBJS += ../src/eap_peer/eap_tls_common.o
 OBJS_h += ../src/eap_server/eap_tls_common.o
+NEED_TLS_PRF=y
 ifeq ($(CONFIG_TLS), openssl)
 CFLAGS += -DEAP_TLS_OPENSSL
 OBJS += ../src/crypto/tls_openssl.o
@@ -577,6 +607,7 @@
 OBJS_p += ../src/tls/asn1.o
 OBJS_p += ../src/crypto/rc4.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o
 NEED_BASE64=y
+NEED_TLS_PRF=y
 CFLAGS += -DCONFIG_TLS_INTERNAL
 CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
 ifeq ($(CONFIG_CRYPTO), internal)
@@ -828,14 +859,32 @@
 CFLAGS += -DCONFIG_NO_WPA2
 endif
 
+ifdef CONFIG_NO_WPA_PASSPHRASE
+CFLAGS += -DCONFIG_NO_PBKDF2
+endif
+
 ifdef CONFIG_NO_AES_EXTRAS
 CFLAGS += -DCONFIG_NO_AES_WRAP
 CFLAGS += -DCONFIG_NO_AES_CTR -DCONFIG_NO_AES_OMAC1
 CFLAGS += -DCONFIG_NO_AES_EAX -DCONFIG_NO_AES_CBC
+CFLAGS += -DCONFIG_NO_AES_ENCRYPT
+CFLAGS += -DCONFIG_NO_AES_ENCRYPT_BLOCK
 endif
 
 ifdef NEED_AES
 OBJS += ../src/crypto/aes_wrap.o ../src/crypto/aes.o
+endif
+
+ifndef NEED_FIPS186_2_PRF
+CFLAGS += -DCONFIG_NO_FIPS186_2_PRF
+endif
+
+ifndef NEED_T_PRF
+CFLAGS += -DCONFIG_NO_T_PRF
+endif
+
+ifndef NEED_TLS_PRF
+CFLAGS += -DCONFIG_NO_TLS_PRF
 endif
 
 ifdef NEED_BASE64
@@ -849,6 +898,10 @@
 
 ifndef CONFIG_MAIN
 CONFIG_MAIN=main
+endif
+
+ifdef CONFIG_DEBUG_FILE
+CFLAGS += -DCONFIG_DEBUG_FILE
 endif
 
 OBJS_wpa_rm := ctrl_iface.o mlme.o ctrl_iface_unix.o
@@ -856,7 +909,7 @@
 ifdef CONFIG_AUTHENTICATOR
 OBJS_wpa += tests/link_test.o
 endif
-OBJS += wpa_supplicant.o events.o
+OBJS += wpa_supplicant.o events.o blacklist.o wpas_glue.o scan.o
 OBJS_t := $(OBJS) eapol_test.o ../src/radius/radius.o ../src/radius/radius_client.o
 OBJS_t += ../src/utils/ip_addr.o
 OBJS_t2 := $(OBJS) preauth_test.o
@@ -930,6 +983,10 @@
 eap_sake.so: ../src/eap_peer/eap_sake.c ../src/eap_common/eap_sake_common.c
 	$(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
+	$(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $^ \
+		-Deap_peer_wsc_register=eap_peer_method_dynamic_init
 
 %.so: %.c
 	$(CC) -o $@ $(CFLAGS) -shared -rdynamic -fPIC $< \

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/README
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/README?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/README (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/README Sun Dec  9 08:34:57 2007
@@ -482,7 +482,7 @@
 --------------------
 
 usage:
-  wpa_supplicant [-BddhKLqqtuvwW] [-P<pid file>] [-g<global ctrl>] \
+  wpa_supplicant [-BddfhKLqqtuvwW] [-P<pid file>] [-g<global ctrl>] \
         -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
         [-b<br_ifname> [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
         [-p<driver_param>] [-b<br_ifname>] ...]
@@ -495,6 +495,7 @@
   -i = interface name
   -d = increase debugging verbosity (-dd even more)
   -D = driver name
+  -f = Log output to default log location (normally /tmp)
   -g = global ctrl_interface
   -K = include keys (passwords, etc.) in debug output
   -t = include timestamp in debug messages

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.c (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,133 @@
+/*
+ * wpa_supplicant - Temporary BSSID blacklist
+ * Copyright (c) 2003-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "wpa_supplicant_i.h"
+#include "blacklist.h"
+
+/**
+ * wpa_blacklist_get - Get the blacklist entry for a BSSID
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID
+ * Returns: Matching blacklist entry for the BSSID or %NULL if not found
+ */
+struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
+					 const u8 *bssid)
+{
+	struct wpa_blacklist *e;
+
+	e = wpa_s->blacklist;
+	while (e) {
+		if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
+			return e;
+		e = e->next;
+	}
+
+	return NULL;
+}
+
+
+/**
+ * wpa_blacklist_add - Add an BSSID to the blacklist
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID to be added to the blacklist
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function adds the specified BSSID to the blacklist or increases the
+ * blacklist count if the BSSID was already listed. It should be called when
+ * an association attempt fails either due to the selected BSS rejecting
+ * association or due to timeout.
+ *
+ * This blacklist is used to force %wpa_supplicant to go through all available
+ * BSSes before retrying to associate with an BSS that rejected or timed out
+ * association. It does not prevent the listed BSS from being used; it only
+ * changes the order in which they are tried.
+ */
+int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+	struct wpa_blacklist *e;
+
+	e = wpa_blacklist_get(wpa_s, bssid);
+	if (e) {
+		e->count++;
+		wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count "
+			   "incremented to %d",
+			   MAC2STR(bssid), e->count);
+		return 0;
+	}
+
+	e = os_zalloc(sizeof(*e));
+	if (e == NULL)
+		return -1;
+	os_memcpy(e->bssid, bssid, ETH_ALEN);
+	e->count = 1;
+	e->next = wpa_s->blacklist;
+	wpa_s->blacklist = e;
+	wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist",
+		   MAC2STR(bssid));
+
+	return 0;
+}
+
+
+/**
+ * wpa_blacklist_del - Remove an BSSID from the blacklist
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID to be removed from the blacklist
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
+{
+	struct wpa_blacklist *e, *prev = NULL;
+
+	e = wpa_s->blacklist;
+	while (e) {
+		if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
+			if (prev == NULL) {
+				wpa_s->blacklist = e->next;
+			} else {
+				prev->next = e->next;
+			}
+			wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
+				   "blacklist", MAC2STR(bssid));
+			os_free(e);
+			return 0;
+		}
+		prev = e;
+		e = e->next;
+	}
+	return -1;
+}
+
+
+/**
+ * wpa_blacklist_clear - Clear the blacklist of all entries
+ * @wpa_s: Pointer to wpa_supplicant data
+ */
+void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_blacklist *e, *prev;
+
+	e = wpa_s->blacklist;
+	wpa_s->blacklist = NULL;
+	while (e) {
+		prev = e;
+		e = e->next;
+		wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
+			   "blacklist (clear)", MAC2STR(prev->bssid));
+		os_free(prev);
+	}
+}

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.h?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.h (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/blacklist.h Sun Dec  9 08:34:57 2007
@@ -1,0 +1,30 @@
+/*
+ * wpa_supplicant - Temporary BSSID blacklist
+ * Copyright (c) 2003-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef BLACKLIST_H
+#define BLACKLIST_H
+
+struct wpa_blacklist {
+	struct wpa_blacklist *next;
+	u8 bssid[ETH_ALEN];
+	int count;
+};
+
+struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
+					 const u8 *bssid);
+int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid);
+int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid);
+void wpa_blacklist_clear(struct wpa_supplicant *wpa_s);
+
+#endif /* BLACKLIST_H */

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/config.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/config.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/config.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/config.c Sun Dec  9 08:34:57 2007
@@ -21,6 +21,10 @@
 #include "config.h"
 
 
+#if !defined(CONFIG_CTRL_IFACE) && defined(CONFIG_NO_CONFIG_WRITE)
+#define NO_CONFIG_WRITE
+#endif
+
 /*
  * Structure for network configuration parsing. This data is used to implement
  * a generic parser for each network block variable. The table of configuration
@@ -34,9 +38,11 @@
 	int (*parser)(const struct parse_data *data, struct wpa_ssid *ssid,
 		      int line, const char *value);
 
+#ifndef NO_CONFIG_WRITE
 	/* Writer function (i.e., to get the variable in text format from
 	 * internal presentation). */
 	char * (*writer)(const struct parse_data *data, struct wpa_ssid *ssid);
+#endif /* NO_CONFIG_WRITE */
 
 	/* Variable specific parameters for the parser. */
 	void *param1, *param2, *param3, *param4;
@@ -64,17 +70,18 @@
 		return os_strdup(value);
 	} else {
 		u8 *str;
-		size_t hlen = os_strlen(value);
+		size_t tlen, hlen = os_strlen(value);
 		if (hlen & 1)
 			return NULL;
-		*len = hlen / 2;
-		str = os_malloc(*len);
+		tlen = hlen / 2;
+		str = os_malloc(tlen);
 		if (str == NULL)
 			return NULL;
-		if (hexstr2bin(value, str, *len)) {
+		if (hexstr2bin(value, str, tlen)) {
 			os_free(str);
 			return NULL;
 		}
+		*len = tlen;
 		return (char *) str;
 	}
 }
@@ -130,6 +137,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static int is_hex(const u8 *data, size_t len)
 {
 	size_t i;
@@ -200,6 +208,7 @@
 
 	return wpa_config_write_string((const u8 *) *src, len);
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_int(const struct parse_data *data,
@@ -232,6 +241,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_int(const struct parse_data *data,
 				   struct wpa_ssid *ssid)
 {
@@ -251,6 +261,7 @@
 	value[20 - 1] = '\0';
 	return value;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_bssid(const struct parse_data *data,
@@ -268,6 +279,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_bssid(const struct parse_data *data,
 				     struct wpa_ssid *ssid)
 {
@@ -288,6 +300,7 @@
 	value[20 - 1] = '\0';
 	return value;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_psk(const struct parse_data *data,
@@ -295,6 +308,7 @@
 				const char *value)
 {
 	if (*value == '"') {
+#ifndef CONFIG_NO_PBKDF2
 		const char *pos;
 		size_t len;
 
@@ -323,6 +337,11 @@
 		os_memcpy(ssid->passphrase, value, len);
 		ssid->passphrase[len] = '\0';
 		return 0;
+#else /* CONFIG_NO_PBKDF2 */
+		wpa_printf(MSG_ERROR, "Line %d: ASCII passphrase not "
+			   "supported.", line);
+		return -1;
+#endif /* CONFIG_NO_PBKDF2 */
 	}
 
 	if (hexstr2bin(value, ssid->psk, PMK_LEN) ||
@@ -341,6 +360,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_psk(const struct parse_data *data,
 				   struct wpa_ssid *ssid)
 {
@@ -354,6 +374,7 @@
 
 	return NULL;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_proto(const struct parse_data *data,
@@ -407,6 +428,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_proto(const struct parse_data *data,
 				     struct wpa_ssid *ssid)
 {
@@ -436,6 +458,7 @@
 
 	return buf;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_key_mgmt(const struct parse_data *data,
@@ -500,6 +523,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_key_mgmt(const struct parse_data *data,
 					struct wpa_ssid *ssid)
 {
@@ -573,6 +597,7 @@
 
 	return buf;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_cipher(int line, const char *value)
@@ -627,6 +652,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_cipher(int cipher)
 {
 	char *buf, *pos, *end;
@@ -689,6 +715,7 @@
 
 	return buf;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_pairwise(const struct parse_data *data,
@@ -711,11 +738,13 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_pairwise(const struct parse_data *data,
 					struct wpa_ssid *ssid)
 {
 	return wpa_config_write_cipher(ssid->pairwise_cipher);
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_group(const struct parse_data *data,
@@ -739,11 +768,13 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_group(const struct parse_data *data,
 				     struct wpa_ssid *ssid)
 {
 	return wpa_config_write_cipher(ssid->group_cipher);
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 static int wpa_config_parse_auth_alg(const struct parse_data *data,
@@ -798,6 +829,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_auth_alg(const struct parse_data *data,
 					struct wpa_ssid *ssid)
 {
@@ -841,6 +873,7 @@
 
 	return buf;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 #ifdef IEEE8021X_EAPOL
@@ -1099,6 +1132,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 static char * wpa_config_write_wep_key(struct wpa_ssid *ssid, int idx)
 {
 	if (ssid->wep_key_len[idx] == 0)
@@ -1134,6 +1168,7 @@
 {
 	return wpa_config_write_wep_key(ssid, 3);
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 /* Helper macros for network block parser */
@@ -1145,7 +1180,11 @@
 #define OFFSET(v) ((void *) &((struct wpa_ssid *) 0)->v)
 
 /* STR: Define a string variable for an ASCII string; f = field name */
+#ifdef NO_CONFIG_WRITE
+#define _STR(f) #f, wpa_config_parse_str, OFFSET(f)
+#else /* NO_CONFIG_WRITE */
 #define _STR(f) #f, wpa_config_parse_str, wpa_config_write_str, OFFSET(f)
+#endif /* NO_CONFIG_WRITE */
 #define STR(f) _STR(f), NULL, NULL, NULL, 0
 #define STR_KEY(f) _STR(f), NULL, NULL, NULL, 1
 
@@ -1162,8 +1201,12 @@
 #define STR_RANGE(f, min, max) _STR_RANGE(f, min, max), 0
 #define STR_RANGE_KEY(f, min, max) _STR_RANGE(f, min, max), 1
 
+#ifdef NO_CONFIG_WRITE
+#define _INT(f) #f, wpa_config_parse_int, OFFSET(f), (void *) 0
+#else /* NO_CONFIG_WRITE */
 #define _INT(f) #f, wpa_config_parse_int, wpa_config_write_int, \
 	OFFSET(f), (void *) 0
+#endif /* NO_CONFIG_WRITE */
 
 /* INT: Define an integer variable */
 #define INT(f) _INT(f), NULL, NULL, 0
@@ -1173,8 +1216,12 @@
 
 /* FUNC: Define a configuration variable that uses a custom function for
  * parsing and writing the value. */
+#ifdef NO_CONFIG_WRITE
+#define _FUNC(f) #f, wpa_config_parse_ ## f, NULL, NULL, NULL, NULL
+#else /* NO_CONFIG_WRITE */
 #define _FUNC(f) #f, wpa_config_parse_ ## f, wpa_config_write_ ## f, \
 	NULL, NULL, NULL, NULL
+#endif /* NO_CONFIG_WRITE */
 #define FUNC(f) _FUNC(f), 0
 #define FUNC_KEY(f) _FUNC(f), 1
 
@@ -1427,7 +1474,9 @@
  */
 void wpa_config_free(struct wpa_config *config)
 {
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	struct wpa_config_blob *blob, *prevblob;
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 	struct wpa_ssid *ssid, *prev = NULL;
 	ssid = config->ssid;
 	while (ssid) {
@@ -1436,6 +1485,7 @@
 		wpa_config_free_ssid(prev);
 	}
 
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	blob = config->blobs;
 	prevblob = NULL;
 	while (blob) {
@@ -1443,44 +1493,19 @@
 		blob = blob->next;
 		wpa_config_free_blob(prevblob);
 	}
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 
 	os_free(config->ctrl_interface);
 	os_free(config->ctrl_interface_group);
+#ifdef EAP_TLS_OPENSSL
 	os_free(config->opensc_engine_path);
 	os_free(config->pkcs11_engine_path);
 	os_free(config->pkcs11_module_path);
+#endif /* EAP_TLS_OPENSSL */
 	os_free(config->driver_param);
 	os_free(config->pssid);
 	os_free(config);
 }
-
-
-#ifdef IEEE8021X_EAPOL
-/**
- * wpa_config_allowed_eap_method - Check whether EAP method is allowed
- * @ssid: Pointer to configuration data
- * @vendor: Vendor-Id for expanded types or 0 = IETF for legacy types
- * @method: EAP type
- * Returns: 1 = allowed EAP method, 0 = not allowed
- */
-int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int vendor,
-				  u32 method)
-{
-	int i;
-	struct eap_method_type *m;
-
-	if (ssid == NULL || ssid->eap_methods == NULL)
-		return 1;
-
-	m = ssid->eap_methods;
-	for (i = 0; m[i].vendor != EAP_VENDOR_IETF ||
-		     m[i].method != EAP_TYPE_NONE; i++) {
-		if (m[i].vendor == vendor && m[i].method == method)
-			return 1;
-	}
-	return 0;
-}
-#endif /* IEEE8021X_EAPOL */
 
 
 /**
@@ -1637,6 +1662,7 @@
 }
 
 
+#ifndef NO_CONFIG_WRITE
 /**
  * wpa_config_get - Get a variable in network configuration
  * @ssid: Pointer to network configuration data
@@ -1711,6 +1737,7 @@
 
 	return NULL;
 }
+#endif /* NO_CONFIG_WRITE */
 
 
 /**
@@ -1722,15 +1749,18 @@
  */
 void wpa_config_update_psk(struct wpa_ssid *ssid)
 {
+#ifndef CONFIG_NO_PBKDF2
 	pbkdf2_sha1(ssid->passphrase,
 		    (char *) ssid->ssid, ssid->ssid_len, 4096,
 		    ssid->psk, PMK_LEN);
 	wpa_hexdump_key(MSG_MSGDUMP, "PSK (from passphrase)",
 			ssid->psk, PMK_LEN);
 	ssid->psk_set = 1;
-}
-
-
+#endif /* CONFIG_NO_PBKDF2 */
+}
+
+
+#ifndef CONFIG_NO_CONFIG_BLOBS
 /**
  * wpa_config_get_blob - Get a named configuration blob
  * @config: Configuration data from wpa_config_read()
@@ -1807,6 +1837,7 @@
 
 	return -1;
 }
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 
 
 /**

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/config.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/config.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/config.h (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/config.h Sun Dec  9 08:34:57 2007
@@ -16,39 +16,15 @@
 #define CONFIG_H
 
 #define DEFAULT_EAPOL_VERSION 1
+#ifdef CONFIG_NO_SCAN_PROCESSING
+#define DEFAULT_AP_SCAN 2
+#else /* CONFIG_NO_SCAN_PROCESSING */
 #define DEFAULT_AP_SCAN 1
+#endif /* CONFIG_NO_SCAN_PROCESSING */
 #define DEFAULT_FAST_REAUTH 1
 
 #include "config_ssid.h"
-
-/**
- * struct wpa_config_blob - Named configuration blob
- *
- * This data structure is used to provide storage for binary objects to store
- * abstract information like certificates and private keys inlined with the
- * configuration data.
- */
-struct wpa_config_blob {
-	/**
-	 * name - Blob name
-	 */
-	char *name;
-
-	/**
-	 * data - Pointer to binary data
-	 */
-	u8 *data;
-
-	/**
-	 * len - Length of binary data
-	 */
-	size_t len;
-
-	/**
-	 * next - Pointer to next blob in the configuration
-	 */
-	struct wpa_config_blob *next;
-};
+#include "config_blob.h"
 
 
 /**
@@ -194,6 +170,7 @@
 	 */
 	int fast_reauth;
 
+#ifdef EAP_TLS_OPENSSL
 	/**
 	 * opensc_engine_path - Path to the OpenSSL engine for opensc
 	 *
@@ -218,6 +195,7 @@
 	 * module is not loaded.
 	 */
 	char *pkcs11_module_path;
+#endif /* EAP_TLS_OPENSSL */
 
 	/**
 	 * driver_param - Driver interface parameters
@@ -289,12 +267,6 @@
 int wpa_config_add_prio_network(struct wpa_config *config,
 				struct wpa_ssid *ssid);
 
-const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
-						   const char *name);
-void wpa_config_set_blob(struct wpa_config *config,
-			 struct wpa_config_blob *blob);
-void wpa_config_free_blob(struct wpa_config_blob *blob);
-int wpa_config_remove_blob(struct wpa_config *config, const char *name);
 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
 					   const char *driver_param);
 #ifndef CONFIG_NO_STDOUT_DEBUG

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/config_blob.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/config_blob.h?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/config_blob.h (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/config_blob.h Sun Dec  9 08:34:57 2007
@@ -1,0 +1,56 @@
+/*
+ * WPA Supplicant / Configuration blobs
+ * Copyright (c) 2003-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef CONFIG_BLOB_H
+#define CONFIG_BLOB_H
+
+/**
+ * struct wpa_config_blob - Named configuration blob
+ *
+ * This data structure is used to provide storage for binary objects to store
+ * abstract information like certificates and private keys inlined with the
+ * configuration data.
+ */
+struct wpa_config_blob {
+	/**
+	 * name - Blob name
+	 */
+	char *name;
+
+	/**
+	 * data - Pointer to binary data
+	 */
+	u8 *data;
+
+	/**
+	 * len - Length of binary data
+	 */
+	size_t len;
+
+	/**
+	 * next - Pointer to next blob in the configuration
+	 */
+	struct wpa_config_blob *next;
+};
+
+struct wpa_config;
+
+const struct wpa_config_blob * wpa_config_get_blob(struct wpa_config *config,
+						   const char *name);
+void wpa_config_set_blob(struct wpa_config *config,
+			 struct wpa_config_blob *blob);
+void wpa_config_free_blob(struct wpa_config_blob *blob);
+int wpa_config_remove_blob(struct wpa_config *config, const char *name);
+
+#endif /* CONFIG_BLOB_H */

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/config_file.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/config_file.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/config_file.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/config_file.c Sun Dec  9 08:34:57 2007
@@ -185,6 +185,7 @@
 }
 
 
+#ifndef CONFIG_NO_CONFIG_BLOBS
 static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
 						     const char *name)
 {
@@ -264,6 +265,7 @@
 	wpa_config_set_blob(config, blob);
 	return 0;
 }
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 
 
 #ifdef CONFIG_CTRL_IFACE
@@ -319,6 +321,8 @@
 }
 
 
+#ifdef EAP_TLS_OPENSSL
+
 static int wpa_config_process_opensc_engine_path(struct wpa_config *config,
 						 char *pos)
 {
@@ -351,6 +355,8 @@
 	return 0;
 }
 
+#endif /* EAP_TLS_OPENSSL */
+
 
 static int wpa_config_process_driver_param(struct wpa_config *config,
 					   char *pos)
@@ -391,6 +397,7 @@
 }
 
 
+#ifndef CONFIG_NO_CONFIG_WRITE
 static int wpa_config_process_update_config(struct wpa_config *config,
 					    char *pos)
 {
@@ -398,6 +405,7 @@
 	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)
@@ -440,6 +448,7 @@
 	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);
 
@@ -448,6 +457,7 @@
 
 	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);
@@ -462,8 +472,10 @@
 	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);
@@ -513,12 +525,14 @@
 				errors++;
 				continue;
 			}
+#ifndef CONFIG_NO_CONFIG_BLOBS
 		} else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
 			if (wpa_config_process_blob(config, f, &line, pos + 12)
 			    < 0) {
 				errors++;
 				continue;
 			}
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 		} else if (wpa_config_process_global(config, pos, line) < 0) {
 			wpa_printf(MSG_ERROR, "Line %d: Invalid configuration "
 				   "line '%s'.", line, pos);
@@ -541,6 +555,8 @@
 	return config;
 }
 
+
+#ifndef CONFIG_NO_CONFIG_WRITE
 
 static void write_str(FILE *f, const char *field, struct wpa_ssid *ssid)
 {
@@ -765,6 +781,7 @@
 }
 
 
+#ifndef CONFIG_NO_CONFIG_BLOBS
 static int wpa_config_write_blob(FILE *f, struct wpa_config_blob *blob)
 {
 	unsigned char *encoded;
@@ -777,6 +794,7 @@
 	os_free(encoded);
 	return 0;
 }
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 
 
 static void wpa_config_write_global(FILE *f, struct wpa_config *config)
@@ -794,6 +812,7 @@
 		fprintf(f, "ap_scan=%d\n", config->ap_scan);
 	if (config->fast_reauth != DEFAULT_FAST_REAUTH)
 		fprintf(f, "fast_reauth=%d\n", config->fast_reauth);
+#ifdef EAP_TLS_OPENSSL
 	if (config->opensc_engine_path)
 		fprintf(f, "opensc_engine_path=%s\n",
 			config->opensc_engine_path);
@@ -803,6 +822,7 @@
 	if (config->pkcs11_module_path)
 		fprintf(f, "pkcs11_module_path=%s\n",
 			config->pkcs11_module_path);
+#endif /* EAP_TLS_OPENSSL */
 	if (config->driver_param)
 		fprintf(f, "driver_param=%s\n", config->driver_param);
 	if (config->dot11RSNAConfigPMKLifetime)
@@ -818,12 +838,17 @@
 		fprintf(f, "update_config=%d\n", config->update_config);
 }
 
+#endif /* CONFIG_NO_CONFIG_WRITE */
+
 
 int wpa_config_write(const char *name, struct wpa_config *config)
 {
+#ifndef CONFIG_NO_CONFIG_WRITE
 	FILE *f;
 	struct wpa_ssid *ssid;
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	struct wpa_config_blob *blob;
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 	int ret = 0;
 
 	wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
@@ -842,15 +867,20 @@
 		fprintf(f, "}\n");
 	}
 
+#ifndef CONFIG_NO_CONFIG_BLOBS
 	for (blob = config->blobs; blob; blob = blob->next) {
 		ret = wpa_config_write_blob(f, blob);
 		if (ret)
 			break;
 	}
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 
 	fclose(f);
 
 	wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully",
 		   name, ret ? "un" : "");
 	return ret;
-}
+#else /* CONFIG_NO_CONFIG_WRITE */
+	return -1;
+#endif /* CONFIG_NO_CONFIG_WRITE */
+}

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/config_ssid.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/config_ssid.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/config_ssid.h (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/config_ssid.h Sun Dec  9 08:34:57 2007
@@ -870,7 +870,4 @@
 	u32 flags;
 };
 
-int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int vendor,
-				  u32 method);
-
 #endif /* CONFIG_SSID_H */

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface.c Sun Dec  9 08:34:57 2007
@@ -18,7 +18,7 @@
 #include "eloop.h"
 #include "wpa.h"
 #include "config.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "wpa_supplicant_i.h"
 #include "ctrl_iface.h"
 #include "l2_packet/l2_packet.h"
@@ -828,6 +828,7 @@
 }
 
 
+#ifndef CONFIG_NO_CONFIG_WRITE
 static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
 {
 	int ret;
@@ -849,6 +850,7 @@
 
 	return ret;
 }
+#endif /* CONFIG_NO_CONFIG_WRITE */
 
 
 static int ctrl_iface_get_capability_pairwise(int res, char *strict,
@@ -1293,9 +1295,11 @@
 	} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
 		reply_len = wpa_supplicant_ctrl_iface_get_network(
 			wpa_s, buf + 12, reply, reply_size);
+#ifndef CONFIG_NO_CONFIG_WRITE
 	} else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
 		if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
 			reply_len = -1;
+#endif /* CONFIG_NO_CONFIG_WRITE */
 	} else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
 		reply_len = wpa_supplicant_ctrl_iface_get_capability(
 			wpa_s, buf + 15, reply, reply_size);

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_named_pipe.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_named_pipe.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_named_pipe.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_named_pipe.c Sun Dec  9 08:34:57 2007
@@ -17,7 +17,7 @@
 #include "common.h"
 #include "eloop.h"
 #include "config.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "wpa_supplicant_i.h"
 #include "ctrl_iface.h"
 #include "wpa_ctrl.h"

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_udp.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_udp.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_udp.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_udp.c Sun Dec  9 08:34:57 2007
@@ -17,7 +17,7 @@
 #include "common.h"
 #include "eloop.h"
 #include "config.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "wpa_supplicant_i.h"
 #include "ctrl_iface.h"
 #include "wpa_ctrl.h"

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_unix.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_unix.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_unix.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/ctrl_iface_unix.c Sun Dec  9 08:34:57 2007
@@ -20,7 +20,7 @@
 #include "common.h"
 #include "eloop.h"
 #include "config.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "wpa_supplicant_i.h"
 #include "ctrl_iface.h"
 

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/defconfig Sun Dec  9 08:34:57 2007
@@ -164,6 +164,9 @@
 # EAP-TNC and related Trusted Network Connect support (experimental)
 #CONFIG_EAP_TNC=y
 
+# EAP-WSC for Wi-Fi Protected Setup
+#CONFIG_EAP_WSC=y
+
 # PKCS#12 (PFX) support (used to read private key and certificate file from
 # a file that usually has extension .p12 or .pfx)
 CONFIG_PKCS12=y
@@ -209,10 +212,21 @@
 # or 6 kB if building for WPA-Enterprise.
 #CONFIG_NO_WPA2=y
 
+# Remove IEEE 802.11i/WPA-Personal ASCII passphrase support
+# This option can be used to reduce code size by removing support for
+# converting ASCII passphrases into PSK. If this functionality is removed, the
+# PSK can only be configured as the 64-octet hexstring (e.g., from
+# wpa_passphrase). This saves about 0.5 kB in code size.
+#CONFIG_NO_WPA_PASSPHRASE=y
+
 # Remove AES extra functions. This can be used to reduce code size by about
 # 1.5 kB by removing extra AES modes that are not needed for commonly used
 # client configurations (they are needed for some EAP types).
 #CONFIG_NO_AES_EXTRAS=y
+
+# Disable scan result processing (ap_mode=1) to save code size by about 1 kB.
+# This can be used if ap_scan=1 mode is never enabled.
+#CONFIG_NO_SCAN_PROCESSING=y
 
 # Select configuration backend:
 # file = text file (e.g., wpa_supplicant.conf; note: the configuration file
@@ -220,6 +234,16 @@
 #	select the backend that allows configuration files to be used)
 # winreg = Windows registry (see win_example.reg for an example)
 CONFIG_BACKEND=file
+
+# Remove configuration write functionality (i.e., to allow the configuration
+# file to be updated based on runtime configuration changes). The runtime
+# configuration can still be changed, the changes are just not going to be
+# persistent over restarts. This option can be used to reduce code size by
+# about 3.5 kB.
+#CONFIG_NO_CONFIG_WRITE=y
+
+# Remove support for configuration blobs to reduce code size by about 1.5 kB.
+#CONFIG_NO_CONFIG_BLOBS=y
 
 # Select program entry point implementation:
 # main = UNIX/POSIX like main() function (default)
@@ -330,3 +354,6 @@
 # IEEE 802.11r. This draft is still subject to change, so it should be noted
 # that this version may not comply with the final standard.
 #CONFIG_IEEE80211R=y
+
+# Add support for writing debug log to a file (/tmp/wpa_supplicant-log-#.txt)
+#CONFIG_DEBUG_FILE=y

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/doc/docbook/wpa_supplicant.sgml Sun Dec  9 08:34:57 2007
@@ -12,7 +12,7 @@
   <refsynopsisdiv>
     <cmdsynopsis>
       <command>wpa_supplicant</command>
-      <arg>-BddhKLqqtuvwW</arg>
+      <arg>-BddfhKLqqtuvwW</arg>
       <arg>-i<replaceable>ifname</replaceable></arg>
       <arg>-c<replaceable>config file</replaceable></arg>
       <arg>-D<replaceable>driver</replaceable></arg>
@@ -372,6 +372,13 @@
 	<term>-D driver</term>
 	<listitem>
 	  <para>Driver to use.  See the available options below.</para>
+	</listitem>
+      </varlistentry>
+
+      <varlistentry>
+	<term>-f</term>
+	<listitem>
+	  <para>Log output to default log location (normally /tmp).</para>
 	</listitem>
       </varlistentry>
 

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_test.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_test.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_test.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/eapol_test.c Sun Dec  9 08:34:57 2007
@@ -20,7 +20,7 @@
 
 #include "common.h"
 #include "config.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "eap_peer/eap.h"
 #include "eloop.h"
 #include "wpa.h"
@@ -312,9 +312,11 @@
 	ctx->eapol_send = eapol_test_eapol_send;
 	ctx->set_config_blob = eapol_test_set_config_blob;
 	ctx->get_config_blob = eapol_test_get_config_blob;
+#ifdef EAP_TLS_OPENSSL
 	ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
 	ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
 	ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
+#endif /* EAP_TLS_OPENSSL */
 
 	wpa_s->eapol = eapol_sm_init(ctx);
 	if (wpa_s->eapol == NULL) {

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/events.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/events.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/events.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/events.c Sun Dec  9 08:34:57 2007
@@ -15,7 +15,7 @@
 #include "includes.h"
 
 #include "common.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "wpa.h"
 #include "eloop.h"
 #include "drivers/driver.h"
@@ -29,6 +29,7 @@
 #include "eap_peer/eap.h"
 #include "ctrl_iface_dbus.h"
 #include "ieee802_11_defs.h"
+#include "blacklist.h"
 
 
 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
@@ -236,6 +237,7 @@
 }
 
 
+#ifndef CONFIG_NO_SCAN_PROCESSING
 static int wpa_supplicant_match_privacy(struct wpa_scan_result *bss,
 					struct wpa_ssid *ssid)
 {
@@ -583,6 +585,7 @@
 	}
 	wpa_supplicant_req_scan(wpa_s, timeout, 0);
 }
+#endif /* CONFIG_NO_SCAN_PROCESSING */
 
 
 static void wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
@@ -900,9 +903,11 @@
 	case EVENT_MICHAEL_MIC_FAILURE:
 		wpa_supplicant_event_michael_mic_failure(wpa_s, data);
 		break;
+#ifndef CONFIG_NO_SCAN_PROCESSING
 	case EVENT_SCAN_RESULTS:
 		wpa_supplicant_event_scan_results(wpa_s);
 		break;
+#endif /* CONFIG_NO_SCAN_PROCESSING */
 	case EVENT_ASSOCINFO:
 		wpa_supplicant_event_associnfo(wpa_s, data);
 		break;

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/main.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/main.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/main.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/main.c Sun Dec  9 08:34:57 2007
@@ -39,7 +39,7 @@
 	int i;
 	printf("%s\n\n%s\n"
 	       "usage:\n"
-	       "  wpa_supplicant [-BddhKLqqtuvwW] [-P<pid file>] "
+	       "  wpa_supplicant [-BddfhKLqqtuvwW] [-P<pid file>] "
 	       "[-g<global ctrl>] \\\n"
 	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
 	       "[-p<driver_param>] \\\n"
@@ -65,6 +65,9 @@
 	       "  -i = interface name\n"
 	       "  -d = increase debugging verbosity (-dd even more)\n"
 	       "  -D = driver name\n"
+#ifdef CONFIG_DEBUG_FILE
+	       "  -f = Log output to default log location (normally /tmp)\n"
+#endif /* CONFIG_DEBUG_FILE */
 	       "  -g = global ctrl_interface\n"
 	       "  -K = include keys (passwords, etc.) in debug output\n"
 	       "  -t = include timestamp in debug messages\n"
@@ -143,7 +146,7 @@
 	wpa_supplicant_fd_workaround();
 
 	for (;;) {
-		c = getopt(argc, argv, "b:Bc:C:D:dg:hi:KLNp:P:qtuvwW");
+		c = getopt(argc, argv, "b:Bc:C:D:dfg:hi:KLNp:P:qtuvwW");
 		if (c < 0)
 			break;
 		switch (c) {
@@ -172,6 +175,11 @@
 			params.wpa_debug_level--;
 			break;
 #endif /* CONFIG_NO_STDOUT_DEBUG */
+#ifdef CONFIG_DEBUG_FILE
+		case 'f':
+			params.wpa_debug_use_file = 1;
+			break;
+#endif /* CONFIG_DEBUG_FILE */
 		case 'g':
 			params.ctrl_interface = optarg;
 			break;
@@ -237,7 +245,7 @@
 	exitcode = 0;
 	global = wpa_supplicant_init(&params);
 	if (global == NULL) {
-		printf("Failed to initialize wpa_supplicant\n");
+		wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
 		exitcode = -1;
 		goto out;
 	}

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/nmake.mak
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/nmake.mak?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/nmake.mak (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/nmake.mak Sun Dec  9 08:34:57 2007
@@ -49,7 +49,7 @@
 CFLAGS = $(CFLAGS) /DCONFIG_CTRL_IFACE_NAMED_PIPE
 CFLAGS = $(CFLAGS) /DCONFIG_DRIVER_NDIS
 CFLAGS = $(CFLAGS) /I..\src /I..\src\utils /I..\src\common /I..\src\crypto
-CFLAGS = $(CFLAGS) /I..\src\rsn_supp /I.
+CFLAGS = $(CFLAGS) /I..\src\rsn_supp /I..\src\eapol_supp /I.
 CFLAGS = $(CFLAGS) /DWIN32
 CFLAGS = $(CFLAGS) /Fo$(OBJDIR)\\ /c
 CFLAGS = $(CFLAGS) /W3
@@ -75,7 +75,7 @@
 	$(OBJDIR)\wpa_ie.obj \
 	$(OBJDIR)\preauth.obj \
 	$(OBJDIR)\pmksa_cache.obj \
-	$(OBJDIR)\eapol_sm.obj \
+	$(OBJDIR)\eapol_supp_sm.obj \
 	$(OBJDIR)\eap.obj \
 	$(OBJDIR)\eap_common.obj \
 	$(OBJDIR)\eap_methods.obj \
@@ -104,6 +104,9 @@
 	$(OBJDIR)\driver_ndis.obj \
 	$(OBJDIR)\driver_ndis_.obj \
 	$(OBJDIR)\events.obj \
+	$(OBJDIR)\blacklist.obj \
+	$(OBJDIR)\scan.obj \
+	$(OBJDIR)\wpas_glue.obj \
 	$(OBJDIR)\config.obj \
 	$(OBJDIR)\l2_packet_winpcap.obj \
 	$(OBJDIR)\tls_openssl.obj \
@@ -125,7 +128,7 @@
 	$(OBJDIR)\config_file.obj $(OBJDIR)\base64.obj
 
 OBJS2 = $(OBJDIR)\drivers.obj \
-	$(OBJDIR)\config_file.obj $(OBJDIR)\base64.obj \
+	$(OBJDIR)\config_file.obj \
 	$(OBJS2) $(OBJDIR)\main.obj
 
 OBJS3 = $(OBJDIR)\drivers.obj \
@@ -190,6 +193,9 @@
 {..\src\rsn_supp}.c{$(OBJDIR)}.obj::
 	$(CC) $(CFLAGS) $<
 
+{..\src\eapol_supp}.c{$(OBJDIR)}.obj::
+	$(CC) $(CFLAGS) $<
+
 {..\src\crypto}.c{$(OBJDIR)}.obj::
 	$(CC) $(CFLAGS) $<
 

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/preauth_test.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/preauth_test.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/preauth_test.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/preauth_test.c Sun Dec  9 08:34:57 2007
@@ -20,7 +20,7 @@
 
 #include "common.h"
 #include "config.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "eloop.h"
 #include "wpa.h"
 #include "eap_peer/eap.h"

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/scan.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/scan.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/scan.c (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/scan.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,187 @@
+/*
+ * WPA Supplicant - Scanning
+ * Copyright (c) 2003-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eloop.h"
+#include "config.h"
+#include "wpa_supplicant_i.h"
+#include "mlme.h"
+
+
+static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_ssid *ssid;
+	union wpa_event_data data;
+
+	ssid = wpa_supplicant_get_ssid(wpa_s);
+	if (ssid == NULL)
+		return;
+
+	if (wpa_s->current_ssid == NULL)
+		wpa_s->current_ssid = ssid;
+	wpa_supplicant_initiate_eapol(wpa_s);
+	wpa_printf(MSG_DEBUG, "Already associated with a configured network - "
+		   "generating associated event");
+	os_memset(&data, 0, sizeof(data));
+	wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
+}
+
+
+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;
+
+	if (wpa_s->disconnected)
+		return;
+
+	enabled = 0;
+	ssid = wpa_s->conf->ssid;
+	while (ssid) {
+		if (!ssid->disabled) {
+			enabled++;
+			break;
+		}
+		ssid = ssid->next;
+	}
+	if (!enabled && !wpa_s->scan_req) {
+		wpa_printf(MSG_DEBUG, "No enabled networks - do not scan");
+		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
+		return;
+	}
+	scan_req = wpa_s->scan_req;
+	wpa_s->scan_req = 0;
+
+	if (wpa_s->conf->ap_scan != 0 &&
+	    wpa_s->driver && os_strcmp(wpa_s->driver->name, "wired") == 0) {
+		wpa_printf(MSG_DEBUG, "Using wired driver - overriding "
+			   "ap_scan configuration");
+		wpa_s->conf->ap_scan = 0;
+	}
+
+	if (wpa_s->conf->ap_scan == 0) {
+		wpa_supplicant_gen_assoc_event(wpa_s);
+		return;
+	}
+
+	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
+	    wpa_s->wpa_state == WPA_INACTIVE)
+		wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
+
+	ssid = wpa_s->conf->ssid;
+	if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
+		while (ssid) {
+			if (ssid == wpa_s->prev_scan_ssid) {
+				ssid = ssid->next;
+				break;
+			}
+			ssid = ssid->next;
+		}
+	}
+	while (ssid) {
+		if (!ssid->disabled &&
+		    (ssid->scan_ssid || wpa_s->conf->ap_scan == 2))
+			break;
+		ssid = ssid->next;
+	}
+
+	if (scan_req != 2 && wpa_s->conf->ap_scan == 2) {
+		/*
+		 * ap_scan=2 mode - try to associate with each SSID instead of
+		 * scanning for each scan_ssid=1 network.
+		 */
+		if (ssid == NULL) {
+			wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached "
+				   "end of scan list - go back to beginning");
+			wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+			wpa_supplicant_req_scan(wpa_s, 0, 0);
+			return;
+		}
+		if (ssid->next) {
+			/* Continue from the next SSID on the next attempt. */
+			wpa_s->prev_scan_ssid = ssid;
+		} else {
+			/* Start from the beginning of the SSID list. */
+			wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+		}
+		wpa_supplicant_associate(wpa_s, NULL, ssid);
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)",
+		   ssid ? "specific": "broadcast");
+	if (ssid) {
+		wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
+				  ssid->ssid, ssid->ssid_len);
+		wpa_s->prev_scan_ssid = ssid;
+	} else
+		wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
+
+	if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
+	    !wpa_s->use_client_mlme) {
+		wpa_s->scan_res_tried++;
+		wpa_printf(MSG_DEBUG, "Trying to get current scan results "
+			   "first without requesting a new scan to speed up "
+			   "initial association");
+		wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL);
+		return;
+	}
+
+	if (wpa_s->use_client_mlme) {
+		ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL,
+					     ssid ? ssid->ssid_len : 0);
+	} else {
+		ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL,
+				   ssid ? ssid->ssid_len : 0);
+	}
+	if (ret) {
+		wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
+		wpa_supplicant_req_scan(wpa_s, 10, 0);
+	}
+}
+
+
+/**
+ * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @sec: Number of seconds after which to scan
+ * @usec: Number of microseconds after which to scan
+ *
+ * This function is used to schedule a scan for neighboring access points after
+ * the specified time.
+ */
+void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
+{
+	wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
+		sec, usec);
+	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
+	eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
+}
+
+
+/**
+ * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
+ * @wpa_s: Pointer to wpa_supplicant data
+ *
+ * This function is used to cancel a scan request scheduled with
+ * wpa_supplicant_req_scan().
+ */
+void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
+{
+	wpa_msg(wpa_s, MSG_DEBUG, "Cancelling scan request");
+	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
+}

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_wpa.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_wpa.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_wpa.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_wpa.c Sun Dec  9 08:34:57 2007
@@ -295,9 +295,10 @@
 
 	os_memset(&conf, 0, sizeof(conf));
 	conf.wpa = 2;
-	conf.wpa_key_mgmt = 2; /* PSK */
-	conf.wpa_pairwise = 16; /* CCMP */
-	conf.wpa_group = 16; /* CCMP */
+	conf.wpa_key_mgmt = WPA_KEY_MGMT_PSK;
+	conf.wpa_pairwise = WPA_CIPHER_CCMP;
+	conf.rsn_pairwise = WPA_CIPHER_CCMP;
+	conf.wpa_group = WPA_CIPHER_CCMP;
 	conf.eapol_version = 2;
 
 	os_memset(&cb, 0, sizeof(cb));

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/todo.txt Sun Dec  9 08:34:57 2007
@@ -108,8 +108,6 @@
 - change TLS/crypto library interface to use a structure of function
   pointers and helper inline functions (like driver_ops) instead of
   requiring every TLS wrapper to implement all functions
-- make it clearer that EAP server/peer can be used as a separate library
-  for other programs
 - add support for encrypted configuration fields (e.g., password, psk,
   passphrase, pin)
 - wpa_gui: add support for setting and showing priority, id_str, auth_alg

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj Sun Dec  9 08:34:57 2007
@@ -191,6 +191,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\blacklist.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\src\utils\common.c"
 				>
 			</File>
@@ -283,7 +287,7 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\eapol_sm.c"
+				RelativePath="..\..\..\src\eapol_supp\eapol_supp_sm.c"
 				>
 			</File>
 			<File
@@ -347,6 +351,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scan.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\src\crypto\sha1.c"
 				>
 			</File>
@@ -376,6 +384,10 @@
 			</File>
 			<File
 				RelativePath="..\..\wpa_supplicant.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\wpas_glue.c"
 				>
 			</File>
 		</Filter>

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj Sun Dec  9 08:34:57 2007
@@ -191,6 +191,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\blacklist.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\src\utils\common.c"
 				>
 			</File>
@@ -283,7 +287,7 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\eapol_sm.c"
+				RelativePath="..\..\..\src\eapol_supp\eapol_supp_sm.c"
 				>
 			</File>
 			<File
@@ -343,6 +347,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scan.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\src\crypto\sha1.c"
 				>
 			</File>
@@ -372,6 +380,10 @@
 			</File>
 			<File
 				RelativePath="..\..\wpa_supplicant.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\wpas_glue.c"
 				>
 			</File>
 		</Filter>

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj Sun Dec  9 08:34:57 2007
@@ -191,6 +191,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\blacklist.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\src\utils\common.c"
 				>
 			</File>
@@ -283,7 +287,7 @@
 				>
 			</File>
 			<File
-				RelativePath="..\..\eapol_sm.c"
+				RelativePath="..\..\..\src\eapol_supp\eapol_supp_sm.c"
 				>
 			</File>
 			<File
@@ -343,6 +347,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\scan.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\..\src\crypto\sha1.c"
 				>
 			</File>
@@ -372,6 +380,10 @@
 			</File>
 			<File
 				RelativePath="..\..\wpa_supplicant.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\wpas_glue.c"
 				>
 			</File>
 		</Filter>

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant.c Sun Dec  9 08:34:57 2007
@@ -19,7 +19,7 @@
 #include "includes.h"
 
 #include "common.h"
-#include "eapol_sm.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "eap_peer/eap.h"
 #include "wpa.h"
 #include "eloop.h"
@@ -36,6 +36,8 @@
 #include "wpa_ctrl.h"
 #include "mlme.h"
 #include "ieee802_11_defs.h"
+#include "blacklist.h"
+#include "wpas_glue.h"
 
 const char *wpa_supplicant_version =
 "wpa_supplicant v" VERSION_STR "\n"
@@ -112,200 +114,24 @@
 extern int wpa_debug_show_keys;
 extern int wpa_debug_timestamp;
 
-static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx);
-
-#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
-static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
-			    const void *data, u16 data_len,
-			    size_t *msg_len, void **data_pos)
-{
-	struct ieee802_1x_hdr *hdr;
-
-	*msg_len = sizeof(*hdr) + data_len;
-	hdr = os_malloc(*msg_len);
-	if (hdr == NULL)
-		return NULL;
-
-	hdr->version = wpa_s->conf->eapol_version;
-	hdr->type = type;
-	hdr->length = host_to_be16(data_len);
-
-	if (data)
-		os_memcpy(hdr + 1, data, data_len);
-	else
-		os_memset(hdr + 1, 0, data_len);
-
-	if (data_pos)
-		*data_pos = hdr + 1;
-
-	return (u8 *) hdr;
-}
-
-
-/**
- * wpa_ether_send - Send Ethernet frame
- * @wpa_s: Pointer to wpa_supplicant data
- * @dest: Destination MAC address
- * @proto: Ethertype in host byte order
- * @buf: Frame payload starting from IEEE 802.1X header
- * @len: Frame payload length
- * Returns: >=0 on success, <0 on failure
- */
-static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
-			  u16 proto, const u8 *buf, size_t len)
-{
-	if (wpa_s->l2) {
-		return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
-	}
-
-	return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len);
-}
-#endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
-
-
-#ifdef IEEE8021X_EAPOL
-/**
- * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
- * @ctx: Pointer to wpa_supplicant data (wpa_s)
- * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
- * @buf: EAPOL payload (after IEEE 802.1X header)
- * @len: EAPOL payload length
- * Returns: >=0 on success, <0 on failure
- *
- * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
- * to the current Authenticator.
- */
-static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
-				     size_t len)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	u8 *msg, *dst, bssid[ETH_ALEN];
-	size_t msglen;
-	int res;
-
-	/* TODO: could add l2_packet_sendmsg that allows fragments to avoid
-	 * extra copy here */
-
-	if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK ||
-	    wpa_s->key_mgmt == WPA_KEY_MGMT_FT_PSK ||
-	    wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
-		/* Current SSID is not using IEEE 802.1X/EAP, so drop possible
-		 * EAPOL frames (mainly, EAPOL-Start) from EAPOL state
-		 * machines. */
-		wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X "
-			   "mode (type=%d len=%lu)", type,
-			   (unsigned long) len);
-		return -1;
-	}
-
-	if (pmksa_cache_get_current(wpa_s->wpa) &&
-	    type == IEEE802_1X_TYPE_EAPOL_START) {
-		/* Trying to use PMKSA caching - do not send EAPOL-Start frames
-		 * since they will trigger full EAPOL authentication. */
-		wpa_printf(MSG_DEBUG, "RSN: PMKSA caching - do not send "
-			   "EAPOL-Start");
-		return -1;
-	}
-
-	if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
-	{
-		wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
-			   "EAPOL frame");
-		if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
-		    os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) !=
-		    0) {
-			dst = bssid;
-			wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
-				   " from the driver as the EAPOL destination",
-				   MAC2STR(dst));
-		} else {
-			dst = wpa_s->last_eapol_src;
-			wpa_printf(MSG_DEBUG, "Using the source address of the"
-				   " last received EAPOL frame " MACSTR " as "
-				   "the EAPOL destination",
-				   MAC2STR(dst));
-		}
-	} else {
-		/* BSSID was already set (from (Re)Assoc event, so use it as
-		 * the EAPOL destination. */
-		dst = wpa_s->bssid;
-	}
-
-	msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL);
-	if (msg == NULL)
-		return -1;
-
-	wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst));
-	wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
-	res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
-	os_free(msg);
-	return res;
-}
-
-
-/**
- * wpa_eapol_set_wep_key - set WEP key for the driver
- * @ctx: Pointer to wpa_supplicant data (wpa_s)
- * @unicast: 1 = individual unicast key, 0 = broadcast key
- * @keyidx: WEP key index (0..3)
- * @key: Pointer to key data
- * @keylen: Key length in bytes
- * Returns: 0 on success or < 0 on error.
- */
-static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
-				 const u8 *key, size_t keylen)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
-		int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
-			WPA_CIPHER_WEP104;
-		if (unicast)
-			wpa_s->pairwise_cipher = cipher;
-		else
-			wpa_s->group_cipher = cipher;
-	}
-	return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
-			       unicast ? wpa_s->bssid :
-			       (u8 *) "\xff\xff\xff\xff\xff\xff",
-			       keyidx, unicast, (u8 *) "", 0, key, keylen);
-}
-
-
-static void wpa_supplicant_aborted_cached(void *ctx)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	wpa_sm_aborted_cached(wpa_s->wpa);
-}
-
-#endif /* IEEE8021X_EAPOL */
-
-
-#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
-static void wpa_supplicant_set_config_blob(void *ctx,
-					   struct wpa_config_blob *blob)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	wpa_config_set_blob(wpa_s->conf, blob);
-}
-
-
-static const struct wpa_config_blob *
-wpa_supplicant_get_config_blob(void *ctx, const char *name)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	return wpa_config_get_blob(wpa_s->conf, name);
-}
-#endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */
-
-
-/* Configure default/group WEP key for static WEP */
-static int wpa_set_wep_key(void *ctx, int set_tx, int keyidx, const u8 *key,
-			   size_t keylen)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
-			       (u8 *) "\xff\xff\xff\xff\xff\xff",
-			       keyidx, set_tx, (u8 *) "", 0, key, keylen);
+/* Configure default/group WEP keys for static WEP */
+static int wpa_set_wep_keys(struct wpa_supplicant *wpa_s,
+			    struct wpa_ssid *ssid)
+{
+	int i, set = 0;
+
+	for (i = 0; i < NUM_WEP_KEYS; i++) {
+		if (ssid->wep_key_len[i] == 0)
+			continue;
+
+		set = 1;
+		wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
+				(u8 *) "\xff\xff\xff\xff\xff\xff",
+				i, i == ssid->wep_tx_keyidx, (u8 *) "", 0,
+				ssid->wep_key[i], ssid->wep_key_len[i]);
+	}
+
+	return set;
 }
 
 
@@ -358,164 +184,6 @@
 }
 
 
-#ifdef IEEE8021X_EAPOL
-static void wpa_supplicant_notify_eapol_done(void *ctx)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
-	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
-	    wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
-		wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
-	} else {
-		eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
-		wpa_supplicant_cancel_auth_timeout(wpa_s);
-		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-	}
-}
-#endif /* IEEE8021X_EAPOL */
-
-
-/**
- * wpa_blacklist_get - Get the blacklist entry for a BSSID
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID
- * Returns: Matching blacklist entry for the BSSID or %NULL if not found
- */
-struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
-					 const u8 *bssid)
-{
-	struct wpa_blacklist *e;
-
-	e = wpa_s->blacklist;
-	while (e) {
-		if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0)
-			return e;
-		e = e->next;
-	}
-
-	return NULL;
-}
-
-
-/**
- * wpa_blacklist_add - Add an BSSID to the blacklist
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID to be added to the blacklist
- * Returns: 0 on success, -1 on failure
- *
- * This function adds the specified BSSID to the blacklist or increases the
- * blacklist count if the BSSID was already listed. It should be called when
- * an association attempt fails either due to the selected BSS rejecting
- * association or due to timeout.
- *
- * This blacklist is used to force %wpa_supplicant to go through all available
- * BSSes before retrying to associate with an BSS that rejected or timed out
- * association. It does not prevent the listed BSS from being used; it only
- * changes the order in which they are tried.
- */
-int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
-	struct wpa_blacklist *e;
-
-	e = wpa_blacklist_get(wpa_s, bssid);
-	if (e) {
-		e->count++;
-		wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count "
-			   "incremented to %d",
-			   MAC2STR(bssid), e->count);
-		return 0;
-	}
-
-	e = os_zalloc(sizeof(*e));
-	if (e == NULL)
-		return -1;
-	os_memcpy(e->bssid, bssid, ETH_ALEN);
-	e->count = 1;
-	e->next = wpa_s->blacklist;
-	wpa_s->blacklist = e;
-	wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist",
-		   MAC2STR(bssid));
-
-	return 0;
-}
-
-
-static int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
-{
-	struct wpa_blacklist *e, *prev = NULL;
-
-	e = wpa_s->blacklist;
-	while (e) {
-		if (os_memcmp(e->bssid, bssid, ETH_ALEN) == 0) {
-			if (prev == NULL) {
-				wpa_s->blacklist = e->next;
-			} else {
-				prev->next = e->next;
-			}
-			wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
-				   "blacklist", MAC2STR(bssid));
-			os_free(e);
-			return 0;
-		}
-		prev = e;
-		e = e->next;
-	}
-	return -1;
-}
-
-
-/**
- * wpa_blacklist_clear - Clear the blacklist of all entries
- * @wpa_s: Pointer to wpa_supplicant data
- */
-void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
-{
-	struct wpa_blacklist *e, *prev;
-
-	e = wpa_s->blacklist;
-	wpa_s->blacklist = NULL;
-	while (e) {
-		prev = e;
-		e = e->next;
-		wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
-			   "blacklist (clear)", MAC2STR(prev->bssid));
-		os_free(prev);
-	}
-}
-
-
-/**
- * wpa_supplicant_req_scan - Schedule a scan for neighboring access points
- * @wpa_s: Pointer to wpa_supplicant data
- * @sec: Number of seconds after which to scan
- * @usec: Number of microseconds after which to scan
- *
- * This function is used to schedule a scan for neighboring access points after
- * the specified time.
- */
-void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec)
-{
-	wpa_msg(wpa_s, MSG_DEBUG, "Setting scan request: %d sec %d usec",
-		sec, usec);
-	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
-	eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
-}
-
-
-/**
- * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
- * @wpa_s: Pointer to wpa_supplicant data
- *
- * This function is used to cancel a scan request scheduled with
- * wpa_supplicant_req_scan().
- */
-void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
-{
-	wpa_msg(wpa_s, MSG_DEBUG, "Cancelling scan request");
-	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
-}
-
-
 static void wpa_supplicant_timeout(void *eloop_ctx, void *timeout_ctx)
 {
 	struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -523,7 +191,7 @@
 	if (os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
 		bssid = wpa_s->pending_bssid;
 	wpa_msg(wpa_s, MSG_INFO, "Authentication with " MACSTR " timed out.",
-		MAC2STR(wpa_s->bssid));
+		MAC2STR(bssid));
 	wpa_blacklist_add(wpa_s, bssid);
 	wpa_sm_notify_disassoc(wpa_s->wpa);
 	wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
@@ -833,17 +501,6 @@
 }
 
 
-/**
- * wpa_supplicant_get_state - Get the connection state
- * @wpa_s: Pointer to wpa_supplicant data
- * Returns: The current connection state (WPA_*)
- */
-wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
-{
-	return wpa_s->wpa_state;
-}
-
-
 static void wpa_supplicant_terminate(int sig, void *eloop_ctx,
 				     void *signal_ctx)
 {
@@ -907,6 +564,14 @@
 	 * TODO: should notify EAPOL SM about changes in opensc_engine_path,
 	 * pkcs11_engine_path, pkcs11_module_path.
 	 */
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK ||
+	    wpa_s->key_mgmt == WPA_KEY_MGMT_FT_PSK) {
+		/*
+		 * Clear forced success to clear EAP state for next
+		 * authentication.
+		 */
+		eapol_sm_notify_eap_success(wpa_s->eapol, FALSE);
+	}
 	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 	wpa_sm_set_config(wpa_s->wpa, NULL);
 	wpa_sm_set_fast_reauth(wpa_s->wpa, wpa_s->conf->fast_reauth);
@@ -934,140 +599,6 @@
 		if (wpa_supplicant_reload_configuration(wpa_s) < 0) {
 			eloop_terminate();
 		}
-	}
-}
-
-
-static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
-{
-	struct wpa_ssid *ssid;
-	union wpa_event_data data;
-
-	ssid = wpa_supplicant_get_ssid(wpa_s);
-	if (ssid == NULL)
-		return;
-
-	if (wpa_s->current_ssid == NULL)
-		wpa_s->current_ssid = ssid;
-	wpa_supplicant_initiate_eapol(wpa_s);
-	wpa_printf(MSG_DEBUG, "Already associated with a configured network - "
-		   "generating associated event");
-	os_memset(&data, 0, sizeof(data));
-	wpa_supplicant_event(wpa_s, EVENT_ASSOC, &data);
-}
-
-
-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;
-
-	if (wpa_s->disconnected)
-		return;
-
-	enabled = 0;
-	ssid = wpa_s->conf->ssid;
-	while (ssid) {
-		if (!ssid->disabled) {
-			enabled++;
-			break;
-		}
-		ssid = ssid->next;
-	}
-	if (!enabled && !wpa_s->scan_req) {
-		wpa_printf(MSG_DEBUG, "No enabled networks - do not scan");
-		wpa_supplicant_set_state(wpa_s, WPA_INACTIVE);
-		return;
-	}
-	scan_req = wpa_s->scan_req;
-	wpa_s->scan_req = 0;
-
-	if (wpa_s->conf->ap_scan != 0 &&
-	    wpa_s->driver && os_strcmp(wpa_s->driver->name, "wired") == 0) {
-		wpa_printf(MSG_DEBUG, "Using wired driver - overriding "
-			   "ap_scan configuration");
-		wpa_s->conf->ap_scan = 0;
-	}
-
-	if (wpa_s->conf->ap_scan == 0) {
-		wpa_supplicant_gen_assoc_event(wpa_s);
-		return;
-	}
-
-	if (wpa_s->wpa_state == WPA_DISCONNECTED ||
-	    wpa_s->wpa_state == WPA_INACTIVE)
-		wpa_supplicant_set_state(wpa_s, WPA_SCANNING);
-
-	ssid = wpa_s->conf->ssid;
-	if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
-		while (ssid) {
-			if (ssid == wpa_s->prev_scan_ssid) {
-				ssid = ssid->next;
-				break;
-			}
-			ssid = ssid->next;
-		}
-	}
-	while (ssid) {
-		if (!ssid->disabled &&
-		    (ssid->scan_ssid || wpa_s->conf->ap_scan == 2))
-			break;
-		ssid = ssid->next;
-	}
-
-	if (scan_req != 2 && wpa_s->conf->ap_scan == 2) {
-		/*
-		 * ap_scan=2 mode - try to associate with each SSID instead of
-		 * scanning for each scan_ssid=1 network.
-		 */
-		if (ssid == NULL) {
-			wpa_printf(MSG_DEBUG, "wpa_supplicant_scan: Reached "
-				   "end of scan list - go back to beginning");
-			wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
-			wpa_supplicant_req_scan(wpa_s, 0, 0);
-			return;
-		}
-		if (ssid->next) {
-			/* Continue from the next SSID on the next attempt. */
-			wpa_s->prev_scan_ssid = ssid;
-		} else {
-			/* Start from the beginning of the SSID list. */
-			wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
-		}
-		wpa_supplicant_associate(wpa_s, NULL, ssid);
-		return;
-	}
-
-	wpa_printf(MSG_DEBUG, "Starting AP scan (%s SSID)",
-		   ssid ? "specific": "broadcast");
-	if (ssid) {
-		wpa_hexdump_ascii(MSG_DEBUG, "Scan SSID",
-				  ssid->ssid, ssid->ssid_len);
-		wpa_s->prev_scan_ssid = ssid;
-	} else
-		wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
-
-	if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
-	    !wpa_s->use_client_mlme) {
-		wpa_s->scan_res_tried++;
-		wpa_printf(MSG_DEBUG, "Trying to get current scan results "
-			   "first without requesting a new scan to speed up "
-			   "initial association");
-		wpa_supplicant_event(wpa_s, EVENT_SCAN_RESULTS, NULL);
-		return;
-	}
-
-	if (wpa_s->use_client_mlme) {
-		ret = ieee80211_sta_req_scan(wpa_s, ssid ? ssid->ssid : NULL,
-					     ssid ? ssid->ssid_len : 0);
-	} else {
-		ret = wpa_drv_scan(wpa_s, ssid ? ssid->ssid : NULL,
-				   ssid ? ssid->ssid_len : 0);
-	}
-	if (ret) {
-		wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
-		wpa_supplicant_req_scan(wpa_s, 10, 0);
 	}
 }
 
@@ -1451,15 +982,9 @@
 	    wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
 		if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE)
 			use_crypt = 0;
-		for (i = 0; i < NUM_WEP_KEYS; i++) {
-			if (ssid->wep_key_len[i]) {
-				use_crypt = 1;
-				wep_keys_set = 1;
-				wpa_set_wep_key(wpa_s,
-						i == ssid->wep_tx_keyidx,
-						i, ssid->wep_key[i],
-						ssid->wep_key_len[i]);
-			}
+		if (wpa_set_wep_keys(wpa_s, ssid)) {
+			use_crypt = 1;
+			wep_keys_set = 1;
 		}
 	}
 
@@ -1569,15 +1094,7 @@
 	if (wep_keys_set && wpa_drv_get_capa(wpa_s, &capa) == 0 &&
 	    capa.flags & WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC) {
 		/* Set static WEP keys again */
-		int j;
-		for (j = 0; j < NUM_WEP_KEYS; j++) {
-			if (ssid->wep_key_len[j]) {
-				wpa_set_wep_key(wpa_s,
-						j == ssid->wep_tx_keyidx,
-						j, ssid->wep_key[j],
-						ssid->wep_key_len[j]);
-			}
-		}
+		wpa_set_wep_keys(wpa_s, ssid);
 	}
 
 	if (wpa_s->current_ssid && wpa_s->current_ssid != ssid) {
@@ -1704,63 +1221,6 @@
 }
 
 
-#ifndef CONFIG_NO_WPA
-static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
-{
-	int i, ret = 0;
-	struct wpa_scan_result *results, *curr = NULL;
-
-	results = wpa_s->scan_results;
-	if (results == NULL) {
-		return -1;
-	}
-
-	for (i = 0; i < wpa_s->num_scan_results; i++) {
-		struct wpa_ssid *ssid = wpa_s->current_ssid;
-		if (os_memcmp(results[i].bssid, wpa_s->bssid, ETH_ALEN) != 0)
-			continue;
-		if (ssid == NULL ||
-		    ((results[i].ssid_len == ssid->ssid_len &&
-		      os_memcmp(results[i].ssid, ssid->ssid, ssid->ssid_len)
-		      == 0) ||
-		     ssid->ssid_len == 0)) {
-			curr = &results[i];
-			break;
-		}
-	}
-
-	if (curr) {
-		if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, curr->wpa_ie,
-					 curr->wpa_ie_len) ||
-		    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, curr->rsn_ie,
-					 curr->rsn_ie_len))
-			ret = -1;
-	} else {
-		ret = -1;
-	}
-
-	return ret;
-}
-
-
-static int wpa_supplicant_get_beacon_ie(void *ctx)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	if (wpa_get_beacon_ie(wpa_s) == 0) {
-		return 0;
-	}
-
-	/* No WPA/RSN IE found in the cached scan results. Try to get updated
-	 * scan results from the driver. */
-	if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
-		return -1;
-	}
-
-	return wpa_get_beacon_ie(wpa_s);
-}
-#endif /* CONFIG_NO_WPA */
-
-
 /**
  * wpa_supplicant_get_ssid - Get a pointer to the current network structure
  * @wpa_s: Pointer to wpa_supplicant data
@@ -1814,139 +1274,6 @@
 
 	return NULL;
 }
-
-
-#ifndef CONFIG_NO_WPA
-static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
-			     const void *data, u16 data_len,
-			     size_t *msg_len, void **data_pos)
-{
-	return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
-}
-
-
-static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
-			   const u8 *buf, size_t len)
-{
-	return wpa_ether_send(wpa_s, dest, proto, buf, len);
-}
-
-
-static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
-{
-	wpa_supplicant_req_scan(wpa_s, sec, usec);
-}
-
-
-static void _wpa_supplicant_cancel_scan(void *wpa_s)
-{
-	wpa_supplicant_cancel_scan(wpa_s);
-}
-
-
-static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
-{
-	wpa_supplicant_cancel_auth_timeout(wpa_s);
-}
-
-
-static void _wpa_supplicant_set_state(void *wpa_s, wpa_states state)
-{
-	wpa_supplicant_set_state(wpa_s, state);
-}
-
-
-static wpa_states _wpa_supplicant_get_state(void *wpa_s)
-{
-	return wpa_supplicant_get_state(wpa_s);
-}
-
-
-static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
-{
-	wpa_supplicant_disassociate(wpa_s, reason_code);
-}
-
-
-static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
-{
-	wpa_supplicant_deauthenticate(wpa_s, reason_code);
-}
-
-
-static struct wpa_ssid * _wpa_supplicant_get_ssid(void *wpa_s)
-{
-	return wpa_supplicant_get_ssid(wpa_s);
-}
-
-
-static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	if (wpa_s->use_client_mlme) {
-		os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
-		return 0;
-	}
-	return wpa_drv_get_bssid(wpa_s, bssid);
-}
-
-
-static int wpa_supplicant_set_key(void *wpa_s, wpa_alg alg,
-				  const u8 *addr, int key_idx, int set_tx,
-				  const u8 *seq, size_t seq_len,
-				  const u8 *key, size_t key_len)
-{
-	return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
-			       key, key_len);
-}
-
-
-static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
-					     int protection_type,
-					     int key_type)
-{
-	return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
-					  key_type);
-}
-
-
-static int wpa_supplicant_add_pmkid(void *wpa_s,
-				    const u8 *bssid, const u8 *pmkid)
-{
-	return wpa_drv_add_pmkid(wpa_s, bssid, pmkid);
-}
-
-
-static int wpa_supplicant_remove_pmkid(void *wpa_s,
-				       const u8 *bssid, const u8 *pmkid)
-{
-	return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid);
-}
-
-
-#ifdef CONFIG_IEEE80211R
-static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
-					const u8 *ies, size_t ies_len)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	if (wpa_s->use_client_mlme)
-		return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len);
-	return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
-}
-
-
-static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
-					 const u8 *target_ap,
-					 const u8 *ies, size_t ies_len)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	if (wpa_s->use_client_mlme)
-		return ieee80211_sta_send_ft_action(wpa_s, action, target_ap,
-						    ies, ies_len);
-	return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len);
-}
-#endif /* CONFIG_IEEE80211R */
-#endif /* CONFIG_NO_WPA */
 
 
 static int wpa_supplicant_set_driver(struct wpa_supplicant *wpa_s,
@@ -2238,141 +1565,6 @@
 		os_strlcpy(wpa_s->bridge_ifname, iface->bridge_ifname,
 			   sizeof(wpa_s->bridge_ifname));
 	}
-
-	return 0;
-}
-
-
-#ifdef IEEE8021X_EAPOL
-static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success,
-				    void *ctx)
-{
-	struct wpa_supplicant *wpa_s = ctx;
-	int res, pmk_len;
-	u8 pmk[PMK_LEN];
-
-	wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully",
-		   success ? "" : "un");
-
-	if (!success || !wpa_s->driver_4way_handshake)
-		return;
-
-	if (wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
-	    wpa_s->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
-		   "handshake");
-
-	pmk_len = PMK_LEN;
-	res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
-	if (res) {
-		/*
-		 * EAP-LEAP is an exception from other EAP methods: it
-		 * uses only 16-byte PMK.
-		 */
-		res = eapol_sm_get_key(eapol, pmk, 16);
-		pmk_len = 16;
-	}
-
-	if (res) {
-		wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
-			   "machines");
-		return;
-	}
-
-	if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
-			    pmk_len)) {
-		wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
-	}
-
-	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
-	wpa_supplicant_cancel_auth_timeout(wpa_s);
-	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-
-}
-#endif /* IEEE8021X_EAPOL */
-
-
-static int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
-{
-#ifdef IEEE8021X_EAPOL
-	struct eapol_ctx *ctx;
-	ctx = os_zalloc(sizeof(*ctx));
-	if (ctx == NULL) {
-		wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
-		return -1;
-	}
-
-	ctx->ctx = wpa_s;
-	ctx->msg_ctx = wpa_s;
-	ctx->eapol_send_ctx = wpa_s;
-	ctx->preauth = 0;
-	ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
-	ctx->eapol_send = wpa_supplicant_eapol_send;
-	ctx->set_wep_key = wpa_eapol_set_wep_key;
-	ctx->set_config_blob = wpa_supplicant_set_config_blob;
-	ctx->get_config_blob = wpa_supplicant_get_config_blob;
-	ctx->aborted_cached = wpa_supplicant_aborted_cached;
-	ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
-	ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
-	ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
-	ctx->cb = wpa_supplicant_eapol_cb;
-	ctx->cb_ctx = wpa_s;
-	wpa_s->eapol = eapol_sm_init(ctx);
-	if (wpa_s->eapol == NULL) {
-		os_free(ctx);
-		wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
-			   "machines.");
-		return -1;
-	}
-#endif /* IEEE8021X_EAPOL */
-
-	return 0;
-}
-
-
-static int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
-{
-#ifndef CONFIG_NO_WPA
-	struct wpa_sm_ctx *ctx;
-	ctx = os_zalloc(sizeof(*ctx));
-	if (ctx == NULL) {
-		wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
-		return -1;
-	}
-
-	ctx->ctx = wpa_s;
-	ctx->set_state = _wpa_supplicant_set_state;
-	ctx->get_state = _wpa_supplicant_get_state;
-	ctx->req_scan = _wpa_supplicant_req_scan;
-	ctx->cancel_scan = _wpa_supplicant_cancel_scan;
-	ctx->deauthenticate = _wpa_supplicant_deauthenticate;
-	ctx->disassociate = _wpa_supplicant_disassociate;
-	ctx->set_key = wpa_supplicant_set_key;
-	ctx->get_ssid = _wpa_supplicant_get_ssid;
-	ctx->get_bssid = wpa_supplicant_get_bssid;
-	ctx->ether_send = _wpa_ether_send;
-	ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
-	ctx->alloc_eapol = _wpa_alloc_eapol;
-	ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
-	ctx->add_pmkid = wpa_supplicant_add_pmkid;
-	ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
-	ctx->set_config_blob = wpa_supplicant_set_config_blob;
-	ctx->get_config_blob = wpa_supplicant_get_config_blob;
-	ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
-#ifdef CONFIG_IEEE80211R
-	ctx->update_ft_ies = wpa_supplicant_update_ft_ies;
-	ctx->send_ft_action = wpa_supplicant_send_ft_action;
-#endif /* CONFIG_IEEE80211R */
-
-	wpa_s->wpa = wpa_sm_init(ctx);
-	if (wpa_s->wpa == NULL) {
-		wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
-			   "machine");
-		return -1;
-	}
-#endif /* CONFIG_NO_WPA */
 
 	return 0;
 }

Modified: wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h?rev=909&op=diff
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h (original)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpa_supplicant_i.h Sun Dec  9 08:34:57 2007
@@ -16,13 +16,6 @@
 #define WPA_SUPPLICANT_I_H
 
 #include "drivers/driver.h"
-
-struct wpa_blacklist {
-	struct wpa_blacklist *next;
-	u8 bssid[ETH_ALEN];
-	int count;
-};
-
 
 struct wpa_scan_result;
 struct wpa_sm;
@@ -354,17 +347,11 @@
 
 
 /* wpa_supplicant.c */
-void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
-
 int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s);
 
 const char * wpa_supplicant_state_txt(int state);
 int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s,
 			       int wait_for_interface);
-struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s,
-					 const u8 *bssid);
-int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid);
-void wpa_blacklist_clear(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
 			      struct wpa_scan_result *bss,
 			      struct wpa_ssid *ssid,
@@ -386,7 +373,6 @@
 				   int reason_code);
 void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
 				 int reason_code);
-void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
 
 void wpa_show_license(void);
 
@@ -403,6 +389,10 @@
 int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
 			      struct wpa_ssid *ssid);
 
+/* scan.c */
+void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
+void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
+
 /* events.c */
 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);
 

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.c
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.c?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.c (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.c Sun Dec  9 08:34:57 2007
@@ -1,0 +1,567 @@
+/*
+ * WPA Supplicant - Glue code to setup EAPOL and RSN modules
+ * Copyright (c) 2003-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "eapol_supp/eapol_supp_sm.h"
+#include "wpa.h"
+#include "eloop.h"
+#include "config.h"
+#include "l2_packet/l2_packet.h"
+#include "wpa_common.h"
+#include "wpa_supplicant_i.h"
+#include "pmksa_cache.h"
+#include "mlme.h"
+#include "wpas_glue.h"
+
+
+#ifndef CONFIG_NO_CONFIG_BLOBS
+#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
+static void wpa_supplicant_set_config_blob(void *ctx,
+					   struct wpa_config_blob *blob)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	wpa_config_set_blob(wpa_s->conf, blob);
+}
+
+
+static const struct wpa_config_blob *
+wpa_supplicant_get_config_blob(void *ctx, const char *name)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	return wpa_config_get_blob(wpa_s->conf, name);
+}
+#endif /* defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) */
+#endif /* CONFIG_NO_CONFIG_BLOBS */
+
+
+#if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA)
+static u8 * wpa_alloc_eapol(const struct wpa_supplicant *wpa_s, u8 type,
+			    const void *data, u16 data_len,
+			    size_t *msg_len, void **data_pos)
+{
+	struct ieee802_1x_hdr *hdr;
+
+	*msg_len = sizeof(*hdr) + data_len;
+	hdr = os_malloc(*msg_len);
+	if (hdr == NULL)
+		return NULL;
+
+	hdr->version = wpa_s->conf->eapol_version;
+	hdr->type = type;
+	hdr->length = host_to_be16(data_len);
+
+	if (data)
+		os_memcpy(hdr + 1, data, data_len);
+	else
+		os_memset(hdr + 1, 0, data_len);
+
+	if (data_pos)
+		*data_pos = hdr + 1;
+
+	return (u8 *) hdr;
+}
+
+
+/**
+ * wpa_ether_send - Send Ethernet frame
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @dest: Destination MAC address
+ * @proto: Ethertype in host byte order
+ * @buf: Frame payload starting from IEEE 802.1X header
+ * @len: Frame payload length
+ * Returns: >=0 on success, <0 on failure
+ */
+static int wpa_ether_send(struct wpa_supplicant *wpa_s, const u8 *dest,
+			  u16 proto, const u8 *buf, size_t len)
+{
+	if (wpa_s->l2) {
+		return l2_packet_send(wpa_s->l2, dest, proto, buf, len);
+	}
+
+	return wpa_drv_send_eapol(wpa_s, dest, proto, buf, len);
+}
+#endif /* IEEE8021X_EAPOL || !CONFIG_NO_WPA */
+
+
+#ifdef IEEE8021X_EAPOL
+
+/**
+ * wpa_supplicant_eapol_send - Send IEEE 802.1X EAPOL packet to Authenticator
+ * @ctx: Pointer to wpa_supplicant data (wpa_s)
+ * @type: IEEE 802.1X packet type (IEEE802_1X_TYPE_*)
+ * @buf: EAPOL payload (after IEEE 802.1X header)
+ * @len: EAPOL payload length
+ * Returns: >=0 on success, <0 on failure
+ *
+ * This function adds Ethernet and IEEE 802.1X header and sends the EAPOL frame
+ * to the current Authenticator.
+ */
+static int wpa_supplicant_eapol_send(void *ctx, int type, const u8 *buf,
+				     size_t len)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	u8 *msg, *dst, bssid[ETH_ALEN];
+	size_t msglen;
+	int res;
+
+	/* TODO: could add l2_packet_sendmsg that allows fragments to avoid
+	 * extra copy here */
+
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK ||
+	    wpa_s->key_mgmt == WPA_KEY_MGMT_FT_PSK ||
+	    wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
+		/* Current SSID is not using IEEE 802.1X/EAP, so drop possible
+		 * EAPOL frames (mainly, EAPOL-Start) from EAPOL state
+		 * machines. */
+		wpa_printf(MSG_DEBUG, "WPA: drop TX EAPOL in non-IEEE 802.1X "
+			   "mode (type=%d len=%lu)", type,
+			   (unsigned long) len);
+		return -1;
+	}
+
+	if (pmksa_cache_get_current(wpa_s->wpa) &&
+	    type == IEEE802_1X_TYPE_EAPOL_START) {
+		/* Trying to use PMKSA caching - do not send EAPOL-Start frames
+		 * since they will trigger full EAPOL authentication. */
+		wpa_printf(MSG_DEBUG, "RSN: PMKSA caching - do not send "
+			   "EAPOL-Start");
+		return -1;
+	}
+
+	if (os_memcmp(wpa_s->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0)
+	{
+		wpa_printf(MSG_DEBUG, "BSSID not set when trying to send an "
+			   "EAPOL frame");
+		if (wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
+		    os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) !=
+		    0) {
+			dst = bssid;
+			wpa_printf(MSG_DEBUG, "Using current BSSID " MACSTR
+				   " from the driver as the EAPOL destination",
+				   MAC2STR(dst));
+		} else {
+			dst = wpa_s->last_eapol_src;
+			wpa_printf(MSG_DEBUG, "Using the source address of the"
+				   " last received EAPOL frame " MACSTR " as "
+				   "the EAPOL destination",
+				   MAC2STR(dst));
+		}
+	} else {
+		/* BSSID was already set (from (Re)Assoc event, so use it as
+		 * the EAPOL destination. */
+		dst = wpa_s->bssid;
+	}
+
+	msg = wpa_alloc_eapol(wpa_s, type, buf, len, &msglen, NULL);
+	if (msg == NULL)
+		return -1;
+
+	wpa_printf(MSG_DEBUG, "TX EAPOL: dst=" MACSTR, MAC2STR(dst));
+	wpa_hexdump(MSG_MSGDUMP, "TX EAPOL", msg, msglen);
+	res = wpa_ether_send(wpa_s, dst, ETH_P_EAPOL, msg, msglen);
+	os_free(msg);
+	return res;
+}
+
+
+/**
+ * wpa_eapol_set_wep_key - set WEP key for the driver
+ * @ctx: Pointer to wpa_supplicant data (wpa_s)
+ * @unicast: 1 = individual unicast key, 0 = broadcast key
+ * @keyidx: WEP key index (0..3)
+ * @key: Pointer to key data
+ * @keylen: Key length in bytes
+ * Returns: 0 on success or < 0 on error.
+ */
+static int wpa_eapol_set_wep_key(void *ctx, int unicast, int keyidx,
+				 const u8 *key, size_t keylen)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
+		int cipher = (keylen == 5) ? WPA_CIPHER_WEP40 :
+			WPA_CIPHER_WEP104;
+		if (unicast)
+			wpa_s->pairwise_cipher = cipher;
+		else
+			wpa_s->group_cipher = cipher;
+	}
+	return wpa_drv_set_key(wpa_s, WPA_ALG_WEP,
+			       unicast ? wpa_s->bssid :
+			       (u8 *) "\xff\xff\xff\xff\xff\xff",
+			       keyidx, unicast, (u8 *) "", 0, key, keylen);
+}
+
+
+static void wpa_supplicant_aborted_cached(void *ctx)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	wpa_sm_aborted_cached(wpa_s->wpa);
+}
+
+
+static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success,
+				    void *ctx)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	int res, pmk_len;
+	u8 pmk[PMK_LEN];
+
+	wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully",
+		   success ? "" : "un");
+
+	if (!success || !wpa_s->driver_4way_handshake)
+		return;
+
+	if (wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
+	    wpa_s->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
+		   "handshake");
+
+	pmk_len = PMK_LEN;
+	res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
+	if (res) {
+		/*
+		 * EAP-LEAP is an exception from other EAP methods: it
+		 * uses only 16-byte PMK.
+		 */
+		res = eapol_sm_get_key(eapol, pmk, 16);
+		pmk_len = 16;
+	}
+
+	if (res) {
+		wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
+			   "machines");
+		return;
+	}
+
+	if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
+			    pmk_len)) {
+		wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
+	}
+
+	wpa_supplicant_cancel_scan(wpa_s);
+	wpa_supplicant_cancel_auth_timeout(wpa_s);
+	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+
+}
+
+
+static void wpa_supplicant_notify_eapol_done(void *ctx)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	wpa_msg(wpa_s, MSG_DEBUG, "WPA: EAPOL processing complete");
+	if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
+	    wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
+		wpa_supplicant_set_state(wpa_s, WPA_4WAY_HANDSHAKE);
+	} else {
+		wpa_supplicant_cancel_scan(wpa_s);
+		wpa_supplicant_cancel_auth_timeout(wpa_s);
+		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+	}
+}
+
+#endif /* IEEE8021X_EAPOL */
+
+
+#ifndef CONFIG_NO_WPA
+
+static int wpa_get_beacon_ie(struct wpa_supplicant *wpa_s)
+{
+	int i, ret = 0;
+	struct wpa_scan_result *results, *curr = NULL;
+
+	results = wpa_s->scan_results;
+	if (results == NULL) {
+		return -1;
+	}
+
+	for (i = 0; i < wpa_s->num_scan_results; i++) {
+		struct wpa_ssid *ssid = wpa_s->current_ssid;
+		if (os_memcmp(results[i].bssid, wpa_s->bssid, ETH_ALEN) != 0)
+			continue;
+		if (ssid == NULL ||
+		    ((results[i].ssid_len == ssid->ssid_len &&
+		      os_memcmp(results[i].ssid, ssid->ssid, ssid->ssid_len)
+		      == 0) ||
+		     ssid->ssid_len == 0)) {
+			curr = &results[i];
+			break;
+		}
+	}
+
+	if (curr) {
+		if (wpa_sm_set_ap_wpa_ie(wpa_s->wpa, curr->wpa_ie,
+					 curr->wpa_ie_len) ||
+		    wpa_sm_set_ap_rsn_ie(wpa_s->wpa, curr->rsn_ie,
+					 curr->rsn_ie_len))
+			ret = -1;
+	} else {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+
+static int wpa_supplicant_get_beacon_ie(void *ctx)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	if (wpa_get_beacon_ie(wpa_s) == 0) {
+		return 0;
+	}
+
+	/* No WPA/RSN IE found in the cached scan results. Try to get updated
+	 * scan results from the driver. */
+	if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
+		return -1;
+	}
+
+	return wpa_get_beacon_ie(wpa_s);
+}
+
+
+static u8 * _wpa_alloc_eapol(void *wpa_s, u8 type,
+			     const void *data, u16 data_len,
+			     size_t *msg_len, void **data_pos)
+{
+	return wpa_alloc_eapol(wpa_s, type, data, data_len, msg_len, data_pos);
+}
+
+
+static int _wpa_ether_send(void *wpa_s, const u8 *dest, u16 proto,
+			   const u8 *buf, size_t len)
+{
+	return wpa_ether_send(wpa_s, dest, proto, buf, len);
+}
+
+
+static void _wpa_supplicant_req_scan(void *wpa_s, int sec, int usec)
+{
+	wpa_supplicant_req_scan(wpa_s, sec, usec);
+}
+
+
+static void _wpa_supplicant_cancel_scan(void *wpa_s)
+{
+	wpa_supplicant_cancel_scan(wpa_s);
+}
+
+
+static void _wpa_supplicant_cancel_auth_timeout(void *wpa_s)
+{
+	wpa_supplicant_cancel_auth_timeout(wpa_s);
+}
+
+
+static void _wpa_supplicant_set_state(void *wpa_s, wpa_states state)
+{
+	wpa_supplicant_set_state(wpa_s, state);
+}
+
+
+/**
+ * wpa_supplicant_get_state - Get the connection state
+ * @wpa_s: Pointer to wpa_supplicant data
+ * Returns: The current connection state (WPA_*)
+ */
+static wpa_states wpa_supplicant_get_state(struct wpa_supplicant *wpa_s)
+{
+	return wpa_s->wpa_state;
+}
+
+
+static wpa_states _wpa_supplicant_get_state(void *wpa_s)
+{
+	return wpa_supplicant_get_state(wpa_s);
+}
+
+
+static void _wpa_supplicant_disassociate(void *wpa_s, int reason_code)
+{
+	wpa_supplicant_disassociate(wpa_s, reason_code);
+}
+
+
+static void _wpa_supplicant_deauthenticate(void *wpa_s, int reason_code)
+{
+	wpa_supplicant_deauthenticate(wpa_s, reason_code);
+}
+
+
+static struct wpa_ssid * _wpa_supplicant_get_ssid(void *wpa_s)
+{
+	return wpa_supplicant_get_ssid(wpa_s);
+}
+
+
+static int wpa_supplicant_get_bssid(void *ctx, u8 *bssid)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	if (wpa_s->use_client_mlme) {
+		os_memcpy(bssid, wpa_s->bssid, ETH_ALEN);
+		return 0;
+	}
+	return wpa_drv_get_bssid(wpa_s, bssid);
+}
+
+
+static int wpa_supplicant_set_key(void *wpa_s, wpa_alg alg,
+				  const u8 *addr, int key_idx, int set_tx,
+				  const u8 *seq, size_t seq_len,
+				  const u8 *key, size_t key_len)
+{
+	return wpa_drv_set_key(wpa_s, alg, addr, key_idx, set_tx, seq, seq_len,
+			       key, key_len);
+}
+
+
+static int wpa_supplicant_mlme_setprotection(void *wpa_s, const u8 *addr,
+					     int protection_type,
+					     int key_type)
+{
+	return wpa_drv_mlme_setprotection(wpa_s, addr, protection_type,
+					  key_type);
+}
+
+
+static int wpa_supplicant_add_pmkid(void *wpa_s,
+				    const u8 *bssid, const u8 *pmkid)
+{
+	return wpa_drv_add_pmkid(wpa_s, bssid, pmkid);
+}
+
+
+static int wpa_supplicant_remove_pmkid(void *wpa_s,
+				       const u8 *bssid, const u8 *pmkid)
+{
+	return wpa_drv_remove_pmkid(wpa_s, bssid, pmkid);
+}
+
+
+#ifdef CONFIG_IEEE80211R
+static int wpa_supplicant_update_ft_ies(void *ctx, const u8 *md,
+					const u8 *ies, size_t ies_len)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	if (wpa_s->use_client_mlme)
+		return ieee80211_sta_update_ft_ies(wpa_s, md, ies, ies_len);
+	return wpa_drv_update_ft_ies(wpa_s, md, ies, ies_len);
+}
+
+
+static int wpa_supplicant_send_ft_action(void *ctx, u8 action,
+					 const u8 *target_ap,
+					 const u8 *ies, size_t ies_len)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+	if (wpa_s->use_client_mlme)
+		return ieee80211_sta_send_ft_action(wpa_s, action, target_ap,
+						    ies, ies_len);
+	return wpa_drv_send_ft_action(wpa_s, action, target_ap, ies, ies_len);
+}
+#endif /* CONFIG_IEEE80211R */
+
+#endif /* CONFIG_NO_WPA */
+
+
+int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
+{
+#ifdef IEEE8021X_EAPOL
+	struct eapol_ctx *ctx;
+	ctx = os_zalloc(sizeof(*ctx));
+	if (ctx == NULL) {
+		wpa_printf(MSG_ERROR, "Failed to allocate EAPOL context.");
+		return -1;
+	}
+
+	ctx->ctx = wpa_s;
+	ctx->msg_ctx = wpa_s;
+	ctx->eapol_send_ctx = wpa_s;
+	ctx->preauth = 0;
+	ctx->eapol_done_cb = wpa_supplicant_notify_eapol_done;
+	ctx->eapol_send = wpa_supplicant_eapol_send;
+	ctx->set_wep_key = wpa_eapol_set_wep_key;
+	ctx->set_config_blob = wpa_supplicant_set_config_blob;
+	ctx->get_config_blob = wpa_supplicant_get_config_blob;
+	ctx->aborted_cached = wpa_supplicant_aborted_cached;
+#ifdef EAP_TLS_OPENSSL
+	ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
+	ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
+	ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
+#endif /* EAP_TLS_OPENSSL */
+	ctx->cb = wpa_supplicant_eapol_cb;
+	ctx->cb_ctx = wpa_s;
+	wpa_s->eapol = eapol_sm_init(ctx);
+	if (wpa_s->eapol == NULL) {
+		os_free(ctx);
+		wpa_printf(MSG_ERROR, "Failed to initialize EAPOL state "
+			   "machines.");
+		return -1;
+	}
+#endif /* IEEE8021X_EAPOL */
+
+	return 0;
+}
+
+
+int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
+{
+#ifndef CONFIG_NO_WPA
+	struct wpa_sm_ctx *ctx;
+	ctx = os_zalloc(sizeof(*ctx));
+	if (ctx == NULL) {
+		wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
+		return -1;
+	}
+
+	ctx->ctx = wpa_s;
+	ctx->set_state = _wpa_supplicant_set_state;
+	ctx->get_state = _wpa_supplicant_get_state;
+	ctx->req_scan = _wpa_supplicant_req_scan;
+	ctx->cancel_scan = _wpa_supplicant_cancel_scan;
+	ctx->deauthenticate = _wpa_supplicant_deauthenticate;
+	ctx->disassociate = _wpa_supplicant_disassociate;
+	ctx->set_key = wpa_supplicant_set_key;
+	ctx->get_ssid = _wpa_supplicant_get_ssid;
+	ctx->get_bssid = wpa_supplicant_get_bssid;
+	ctx->ether_send = _wpa_ether_send;
+	ctx->get_beacon_ie = wpa_supplicant_get_beacon_ie;
+	ctx->alloc_eapol = _wpa_alloc_eapol;
+	ctx->cancel_auth_timeout = _wpa_supplicant_cancel_auth_timeout;
+	ctx->add_pmkid = wpa_supplicant_add_pmkid;
+	ctx->remove_pmkid = wpa_supplicant_remove_pmkid;
+#ifndef CONFIG_NO_CONFIG_BLOBS
+	ctx->set_config_blob = wpa_supplicant_set_config_blob;
+	ctx->get_config_blob = wpa_supplicant_get_config_blob;
+#endif /* CONFIG_NO_CONFIG_BLOBS */
+	ctx->mlme_setprotection = wpa_supplicant_mlme_setprotection;
+#ifdef CONFIG_IEEE80211R
+	ctx->update_ft_ies = wpa_supplicant_update_ft_ies;
+	ctx->send_ft_action = wpa_supplicant_send_ft_action;
+#endif /* CONFIG_IEEE80211R */
+
+	wpa_s->wpa = wpa_sm_init(ctx);
+	if (wpa_s->wpa == NULL) {
+		wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
+			   "machine");
+		return -1;
+	}
+#endif /* CONFIG_NO_WPA */
+
+	return 0;
+}

Added: wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.h
URL: http://svn.debian.org/wsvn/wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.h?rev=909&op=file
==============================================================================
--- wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.h (added)
+++ wpasupplicant/branches/upstream/current/wpa_supplicant/wpas_glue.h Sun Dec  9 08:34:57 2007
@@ -1,0 +1,21 @@
+/*
+ * WPA Supplicant - Glue code to setup EAPOL and RSN modules
+ * Copyright (c) 2003-2007, 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
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ *
+ * See README and COPYING for more details.
+ */
+
+#ifndef WPAS_GLUE_H
+#define WPAS_GLUE_H
+
+int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s);
+int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
+
+#endif /* WPAS_GLUE_H */




More information about the Pkg-wpa-devel mailing list