[pkg-wpa-devel] r923 - in /wpasupplicant/trunk: debian/ src/ src/crypto/ src/drivers/ src/eap_common/ src/eap_peer/ src/eap_server/ src/eapol_supp/ src/radius/ src/utils/ wpa_supplicant/ wpa_supplicant/doc/ 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
Tue Dec 25 15:23:24 UTC 2007


Author: kelmo-guest
Date: Tue Dec 25 15:23:24 2007
New Revision: 923

URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=923
Log:
import new upstream git snapshot

Added:
    wpasupplicant/trunk/src/eap_common/chap.c
      - copied unchanged from r922, wpasupplicant/branches/upstream/current/src/eap_common/chap.c
    wpasupplicant/trunk/src/eap_common/chap.h
      - copied unchanged from r922, wpasupplicant/branches/upstream/current/src/eap_common/chap.h
    wpasupplicant/trunk/src/utils/wpabuf.c
      - copied unchanged from r922, wpasupplicant/branches/upstream/current/src/utils/wpabuf.c
    wpasupplicant/trunk/src/utils/wpabuf.h
      - copied unchanged from r922, wpasupplicant/branches/upstream/current/src/utils/wpabuf.h
Modified:
    wpasupplicant/trunk/debian/changelog
    wpasupplicant/trunk/src/Makefile
    wpasupplicant/trunk/src/crypto/crypto_openssl.c
    wpasupplicant/trunk/src/drivers/driver_broadcom.c
    wpasupplicant/trunk/src/drivers/driver_hostap.c
    wpasupplicant/trunk/src/drivers/driver_madwifi.c
    wpasupplicant/trunk/src/drivers/driver_ndis.c
    wpasupplicant/trunk/src/drivers/driver_ralink.c
    wpasupplicant/trunk/src/drivers/driver_test.c
    wpasupplicant/trunk/src/drivers/driver_wext.c
    wpasupplicant/trunk/src/eap_common/eap_common.c
    wpasupplicant/trunk/src/eap_common/eap_common.h
    wpasupplicant/trunk/src/eap_common/eap_pax_common.h
    wpasupplicant/trunk/src/eap_common/eap_psk_common.h
    wpasupplicant/trunk/src/eap_common/eap_sake_common.c
    wpasupplicant/trunk/src/eap_common/eap_sake_common.h
    wpasupplicant/trunk/src/eap_common/eap_sim_common.c
    wpasupplicant/trunk/src/eap_common/eap_sim_common.h
    wpasupplicant/trunk/src/eap_common/eap_wsc_common.c
    wpasupplicant/trunk/src/eap_common/eap_wsc_common.h
    wpasupplicant/trunk/src/eap_peer/eap.c
    wpasupplicant/trunk/src/eap_peer/eap.h
    wpasupplicant/trunk/src/eap_peer/eap_aka.c
    wpasupplicant/trunk/src/eap_peer/eap_fast.c
    wpasupplicant/trunk/src/eap_peer/eap_gpsk.c
    wpasupplicant/trunk/src/eap_peer/eap_gtc.c
    wpasupplicant/trunk/src/eap_peer/eap_i.h
    wpasupplicant/trunk/src/eap_peer/eap_leap.c
    wpasupplicant/trunk/src/eap_peer/eap_md5.c
    wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c
    wpasupplicant/trunk/src/eap_peer/eap_otp.c
    wpasupplicant/trunk/src/eap_peer/eap_pax.c
    wpasupplicant/trunk/src/eap_peer/eap_peap.c
    wpasupplicant/trunk/src/eap_peer/eap_psk.c
    wpasupplicant/trunk/src/eap_peer/eap_sake.c
    wpasupplicant/trunk/src/eap_peer/eap_sim.c
    wpasupplicant/trunk/src/eap_peer/eap_tls.c
    wpasupplicant/trunk/src/eap_peer/eap_tls_common.c
    wpasupplicant/trunk/src/eap_peer/eap_tls_common.h
    wpasupplicant/trunk/src/eap_peer/eap_tlv.c
    wpasupplicant/trunk/src/eap_peer/eap_tlv.h
    wpasupplicant/trunk/src/eap_peer/eap_tnc.c
    wpasupplicant/trunk/src/eap_peer/eap_ttls.c
    wpasupplicant/trunk/src/eap_peer/eap_vendor_test.c
    wpasupplicant/trunk/src/eap_peer/eap_wsc.c
    wpasupplicant/trunk/src/eap_server/eap.c
    wpasupplicant/trunk/src/eap_server/eap.h
    wpasupplicant/trunk/src/eap_server/eap_aka.c
    wpasupplicant/trunk/src/eap_server/eap_fast.c
    wpasupplicant/trunk/src/eap_server/eap_gpsk.c
    wpasupplicant/trunk/src/eap_server/eap_gtc.c
    wpasupplicant/trunk/src/eap_server/eap_i.h
    wpasupplicant/trunk/src/eap_server/eap_identity.c
    wpasupplicant/trunk/src/eap_server/eap_md5.c
    wpasupplicant/trunk/src/eap_server/eap_mschapv2.c
    wpasupplicant/trunk/src/eap_server/eap_pax.c
    wpasupplicant/trunk/src/eap_server/eap_peap.c
    wpasupplicant/trunk/src/eap_server/eap_psk.c
    wpasupplicant/trunk/src/eap_server/eap_sake.c
    wpasupplicant/trunk/src/eap_server/eap_sim.c
    wpasupplicant/trunk/src/eap_server/eap_tls.c
    wpasupplicant/trunk/src/eap_server/eap_tls_common.c
    wpasupplicant/trunk/src/eap_server/eap_tls_common.h
    wpasupplicant/trunk/src/eap_server/eap_tlv.c
    wpasupplicant/trunk/src/eap_server/eap_ttls.c
    wpasupplicant/trunk/src/eap_server/eap_vendor_test.c
    wpasupplicant/trunk/src/eap_server/eap_wsc.c
    wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c
    wpasupplicant/trunk/src/radius/radius_server.c
    wpasupplicant/trunk/src/radius/radius_server.h
    wpasupplicant/trunk/src/utils/common.h
    wpasupplicant/trunk/src/utils/wpa_debug.h
    wpasupplicant/trunk/wpa_supplicant/ChangeLog
    wpasupplicant/trunk/wpa_supplicant/Makefile
    wpasupplicant/trunk/wpa_supplicant/config_ssid.h
    wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c
    wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen
    wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full
    wpasupplicant/trunk/wpa_supplicant/doc/eap.doxygen
    wpasupplicant/trunk/wpa_supplicant/doc/mainpage.doxygen
    wpasupplicant/trunk/wpa_supplicant/eap_testing.txt
    wpasupplicant/trunk/wpa_supplicant/nmake.mak
    wpasupplicant/trunk/wpa_supplicant/todo.txt
    wpasupplicant/trunk/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
    wpasupplicant/trunk/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
    wpasupplicant/trunk/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
    wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c
    wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf

Modified: wpasupplicant/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/changelog?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/changelog (original)
+++ wpasupplicant/trunk/debian/changelog Tue Dec 25 15:23:24 2007
@@ -1,4 +1,4 @@
-wpasupplicant (0.6.1~git20071209-1) UNRELEASED; urgency=low
+wpasupplicant (0.6.2~git20071226-1) UNRELEASED; urgency=low
 
   * New upstream git snapshot.
   * Allow "wpa-key-mgmt NONE" to form a network block via the wpa_cli calls in
@@ -23,7 +23,7 @@
     about deprecated conversions string constant to char* with g++ 4.2 and
     above.
 
- -- Kel Modderman <kel at otaku42.de>  Wed, 26 Dec 2007 01:01:56 +1000
+ -- Kel Modderman <kel at otaku42.de>  Wed, 26 Dec 2007 01:21:42 +1000
 
 wpasupplicant (0.6.1~git20071119-1) unstable; urgency=low
 

Modified: wpasupplicant/trunk/src/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/Makefile?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/Makefile (original)
+++ wpasupplicant/trunk/src/Makefile Tue Dec 25 15:23:24 2007
@@ -1,4 +1,4 @@
-SUBDIRS=common crypto drivers hlr_auc_gw eap_common eap_peer eap_server l2_packet radius rsn_supp tls utils
+SUBDIRS=common crypto drivers hlr_auc_gw eapol_supp eap_common eap_peer eap_server l2_packet radius rsn_supp tls utils
 
 all:
 	@echo Nothing to be made.

Modified: wpasupplicant/trunk/src/crypto/crypto_openssl.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/crypto_openssl.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/crypto_openssl.c (original)
+++ wpasupplicant/trunk/src/crypto/crypto_openssl.c Tue Dec 25 15:23:24 2007
@@ -90,6 +90,7 @@
 }
 
 
+#ifndef CONFIG_NO_FIPS186_2_PRF
 static void sha1_transform(u8 *state, const u8 data[64])
 {
 	SHA_CTX context;
@@ -100,7 +101,6 @@
 }
 
 
-#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];

Modified: wpasupplicant/trunk/src/drivers/driver_broadcom.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_broadcom.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_broadcom.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_broadcom.c Tue Dec 25 15:23:24 2007
@@ -407,6 +407,7 @@
 	if (broadcom_ioctl(drv, WLC_SCAN, &wst, sizeof(wst)) < 0)
 		return -1;
 
+	eloop_cancel_timeout(wpa_driver_broadcom_scan_timeout, drv, drv->ctx);
 	eloop_register_timeout(3, 0, wpa_driver_broadcom_scan_timeout, drv,
 			       drv->ctx);
 	return 0;

Modified: wpasupplicant/trunk/src/drivers/driver_hostap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_hostap.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_hostap.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_hostap.c Tue Dec 25 15:23:24 2007
@@ -390,6 +390,8 @@
 
 	/* Not all drivers generate "scan completed" wireless event, so try to
 	 * read results after a timeout. */
+	eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext,
+			     drv->ctx);
 	eloop_register_timeout(3, 0, wpa_driver_wext_scan_timeout, drv->wext,
 			       drv->ctx);
 

Modified: wpasupplicant/trunk/src/drivers/driver_madwifi.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_madwifi.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_madwifi.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_madwifi.c Tue Dec 25 15:23:24 2007
@@ -439,6 +439,8 @@
 	 * will only be used if the event is not delivered (event handler will
 	 * cancel the timeout).
 	 */
+	eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext,
+			     drv->ctx);
 	eloop_register_timeout(30, 0, wpa_driver_wext_scan_timeout, drv->wext,
 			       drv->ctx);
 

Modified: wpasupplicant/trunk/src/drivers/driver_ndis.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_ndis.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_ndis.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_ndis.c Tue Dec 25 15:23:24 2007
@@ -722,6 +722,7 @@
 	}
 
 	res = ndis_set_oid(drv, OID_802_11_BSSID_LIST_SCAN, "    ", 4);
+	eloop_cancel_timeout(wpa_driver_ndis_scan_timeout, drv, drv->ctx);
 	eloop_register_timeout(7, 0, wpa_driver_ndis_scan_timeout, drv,
 			       drv->ctx);
 	return res;

Modified: wpasupplicant/trunk/src/drivers/driver_ralink.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_ralink.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_ralink.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_ralink.c Tue Dec 25 15:23:24 2007
@@ -25,6 +25,8 @@
 #include "ieee802_11_defs.h"
 #include "priv_netlink.h"
 #include "driver_ralink.h"
+
+static void wpa_driver_ralink_scan_timeout(void *eloop_ctx, void *timeout_ctx);
 
 #define MAX_SSID_LEN 32
 
@@ -992,6 +994,7 @@
 		ralink_set_iface_flags(drv, 0);
 	}
 
+	eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
 	eloop_unregister_read_sock(drv->event_sock);
 	close(drv->event_sock);
 	close(drv->ioctl_sock);
@@ -1040,6 +1043,7 @@
 
 	/* Not all drivers generate "scan completed" wireless event, so try to
 	 * read results after a timeout. */
+	eloop_cancel_timeout(wpa_driver_ralink_scan_timeout, drv, drv->ctx);
 	eloop_register_timeout(4, 0, wpa_driver_ralink_scan_timeout, drv,
 			       drv->ctx);
 

Modified: wpasupplicant/trunk/src/drivers/driver_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_test.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_test.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_test.c Tue Dec 25 15:23:24 2007
@@ -127,6 +127,7 @@
 		perror("sendto(test_socket)");
 	}
 
+	eloop_cancel_timeout(wpa_driver_test_scan_timeout, drv, drv->ctx);
 	eloop_register_timeout(1, 0, wpa_driver_test_scan_timeout, drv,
 			       drv->ctx);
 	return 0;

Modified: wpasupplicant/trunk/src/drivers/driver_wext.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_wext.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_wext.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_wext.c Tue Dec 25 15:23:24 2007
@@ -75,6 +75,8 @@
 	int operstate;
 
 	char mlmedev[IFNAMSIZ + 1];
+
+	int scan_complete_events;
 };
 
 
@@ -590,6 +592,7 @@
 			os_free(buf);
 			break;
 		case SIOCGIWSCAN:
+			drv->scan_complete_events = 1;
 			eloop_cancel_timeout(wpa_driver_wext_scan_timeout,
 					     drv, ctx);
 			wpa_supplicant_event(ctx, EVENT_SCAN_RESULTS, NULL);
@@ -1076,7 +1079,7 @@
 {
 	struct wpa_driver_wext_data *drv = priv;
 	struct iwreq iwr;
-	int ret = 0;
+	int ret = 0, timeout;
 	struct iw_scan_req req;
 
 	if (ssid_len > IW_ESSID_MAX_SIZE) {
@@ -1106,7 +1109,19 @@
 
 	/* Not all drivers generate "scan completed" wireless event, so try to
 	 * read results after a timeout. */
-	eloop_register_timeout(3, 0, wpa_driver_wext_scan_timeout, drv,
+	timeout = 5;
+	if (drv->scan_complete_events) {
+		/*
+		 * The driver seems to deliver SIOCGIWSCAN events to notify
+		 * when scan is complete, so use longer timeout to avoid race
+		 * conditions with scanning and following association request.
+		 */
+		timeout = 30;
+	}
+	wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d "
+		   "seconds", ret, timeout);
+	eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
+	eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
 			       drv->ctx);
 
 	return ret;

Modified: wpasupplicant/trunk/src/eap_common/eap_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_common.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_common.c Tue Dec 25 15:23:24 2007
@@ -1,6 +1,6 @@
 /*
  * EAP common peer/server definitions
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * 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
@@ -23,7 +23,6 @@
  * @vendor: Expected EAP Vendor-Id (0 = IETF)
  * @eap_type: Expected EAP type number
  * @msg: EAP frame (starting with EAP header)
- * @msglen: Length of msg
  * @plen: Pointer to variable to contain the returned payload length
  * Returns: Pointer to EAP payload (after type field), or %NULL on failure
  *
@@ -36,21 +35,21 @@
  * not.
  */
 const u8 * eap_hdr_validate(int vendor, EapType eap_type,
-			    const u8 *msg, size_t msglen, size_t *plen)
+			    const struct wpabuf *msg, size_t *plen)
 {
 	const struct eap_hdr *hdr;
 	const u8 *pos;
 	size_t len;
 
-	hdr = (const struct eap_hdr *) msg;
+	hdr = wpabuf_head(msg);
 
-	if (msglen < sizeof(*hdr)) {
+	if (wpabuf_len(msg) < sizeof(*hdr)) {
 		wpa_printf(MSG_INFO, "EAP: Too short EAP frame");
 		return NULL;
 	}
 
 	len = be_to_host16(hdr->length);
-	if (len < sizeof(*hdr) + 1 || len > msglen) {
+	if (len < sizeof(*hdr) + 1 || len > wpabuf_len(msg)) {
 		wpa_printf(MSG_INFO, "EAP: Invalid EAP length");
 		return NULL;
 	}
@@ -93,47 +92,93 @@
  * eap_msg_alloc - Allocate a buffer for an EAP message
  * @vendor: Vendor-Id (0 = IETF)
  * @type: EAP type
- * @len: Buffer for returning message length
  * @payload_len: Payload length in bytes (data after Type)
  * @code: Message Code (EAP_CODE_*)
  * @identifier: Identifier
- * @payload: Pointer to payload pointer that will be set to point to the
- * beginning of the payload or %NULL if payload pointer is not needed
  * Returns: Pointer to the allocated message buffer or %NULL on error
  *
  * This function can be used to allocate a buffer for an EAP message and fill
  * in the EAP header. This function is automatically using expanded EAP header
  * if the selected Vendor-Id is not IETF. In other words, most EAP methods do
  * not need to separately select which header type to use when using this
- * function to allocate the message buffers.
+ * function to allocate the message buffers. The returned buffer has room for
+ * payload_len bytes and has the EAP header and Type field already filled in.
  */
-struct eap_hdr * eap_msg_alloc(int vendor, EapType type, size_t *len,
-			       size_t payload_len, u8 code, u8 identifier,
-			       u8 **payload)
+struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len,
+			      u8 code, u8 identifier)
+{
+	struct wpabuf *buf;
+	struct eap_hdr *hdr;
+	size_t len;
+
+	len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) +
+		payload_len;
+	buf = wpabuf_alloc(len);
+	if (buf == NULL)
+		return NULL;
+
+	hdr = wpabuf_put(buf, sizeof(*hdr));
+	hdr->code = code;
+	hdr->identifier = identifier;
+	hdr->length = host_to_be16(len);
+
+	if (vendor == EAP_VENDOR_IETF) {
+		wpabuf_put_u8(buf, type);
+	} else {
+		wpabuf_put_u8(buf, EAP_TYPE_EXPANDED);
+		wpabuf_put_be24(buf, vendor);
+		wpabuf_put_be32(buf, type);
+	}
+
+	return buf;
+}
+
+
+/**
+ * eap_update_len - Update EAP header length
+ * @msg: EAP message from eap_msg_alloc
+ *
+ * This function updates the length field in the EAP header to match with the
+ * current length for the buffer. This allows eap_msg_alloc() to be used to
+ * allocate a larger buffer than the exact message length (e.g., if exact
+ * message length is not yet known).
+ */
+void eap_update_len(struct wpabuf *msg)
 {
 	struct eap_hdr *hdr;
-	u8 *pos;
+	hdr = wpabuf_mhead(msg);
+	if (wpabuf_len(msg) < sizeof(*hdr))
+		return;
+	hdr->length = host_to_be16(wpabuf_len(msg));
+}
 
-	*len = sizeof(struct eap_hdr) + (vendor == EAP_VENDOR_IETF ? 1 : 8) +
-		payload_len;
-	hdr = os_malloc(*len);
-	if (hdr) {
-		hdr->code = code;
-		hdr->identifier = identifier;
-		hdr->length = host_to_be16(*len);
-		pos = (u8 *) (hdr + 1);
-		if (vendor == EAP_VENDOR_IETF) {
-			*pos++ = type;
-		} else {
-			*pos++ = EAP_TYPE_EXPANDED;
-			WPA_PUT_BE24(pos, vendor);
-			pos += 3;
-			WPA_PUT_BE32(pos, type);
-			pos += 4;
-		}
-		if (payload)
-			*payload = pos;
-	}
 
-	return hdr;
+/**
+ * eap_get_id - Get EAP Identifier from wpabuf
+ * @msg: Buffer starting with an EAP header
+ * Returns: The Identifier field from the EAP header
+ */
+u8 eap_get_id(const struct wpabuf *msg)
+{
+	const struct eap_hdr *eap;
+
+	if (wpabuf_len(msg) < sizeof(*eap))
+		return 0;
+
+	eap = wpabuf_head(msg);
+	return eap->identifier;
 }
+
+
+/**
+ * eap_get_id - Get EAP Type from wpabuf
+ * @msg: Buffer starting with an EAP header
+ * Returns: The EAP Type after the EAP header
+ */
+EapType eap_get_type(const struct wpabuf *msg)
+{
+	if (wpabuf_len(msg) < sizeof(struct eap_hdr) + 1)
+		return EAP_TYPE_NONE;
+
+	return ((const u8 *) wpabuf_head(msg))[sizeof(struct eap_hdr)];
+}

Modified: wpasupplicant/trunk/src/eap_common/eap_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_common.h Tue Dec 25 15:23:24 2007
@@ -1,6 +1,6 @@
 /*
  * EAP common peer/server definitions
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * 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
@@ -15,10 +15,14 @@
 #ifndef EAP_COMMON_H
 #define EAP_COMMON_H
 
+#include "wpabuf.h"
+
 const u8 * eap_hdr_validate(int vendor, EapType eap_type,
-			    const u8 *msg, size_t msglen, size_t *plen);
-struct eap_hdr * eap_msg_alloc(int vendor, EapType type, size_t *len,
-			       size_t payload_len, u8 code, u8 identifier,
-			       u8 **payload);
+			    const struct wpabuf *msg, size_t *plen);
+struct wpabuf * eap_msg_alloc(int vendor, EapType type, size_t payload_len,
+			      u8 code, u8 identifier);
+void eap_update_len(struct wpabuf *msg);
+u8 eap_get_id(const struct wpabuf *msg);
+EapType eap_get_type(const struct wpabuf *msg);
 
 #endif /* EAP_COMMON_H */

Modified: wpasupplicant/trunk/src/eap_common/eap_pax_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_pax_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_pax_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_pax_common.h Tue Dec 25 15:23:24 2007
@@ -20,10 +20,6 @@
 #endif /* _MSC_VER */
 
 struct eap_pax_hdr {
-	u8 code;
-	u8 identifier;
-	be16 length; /* including code, identifier, and length */
-	u8 type; /* EAP_TYPE_PAX */
 	u8 op_code;
 	u8 flags;
 	u8 mac_id;

Modified: wpasupplicant/trunk/src/eap_common/eap_psk_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_psk_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_psk_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_psk_common.h Tue Dec 25 15:23:24 2007
@@ -35,21 +35,8 @@
 #pragma pack(push, 1)
 #endif /* _MSC_VER */
 
-/* Shared prefix for all EAP-PSK frames */
-struct eap_psk_hdr {
-	u8 code;
-	u8 identifier;
-	u16 length; /* including code, identifier, and length */
-	u8 type; /* EAP_TYPE_PSK */
-	u8 flags;
-} STRUCT_PACKED;
-
 /* EAP-PSK First Message (AS -> Supplicant) */
 struct eap_psk_hdr_1 {
-	u8 code;
-	u8 identifier;
-	be16 length; /* including code, identifier, and length */
-	u8 type; /* EAP_TYPE_PSK */
 	u8 flags;
 	u8 rand_s[EAP_PSK_RAND_LEN];
 	/* Followed by variable length ID_S */
@@ -57,10 +44,6 @@
 
 /* EAP-PSK Second Message (Supplicant -> AS) */
 struct eap_psk_hdr_2 {
-	u8 code;
-	u8 identifier;
-	be16 length; /* including code, identifier, and length */
-	u8 type; /* EAP_TYPE_PSK */
 	u8 flags;
 	u8 rand_s[EAP_PSK_RAND_LEN];
 	u8 rand_p[EAP_PSK_RAND_LEN];
@@ -70,10 +53,6 @@
 
 /* EAP-PSK Third Message (AS -> Supplicant) */
 struct eap_psk_hdr_3 {
-	u8 code;
-	u8 identifier;
-	be16 length; /* including code, identifier, and length */
-	u8 type; /* EAP_TYPE_PSK */
 	u8 flags;
 	u8 rand_s[EAP_PSK_RAND_LEN];
 	u8 mac_s[EAP_PSK_MAC_LEN];
@@ -82,10 +61,6 @@
 
 /* EAP-PSK Fourth Message (Supplicant -> AS) */
 struct eap_psk_hdr_4 {
-	u8 code;
-	u8 identifier;
-	be16 length; /* including code, identifier, and length */
-	u8 type; /* EAP_TYPE_PSK */
 	u8 flags;
 	u8 rand_s[EAP_PSK_RAND_LEN];
 	/* Followed by variable length PCHANNEL */

Modified: wpasupplicant/trunk/src/eap_common/eap_sake_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_sake_common.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_sake_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_sake_common.c Tue Dec 25 15:23:24 2007
@@ -1,6 +1,6 @@
 /*
  * EAP server/peer: EAP-SAKE shared routines
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2006-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
@@ -16,6 +16,7 @@
 
 #include "common.h"
 #include "sha1.h"
+#include "wpabuf.h"
 #include "eap_defs.h"
 #include "eap_sake_common.h"
 
@@ -378,3 +379,15 @@
 
 	return 0;
 }
+
+
+void eap_sake_add_attr(struct wpabuf *buf, u8 type, const u8 *data,
+		       size_t len)
+{
+	wpabuf_put_u8(buf, type);
+	wpabuf_put_u8(buf, 2 + len); /* Length; including attr header */
+	if (data)
+		wpabuf_put_data(buf, data, len);
+	else
+		os_memset(wpabuf_put(buf, len), 0, len);
+}

Modified: wpasupplicant/trunk/src/eap_common/eap_sake_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_sake_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_sake_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_sake_common.h Tue Dec 25 15:23:24 2007
@@ -51,10 +51,6 @@
 #endif /* _MSC_VER */
 
 struct eap_sake_hdr {
-	u8 code;
-	u8 identifier;
-	be16 length;
-	u8 type; /* EAP_TYPE_SAKE */
 	u8 version; /* EAP_SAKE_VERSION */
 	u8 session_id;
 	u8 subtype;
@@ -100,5 +96,7 @@
 			 const u8 *peerid, size_t peerid_len,
 			 int peer, const u8 *eap, size_t eap_len,
 			 const u8 *mic_pos, u8 *mic);
+void eap_sake_add_attr(struct wpabuf *buf, u8 type, const u8 *data,
+		       size_t len);
 
 #endif /* EAP_SAKE_COMMON_H */

Modified: wpasupplicant/trunk/src/eap_common/eap_sim_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_sim_common.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_sim_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_sim_common.c Tue Dec 25 15:23:24 2007
@@ -1,5 +1,5 @@
 /*
- * EAP peer: EAP-SIM/AKA shared routines
+ * EAP peer/server: EAP-SIM/AKA shared routines
  * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
 #include "sha1.h"
 #include "crypto.h"
 #include "aes_wrap.h"
+#include "wpabuf.h"
 #include "eap_common/eap_sim_common.h"
 
 
@@ -160,7 +161,7 @@
 }
 
 
-int eap_sim_verify_mac(const u8 *k_aut, const u8 *req, size_t req_len,
+int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req,
 		       const u8 *mac, const u8 *extra, size_t extra_len)
 {
 	unsigned char hmac[SHA1_MAC_LEN];
@@ -168,23 +169,25 @@
 	size_t len[2];
 	u8 *tmp;
 
-	if (mac == NULL || req_len < EAP_SIM_MAC_LEN || mac < req ||
-	    mac > req + req_len - EAP_SIM_MAC_LEN)
+	if (mac == NULL || wpabuf_len(req) < EAP_SIM_MAC_LEN ||
+	    mac < wpabuf_head_u8(req) ||
+	    mac > wpabuf_head_u8(req) + wpabuf_len(req) - EAP_SIM_MAC_LEN)
 		return -1;
 
-	tmp = os_malloc(req_len);
+	tmp = os_malloc(wpabuf_len(req));
 	if (tmp == NULL)
 		return -1;
 
 	addr[0] = tmp;
-	len[0] = req_len;
+	len[0] = wpabuf_len(req);
 	addr[1] = extra;
 	len[1] = extra_len;
 
 	/* HMAC-SHA1-128 */
-	os_memcpy(tmp, req, req_len);
-	os_memset(tmp + (mac - req), 0, EAP_SIM_MAC_LEN);
-	wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - msg", tmp, req_len);
+	os_memcpy(tmp, wpabuf_head(req), wpabuf_len(req));
+	os_memset(tmp + (mac - wpabuf_head_u8(req)), 0, EAP_SIM_MAC_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - msg",
+		    tmp, wpabuf_len(req));
 	wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Verify MAC - extra data",
 		    extra, extra_len);
 	wpa_hexdump_key(MSG_MSGDUMP, "EAP-SIM: Verify MAC - K_aut",
@@ -198,7 +201,7 @@
 }
 
 
-void eap_sim_add_mac(const u8 *k_aut, u8 *msg, size_t msg_len, u8 *mac,
+void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
 		     const u8 *extra, size_t extra_len)
 {
 	unsigned char hmac[SHA1_MAC_LEN];
@@ -250,6 +253,10 @@
 				   pos, pos[1] * 4, end);
 			return -1;
 		}
+		if (pos[1] == 0) {
+			wpa_printf(MSG_INFO, "EAP-SIM: Attribute underflow");
+			return -1;
+		}
 		apos = pos + 2;
 		alen = pos[1] * 4 - 2;
 		wpa_hexdump(MSG_MSGDUMP, "EAP-SIM: Attribute data",
@@ -532,6 +539,39 @@
 			}
 			attr->auts = apos;
 			break;
+		case EAP_SIM_AT_CHECKCODE:
+			wpa_printf(MSG_DEBUG, "EAP-AKA: AT_CHECKCODE");
+			if (!aka) {
+				wpa_printf(MSG_DEBUG, "EAP-SIM: "
+					   "Unexpected AT_CHECKCODE");
+				return -1;
+			}
+			apos += 2;
+			alen -= 2;
+			if (alen != 0 && alen != EAP_AKA_CHECKCODE_LEN) {
+				wpa_printf(MSG_INFO, "EAP-AKA: Invalid "
+					   "AT_CHECKCODE (len %lu)",
+					   (unsigned long) alen);
+				return -1;
+			}
+			attr->checkcode = apos;
+			attr->checkcode_len = alen;
+			break;
+		case EAP_SIM_AT_RESULT_IND:
+			if (encr) {
+				wpa_printf(MSG_ERROR, "EAP-SIM: Encrypted "
+					   "AT_RESULT_IND");
+				return -1;
+			}
+			if (alen != 2) {
+				wpa_printf(MSG_INFO, "EAP-SIM: Invalid "
+					   "AT_RESULT_IND (alen=%lu)",
+					   (unsigned long) alen);
+				return -1;
+			}
+			wpa_printf(MSG_DEBUG, "EAP-SIM: AT_RESULT_IND");
+			attr->result_ind = 1;
+			break;
 		default:
 			if (pos[0] < 128) {
 				wpa_printf(MSG_INFO, "EAP-SIM: Unrecognized "
@@ -590,8 +630,7 @@
 #define EAP_SIM_INIT_LEN 128
 
 struct eap_sim_msg {
-	u8 *buf;
-	size_t buf_len, used;
+	struct wpabuf *buf;
 	size_t mac, iv, encr; /* index from buf */
 };
 
@@ -606,46 +645,44 @@
 	if (msg == NULL)
 		return NULL;
 
-	msg->buf = os_zalloc(EAP_SIM_INIT_LEN);
+	msg->buf = wpabuf_alloc(EAP_SIM_INIT_LEN);
 	if (msg->buf == NULL) {
 		os_free(msg);
 		return NULL;
 	}
-	msg->buf_len = EAP_SIM_INIT_LEN;
-	eap = (struct eap_hdr *) msg->buf;
+	eap = wpabuf_put(msg->buf, sizeof(*eap));
 	eap->code = code;
 	eap->identifier = id;
-	msg->used = sizeof(*eap);
-
-	pos = (u8 *) (eap + 1);
+
+	pos = wpabuf_put(msg->buf, 4);
 	*pos++ = type;
 	*pos++ = subtype;
 	*pos++ = 0; /* Reserved */
 	*pos++ = 0; /* Reserved */
-	msg->used += 4;
 
 	return msg;
 }
 
 
-u8 * eap_sim_msg_finish(struct eap_sim_msg *msg, size_t *len, const u8 *k_aut,
-			const u8 *extra, size_t extra_len)
+struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut,
+				   const u8 *extra, size_t extra_len)
 {
 	struct eap_hdr *eap;
-	u8 *buf;
+	struct wpabuf *buf;
 
 	if (msg == NULL)
 		return NULL;
 
-	eap = (struct eap_hdr *) msg->buf;
-	eap->length = host_to_be16(msg->used);
+	eap = wpabuf_mhead(msg->buf);
+	eap->length = host_to_be16(wpabuf_len(msg->buf));
 
 	if (k_aut && msg->mac) {
-		eap_sim_add_mac(k_aut, msg->buf, msg->used,
-				msg->buf + msg->mac, extra, extra_len);
-	}
-
-	*len = msg->used;
+		eap_sim_add_mac(k_aut, (u8 *) wpabuf_head(msg->buf),
+				wpabuf_len(msg->buf),
+				(u8 *) wpabuf_mhead(msg->buf) + msg->mac,
+				extra, extra_len);
+	}
+
 	buf = msg->buf;
 	os_free(msg);
 	return buf;
@@ -655,22 +692,9 @@
 void eap_sim_msg_free(struct eap_sim_msg *msg)
 {
 	if (msg) {
-		os_free(msg->buf);
+		wpabuf_free(msg->buf);
 		os_free(msg);
 	}
-}
-
-
-static int eap_sim_msg_resize(struct eap_sim_msg *msg, size_t add_len)
-{
-	if (msg->used + add_len > msg->buf_len) {
-		u8 *nbuf = os_realloc(msg->buf, msg->used + add_len);
-		if (nbuf == NULL)
-			return -1;
-		msg->buf = nbuf;
-		msg->buf_len = msg->used + add_len;
-	}
-	return 0;
 }
 
 
@@ -679,24 +703,21 @@
 {
 	int attr_len = 2 + len;
 	int pad_len;
-	u8 *start, *pos;
+	u8 *start;
 
 	if (msg == NULL)
 		return NULL;
 
 	pad_len = (4 - attr_len % 4) % 4;
 	attr_len += pad_len;
-	if (eap_sim_msg_resize(msg, attr_len))
-		return NULL;
-	start = pos = msg->buf + msg->used;
-	*pos++ = attr;
-	*pos++ = attr_len / 4;
-	os_memcpy(pos, data, len);
-	if (pad_len) {
-		pos += len;
-		os_memset(pos, 0, pad_len);
-	}
-	msg->used += attr_len;
+	if (wpabuf_resize(&msg->buf, attr_len))
+		return NULL;
+	start = wpabuf_put(msg->buf, 0);
+	wpabuf_put_u8(msg->buf, attr);
+	wpabuf_put_u8(msg->buf, attr_len / 4);
+	wpabuf_put_data(msg->buf, data, len);
+	if (pad_len)
+		os_memset(wpabuf_put(msg->buf, pad_len), 0, pad_len);
 	return start;
 }
 
@@ -706,27 +727,25 @@
 {
 	int attr_len = 4 + len;
 	int pad_len;
-	u8 *start, *pos;
+	u8 *start;
 
 	if (msg == NULL)
 		return NULL;
 
 	pad_len = (4 - attr_len % 4) % 4;
 	attr_len += pad_len;
-	if (eap_sim_msg_resize(msg, attr_len))
-		return NULL;
-	start = pos = msg->buf + msg->used;
-	*pos++ = attr;
-	*pos++ = attr_len / 4;
-	WPA_PUT_BE16(pos, value);
-	pos += 2;
+	if (wpabuf_resize(&msg->buf, attr_len))
+		return NULL;
+	start = wpabuf_put(msg->buf, 0);
+	wpabuf_put_u8(msg->buf, attr);
+	wpabuf_put_u8(msg->buf, attr_len / 4);
+	wpabuf_put_be16(msg->buf, value);
 	if (data)
-		os_memcpy(pos, data, len);
-	if (pad_len) {
-		pos += len;
-		os_memset(pos, 0, pad_len);
-	}
-	msg->used += attr_len;
+		wpabuf_put_data(msg->buf, data, len);
+	else
+		wpabuf_put(msg->buf, len);
+	if (pad_len)
+		os_memset(wpabuf_put(msg->buf, pad_len), 0, pad_len);
 	return start;
 }
 
@@ -735,7 +754,7 @@
 {
 	u8 *pos = eap_sim_msg_add(msg, attr, 0, NULL, EAP_SIM_MAC_LEN);
 	if (pos)
-		msg->mac = (pos - msg->buf) + 4;
+		msg->mac = (pos - wpabuf_head_u8(msg->buf)) + 4;
 	return pos;
 }
 
@@ -746,8 +765,9 @@
 	u8 *pos = eap_sim_msg_add(msg, attr_iv, 0, NULL, EAP_SIM_IV_LEN);
 	if (pos == NULL)
 		return -1;
-	msg->iv = (pos - msg->buf) + 4;
-	if (os_get_random(msg->buf + msg->iv, EAP_SIM_IV_LEN)) {
+	msg->iv = (pos - wpabuf_head_u8(msg->buf)) + 4;
+	if (os_get_random(wpabuf_mhead_u8(msg->buf) + msg->iv,
+			  EAP_SIM_IV_LEN)) {
 		msg->iv = 0;
 		return -1;
 	}
@@ -757,7 +777,7 @@
 		msg->iv = 0;
 		return -1;
 	}
-	msg->encr = pos - msg->buf;
+	msg->encr = pos - wpabuf_head_u8(msg->buf);
 
 	return 0;
 }
@@ -770,7 +790,7 @@
 	if (msg == NULL || k_encr == NULL || msg->iv == 0 || msg->encr == 0)
 		return -1;
 
-	encr_len = msg->used - msg->encr - 4;
+	encr_len = wpabuf_len(msg->buf) - msg->encr - 4;
 	if (encr_len % 16) {
 		u8 *pos;
 		int pad_len = 16 - (encr_len % 16);
@@ -789,9 +809,10 @@
 	}
 	wpa_printf(MSG_DEBUG, "   (AT_ENCR_DATA data len %lu)",
 		   (unsigned long) encr_len);
-	msg->buf[msg->encr + 1] = encr_len / 4 + 1;
-	aes_128_cbc_encrypt(k_encr, msg->buf + msg->iv,
-			    msg->buf + msg->encr + 4, encr_len);
+	wpabuf_mhead_u8(msg->buf)[msg->encr + 1] = encr_len / 4 + 1;
+	aes_128_cbc_encrypt(k_encr, wpabuf_head_u8(msg->buf) + msg->iv,
+			    wpabuf_mhead_u8(msg->buf) + msg->encr + 4,
+			    encr_len);
 
 	return 0;
 }

Modified: wpasupplicant/trunk/src/eap_common/eap_sim_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_sim_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_sim_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_sim_common.h Tue Dec 25 15:23:24 2007
@@ -1,6 +1,6 @@
 /*
- * EAP peer: EAP-SIM/AKA shared routines
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * EAP peer/server: EAP-SIM/AKA shared routines
+ * 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
@@ -69,6 +69,9 @@
 #define EAP_AKA_MAX_FAST_REAUTHS 1000
 #define EAP_AKA_MIN_RES_LEN 4
 #define EAP_AKA_MAX_RES_LEN 16
+#define EAP_AKA_CHECKCODE_LEN 20
+
+struct wpabuf;
 
 void eap_sim_derive_mk(const u8 *identity, size_t identity_len,
 		       const u8 *nonce_mt, u16 selected_version,
@@ -82,9 +85,9 @@
 			       const u8 *identity, size_t identity_len,
 			       const u8 *nonce_s, const u8 *mk, u8 *msk,
 			       u8 *emsk);
-int eap_sim_verify_mac(const u8 *k_aut, const u8 *req, size_t req_len,
+int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req,
 		       const u8 *mac, const u8 *extra, size_t extra_len);
-void eap_sim_add_mac(const u8 *k_aut, u8 *msg, size_t msg_len, u8 *mac,
+void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
 		     const u8 *extra, size_t extra_len);
 
 
@@ -131,11 +134,14 @@
 	const u8 *rand, *autn, *mac, *iv, *encr_data, *version_list, *nonce_s;
 	const u8 *next_pseudonym, *next_reauth_id;
 	const u8 *nonce_mt, *identity, *res, *auts;
+	const u8 *checkcode;
 	size_t num_chal, version_list_len, encr_data_len;
 	size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
+	size_t checkcode_len;
 	enum eap_sim_id_req id_req;
 	int notification, counter, selected_version, client_error_code;
 	int counter_too_small;
+	int result_ind;
 };
 
 int eap_sim_parse_attr(const u8 *start, const u8 *end,
@@ -148,8 +154,8 @@
 struct eap_sim_msg;
 
 struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype);
-u8 * eap_sim_msg_finish(struct eap_sim_msg *msg, size_t *len, const u8 *k_aut,
-			const u8 *extra, size_t extra_len);
+struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, const u8 *k_aut,
+				   const u8 *extra, size_t extra_len);
 void eap_sim_msg_free(struct eap_sim_msg *msg);
 u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr,
 			  const u8 *data, size_t len);

Modified: wpasupplicant/trunk/src/eap_common/eap_wsc_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_wsc_common.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_wsc_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_wsc_common.c Tue Dec 25 15:23:24 2007
@@ -19,13 +19,11 @@
 #include "eap_common.h"
 #include "eap_wsc_common.h"
 
-u8 * eap_wsc_build_frag_ack(u8 id, u8 code, size_t *len)
+struct wpabuf * eap_wsc_build_frag_ack(u8 id, u8 code)
 {
-	struct eap_hdr *msg;
-	u8 *pos;
+	struct wpabuf *msg;
 
-	msg = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, len, 2, code,
-			    id, &pos);
+	msg = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, 2, code, id);
 	if (msg == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for "
 			   "FRAG_ACK");
@@ -33,8 +31,8 @@
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-WSC: Send WSC/FRAG_ACK");
-	*pos++ = WSC_FRAG_ACK; /* Op-Code */
-	*pos = 0; /* Flags */
+	wpabuf_put_u8(msg, WSC_FRAG_ACK); /* Op-Code */
+	wpabuf_put_u8(msg, 0); /* Flags */
 
-	return (u8 *) msg;
+	return msg;
 }

Modified: wpasupplicant/trunk/src/eap_common/eap_wsc_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_wsc_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_wsc_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_wsc_common.h Tue Dec 25 15:23:24 2007
@@ -37,6 +37,6 @@
 #define WSC_FRAGMENT_SIZE 1400
 
 
-u8 * eap_wsc_build_frag_ack(u8 id, u8 code, size_t *len);
+struct wpabuf * eap_wsc_build_frag_ack(u8 id, u8 code);
 
 #endif /* EAP_WSC_COMMON_H */

Modified: wpasupplicant/trunk/src/eap_peer/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap.c Tue Dec 25 15:23:24 2007
@@ -40,11 +40,12 @@
 
 static Boolean eap_sm_allowMethod(struct eap_sm *sm, int vendor,
 				  EapType method);
-static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len);
-static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req);
-static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req);
-static u8 * eap_sm_buildNotify(int id, size_t *len);
-static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len);
+static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id);
+static void eap_sm_processIdentity(struct eap_sm *sm,
+				   const struct wpabuf *req);
+static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req);
+static struct wpabuf * eap_sm_buildNotify(int id);
+static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req);
 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
 static const char * eap_sm_method_state_txt(EapMethodState state);
 static const char * eap_sm_decision_txt(EapDecision decision);
@@ -78,9 +79,9 @@
 }
 
 
-static u8 * eapol_get_eapReqData(struct eap_sm *sm, size_t *len)
-{
-	return sm->eapol_cb->get_eapReqData(sm->eapol_ctx, len);
+static struct wpabuf * eapol_get_eapReqData(struct eap_sm *sm)
+{
+	return sm->eapol_cb->get_eapReqData(sm->eapol_ctx);
 }
 
 
@@ -195,13 +196,12 @@
  */
 SM_STATE(EAP, RECEIVED)
 {
-	const u8 *eapReqData;
-	size_t eapReqDataLen;
+	const struct wpabuf *eapReqData;
 
 	SM_ENTRY(EAP, RECEIVED);
-	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
+	eapReqData = eapol_get_eapReqData(sm);
 	/* parse rxReq, rxSuccess, rxFailure, reqId, reqMethod */
-	eap_sm_parseEapReq(sm, eapReqData, eapReqDataLen);
+	eap_sm_parseEapReq(sm, eapReqData);
 	sm->num_rounds++;
 }
 
@@ -300,9 +300,9 @@
 	return;
 
 nak:
-	os_free(sm->eapRespData);
+	wpabuf_free(sm->eapRespData);
 	sm->eapRespData = NULL;
-	sm->eapRespData = eap_sm_buildNak(sm, sm->reqId, &sm->eapRespDataLen);
+	sm->eapRespData = eap_sm_buildNak(sm, sm->reqId);
 }
 
 
@@ -312,8 +312,7 @@
  */
 SM_STATE(EAP, METHOD)
 {
-	u8 *eapReqData;
-	size_t eapReqDataLen;
+	struct wpabuf *eapReqData;
 	struct eap_method_ret ret;
 
 	SM_ENTRY(EAP, METHOD);
@@ -322,7 +321,7 @@
 		return;
 	}
 
-	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
+	eapReqData = eapol_get_eapReqData(sm);
 
 	/*
 	 * Get ignore, methodState, decision, allowNotifications, and
@@ -343,11 +342,10 @@
 	ret.methodState = sm->methodState;
 	ret.decision = sm->decision;
 	ret.allowNotifications = sm->allowNotifications;
-	os_free(sm->eapRespData);
+	wpabuf_free(sm->eapRespData);
 	sm->eapRespData = NULL;
 	sm->eapRespData = sm->m->process(sm, sm->eap_method_priv, &ret,
-					 eapReqData, eapReqDataLen,
-					 &sm->eapRespDataLen);
+					 eapReqData);
 	wpa_printf(MSG_DEBUG, "EAP: method process -> ignore=%s "
 		   "methodState=%s decision=%s",
 		   ret.ignore ? "TRUE" : "FALSE",
@@ -377,17 +375,12 @@
 SM_STATE(EAP, SEND_RESPONSE)
 {
 	SM_ENTRY(EAP, SEND_RESPONSE);
-	os_free(sm->lastRespData);
+	wpabuf_free(sm->lastRespData);
 	if (sm->eapRespData) {
 		if (sm->workaround)
 			os_memcpy(sm->last_md5, sm->req_md5, 16);
 		sm->lastId = sm->reqId;
-		sm->lastRespData = os_malloc(sm->eapRespDataLen);
-		if (sm->lastRespData) {
-			os_memcpy(sm->lastRespData, sm->eapRespData,
-				  sm->eapRespDataLen);
-			sm->lastRespDataLen = sm->eapRespDataLen;
-		}
+		sm->lastRespData = wpabuf_dup(sm->eapRespData);
 		eapol_set_bool(sm, EAPOL_eapResp, TRUE);
 	} else
 		sm->lastRespData = NULL;
@@ -413,16 +406,14 @@
  */
 SM_STATE(EAP, IDENTITY)
 {
-	const u8 *eapReqData;
-	size_t eapReqDataLen;
+	const struct wpabuf *eapReqData;
 
 	SM_ENTRY(EAP, IDENTITY);
-	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
+	eapReqData = eapol_get_eapReqData(sm);
 	eap_sm_processIdentity(sm, eapReqData);
-	os_free(sm->eapRespData);
+	wpabuf_free(sm->eapRespData);
 	sm->eapRespData = NULL;
-	sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId,
-					       &sm->eapRespDataLen, 0);
+	sm->eapRespData = eap_sm_buildIdentity(sm, sm->reqId, 0);
 }
 
 
@@ -431,15 +422,14 @@
  */
 SM_STATE(EAP, NOTIFICATION)
 {
-	const u8 *eapReqData;
-	size_t eapReqDataLen;
+	const struct wpabuf *eapReqData;
 
 	SM_ENTRY(EAP, NOTIFICATION);
-	eapReqData = eapol_get_eapReqData(sm, &eapReqDataLen);
+	eapReqData = eapol_get_eapReqData(sm);
 	eap_sm_processNotify(sm, eapReqData);
-	os_free(sm->eapRespData);
+	wpabuf_free(sm->eapRespData);
 	sm->eapRespData = NULL;
-	sm->eapRespData = eap_sm_buildNotify(sm->reqId, &sm->eapRespDataLen);
+	sm->eapRespData = eap_sm_buildNotify(sm->reqId);
 }
 
 
@@ -449,15 +439,10 @@
 SM_STATE(EAP, RETRANSMIT)
 {
 	SM_ENTRY(EAP, RETRANSMIT);
-	os_free(sm->eapRespData);
-	if (sm->lastRespData) {
-		sm->eapRespData = os_malloc(sm->lastRespDataLen);
-		if (sm->eapRespData) {
-			os_memcpy(sm->eapRespData, sm->lastRespData,
-				  sm->lastRespDataLen);
-			sm->eapRespDataLen = sm->lastRespDataLen;
-		}
-	} else
+	wpabuf_free(sm->eapRespData);
+	if (sm->lastRespData)
+		sm->eapRespData = wpabuf_dup(sm->lastRespData);
+	else
 		sm->eapRespData = NULL;
 }
 
@@ -758,31 +743,24 @@
 }
 
 
-static u8 * eap_sm_build_expanded_nak(struct eap_sm *sm, int id, size_t *len,
-				      const struct eap_method *methods,
-				      size_t count)
-{
-	struct eap_hdr *resp;
-	u8 *pos;
+static struct wpabuf * eap_sm_build_expanded_nak(
+	struct eap_sm *sm, int id, const struct eap_method *methods,
+	size_t count)
+{
+	struct wpabuf *resp;
 	int found = 0;
 	const struct eap_method *m;
 
 	wpa_printf(MSG_DEBUG, "EAP: Building expanded EAP-Nak");
 
 	/* RFC 3748 - 5.3.2: Expanded Nak */
-	*len = sizeof(struct eap_hdr) + 8;
-	resp = os_malloc(*len + 8 * (count + 1));
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_EXPANDED,
+			     8 + 8 * (count + 1), EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	resp->code = EAP_CODE_RESPONSE;
-	resp->identifier = id;
-	pos = (u8 *) (resp + 1);
-	*pos++ = EAP_TYPE_EXPANDED;
-	WPA_PUT_BE24(pos, EAP_VENDOR_IETF);
-	pos += 3;
-	WPA_PUT_BE32(pos, EAP_TYPE_NAK);
-	pos += 4;
+	wpabuf_put_be24(resp, EAP_VENDOR_IETF);
+	wpabuf_put_be32(resp, EAP_TYPE_NAK);
 
 	for (m = methods; m; m = m->next) {
 		if (sm->reqVendor == m->vendor &&
@@ -792,37 +770,30 @@
 			wpa_printf(MSG_DEBUG, "EAP: allowed type: "
 				   "vendor=%u method=%u",
 				   m->vendor, m->method);
-			*pos++ = EAP_TYPE_EXPANDED;
-			WPA_PUT_BE24(pos, m->vendor);
-			pos += 3;
-			WPA_PUT_BE32(pos, m->method);
-			pos += 4;
-
-			(*len) += 8;
+			wpabuf_put_u8(resp, EAP_TYPE_EXPANDED);
+			wpabuf_put_be24(resp, m->vendor);
+			wpabuf_put_be32(resp, m->method);
+
 			found++;
 		}
 	}
 	if (!found) {
 		wpa_printf(MSG_DEBUG, "EAP: no more allowed methods");
-		*pos++ = EAP_TYPE_EXPANDED;
-		WPA_PUT_BE24(pos, EAP_VENDOR_IETF);
-		pos += 3;
-		WPA_PUT_BE32(pos, EAP_TYPE_NONE);
-		pos += 4;
-
-		(*len) += 8;
-	}
-
-	resp->length = host_to_be16(*len);
-
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_sm_buildNak(struct eap_sm *sm, int id, size_t *len)
-{
-	struct eap_hdr *resp;
-	u8 *pos;
+		wpabuf_put_u8(resp, EAP_TYPE_EXPANDED);
+		wpabuf_put_be24(resp, EAP_VENDOR_IETF);
+		wpabuf_put_be32(resp, EAP_TYPE_NONE);
+	}
+
+	eap_update_len(resp);
+
+	return resp;
+}
+
+
+static struct wpabuf * eap_sm_buildNak(struct eap_sm *sm, int id)
+{
+	struct wpabuf *resp;
+	u8 *start;
 	int found = 0, expanded_found = 0;
 	size_t count;
 	const struct eap_method *methods, *m;
@@ -834,19 +805,16 @@
 	if (methods == NULL)
 		return NULL;
 	if (sm->reqMethod == EAP_TYPE_EXPANDED)
-		return eap_sm_build_expanded_nak(sm, id, len, methods, count);
+		return eap_sm_build_expanded_nak(sm, id, methods, count);
 
 	/* RFC 3748 - 5.3.1: Legacy Nak */
-	*len = sizeof(struct eap_hdr) + 1;
-	resp = os_malloc(*len + count + 1);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK,
+			     sizeof(struct eap_hdr) + 1 + count + 1,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	resp->code = EAP_CODE_RESPONSE;
-	resp->identifier = id;
-	pos = (u8 *) (resp + 1);
-	*pos++ = EAP_TYPE_NAK;
-
+	start = wpabuf_put(resp, 0);
 	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 */
@@ -855,29 +823,25 @@
 				if (expanded_found)
 					continue;
 				expanded_found = 1;
-				*pos++ = EAP_TYPE_EXPANDED;
+				wpabuf_put_u8(resp, EAP_TYPE_EXPANDED);
 			} else
-				*pos++ = m->method;
-			(*len)++;
+				wpabuf_put_u8(resp, m->method);
 			found++;
 		}
 	}
-	if (!found) {
-		*pos = EAP_TYPE_NONE;
-		(*len)++;
-	}
-	wpa_hexdump(MSG_DEBUG, "EAP: allowed methods",
-		    ((u8 *) (resp + 1)) + 1, found);
-
-	resp->length = host_to_be16(*len);
-
-	return (u8 *) resp;
-}
-
-
-static void eap_sm_processIdentity(struct eap_sm *sm, const u8 *req)
-{
-	const struct eap_hdr *hdr = (const struct eap_hdr *) req;
+	if (!found)
+		wpabuf_put_u8(resp, EAP_TYPE_NONE);
+	wpa_hexdump(MSG_DEBUG, "EAP: allowed methods", start, found);
+
+	eap_update_len(resp);
+
+	return resp;
+}
+
+
+static void eap_sm_processIdentity(struct eap_sm *sm, const struct wpabuf *req)
+{
+	const struct eap_hdr *hdr = wpabuf_head(req);
 	const u8 *pos = (const u8 *) (hdr + 1);
 	pos++;
 
@@ -968,7 +932,6 @@
  * eap_sm_buildIdentity - Build EAP-Identity/Response for the current network
  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
  * @id: EAP identifier for the packet
- * @len: Pointer to a variable that will be set to the length of the response
  * @encrypted: Whether the packet is for encrypted tunnel (EAP phase 2)
  * Returns: Pointer to the allocated EAP-Identity/Response packet or %NULL on
  * failure
@@ -976,12 +939,10 @@
  * This function allocates and builds an EAP-Identity/Response packet for the
  * current network. The caller is responsible for freeing the returned data.
  */
-u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
-			  int encrypted)
+struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted)
 {
 	struct wpa_ssid *config = eap_get_config(sm);
-	struct eap_hdr *resp;
-	u8 *pos;
+	struct wpabuf *resp;
 	const u8 *identity;
 	size_t identity_len;
 
@@ -1024,36 +985,27 @@
 		}
 	}
 
-	*len = sizeof(struct eap_hdr) + 1 + identity_len;
-	resp = os_malloc(*len);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, identity_len,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	resp->code = EAP_CODE_RESPONSE;
-	resp->identifier = id;
-	resp->length = host_to_be16(*len);
-	pos = (u8 *) (resp + 1);
-	*pos++ = EAP_TYPE_IDENTITY;
-	os_memcpy(pos, identity, identity_len);
-
-	return (u8 *) resp;
-}
-
-
-static void eap_sm_processNotify(struct eap_sm *sm, const u8 *req)
-{
-	const struct eap_hdr *hdr = (const struct eap_hdr *) req;
+	wpabuf_put_data(resp, identity, identity_len);
+
+	return resp;
+}
+
+
+static void eap_sm_processNotify(struct eap_sm *sm, const struct wpabuf *req)
+{
 	const u8 *pos;
 	char *msg;
 	size_t i, msg_len;
 
-	pos = (const u8 *) (hdr + 1);
-	pos++;
-
-	msg_len = be_to_host16(hdr->length);
-	if (msg_len < 5)
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, req,
+			       &msg_len);
+	if (pos == NULL)
 		return;
-	msg_len -= 5;
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP: EAP-Request Notification data",
 			  pos, msg_len);
 
@@ -1069,28 +1021,21 @@
 }
 
 
-static u8 * eap_sm_buildNotify(int id, size_t *len)
-{
-	struct eap_hdr *resp;
-	u8 *pos;
+static struct wpabuf * eap_sm_buildNotify(int id)
+{
+	struct wpabuf *resp;
 
 	wpa_printf(MSG_DEBUG, "EAP: Generating EAP-Response Notification");
-	*len = sizeof(struct eap_hdr) + 1;
-	resp = os_malloc(*len);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NOTIFICATION, 0,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	resp->code = EAP_CODE_RESPONSE;
-	resp->identifier = id;
-	resp->length = host_to_be16(*len);
-	pos = (u8 *) (resp + 1);
-	*pos = EAP_TYPE_NOTIFICATION;
-
-	return (u8 *) resp;
-}
-
-
-static void eap_sm_parseEapReq(struct eap_sm *sm, const u8 *req, size_t len)
+	return resp;
+}
+
+
+static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req)
 {
 	const struct eap_hdr *hdr;
 	size_t plen;
@@ -1102,22 +1047,25 @@
 	sm->reqVendor = EAP_VENDOR_IETF;
 	sm->reqVendorMethod = EAP_TYPE_NONE;
 
-	if (req == NULL || len < sizeof(*hdr))
+	if (req == NULL || wpabuf_len(req) < sizeof(*hdr))
 		return;
 
-	hdr = (const struct eap_hdr *) req;
+	hdr = wpabuf_head(req);
 	plen = be_to_host16(hdr->length);
-	if (plen > len) {
+	if (plen > wpabuf_len(req)) {
 		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
 			   "(len=%lu plen=%lu)",
-			   (unsigned long) len, (unsigned long) plen);
+			   (unsigned long) wpabuf_len(req),
+			   (unsigned long) plen);
 		return;
 	}
 
 	sm->reqId = hdr->identifier;
 
 	if (sm->workaround) {
-		md5_vector(1, (const u8 **) &req, &plen, sm->req_md5);
+		const u8 *addr[1];
+		addr[0] = wpabuf_head(req);
+		md5_vector(1, addr, &plen, sm->req_md5);
 	}
 
 	switch (hdr->code) {
@@ -1278,9 +1226,9 @@
  */
 void eap_sm_abort(struct eap_sm *sm)
 {
-	os_free(sm->lastRespData);
+	wpabuf_free(sm->lastRespData);
 	sm->lastRespData = NULL;
-	os_free(sm->eapRespData);
+	wpabuf_free(sm->eapRespData);
 	sm->eapRespData = NULL;
 	os_free(sm->eapKeyData);
 	sm->eapKeyData = NULL;
@@ -1962,7 +1910,6 @@
 /**
  * eap_get_eapKeyData - Get EAP response data
  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
- * @len: Pointer to variable that will be set to the length of the response
  * Returns: Pointer to the EAP response (eapRespData) or %NULL on failure
  *
  * Fetch EAP response (eapRespData) from the EAP state machine. This data is
@@ -1970,19 +1917,15 @@
  * EAP state machine does not maintain a reference to the response after this
  * function is called and the caller is responsible for freeing the data.
  */
-u8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len)
-{
-	u8 *resp;
-
-	if (sm == NULL || sm->eapRespData == NULL) {
-		*len = 0;
+struct wpabuf * eap_get_eapRespData(struct eap_sm *sm)
+{
+	struct wpabuf *resp;
+
+	if (sm == NULL || sm->eapRespData == NULL)
 		return NULL;
-	}
 
 	resp = sm->eapRespData;
-	*len = sm->eapRespDataLen;
 	sm->eapRespData = NULL;
-	sm->eapRespDataLen = 0;
 
 	return resp;
 }

Modified: wpasupplicant/trunk/src/eap_peer/eap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap.h Tue Dec 25 15:23:24 2007
@@ -22,6 +22,7 @@
 struct eap_sm;
 struct wpa_ssid;
 struct wpa_config_blob;
+struct wpabuf;
 
 struct eap_method_type {
 	int vendor;
@@ -180,7 +181,7 @@
 	 * Returns: Reference to eapReqData (EAP state machine will not free
 	 * this) or %NULL if eapReqData not available.
 	 */
-	u8 * (*get_eapReqData)(void *ctx, size_t *len);
+	struct wpabuf * (*get_eapReqData)(void *ctx);
 
 	/**
 	 * set_config_blob - Set named configuration blob
@@ -246,8 +247,7 @@
 void eap_sm_abort(struct eap_sm *sm);
 int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen,
 		      int verbose);
-u8 * eap_sm_buildIdentity(struct eap_sm *sm, int id, size_t *len,
-			  int encrypted);
+struct wpabuf * eap_sm_buildIdentity(struct eap_sm *sm, int id, int encrypted);
 void eap_sm_request_identity(struct eap_sm *sm);
 void eap_sm_request_password(struct eap_sm *sm);
 void eap_sm_request_new_password(struct eap_sm *sm);
@@ -265,7 +265,7 @@
 void eap_notify_success(struct eap_sm *sm);
 void eap_notify_lower_layer_success(struct eap_sm *sm);
 const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len);
-u8 * eap_get_eapRespData(struct eap_sm *sm, size_t *len);
+struct wpabuf * eap_get_eapRespData(struct eap_sm *sm);
 void eap_register_scard_ctx(struct eap_sm *sm, void *ctx);
 void eap_invalidate_cached_session(struct eap_sm *sm);
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_aka.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_aka.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_aka.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_aka.c Tue Dec 25 15:23:24 2007
@@ -18,6 +18,9 @@
 #include "eap_peer/eap_i.h"
 #include "pcsc_funcs.h"
 #include "eap_common/eap_sim_common.h"
+#include "sha1.h"
+#include "crypto.h"
+#include "config_ssid.h"
 
 
 struct eap_aka_data {
@@ -41,18 +44,60 @@
 	unsigned int counter, counter_too_small;
 	u8 *last_eap_identity;
 	size_t last_eap_identity_len;
-	enum { CONTINUE, SUCCESS, FAILURE } state;
+	enum {
+		CONTINUE, RESULT_SUCCESS, RESULT_FAILURE, SUCCESS, FAILURE
+	} state;
+
+	struct wpabuf *id_msgs;
+	int prev_id;
+	int result_ind, use_result_ind;
 };
 
 
+#ifndef CONFIG_NO_STDOUT_DEBUG
+static const char * eap_aka_state_txt(int state)
+{
+	switch (state) {
+	case CONTINUE:
+		return "CONTINUE";
+	case RESULT_SUCCESS:
+		return "RESULT_SUCCESS";
+	case RESULT_FAILURE:
+		return "RESULT_FAILURE";
+	case SUCCESS:
+		return "SUCCESS";
+	case FAILURE:
+		return "FAILURE";
+	default:
+		return "?";
+	}
+}
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+
+
+static void eap_aka_state(struct eap_aka_data *data, int state)
+{
+	wpa_printf(MSG_DEBUG, "EAP-AKA: %s -> %s",
+		   eap_aka_state_txt(data->state),
+		   eap_aka_state_txt(state));
+	data->state = state;
+}
+
+
 static void * eap_aka_init(struct eap_sm *sm)
 {
 	struct eap_aka_data *data;
+	struct wpa_ssid *config = eap_get_config(sm);
+
 	data = os_zalloc(sizeof(*data));
 	if (data == NULL)
 		return NULL;
 
-	data->state = CONTINUE;
+	eap_aka_state(data, CONTINUE);
+	data->prev_id = -1;
+
+	data->result_ind = config && config->phase1 &&
+			    os_strstr(config->phase1, "result_ind=1") != NULL;
 
 	return data;
 }
@@ -65,6 +110,7 @@
 		os_free(data->pseudonym);
 		os_free(data->reauth_id);
 		os_free(data->last_eap_identity);
+		wpabuf_free(data->id_msgs);
 		os_free(data);
 	}
 }
@@ -177,45 +223,130 @@
 }
 
 
-static u8 * eap_aka_client_error(struct eap_aka_data *data,
-				 const struct eap_hdr *req,
-				 size_t *respDataLen, int err)
+static int eap_aka_add_id_msg(struct eap_aka_data *data,
+			      const struct wpabuf *msg)
+{
+	if (msg == NULL)
+		return -1;
+
+	if (data->id_msgs == NULL) {
+		data->id_msgs = wpabuf_dup(msg);
+		return data->id_msgs == NULL ? -1 : 0;
+	}
+
+	if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0)
+		return -1;
+	wpabuf_put_buf(data->id_msgs, msg);
+
+	return 0;
+}
+
+
+static void eap_aka_add_checkcode(struct eap_aka_data *data,
+				  struct eap_sim_msg *msg)
+{
+	const u8 *addr;
+	size_t len;
+	u8 hash[SHA1_MAC_LEN];
+
+	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
+
+	if (data->id_msgs == NULL) {
+		/*
+		 * No EAP-AKA/Identity packets were exchanged - send empty
+		 * checkcode.
+		 */
+		eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0);
+		return;
+	}
+
+	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	addr = wpabuf_head(data->id_msgs);
+	len = wpabuf_len(data->id_msgs);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
+	sha1_vector(1, &addr, &len, hash);
+
+	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
+			EAP_AKA_CHECKCODE_LEN);
+}
+
+
+static int eap_aka_verify_checkcode(struct eap_aka_data *data,
+				    const u8 *checkcode, size_t checkcode_len)
+{
+	const u8 *addr;
+	size_t len;
+	u8 hash[SHA1_MAC_LEN];
+
+	if (checkcode == NULL)
+		return -1;
+
+	if (data->id_msgs == NULL) {
+		if (checkcode_len != 0) {
+			wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
+				   "indicates that AKA/Identity messages were "
+				   "used, but they were not");
+			return -1;
+		}
+		return 0;
+	}
+
+	if (checkcode_len != EAP_AKA_CHECKCODE_LEN) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from server "
+			   "indicates that AKA/Identity message were not "
+			   "used, but they were");
+		return -1;
+	}
+
+	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	addr = wpabuf_head(data->id_msgs);
+	len = wpabuf_len(data->id_msgs);
+	sha1_vector(1, &addr, &len, hash);
+
+	if (os_memcmp(hash, checkcode, EAP_AKA_CHECKCODE_LEN) != 0) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static struct wpabuf * eap_aka_client_error(struct eap_aka_data *data, u8 id,
+					    int err)
 {
 	struct eap_sim_msg *msg;
 
-	data->state = FAILURE;
+	eap_aka_state(data, FAILURE);
 	data->num_id_req = 0;
 	data->num_notification = 0;
 
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CLIENT_ERROR);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+			       EAP_AKA_SUBTYPE_CLIENT_ERROR);
 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
-	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_aka_authentication_reject(struct eap_aka_data *data,
-					  const struct eap_hdr *req,
-					  size_t *respDataLen)
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_authentication_reject(struct eap_aka_data *data,
+						     u8 id)
 {
 	struct eap_sim_msg *msg;
 
-	data->state = FAILURE;
+	eap_aka_state(data, FAILURE);
 	data->num_id_req = 0;
 	data->num_notification = 0;
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Authentication-Reject "
-		   "(id=%d)", req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA,
+		   "(id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
 			       EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT);
-	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_aka_synchronization_failure(struct eap_aka_data *data,
-					    const struct eap_hdr *req,
-					    size_t *respDataLen)
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_synchronization_failure(
+	struct eap_aka_data *data, u8 id)
 {
 	struct eap_sim_msg *msg;
 
@@ -223,22 +354,20 @@
 	data->num_notification = 0;
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Synchronization-Failure "
-		   "(id=%d)", req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA,
+		   "(id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
 			       EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE);
 	wpa_printf(MSG_DEBUG, "   AT_AUTS");
 	eap_sim_msg_add_full(msg, EAP_SIM_AT_AUTS, data->auts,
 			     EAP_AKA_AUTS_LEN);
-	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_aka_response_identity(struct eap_sm *sm,
-				      struct eap_aka_data *data,
-				      const struct eap_hdr *req,
-				      size_t *respDataLen,
-				      enum eap_sim_id_req id_req)
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_response_identity(struct eap_sm *sm,
+						 struct eap_aka_data *data,
+						 u8 id,
+						 enum eap_sim_id_req id_req)
 {
 	const u8 *identity = NULL;
 	size_t identity_len = 0;
@@ -264,10 +393,9 @@
 	if (id_req != NO_ID_REQ)
 		eap_aka_clear_identities(data, CLEAR_EAP_ID);
 
-	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_IDENTITY);
+	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Identity (id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+			       EAP_AKA_SUBTYPE_IDENTITY);
 
 	if (identity) {
 		wpa_hexdump_ascii(MSG_DEBUG, "   AT_IDENTITY",
@@ -276,41 +404,42 @@
 				identity, identity_len);
 	}
 
-	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_aka_response_challenge(struct eap_aka_data *data,
-				       const struct eap_hdr *req,
-				       size_t *respDataLen)
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_response_challenge(struct eap_aka_data *data,
+						  u8 id)
 {
 	struct eap_sim_msg *msg;
 
-	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_CHALLENGE);
+	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Challenge (id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+			       EAP_AKA_SUBTYPE_CHALLENGE);
 	wpa_printf(MSG_DEBUG, "   AT_RES");
 	eap_sim_msg_add(msg, EAP_SIM_AT_RES, data->res_len,
 			data->res, data->res_len);
+	eap_aka_add_checkcode(data, msg);
+	if (data->use_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, respDataLen, data->k_aut, (u8 *) "", 0);
-}
-
-
-static u8 * eap_aka_response_reauth(struct eap_aka_data *data,
-				    const struct eap_hdr *req,
-				    size_t *respDataLen, int counter_too_small,
-				    const u8 *nonce_s)
+	return eap_sim_msg_finish(msg, data->k_aut, (u8 *) "", 0);
+}
+
+
+static struct wpabuf * eap_aka_response_reauth(struct eap_aka_data *data,
+					       u8 id, int counter_too_small,
+					       const u8 *nonce_s)
 {
 	struct eap_sim_msg *msg;
 	unsigned int counter;
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Reauthentication (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA,
+		   id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
 			       EAP_AKA_SUBTYPE_REAUTHENTICATION);
 	wpa_printf(MSG_DEBUG, "   AT_IV");
 	wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
@@ -332,25 +461,27 @@
 		eap_sim_msg_free(msg);
 		return NULL;
 	}
+	eap_aka_add_checkcode(data, msg);
+	if (data->use_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, respDataLen, data->k_aut, nonce_s,
+	return eap_sim_msg_finish(msg, data->k_aut, nonce_s,
 				  EAP_SIM_NONCE_S_LEN);
 }
 
 
-static u8 * eap_aka_response_notification(struct eap_aka_data *data,
-					  const struct eap_hdr *req,
-					  size_t *respDataLen,
-					  u16 notification)
+static struct wpabuf * eap_aka_response_notification(struct eap_aka_data *data,
+						     u8 id, u16 notification)
 {
 	struct eap_sim_msg *msg;
 	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
 
-	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_AKA, EAP_AKA_SUBTYPE_NOTIFICATION);
+	wpa_printf(MSG_DEBUG, "Generating EAP-AKA Notification (id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_AKA,
+			       EAP_AKA_SUBTYPE_NOTIFICATION);
 	if (k_aut && data->reauth) {
 		wpa_printf(MSG_DEBUG, "   AT_IV");
 		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
@@ -371,17 +502,18 @@
 		wpa_printf(MSG_DEBUG, "   AT_MAC");
 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
 	}
-	return eap_sim_msg_finish(msg, respDataLen, k_aut, (u8 *) "", 0);
-}
-
-
-static u8 * eap_aka_process_identity(struct eap_sm *sm,
-				     struct eap_aka_data *data,
-				     const struct eap_hdr *req,
-				     size_t *respDataLen,
-				     struct eap_sim_attrs *attr)
+	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
+}
+
+
+static struct wpabuf * eap_aka_process_identity(struct eap_sm *sm,
+						struct eap_aka_data *data,
+						u8 id,
+						const struct wpabuf *reqData,
+						struct eap_sim_attrs *attr)
 {
 	int id_error;
+	struct wpabuf *buf;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Identity");
 
@@ -408,21 +540,27 @@
 	if (id_error) {
 		wpa_printf(MSG_INFO, "EAP-AKA: Too many ID requests "
 			   "used within one authentication");
-		return eap_aka_client_error(data, req, respDataLen,
-					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
-	}
-
-	return eap_aka_response_identity(sm, data, req, respDataLen,
-					 attr->id_req);
-}
-
-
-static u8 * eap_aka_process_challenge(struct eap_sm *sm,
-				      struct eap_aka_data *data,
-				      const struct eap_hdr *req,
-				      size_t reqDataLen,
-				      size_t *respDataLen,
-				      struct eap_sim_attrs *attr)
+		return eap_aka_client_error(data, id,
+					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+	}
+
+	buf = eap_aka_response_identity(sm, data, id, attr->id_req);
+
+	if (data->prev_id != id) {
+		eap_aka_add_id_msg(data, reqData);
+		eap_aka_add_id_msg(data, buf);
+		data->prev_id = id;
+	}
+
+	return buf;
+}
+
+
+static struct wpabuf * eap_aka_process_challenge(struct eap_sm *sm,
+						 struct eap_aka_data *data,
+						 u8 id,
+						 const struct wpabuf *reqData,
+						 struct eap_sim_attrs *attr)
 {
 	const u8 *identity;
 	size_t identity_len;
@@ -430,6 +568,16 @@
 	struct eap_sim_attrs eattr;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Challenge");
+
+	if (attr->checkcode &&
+	    eap_aka_verify_checkcode(data, attr->checkcode,
+				     attr->checkcode_len)) {
+		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
+			   "message");
+		return eap_aka_client_error(data, id,
+					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+	}
+
 	data->reauth = 0;
 	if (!attr->mac || !attr->rand || !attr->autn) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
@@ -437,7 +585,7 @@
 			   !attr->mac ? " AT_MAC" : "",
 			   !attr->rand ? " AT_RAND" : "",
 			   !attr->autn ? " AT_AUTN" : "");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 	os_memcpy(data->rand, attr->rand, EAP_AKA_RAND_LEN);
@@ -447,14 +595,14 @@
 	if (res == -1) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
 			   "failed (AUTN)");
-		return eap_aka_authentication_reject(data, req, respDataLen);
+		return eap_aka_authentication_reject(data, id);
 	} else if (res == -2) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication "
 			   "failed (AUTN seq# -> AUTS)");
-		return eap_aka_synchronization_failure(data, req, respDataLen);
+		return eap_aka_synchronization_failure(data, id);
 	} else if (res) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: UMTS authentication failed");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 	if (data->last_eap_identity) {
@@ -471,11 +619,11 @@
 			  data->mk);
 	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
 			    data->emsk);
-	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
-			       attr->mac, (u8 *) "", 0)) {
+	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
+	{
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
 			   "used invalid AT_MAC");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -492,15 +640,19 @@
 					       &eattr, 0);
 		if (decrypted == NULL) {
 			return eap_aka_client_error(
-				data, req, respDataLen,
-				EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+				data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 		}
 		eap_aka_learn_ids(data, &eattr);
 		os_free(decrypted);
 	}
 
-	if (data->state != FAILURE)
-		data->state = SUCCESS;
+	if (data->result_ind && attr->result_ind)
+		data->use_result_ind = 1;
+
+	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
+		eap_aka_state(data, data->use_result_ind ?
+			      RESULT_SUCCESS : SUCCESS);
+	}
 
 	data->num_id_req = 0;
 	data->num_notification = 0;
@@ -508,7 +660,7 @@
 	 * fullauth, but initializing it to zero makes it easier to implement
 	 * reauth verification. */
 	data->counter = 0;
-	return eap_aka_response_challenge(data, req, respDataLen);
+	return eap_aka_response_challenge(data, id);
 }
 
 
@@ -547,8 +699,7 @@
 
 
 static int eap_aka_process_notification_auth(struct eap_aka_data *data,
-					     const struct eap_hdr *req,
-					     size_t reqDataLen,
+					     const struct wpabuf *reqData,
 					     struct eap_sim_attrs *attr)
 {
 	if (attr->mac == NULL) {
@@ -557,8 +708,8 @@
 		return -1;
 	}
 
-	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
-			       attr->mac, (u8 *) "", 0)) {
+	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
+	{
 		wpa_printf(MSG_WARNING, "EAP-AKA: Notification message "
 			   "used invalid AT_MAC");
 		return -1;
@@ -575,75 +726,79 @@
 }
 
 
-static u8 * eap_aka_process_notification(struct eap_sm *sm,
-					 struct eap_aka_data *data,
-					 const struct eap_hdr *req,
-					 size_t reqDataLen,
-					 size_t *respDataLen,
-					 struct eap_sim_attrs *attr)
+static struct wpabuf * eap_aka_process_notification(
+	struct eap_sm *sm, struct eap_aka_data *data, u8 id,
+	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Notification");
 	if (data->num_notification > 0) {
 		wpa_printf(MSG_INFO, "EAP-AKA: too many notification "
 			   "rounds (only one allowed)");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 	data->num_notification++;
 	if (attr->notification == -1) {
 		wpa_printf(MSG_INFO, "EAP-AKA: no AT_NOTIFICATION in "
 			   "Notification message");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	if ((attr->notification & 0x4000) == 0 &&
-	    eap_aka_process_notification_auth(data, req, reqDataLen, attr)) {
-		return eap_aka_client_error(data, req, respDataLen,
+	    eap_aka_process_notification_auth(data, reqData, attr)) {
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	eap_sim_report_notification(sm->msg_ctx, attr->notification, 1);
 	if (attr->notification >= 0 && attr->notification < 32768) {
-		data->state = FAILURE;
-	}
-	return eap_aka_response_notification(data, req, respDataLen,
-					     attr->notification);
-}
-
-
-static u8 * eap_aka_process_reauthentication(struct eap_sm *sm,
-					     struct eap_aka_data *data,
-					     const struct eap_hdr *req,
-					     size_t reqDataLen,
-					     size_t *respDataLen,
-					     struct eap_sim_attrs *attr)
+		eap_aka_state(data, FAILURE);
+	} else if (attr->notification == EAP_SIM_SUCCESS &&
+		   data->state == RESULT_SUCCESS)
+		eap_aka_state(data, SUCCESS);
+	return eap_aka_response_notification(data, id, attr->notification);
+}
+
+
+static struct wpabuf * eap_aka_process_reauthentication(
+	struct eap_sm *sm, struct eap_aka_data *data, u8 id,
+	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
 {
 	struct eap_sim_attrs eattr;
 	u8 *decrypted;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Reauthentication");
+
+	if (attr->checkcode &&
+	    eap_aka_verify_checkcode(data, attr->checkcode,
+				     attr->checkcode_len)) {
+		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
+			   "message");
+		return eap_aka_client_error(data, id,
+					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+	}
 
 	if (data->reauth_id == NULL) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Server is trying "
 			   "reauthentication, but no reauth_id available");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	data->reauth = 1;
-	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
-			       attr->mac, (u8 *) "", 0)) {
+	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
+	{
 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
 			   "did not have valid AT_MAC");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	if (attr->encr_data == NULL || attr->iv == NULL) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Reauthentication "
 			   "message did not include encrypted data");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -653,7 +808,7 @@
 	if (decrypted == NULL) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Failed to parse encrypted "
 			   "data from reauthentication message");
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -662,12 +817,12 @@
 			   !eattr.nonce_s ? " AT_NONCE_S" : "",
 			   eattr.counter < 0 ? " AT_COUNTER" : "");
 		os_free(decrypted);
-		return eap_aka_client_error(data, req, respDataLen,
+		return eap_aka_client_error(data, id,
 					    EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) {
-		u8 *res;
+		struct wpabuf *res;
 		wpa_printf(MSG_INFO, "EAP-AKA: (encr) Invalid counter "
 			   "(%d <= %d)", eattr.counter, data->counter);
 		data->counter_too_small = eattr.counter;
@@ -687,8 +842,7 @@
 		data->reauth_id = NULL;
 		data->reauth_id_len = 0;
 
-		res = eap_aka_response_reauth(data, req, respDataLen, 1,
-					      eattr.nonce_s);
+		res = eap_aka_response_reauth(data, id, 1, eattr.nonce_s);
 		os_free(decrypted);
 
 		return res;
@@ -706,8 +860,13 @@
 	eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 	eap_aka_learn_ids(data, &eattr);
 
-	if (data->state != FAILURE)
-		data->state = SUCCESS;
+	if (data->result_ind && attr->result_ind)
+		data->use_result_ind = 1;
+
+	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
+		eap_aka_state(data, data->use_result_ind ?
+			      RESULT_SUCCESS : SUCCESS);
+	}
 
 	data->num_id_req = 0;
 	data->num_notification = 0;
@@ -717,24 +876,23 @@
 		eap_aka_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 	}
 	os_free(decrypted);
-	return eap_aka_response_reauth(data, req, respDataLen, 0,
-				       data->nonce_s);
-}
-
-
-static u8 * eap_aka_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+	return eap_aka_response_reauth(data, id, 0, data->nonce_s);
+}
+
+
+static struct wpabuf * eap_aka_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_aka_data *data = priv;
 	const struct eap_hdr *req;
-	u8 subtype, *res;
+	u8 subtype, id;
+	struct wpabuf *res;
 	const u8 *pos;
 	struct eap_sim_attrs attr;
 	size_t len;
 
-	wpa_hexdump(MSG_DEBUG, "EAP-AKA: EAP data", reqData, reqDataLen);
+	wpa_hexdump_buf(MSG_DEBUG, "EAP-AKA: EAP data", reqData);
 	if (eap_get_config_identity(sm, &len) == NULL) {
 		wpa_printf(MSG_INFO, "EAP-AKA: Identity not configured");
 		eap_sm_request_identity(sm);
@@ -742,13 +900,13 @@
 		return NULL;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, reqData, &len);
 	if (pos == NULL || len < 1) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	req = (const struct eap_hdr *) reqData;
+	req = wpabuf_head(reqData);
+	id = req->identifier;
 	len = be_to_host16(req->length);
 
 	ret->ignore = FALSE;
@@ -760,37 +918,36 @@
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Subtype=%d", subtype);
 	pos += 2; /* Reserved */
 
-	if (eap_sim_parse_attr(pos, reqData + len, &attr, 1, 0)) {
-		res = eap_aka_client_error(data, req, respDataLen,
+	if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 1,
+			       0)) {
+		res = eap_aka_client_error(data, id,
 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 		goto done;
 	}
 
 	switch (subtype) {
 	case EAP_AKA_SUBTYPE_IDENTITY:
-		res = eap_aka_process_identity(sm, data, req,
-					       respDataLen, &attr);
+		res = eap_aka_process_identity(sm, data, id, reqData, &attr);
 		break;
 	case EAP_AKA_SUBTYPE_CHALLENGE:
-		res = eap_aka_process_challenge(sm, data, req, len,
-						respDataLen, &attr);
+		res = eap_aka_process_challenge(sm, data, id, reqData, &attr);
 		break;
 	case EAP_AKA_SUBTYPE_NOTIFICATION:
-		res = eap_aka_process_notification(sm, data, req, len,
-						   respDataLen, &attr);
+		res = eap_aka_process_notification(sm, data, id, reqData,
+						   &attr);
 		break;
 	case EAP_AKA_SUBTYPE_REAUTHENTICATION:
-		res = eap_aka_process_reauthentication(sm, data, req, len,
-						       respDataLen, &attr);
+		res = eap_aka_process_reauthentication(sm, data, id, reqData,
+						       &attr);
 		break;
 	case EAP_AKA_SUBTYPE_CLIENT_ERROR:
 		wpa_printf(MSG_DEBUG, "EAP-AKA: subtype Client-Error");
-		res = eap_aka_client_error(data, req, respDataLen,
+		res = eap_aka_client_error(data, id,
 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown subtype=%d", subtype);
-		res = eap_aka_client_error(data, req, respDataLen,
+		res = eap_aka_client_error(data, id,
 					   EAP_AKA_UNABLE_TO_PROCESS_PACKET);
 		break;
 	}
@@ -800,14 +957,19 @@
 		ret->decision = DECISION_FAIL;
 		ret->methodState = METHOD_DONE;
 	} else if (data->state == SUCCESS) {
-		ret->decision = DECISION_COND_SUCC;
+		ret->decision = data->use_result_ind ?
+			DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
 		/*
 		 * It is possible for the server to reply with AKA
 		 * Notification, so we must allow the method to continue and
 		 * not only accept EAP-Success at this point.
 		 */
-		ret->methodState = METHOD_MAY_CONT;
-	}
+		ret->methodState = data->use_result_ind ?
+			METHOD_DONE : METHOD_MAY_CONT;
+	} else if (data->state == RESULT_FAILURE)
+		ret->methodState = METHOD_CONT;
+	else if (data->state == RESULT_SUCCESS)
+		ret->methodState = METHOD_CONT;
 
 	if (ret->methodState == METHOD_DONE) {
 		ret->allowNotifications = FALSE;
@@ -828,6 +990,10 @@
 {
 	struct eap_aka_data *data = priv;
 	eap_aka_clear_identities(data, CLEAR_EAP_ID);
+	data->prev_id = -1;
+	wpabuf_free(data->id_msgs);
+	data->id_msgs = NULL;
+	data->use_result_ind = 0;
 }
 
 
@@ -836,7 +1002,7 @@
 	struct eap_aka_data *data = priv;
 	data->num_id_req = 0;
 	data->num_notification = 0;
-	data->state = CONTINUE;
+	eap_aka_state(data, CONTINUE);
 	return priv;
 }
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_fast.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_fast.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_fast.c Tue Dec 25 15:23:24 2007
@@ -70,8 +70,7 @@
 	u8 simck[EAP_FAST_SIMCK_LEN];
 	int simck_idx;
 
-	u8 *pending_phase2_req;
-	size_t pending_phase2_req_len;
+	struct wpabuf *pending_phase2_req;
 };
 
 
@@ -259,7 +258,7 @@
 		pac = pac->next;
 		eap_fast_free_pac(prev);
 	}
-	os_free(data->pending_phase2_req);
+	wpabuf_free(data->pending_phase2_req);
 	os_free(data);
 }
 
@@ -465,12 +464,13 @@
 				   struct eap_fast_data *data,
 				   struct eap_method_ret *ret,
 				   struct eap_hdr *hdr,
-				   u8 **resp, size_t *resp_len)
+				   struct wpabuf **resp)
 {
 	size_t len = be_to_host16(hdr->length);
 	u8 *pos;
 	struct eap_method_ret iret;
 	struct wpa_ssid *config = eap_get_config(sm);
+	struct wpabuf msg;
 
 	if (len <= sizeof(struct eap_hdr)) {
 		wpa_printf(MSG_INFO, "EAP-FAST: too short "
@@ -480,7 +480,7 @@
 	pos = (u8 *) (hdr + 1);
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Phase 2 Request: type=%d", *pos);
 	if (*pos == EAP_TYPE_IDENTITY) {
-		*resp = eap_sm_buildIdentity(sm, hdr->identifier, resp_len, 1);
+		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
 		return 0;
 	}
 
@@ -489,7 +489,7 @@
 	    eap_fast_select_phase2_method(data, *pos) < 0) {
 		if (eap_peer_tls_phase2_nak(data->phase2_types,
 					    data->num_phase2_types,
-					    hdr, resp, resp_len))
+					    hdr, resp))
 			return -1;
 		return 0;
 	}
@@ -504,8 +504,9 @@
 	}
 
 	os_memset(&iret, 0, sizeof(iret));
+	wpabuf_set(&msg, hdr, len);
 	*resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
-					     (u8 *) hdr, len, resp_len);
+					     &msg);
 	if (*resp == NULL ||
 	    (iret.methodState == METHOD_DONE &&
 	     iret.decision == DECISION_FAIL)) {
@@ -521,12 +522,8 @@
 	if (*resp == NULL && config &&
 	    (config->pending_req_identity || config->pending_req_password ||
 	     config->pending_req_otp || config->pending_req_new_password)) {
-		os_free(data->pending_phase2_req);
-		data->pending_phase2_req = os_malloc(len);
-		if (data->pending_phase2_req) {
-			os_memcpy(data->pending_phase2_req, hdr, len);
-			data->pending_phase2_req_len = len;
-		}
+		wpabuf_free(data->pending_phase2_req);
+		data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
 	} else if (*resp == NULL)
 		return -1;
 
@@ -534,54 +531,57 @@
 }
 
 
-static u8 * eap_fast_tlv_nak(int vendor_id, int tlv_type, size_t *len)
-{
+static struct wpabuf * eap_fast_tlv_nak(int vendor_id, int tlv_type)
+{
+	struct wpabuf *buf;
 	struct eap_tlv_nak_tlv *nak;
-	*len = sizeof(*nak);
-	nak = os_malloc(*len);
-	if (nak == NULL)
-		return NULL;
+	buf = wpabuf_alloc(sizeof(*nak));
+	if (buf == NULL)
+		return NULL;
+	nak = wpabuf_put(buf, sizeof(*nak));
 	nak->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | EAP_TLV_NAK_TLV);
 	nak->length = host_to_be16(6);
 	nak->vendor_id = host_to_be32(vendor_id);
 	nak->nak_type = host_to_be16(tlv_type);
-	return (u8 *) nak;
-}
-
-
-static u8 * eap_fast_tlv_result(int status, int intermediate, size_t *len)
-{
+	return buf;
+}
+
+
+static struct wpabuf * eap_fast_tlv_result(int status, int intermediate)
+{
+	struct wpabuf *buf;
 	struct eap_tlv_intermediate_result_tlv *result;
-	*len = sizeof(*result);
-	result = os_malloc(*len);
-	if (result == NULL)
-		return NULL;
+	buf = wpabuf_alloc(sizeof(*result));
+	if (buf == NULL)
+		return NULL;
+	result = wpabuf_put(buf, sizeof(*result));
 	result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 					(intermediate ?
 					 EAP_TLV_INTERMEDIATE_RESULT_TLV :
 					 EAP_TLV_RESULT_TLV));
 	result->length = host_to_be16(2);
 	result->status = host_to_be16(status);
-	return (u8 *) result;
-}
-
-
-static u8 * eap_fast_tlv_pac_ack(size_t *len)
-{
+	return buf;
+}
+
+
+static struct wpabuf * eap_fast_tlv_pac_ack(void)
+{
+	struct wpabuf *buf;
 	struct eap_tlv_result_tlv *res;
 	struct eap_tlv_pac_ack_tlv *ack;
 
-	*len = sizeof(*res) + sizeof(*ack);
-	res = os_zalloc(*len);
-	if (res == NULL)
-		return NULL;
-
+	buf = wpabuf_alloc(sizeof(*res) + sizeof(*ack));
+	if (buf == NULL)
+		return NULL;
+
+	res = wpabuf_put(buf, sizeof(*res));
 	res->tlv_type = host_to_be16(EAP_TLV_RESULT_TLV |
 				     EAP_TLV_TYPE_MANDATORY);
 	res->length = host_to_be16(sizeof(*res) - sizeof(struct eap_tlv_hdr));
 	res->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
 
-	ack = (struct eap_tlv_pac_ack_tlv *) (res + 1);
+	ack = wpabuf_put(buf, sizeof(*ack));
 	ack->tlv_type = host_to_be16(EAP_TLV_PAC_TLV |
 				     EAP_TLV_TYPE_MANDATORY);
 	ack->length = host_to_be16(sizeof(*ack) - sizeof(struct eap_tlv_hdr));
@@ -589,43 +589,43 @@
 	ack->pac_len = host_to_be16(2);
 	ack->result = host_to_be16(EAP_TLV_RESULT_SUCCESS);
 
-	return (u8 *) res;
-}
-
-
-static u8 * eap_fast_tlv_eap_payload(u8 *buf, size_t *len)
-{
+	return buf;
+}
+
+
+static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf)
+{
+	struct wpabuf *msg;
 	struct eap_tlv_hdr *tlv;
 
 	if (buf == NULL)
 		return NULL;
 
 	/* Encapsulate EAP packet in EAP Payload TLV */
-	tlv = os_malloc(sizeof(*tlv) + *len);
-	if (tlv == NULL) {
-		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
-			   "allocate memory for TLV "
-			   "encapsulation");
-		os_free(buf);
-		return NULL;
-	}
+	msg = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
+	if (msg == NULL) {
+		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
+			   "for TLV encapsulation");
+		wpabuf_free(buf);
+		return NULL;
+	}
+	tlv = wpabuf_put(msg, sizeof(*tlv));
 	tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 				     EAP_TLV_EAP_PAYLOAD_TLV);
-	tlv->length = host_to_be16(*len);
-	os_memcpy(tlv + 1, buf, *len);
-	os_free(buf);
-	*len += sizeof(*tlv);
-	return (u8 *) tlv;
-}
-
-
-static u8 * eap_fast_process_eap_payload_tlv(
+	tlv->length = host_to_be16(wpabuf_len(buf));
+	wpabuf_put_buf(msg, buf);
+	wpabuf_free(buf);
+	return msg;
+}
+
+
+static struct wpabuf * eap_fast_process_eap_payload_tlv(
 	struct eap_sm *sm, struct eap_fast_data *data,
 	struct eap_method_ret *ret, const struct eap_hdr *req,
-	u8 *eap_payload_tlv, size_t eap_payload_tlv_len, size_t *resp_len)
+	u8 *eap_payload_tlv, size_t eap_payload_tlv_len)
 {
 	struct eap_hdr *hdr;
-	u8 *resp = NULL;
+	struct wpabuf *resp = NULL;
 
 	if (eap_payload_tlv_len < sizeof(*hdr)) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: too short EAP "
@@ -647,13 +647,13 @@
 		return NULL;
 	}
 
-	if (eap_fast_phase2_request(sm, data, ret, hdr, &resp, resp_len)) {
+	if (eap_fast_phase2_request(sm, data, ret, hdr, &resp)) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Phase2 Request processing "
 			   "failed");
 		return NULL;
 	}
 
-	return eap_fast_tlv_eap_payload(resp, resp_len);
+	return eap_fast_tlv_eap_payload(resp);
 }
 
 
@@ -801,21 +801,20 @@
 }
 
 
-static u8 * eap_fast_process_crypto_binding(
+static struct wpabuf * eap_fast_process_crypto_binding(
 	struct eap_sm *sm, struct eap_fast_data *data,
 	struct eap_method_ret *ret,
-	struct eap_tlv_crypto_binding__tlv *_bind, size_t bind_len,
-	size_t *resp_len, int final)
-{
-	u8 *resp, *pos;
+	struct eap_tlv_crypto_binding__tlv *_bind, size_t bind_len, int final)
+{
+	struct wpabuf *resp;
+	u8 *pos;
 	struct eap_tlv_intermediate_result_tlv *rresult;
 	u8 cmk[20], cmac[20];
 	int res, req_tunnel_pac = 0;
-
-	if (eap_fast_validate_crypto_binding(_bind) < 0) {
-		return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
-					   resp_len);
-	}
+	size_t len;
+
+	if (eap_fast_validate_crypto_binding(_bind) < 0)
+		return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1);
 
 	if (eap_fast_get_cmk(sm, data, cmk) < 0)
 		return NULL;
@@ -833,8 +832,7 @@
 		    _bind->compound_mac, sizeof(cmac));
 	if (res != 0) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Compound MAC did not match");
-		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
-					   resp_len);
+		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1);
 		os_memcpy(_bind->compound_mac, cmac, sizeof(cmac));
 		return resp;
 	}
@@ -854,13 +852,12 @@
 		req_tunnel_pac = 1;
 	}
 
-	*resp_len = sizeof(*rresult) +
-		sizeof(struct eap_tlv_crypto_binding__tlv);
+	len = sizeof(*rresult) + sizeof(struct eap_tlv_crypto_binding__tlv);
 	if (req_tunnel_pac)
-		*resp_len += sizeof(struct eap_tlv_hdr) +
+		len += sizeof(struct eap_tlv_hdr) +
 			sizeof(struct eap_tlv_request_action_tlv) +
 			sizeof(struct eap_tlv_pac_type_tlv);
-	resp = os_zalloc(*resp_len);
+	resp = wpabuf_alloc(len);
 	if (resp == NULL)
 		return NULL;
 
@@ -868,7 +865,7 @@
 	 * Both intermediate and final Result TLVs are identical, so ok to use
 	 * the same structure definition for them.
 	 */
-	rresult = (struct eap_tlv_intermediate_result_tlv *) resp;
+	rresult = wpabuf_put(resp, sizeof(*rresult));
 	rresult->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 					 (final ? EAP_TLV_RESULT_TLV :
 					  EAP_TLV_INTERMEDIATE_RESULT_TLV));
@@ -884,13 +881,16 @@
 		data->phase2_success = 0;
 	}
 
-	pos = (u8 *) (rresult + 1);
+	pos = wpabuf_put(resp, sizeof(struct eap_tlv_crypto_binding__tlv));
 	eap_fast_write_crypto_binding((struct eap_tlv_crypto_binding__tlv *)
 				      pos, _bind, cmk);
-	pos += sizeof(struct eap_tlv_crypto_binding__tlv);
-
-	if (req_tunnel_pac)
-		eap_fast_write_pac_request(pos, PAC_TYPE_TUNNEL_PAC);
+
+	if (req_tunnel_pac) {
+		u8 *pos2;
+		pos = wpabuf_put(resp, 0);
+		pos2 = eap_fast_write_pac_request(pos, PAC_TYPE_TUNNEL_PAC);
+		wpabuf_put(resp, pos2 - pos);
+	}
 
 	if (final && data->phase2_success) {
 		if (data->anon_provisioning) {
@@ -1114,9 +1114,10 @@
 }
 
 
-static u8 * eap_fast_process_pac(struct eap_sm *sm, struct eap_fast_data *data,
-				 struct eap_method_ret *ret,
-				 u8 *pac, size_t pac_len, size_t *resp_len)
+static struct wpabuf * eap_fast_process_pac(struct eap_sm *sm,
+					    struct eap_fast_data *data,
+					    struct eap_method_ret *ret,
+					    u8 *pac, size_t pac_len)
 {
 	struct wpa_ssid *config = eap_get_config(sm);
 	struct eap_fast_pac entry;
@@ -1124,8 +1125,7 @@
 	os_memset(&entry, 0, sizeof(entry));
 	if (eap_fast_process_pac_tlv(&entry, pac, pac_len) ||
 	    eap_fast_process_pac_info(&entry))
-		return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
-					   resp_len);
+		return eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);
 
 	eap_fast_add_pac(&data->pac, &data->current_pac, &entry);
 	eap_fast_pac_list_truncate(data->pac, data->max_pac_list_len);
@@ -1162,7 +1162,7 @@
 		ret->decision = DECISION_UNCOND_SUCC;
 	}
 	ret->methodState = METHOD_DONE;
-	return eap_fast_tlv_pac_ack(resp_len);
+	return eap_fast_tlv_pac_ack();
 }
 
 
@@ -1254,9 +1254,9 @@
 }
 
 
-static int eap_fast_parse_decrypted(u8 *decrypted, size_t decrypted_len,
+static int eap_fast_parse_decrypted(struct wpabuf *decrypted,
 				    struct eap_fast_tlv_parse *tlv,
-				    u8 **resp, size_t *resp_len)
+				    struct wpabuf **resp)
 {
 	int mandatory, tlv_type, len, res;
 	u8 *pos, *end;
@@ -1264,8 +1264,8 @@
 	os_memset(tlv, 0, sizeof(*tlv));
 
 	/* Parse TLVs from the decrypted Phase 2 data */
-	pos = decrypted;
-	end = decrypted + decrypted_len;
+	pos = wpabuf_mhead(decrypted);
+	end = pos + wpabuf_len(decrypted);
 	while (pos + 4 < end) {
 		mandatory = pos[0] & 0x80;
 		tlv_type = WPA_GET_BE16(pos) & 0x3fff;
@@ -1287,8 +1287,7 @@
 			if (mandatory) {
 				wpa_printf(MSG_DEBUG, "EAP-FAST: Nak unknown "
 					   "mandatory TLV type %d", tlv_type);
-				*resp = eap_fast_tlv_nak(0, tlv_type,
-							 resp_len);
+				*resp = eap_fast_tlv_nak(0, tlv_type);
 				break;
 			} else {
 				wpa_printf(MSG_DEBUG, "EAP-FAST: ignored "
@@ -1306,22 +1305,21 @@
 
 static int eap_fast_encrypt_response(struct eap_sm *sm,
 				     struct eap_fast_data *data,
-				     u8 *resp, size_t resp_len,
-				     u8 identifier,
-				     u8 **out_data, size_t *out_len)
+				     struct wpabuf *resp,
+				     u8 identifier, struct wpabuf **out_data)
 {
 	if (resp == NULL)
 		return 0;
 
-	wpa_hexdump(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",
-		    resp, resp_len);
+	wpa_hexdump_buf(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 data",
+			resp);
 	if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST,
 				 data->fast_version, identifier,
-				 resp, resp_len, out_data, out_len)) {
+				 resp, out_data)) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt a Phase 2 "
 			   "frame");
 	}
-	os_free(resp);
+	wpabuf_free(resp);
 
 	return 0;
 }
@@ -1331,44 +1329,36 @@
 				      struct eap_fast_data *data,
 				      struct eap_method_ret *ret,
 				      const struct eap_hdr *req,
-				      u8 *decrypted, size_t decrypted_len,
-				      u8 **out_data, size_t *out_len)
-{
-	u8 *resp = NULL;
-	size_t resp_len;
+				      struct wpabuf *decrypted,
+				      struct wpabuf **out_data)
+{
+	struct wpabuf *resp = NULL;
 	struct eap_fast_tlv_parse tlv;
 
-	if (eap_fast_parse_decrypted(decrypted, decrypted_len, &tlv,
-				     &resp, &resp_len) < 0)
+	if (eap_fast_parse_decrypted(decrypted, &tlv, &resp) < 0)
 		return 0;
 	if (resp)
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 
 	if (tlv.result == EAP_TLV_RESULT_FAILURE) {
-		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
-					   &resp_len);
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 	}
 
 	if (tlv.iresult == EAP_TLV_RESULT_FAILURE) {
-		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1,
-					   &resp_len);
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 1);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 	}
 
 	if (tlv.eap_payload_tlv) {
 		resp = eap_fast_process_eap_payload_tlv(
 			sm, data, ret, req, tlv.eap_payload_tlv,
-			tlv.eap_payload_tlv_len, &resp_len);
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+			tlv.eap_payload_tlv_len);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 	}
 
 	if (tlv.crypto_binding) {
@@ -1376,91 +1366,83 @@
 		resp = eap_fast_process_crypto_binding(sm, data, ret,
 						       tlv.crypto_binding,
 						       tlv.crypto_binding_len,
-						       &resp_len, final);
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+						       final);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 	}
 
 	if (tlv.pac && tlv.result != EAP_TLV_RESULT_SUCCESS) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: PAC TLV without Result TLV "
 			   "acknowledging success");
-		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0,
-					   &resp_len);
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+		resp = eap_fast_tlv_result(EAP_TLV_RESULT_FAILURE, 0);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 	}
 
 	if (tlv.pac && tlv.result == EAP_TLV_RESULT_SUCCESS) {
 		resp = eap_fast_process_pac(sm, data, ret, tlv.pac,
-					    tlv.pac_len, &resp_len);
-		return eap_fast_encrypt_response(sm, data, resp, resp_len,
-						 req->identifier,
-						 out_data, out_len);
+					    tlv.pac_len);
+		return eap_fast_encrypt_response(sm, data, resp,
+						 req->identifier, out_data);
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-FAST: No recognized TLVs - send "
 		   "empty response packet");
-	return eap_fast_encrypt_response(sm, data, os_malloc(1), 0,
-					 req->identifier,
-					 out_data, out_len);
+	return eap_fast_encrypt_response(sm, data, wpabuf_alloc(1),
+					 req->identifier, out_data);
 }
 
 
 static int eap_fast_decrypt(struct eap_sm *sm, struct eap_fast_data *data,
 			    struct eap_method_ret *ret,
 			    const struct eap_hdr *req,
-			    const u8 *in_data, size_t in_len,
-			    u8 **out_data, size_t *out_len)
-{
-	u8 *in_decrypted;
-	size_t len_decrypted;
+			    const struct wpabuf *in_data,
+			    struct wpabuf **out_data)
+{
+	struct wpabuf *in_decrypted;
 	int res;
 
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"
-		   " Phase 2", (unsigned long) in_len);
+		   " Phase 2", (unsigned long) wpabuf_len(in_data));
 
 	if (data->pending_phase2_req) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Pending Phase 2 request - "
 			   "skip decryption and use old data");
 		/* Clear TLS reassembly state. */
 		eap_peer_tls_reset_input(&data->ssl);
+
 		in_decrypted = data->pending_phase2_req;
 		data->pending_phase2_req = NULL;
-		len_decrypted = data->pending_phase2_req_len;
 		goto continue_req;
 	}
 
-	if (in_len == 0) {
+	if (wpabuf_len(in_data) == 0) {
 		/* Received TLS ACK - requesting more fragments */
 		return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_FAST,
 					    data->fast_version,
-					    req->identifier, NULL, 0,
-					    out_data, out_len);
-	}
-
-	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, in_len,
-				   &in_decrypted, &len_decrypted);
+					    req->identifier, NULL, out_data);
+	}
+
+	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
 	if (res)
 		return res;
 
 continue_req:
-	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",
-		    in_decrypted, len_decrypted);
-
-	if (len_decrypted < 4) {
-		os_free(in_decrypted);
+	wpa_hexdump_buf(MSG_MSGDUMP, "EAP-FAST: Decrypted Phase 2 TLV(s)",
+			in_decrypted);
+
+	if (wpabuf_len(in_decrypted) < 4) {
+		wpabuf_free(in_decrypted);
 		wpa_printf(MSG_INFO, "EAP-FAST: Too short Phase 2 "
-			   "TLV frame (len=%d)", len_decrypted);
+			   "TLV frame (len=%lu)",
+			   (unsigned long) wpabuf_len(in_decrypted));
 		return -1;
 	}
 
 	res = eap_fast_process_decrypted(sm, data, ret, req,
-					 in_decrypted, len_decrypted,
-					 out_data, out_len);
-
-	os_free(in_decrypted);
+					 in_decrypted, out_data);
+
+	wpabuf_free(in_decrypted);
 
 	return res;
 }
@@ -1647,24 +1629,24 @@
 }
 
 
-static u8 * eap_fast_process(struct eap_sm *sm, void *priv,
-			     struct eap_method_ret *ret,
-			     const u8 *reqData, size_t reqDataLen,
-			     size_t *respDataLen)
+static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv,
+					struct eap_method_ret *ret,
+					const struct wpabuf *reqData)
 {
 	const struct eap_hdr *req;
 	size_t left;
 	int res;
-	u8 flags, *resp, id;
+	u8 flags, id;
+	struct wpabuf *resp;
 	const u8 *pos;
 	struct eap_fast_data *data = priv;
 
 	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret,
-					reqData, reqDataLen, &left, &flags);
+					reqData, &left, &flags);
 	if (pos == NULL)
 		return NULL;
 
-	req = (const struct eap_hdr *) reqData;
+	req = wpabuf_head(reqData);
 	id = req->identifier;
 
 	if (flags & EAP_TLS_FLAGS_START) {
@@ -1678,8 +1660,9 @@
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
 	    !data->resuming) {
 		/* Process tunneled (encrypted) phase 2 data. */
-		res = eap_fast_decrypt(sm, data, ret, req, pos, left,
-				       &resp, respDataLen);
+		struct wpabuf msg;
+		wpabuf_set(&msg, pos, left);
+		res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp);
 		if (res < 0) {
 			ret->methodState = METHOD_DONE;
 			ret->decision = DECISION_FAIL;
@@ -1694,7 +1677,7 @@
 		res = eap_peer_tls_process_helper(sm, &data->ssl,
 						  EAP_TYPE_FAST,
 						  data->fast_version, id, pos,
-						  left, &resp, respDataLen);
+						  left, &resp);
 
 		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 			char cipher[80];
@@ -1718,22 +1701,22 @@
 		}
 
 		if (res == 2) {
+			struct wpabuf msg;
 			/*
 			 * Application data included in the handshake message.
 			 */
-			os_free(data->pending_phase2_req);
+			wpabuf_free(data->pending_phase2_req);
 			data->pending_phase2_req = resp;
-			data->pending_phase2_req_len = *respDataLen;
 			resp = NULL;
-			*respDataLen = 0;
-			res = eap_fast_decrypt(sm, data, ret, req, pos, left,
-					       &resp, respDataLen);
+			wpabuf_set(&msg, pos, left);
+			res = eap_fast_decrypt(sm, data, ret, req, &msg,
+					       &resp);
 		}
 	}
 
 	if (res == 1) {
-		os_free(resp);
-		return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_FAST,
+		wpabuf_free(resp);
+		return eap_peer_tls_build_ack(id, EAP_TYPE_FAST,
 					      data->fast_version);
 	}
 
@@ -1754,7 +1737,7 @@
 	struct eap_fast_data *data = priv;
 	os_free(data->key_block_p);
 	data->key_block_p = NULL;
-	os_free(data->pending_phase2_req);
+	wpabuf_free(data->pending_phase2_req);
 	data->pending_phase2_req = NULL;
 }
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_gpsk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_gpsk.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_gpsk.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_gpsk.c Tue Dec 25 15:23:24 2007
@@ -42,11 +42,12 @@
 };
 
 
-static u8 * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier,
-				 const u8 *csuite_list, size_t csuite_list_len,
-				 size_t *respDataLen);
-static u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier,
-				 size_t *respDataLen);
+static struct wpabuf * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data,
+					    u8 identifier,
+					    const u8 *csuite_list,
+					    size_t csuite_list_len);
+static struct wpabuf * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data,
+					    u8 identifier);
 
 
 #ifndef CONFIG_NO_STDOUT_DEBUG
@@ -254,17 +255,16 @@
 }
 
 
-static u8 * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
-				    struct eap_gpsk_data *data,
-				    struct eap_method_ret *ret,
-				    const u8 *reqData, size_t reqDataLen,
-				    const u8 *payload, size_t payload_len,
-				    size_t *respDataLen)
+static struct wpabuf * eap_gpsk_process_gpsk_1(struct eap_sm *sm,
+					       struct eap_gpsk_data *data,
+					       struct eap_method_ret *ret,
+					       const struct wpabuf *reqData,
+					       const u8 *payload,
+					       size_t payload_len)
 {
 	size_t csuite_list_len;
 	const u8 *csuite_list, *pos, *end;
-	const struct eap_hdr *req;
-	u8 *resp;
+	struct wpabuf *resp;
 
 	if (data->state != GPSK_1) {
 		ret->ignore = TRUE;
@@ -284,24 +284,23 @@
 		return NULL;
 	}
 
-	req = (const struct eap_hdr *) reqData;
-	resp = eap_gpsk_send_gpsk_2(data, req->identifier,
-				    csuite_list, csuite_list_len,
-				    respDataLen);
+	resp = eap_gpsk_send_gpsk_2(data, eap_get_id(reqData),
+				    csuite_list, csuite_list_len);
 	if (resp == NULL)
 		return NULL;
 
 	eap_gpsk_state(data, GPSK_3);
 
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data, u8 identifier,
-				 const u8 *csuite_list, size_t csuite_list_len,
-				 size_t *respDataLen)
-{
-	struct eap_hdr *resp;
+	return resp;
+}
+
+
+static struct wpabuf * eap_gpsk_send_gpsk_2(struct eap_gpsk_data *data,
+					    u8 identifier,
+					    const u8 *csuite_list,
+					    size_t csuite_list_len)
+{
+	struct wpabuf *resp;
 	size_t len, miclen;
 	u8 *rpos, *start;
 	struct eap_gpsk_csuite *csuite;
@@ -313,52 +312,40 @@
 		2 * EAP_GPSK_RAND_LEN + 2 + csuite_list_len +
 		sizeof(struct eap_gpsk_csuite) + 2 + miclen;
 
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len,
-			     EAP_CODE_RESPONSE, identifier, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
+			     EAP_CODE_RESPONSE, identifier);
 	if (resp == NULL)
 		return NULL;
 
-	*rpos++ = EAP_GPSK_OPCODE_GPSK_2;
-	start = rpos;
+	wpabuf_put_u8(resp, EAP_GPSK_OPCODE_GPSK_2);
+	start = wpabuf_put(resp, 0);
 
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
 			  data->id_peer, data->id_peer_len);
-	WPA_PUT_BE16(rpos, data->id_peer_len);
-	rpos += 2;
-	if (data->id_peer)
-		os_memcpy(rpos, data->id_peer, data->id_peer_len);
-	rpos += data->id_peer_len;
-
-	WPA_PUT_BE16(rpos, data->id_server_len);
-	rpos += 2;
-	if (data->id_server)
-		os_memcpy(rpos, data->id_server, data->id_server_len);
-	rpos += data->id_server_len;
+	wpabuf_put_be16(resp, data->id_peer_len);
+	wpabuf_put_data(resp, data->id_peer, data->id_peer_len);
+
+	wpabuf_put_be16(resp, data->id_server_len);
+	wpabuf_put_data(resp, data->id_server, data->id_server_len);
 
 	if (os_get_random(data->rand_peer, EAP_GPSK_RAND_LEN)) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to get random data "
 			   "for RAND_Peer");
 		eap_gpsk_state(data, FAILURE);
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 	wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
 		    data->rand_peer, EAP_GPSK_RAND_LEN);
-	os_memcpy(rpos, data->rand_peer, EAP_GPSK_RAND_LEN);
-	rpos += EAP_GPSK_RAND_LEN;
-
-	os_memcpy(rpos, data->rand_server, EAP_GPSK_RAND_LEN);
-	rpos += EAP_GPSK_RAND_LEN;
-
-	WPA_PUT_BE16(rpos, csuite_list_len);
-	rpos += 2;
-	os_memcpy(rpos, csuite_list, csuite_list_len);
-	rpos += csuite_list_len;
-
-	csuite = (struct eap_gpsk_csuite *) rpos;
+	wpabuf_put_data(resp, data->rand_peer, EAP_GPSK_RAND_LEN);
+	wpabuf_put_data(resp, data->rand_server, EAP_GPSK_RAND_LEN);
+
+	wpabuf_put_be16(resp, csuite_list_len);
+	wpabuf_put_data(resp, csuite_list, csuite_list_len);
+
+	csuite = wpabuf_put(resp, sizeof(*csuite));
 	WPA_PUT_BE32(csuite->vendor, data->vendor);
 	WPA_PUT_BE16(csuite->specifier, data->specifier);
-	rpos = (u8 *) (csuite + 1);
 
 	if (eap_gpsk_derive_keys(data->psk, data->psk_len,
 				 data->vendor, data->specifier,
@@ -370,23 +357,23 @@
 				 data->pk, &data->pk_len) < 0) {
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive keys");
 		eap_gpsk_state(data, FAILURE);
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 
 	/* No PD_Payload_1 */
-	WPA_PUT_BE16(rpos, 0);
-	rpos += 2;
-
+	wpabuf_put_be16(resp, 0);
+
+	rpos = wpabuf_put(resp, miclen);
 	if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
 				 data->specifier, start, rpos - start, rpos) <
 	    0) {
 		eap_gpsk_state(data, FAILURE);
-		os_free(resp);
-		return NULL;
-	}
-
-	return (u8 *) resp;
+		wpabuf_free(resp);
+		return NULL;
+	}
+
+	return resp;
 }
 
 
@@ -558,15 +545,14 @@
 }
 
 
-static u8 * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
-				    struct eap_gpsk_data *data,
-				    struct eap_method_ret *ret,
-				    const u8 *reqData, size_t reqDataLen,
-				    const u8 *payload, size_t payload_len,
-				    size_t *respDataLen)
-{
-	u8 *resp;
-	const struct eap_hdr *req;
+static struct wpabuf * eap_gpsk_process_gpsk_3(struct eap_sm *sm,
+					       struct eap_gpsk_data *data,
+					       struct eap_method_ret *ret,
+					       const struct wpabuf *reqData,
+					       const u8 *payload,
+					       size_t payload_len)
+{
+	struct wpabuf *resp;
 	const u8 *pos, *end;
 
 	if (data->state != GPSK_3) {
@@ -593,8 +579,7 @@
 			   "data in the end of GPSK-2", end - pos);
 	}
 
-	req = (const struct eap_hdr *) reqData;
-	resp = eap_gpsk_send_gpsk_4(data, req->identifier, respDataLen);
+	resp = eap_gpsk_send_gpsk_4(data, eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
 
@@ -602,57 +587,55 @@
 	ret->methodState = METHOD_DONE;
 	ret->decision = DECISION_UNCOND_SUCC;
 
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data, u8 identifier,
-				 size_t *respDataLen)
-{
-	struct eap_hdr *resp;
+	return resp;
+}
+
+
+static struct wpabuf * eap_gpsk_send_gpsk_4(struct eap_gpsk_data *data,
+					    u8 identifier)
+{
+	struct wpabuf *resp;
 	u8 *rpos, *start;
-	size_t len;
+	size_t mlen;
 
 	wpa_printf(MSG_DEBUG, "EAP-GPSK: Sending Response/GPSK-4");
 
-	len = 1 + 2 + eap_gpsk_mic_len(data->vendor, data->specifier);
-
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respDataLen, len,
-			     EAP_CODE_RESPONSE, identifier, &rpos);
+	mlen = eap_gpsk_mic_len(data->vendor, data->specifier);
+
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, 1 + 2 + mlen,
+			     EAP_CODE_RESPONSE, identifier);
 	if (resp == NULL)
 		return NULL;
 
-	*rpos++ = EAP_GPSK_OPCODE_GPSK_4;
-	start = rpos;
+	wpabuf_put_u8(resp, EAP_GPSK_OPCODE_GPSK_4);
+	start = wpabuf_put(resp, 0);
 
 	/* No PD_Payload_3 */
-	WPA_PUT_BE16(rpos, 0);
-	rpos += 2;
-
+	wpabuf_put_be16(resp, 0);
+
+	rpos = wpabuf_put(resp, mlen);
 	if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
 				 data->specifier, start, rpos - start, rpos) <
 	    0) {
 		eap_gpsk_state(data, FAILURE);
-		os_free(resp);
-		return NULL;
-	}
-
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_gpsk_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+		wpabuf_free(resp);
+		return NULL;
+	}
+
+	return resp;
+}
+
+
+static struct wpabuf * eap_gpsk_process(struct eap_sm *sm, void *priv,
+					struct eap_method_ret *ret,
+					const struct wpabuf *reqData)
 {
 	struct eap_gpsk_data *data = priv;
-	u8 *resp;
+	struct wpabuf *resp;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqData, &len);
 	if (pos == NULL || len < 1) {
 		ret->ignore = TRUE;
 		return NULL;
@@ -668,13 +651,11 @@
 	switch (*pos) {
 	case EAP_GPSK_OPCODE_GPSK_1:
 		resp = eap_gpsk_process_gpsk_1(sm, data, ret, reqData,
-					       reqDataLen, pos + 1, len - 1,
-					       respDataLen);
+					       pos + 1, len - 1);
 		break;
 	case EAP_GPSK_OPCODE_GPSK_3:
 		resp = eap_gpsk_process_gpsk_3(sm, data, ret, reqData,
-					       reqDataLen, pos + 1, len - 1,
-					       respDataLen);
+					       pos + 1, len - 1);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignoring message with "

Modified: wpasupplicant/trunk/src/eap_peer/eap_gtc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_gtc.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_gtc.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_gtc.c Tue Dec 25 15:23:24 2007
@@ -47,26 +47,23 @@
 }
 
 
-static u8 * eap_gtc_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+static struct wpabuf * eap_gtc_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_gtc_data *data = priv;
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	const u8 *pos, *password, *identity;
-	u8 *rpos;
 	size_t password_len, identity_len, len, plen;
 	int otp;
+	u8 id;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqData, &len);
 	if (pos == NULL) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	req = (const struct eap_hdr *) reqData;
+	id = eap_get_id(reqData);
 
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Request message", pos, len);
 	if (data->prefix &&
@@ -79,9 +76,8 @@
 		 * error case which seems to use EAP-MSCHAPv2 like error
 		 * reporting with EAP-GTC inside EAP-FAST tunnel. */
 		resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC,
-				     respDataLen, 0, EAP_CODE_RESPONSE,
-				     req->identifier, NULL);
-		return (u8 *) resp;
+				     0, EAP_CODE_RESPONSE, id);
+		return resp;
 	}
 
 	password = eap_get_config_otp(sm, &password_len);
@@ -111,27 +107,26 @@
 		return NULL;
 	if (data->prefix)
 		plen += 9 + identity_len + 1;
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, respDataLen,
-			     plen, EAP_CODE_RESPONSE, req->identifier, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, plen,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 	if (data->prefix) {
-		os_memcpy(rpos, "RESPONSE=", 9);
-		rpos += 9;
-		os_memcpy(rpos, identity, identity_len);
-		rpos += identity_len;
-		*rpos++ = '\0';
+		wpabuf_put_data(resp, "RESPONSE=", 9);
+		wpabuf_put_data(resp, identity, identity_len);
+		wpabuf_put_u8(resp, '\0');
 	}
-	os_memcpy(rpos, password, password_len);
+	wpabuf_put_data(resp, password, password_len);
 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response",
-			      (u8 *) (resp + 1) + 1, plen);
+			      wpabuf_head_u8(resp) + sizeof(struct eap_hdr) +
+			      1, plen);
 
 	if (otp) {
 		wpa_printf(MSG_DEBUG, "EAP-GTC: Forgetting used password");
 		eap_clear_config_otp(sm);
 	}
 
-	return (u8 *) resp;
+	return resp;
 }
 
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_i.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_i.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_i.h Tue Dec 25 15:23:24 2007
@@ -15,6 +15,7 @@
 #ifndef EAP_I_H
 #define EAP_I_H
 
+#include "wpabuf.h"
 #include "eap_peer/eap.h"
 #include "eap_common/eap_common.h"
 
@@ -108,8 +109,6 @@
 	 * @priv: Pointer to private EAP method data from eap_method::init()
 	 * @ret: Return values from EAP request validation and processing
 	 * @reqData: EAP request to be processed (eapReqData)
-	 * @reqDataLen: Length of the EAP request
-	 * @respDataLen: Length of the returned EAP response
 	 * Returns: Pointer to allocated EAP response packet (eapRespData)
 	 *
 	 * This function is a combination of m.check(), m.process(), and
@@ -119,10 +118,9 @@
 	 * are returned through struct eap_method_ret *ret variable. Caller is
 	 * responsible for freeing the returned EAP response packet.
 	 */
-	u8 * (*process)(struct eap_sm *sm, void *priv,
-			struct eap_method_ret *ret,
-			const u8 *reqData, size_t reqDataLen,
-			size_t *respDataLen);
+	struct wpabuf * (*process)(struct eap_sm *sm, void *priv,
+				   struct eap_method_ret *ret,
+				   const struct wpabuf *reqData);
 
 	/**
 	 * isKeyAvailable - Find out whether EAP method has keying material
@@ -286,8 +284,7 @@
 	EapType selectedMethod;
 	EapMethodState methodState;
 	int lastId;
-	u8 *lastRespData;
-	size_t lastRespDataLen;
+	struct wpabuf *lastRespData;
 	EapDecision decision;
 	/* Short-term local variables */
 	Boolean rxReq;
@@ -303,8 +300,7 @@
 
 	/* Miscellaneous variables */
 	Boolean allowNotifications; /* peer state machine <-> methods */
-	u8 *eapRespData; /* peer to lower layer */
-	size_t eapRespDataLen; /* peer to lower layer */
+	struct wpabuf *eapRespData; /* peer to lower layer */
 	Boolean eapKeyAvailable; /* peer to lower layer */
 	u8 *eapKeyData; /* peer to lower layer */
 	size_t eapKeyDataLen; /* peer to lower layer */

Modified: wpasupplicant/trunk/src/eap_peer/eap_leap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_leap.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_leap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_leap.c Tue Dec 25 15:23:24 2007
@@ -61,17 +61,15 @@
 }
 
 
-static u8 * eap_leap_process_request(struct eap_sm *sm, void *priv,
-				     struct eap_method_ret *ret,
-				     const u8 *reqData, size_t reqDataLen,
-				     size_t *respDataLen)
+static struct wpabuf * eap_leap_process_request(struct eap_sm *sm, void *priv,
+						struct eap_method_ret *ret,
+						const struct wpabuf *reqData)
 {
 	struct eap_leap_data *data = priv;
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	const u8 *pos, *challenge, *identity, *password;
 	u8 challenge_len, *rpos;
-	size_t identity_len, password_len;
+	size_t identity_len, password_len, len;
 	int pwhash;
 
 	wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Request");
@@ -81,14 +79,12 @@
 	if (identity == NULL || password == NULL)
 		return NULL;
 
-	req = (const struct eap_hdr *) reqData;
-	pos = (const u8 *) (req + 1);
-	if (reqDataLen < sizeof(*req) + 4 || *pos != EAP_TYPE_LEAP) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_LEAP, reqData, &len);
+	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-LEAP: Invalid EAP-Request frame");
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	pos++;
 
 	if (*pos != LEAP_VERSION) {
 		wpa_printf(MSG_WARNING, "EAP-LEAP: Unsupported LEAP version "
@@ -101,11 +97,10 @@
 	pos++; /* skip unused byte */
 
 	challenge_len = *pos++;
-	if (challenge_len != LEAP_CHALLENGE_LEN ||
-	    challenge_len > reqDataLen - sizeof(*req) - 4) {
+	if (challenge_len != LEAP_CHALLENGE_LEN || challenge_len > len - 3) {
 		wpa_printf(MSG_INFO, "EAP-LEAP: Invalid challenge "
 			   "(challenge_len=%d reqDataLen=%lu)",
-			   challenge_len, (unsigned long) reqDataLen);
+			   challenge_len, (unsigned long) wpabuf_len(reqData));
 		ret->ignore = TRUE;
 		return NULL;
 	}
@@ -116,14 +111,15 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-LEAP: Generating Challenge Response");
 
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP, respDataLen,
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP,
 			     3 + LEAP_RESPONSE_LEN + identity_len,
-			     EAP_CODE_RESPONSE, req->identifier, &rpos);
+			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
-	*rpos++ = LEAP_VERSION;
-	*rpos++ = 0; /* unused */
-	*rpos++ = LEAP_RESPONSE_LEN;
+	wpabuf_put_u8(resp, LEAP_VERSION);
+	wpabuf_put_u8(resp, 0); /* unused */
+	wpabuf_put_u8(resp, LEAP_RESPONSE_LEN);
+	rpos = wpabuf_put(resp, LEAP_RESPONSE_LEN);
 	if (pwhash)
 		challenge_response(challenge, password, rpos);
 	else
@@ -131,22 +127,20 @@
 	os_memcpy(data->peer_response, rpos, LEAP_RESPONSE_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Response",
 		    rpos, LEAP_RESPONSE_LEN);
-	rpos += LEAP_RESPONSE_LEN;
-	os_memcpy(rpos, identity, identity_len);
+	wpabuf_put_data(resp, identity, identity_len);
 
 	data->state = LEAP_WAIT_SUCCESS;
 
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_leap_process_success(struct eap_sm *sm, void *priv,
-				     struct eap_method_ret *ret,
-				     const u8 *reqData, size_t *respDataLen)
+	return resp;
+}
+
+
+static struct wpabuf * eap_leap_process_success(struct eap_sm *sm, void *priv,
+						struct eap_method_ret *ret,
+						const struct wpabuf *reqData)
 {
 	struct eap_leap_data *data = priv;
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	u8 *pos;
 	const u8 *identity;
 	size_t identity_len;
@@ -164,45 +158,42 @@
 		return NULL;
 	}
 
-	req = (const struct eap_hdr *) reqData;
-
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP, respDataLen,
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_LEAP,
 			     3 + LEAP_CHALLENGE_LEN + identity_len,
-			     EAP_CODE_REQUEST, req->identifier, &pos);
+			     EAP_CODE_REQUEST, eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
-	*pos++ = LEAP_VERSION;
-	*pos++ = 0; /* unused */
-	*pos++ = LEAP_CHALLENGE_LEN;
+	wpabuf_put_u8(resp, LEAP_VERSION);
+	wpabuf_put_u8(resp, 0); /* unused */
+	wpabuf_put_u8(resp, LEAP_CHALLENGE_LEN);
+	pos = wpabuf_put(resp, 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);
+		wpabuf_free(resp);
 		ret->ignore = TRUE;
 		return NULL;
 	}
 	os_memcpy(data->ap_challenge, pos, LEAP_CHALLENGE_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Challenge to AP/AS", pos,
 		    LEAP_CHALLENGE_LEN);
-	pos += LEAP_CHALLENGE_LEN;
-	os_memcpy(pos, identity, identity_len);
+	wpabuf_put_data(resp, identity, identity_len);
 
 	data->state = LEAP_WAIT_RESPONSE;
 
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_leap_process_response(struct eap_sm *sm, void *priv,
-				      struct eap_method_ret *ret,
-				      const u8 *reqData, size_t reqDataLen)
+	return resp;
+}
+
+
+static struct wpabuf * eap_leap_process_response(struct eap_sm *sm, void *priv,
+						 struct eap_method_ret *ret,
+						 const struct wpabuf *reqData)
 {
 	struct eap_leap_data *data = priv;
-	const struct eap_hdr *resp;
 	const u8 *pos, *password;
 	u8 response_len, pw_hash[16], pw_hash_hash[16],
 		expected[LEAP_RESPONSE_LEN];
-	size_t password_len;
+	size_t password_len, len;
 	int pwhash;
 
 	wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Response");
@@ -211,14 +202,12 @@
 	if (password == NULL)
 		return NULL;
 
-	resp = (const struct eap_hdr *) reqData;
-	pos = (const u8 *) (resp + 1);
-	if (reqDataLen < sizeof(*resp) + 4 || *pos != EAP_TYPE_LEAP) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_LEAP, reqData, &len);
+	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-LEAP: Invalid EAP-Response frame");
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	pos++;
 
 	if (*pos != LEAP_VERSION) {
 		wpa_printf(MSG_WARNING, "EAP-LEAP: Unsupported LEAP version "
@@ -231,11 +220,10 @@
 	pos++; /* skip unused byte */
 
 	response_len = *pos++;
-	if (response_len != LEAP_RESPONSE_LEN ||
-	    response_len > reqDataLen - sizeof(*resp) - 4) {
+	if (response_len != LEAP_RESPONSE_LEN || response_len > len - 3) {
 		wpa_printf(MSG_INFO, "EAP-LEAP: Invalid response "
 			   "(response_len=%d reqDataLen=%lu)",
-			   response_len, (unsigned long) reqDataLen);
+			   response_len, (unsigned long) wpabuf_len(reqData));
 		ret->ignore = TRUE;
 		return NULL;
 	}
@@ -278,13 +266,12 @@
 }
 
 
-static u8 * eap_leap_process(struct eap_sm *sm, void *priv,
-			     struct eap_method_ret *ret,
-			     const u8 *reqData, size_t reqDataLen,
-			     size_t *respDataLen)
+static struct wpabuf * eap_leap_process(struct eap_sm *sm, void *priv,
+					struct eap_method_ret *ret,
+					const struct wpabuf *reqData)
 {
 	const struct eap_hdr *eap;
-	size_t len, password_len;
+	size_t password_len;
 	const u8 *password;
 
 	password = eap_get_config_password(sm, &password_len);
@@ -295,10 +282,15 @@
 		return NULL;
 	}
 
-	eap = (const struct eap_hdr *) reqData;
-
-	if (reqDataLen < sizeof(*eap) ||
-	    (len = be_to_host16(eap->length)) > reqDataLen) {
+	/*
+	 * LEAP needs to be able to handle EAP-Success frame which does not
+	 * include Type field. Consequently, eap_hdr_validate() cannot be used
+	 * here. This validation will be done separately for EAP-Request and
+	 * EAP-Response frames.
+	 */
+	eap = wpabuf_head(reqData);
+	if (wpabuf_len(reqData) < sizeof(*eap) ||
+	    be_to_host16(eap->length) > wpabuf_len(reqData)) {
 		wpa_printf(MSG_INFO, "EAP-LEAP: Invalid frame");
 		ret->ignore = TRUE;
 		return NULL;
@@ -313,13 +305,11 @@
 
 	switch (eap->code) {
 	case EAP_CODE_REQUEST:
-		return eap_leap_process_request(sm, priv, ret, reqData, len,
-						respDataLen);
+		return eap_leap_process_request(sm, priv, ret, reqData);
 	case EAP_CODE_SUCCESS:
-		return eap_leap_process_success(sm, priv, ret, reqData,
-						respDataLen);
+		return eap_leap_process_success(sm, priv, ret, reqData);
 	case EAP_CODE_RESPONSE:
-		return eap_leap_process_response(sm, priv, ret, reqData, len);
+		return eap_leap_process_response(sm, priv, ret, reqData);
 	default:
 		wpa_printf(MSG_INFO, "EAP-LEAP: Unexpected EAP code (%d) - "
 			   "ignored", eap->code);

Modified: wpasupplicant/trunk/src/eap_peer/eap_md5.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_md5.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_md5.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_md5.c Tue Dec 25 15:23:24 2007
@@ -16,8 +16,7 @@
 
 #include "common.h"
 #include "eap_i.h"
-#include "md5.h"
-#include "crypto.h"
+#include "eap_common/chap.h"
 
 
 static void * eap_md5_init(struct eap_sm *sm)
@@ -33,18 +32,14 @@
 }
 
 
-static u8 * eap_md5_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+static struct wpabuf * eap_md5_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	const u8 *pos, *challenge, *password;
-	u8 *rpos;
+	u8 *rpos, id;
 	size_t len, challenge_len, password_len;
-	const u8 *addr[3];
-	size_t elen[3];
 
 	password = eap_get_config_password(sm, &password_len);
 	if (password == NULL) {
@@ -54,8 +49,7 @@
 		return NULL;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqData, &len);
 	if (pos == NULL || len == 0) {
 		wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame (pos=%p len=%lu)",
 			   pos, (unsigned long) len);
@@ -67,7 +61,6 @@
 	 * CHAP Challenge:
 	 * Value-Size (1 octet) | Value(Challenge) | Name(optional)
 	 */
-	req = (const struct eap_hdr *) reqData;
 	challenge_len = *pos++;
 	if (challenge_len == 0 || challenge_len > len - 1) {
 		wpa_printf(MSG_INFO, "EAP-MD5: Invalid challenge "
@@ -86,9 +79,8 @@
 	ret->decision = DECISION_UNCOND_SUCC;
 	ret->allowNotifications = TRUE;
 
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, respDataLen,
-			     1 + MD5_MAC_LEN, EAP_CODE_RESPONSE,
-			     req->identifier, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHAP_MD5_LEN,
+			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
 
@@ -96,18 +88,14 @@
 	 * CHAP Response:
 	 * Value-Size (1 octet) | Value(Response) | Name(optional)
 	 */
-	*rpos++ = MD5_MAC_LEN;
+	wpabuf_put_u8(resp, CHAP_MD5_LEN);
 
-	addr[0] = &resp->identifier;
-	elen[0] = 1;
-	addr[1] = password;
-	elen[1] = password_len;
-	addr[2] = challenge;
-	elen[2] = challenge_len;
-	md5_vector(3, addr, elen, rpos);
-	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, MD5_MAC_LEN);
+	id = eap_get_id(resp);
+	rpos = wpabuf_put(resp, CHAP_MD5_LEN);
+	chap_md5(id, password, password_len, challenge, challenge_len, rpos);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", rpos, CHAP_MD5_LEN);
 
-	return (u8 *) resp;
+	return resp;
 }
 
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c Tue Dec 25 15:23:24 2007
@@ -102,8 +102,7 @@
 	int master_key_valid;
 	int success;
 
-	u8 *prev_challenge;
-	size_t prev_challenge_len;
+	struct wpabuf *prev_challenge;
 };
 
 
@@ -151,7 +150,7 @@
 	struct eap_mschapv2_data *data = priv;
 	os_free(data->peer_challenge);
 	os_free(data->auth_challenge);
-	os_free(data->prev_challenge);
+	wpabuf_free(data->prev_challenge);
 	os_free(data);
 }
 
@@ -236,15 +235,13 @@
 }
 
 
-static u8 * eap_mschapv2_challenge_reply(struct eap_sm *sm,
-					 struct eap_mschapv2_data *data, u8 id,
-					 u8 mschapv2_id,
-					 const u8 *auth_challenge,
-					 size_t *respDataLen)
-{
-	struct eap_hdr *resp;
+static struct wpabuf * eap_mschapv2_challenge_reply(
+	struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id,
+	u8 mschapv2_id, const u8 *auth_challenge)
+{
+	struct wpabuf *resp;
 	struct eap_mschapv2_hdr *ms;
-	u8 *rpos, *peer_challenge;
+	u8 *peer_challenge;
 	int ms_len;
 	struct ms_response *r;
 	size_t username_len, identity_len, password_len;
@@ -262,12 +259,12 @@
 	username = eap_mschapv2_remove_domain(identity, &username_len);
 
 	ms_len = sizeof(*ms) + 1 + sizeof(*r) + identity_len;
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respDataLen,
-			     ms_len, EAP_CODE_RESPONSE, id, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	ms = (struct eap_mschapv2_hdr *) rpos;
+	ms = wpabuf_put(resp, sizeof(*ms));
 	ms->op_code = MSCHAPV2_OP_RESPONSE;
 	ms->mschapv2_id = mschapv2_id;
 	if (data->prev_error) {
@@ -280,11 +277,11 @@
 		ms->mschapv2_id++;
 	}
 	WPA_PUT_BE16(ms->ms_length, ms_len);
-	rpos = (u8 *) (ms + 1);
-	*rpos++ = sizeof(*r); /* Value-Size */
+
+	wpabuf_put_u8(resp, sizeof(*r)); /* Value-Size */
 
 	/* Response */
-	r = (struct ms_response *) rpos;
+	r = wpabuf_put(resp, sizeof(*r));
 	peer_challenge = r->peer_challenge;
 	if (data->peer_challenge) {
 		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: peer_challenge generated "
@@ -292,7 +289,7 @@
 		peer_challenge = data->peer_challenge;
 		os_memset(r->peer_challenge, 0, MSCHAPV2_CHAL_LEN);
 	} else if (os_get_random(peer_challenge, MSCHAPV2_CHAL_LEN)) {
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 	os_memset(r->reserved, 0, 8);
@@ -308,10 +305,10 @@
 
 	r->flags = 0; /* reserved, must be zero */
 
-	os_memcpy((u8 *) (r + 1), identity, identity_len);
+	wpabuf_put_data(resp, identity, identity_len);
 	wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d "
-		   "(response)", resp->identifier, ms->mschapv2_id);
-	return (u8 *) resp;
+		   "(response)", id, ms->mschapv2_id);
+	return resp;
 }
 
 
@@ -322,16 +319,14 @@
  * @ret: Return values from EAP request validation and processing
  * @req: Pointer to EAP-MSCHAPv2 header from the request
  * @req_len: Length of the EAP-MSCHAPv2 data
- * @id: EAP identifier used in th erequest
- * @respDataLen: Length of the returned EAP response
+ * @id: EAP identifier used in the request
  * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
  * no reply available
  */
-static u8 * eap_mschapv2_challenge(struct eap_sm *sm,
-				   struct eap_mschapv2_data *data,
-				   struct eap_method_ret *ret,
-				   const struct eap_mschapv2_hdr *req,
-				   size_t req_len, u8 id, size_t *respDataLen)
+static struct wpabuf * eap_mschapv2_challenge(
+	struct eap_sm *sm, struct eap_mschapv2_data *data,
+	struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req,
+	size_t req_len, u8 id)
 {
 	size_t len, challenge_len;
 	const u8 *pos, *challenge;
@@ -382,7 +377,7 @@
 	ret->allowNotifications = TRUE;
 
 	return eap_mschapv2_challenge_reply(sm, data, id, req->mschapv2_id,
-					    challenge, respDataLen);
+					    challenge);
 }
 
 
@@ -423,22 +418,19 @@
  * @req: Pointer to EAP-MSCHAPv2 header from the request
  * @req_len: Length of the EAP-MSCHAPv2 data
  * @id: EAP identifier used in th erequest
- * @respDataLen: Length of the returned EAP response
  * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
  * no reply available
  */
-static u8 * eap_mschapv2_success(struct eap_sm *sm,
-				 struct eap_mschapv2_data *data,
-				 struct eap_method_ret *ret,
-				 const struct eap_mschapv2_hdr *req,
-				 size_t req_len, u8 id, size_t *respDataLen)
-{
-	struct eap_hdr *resp;
-	struct eap_mschapv2_hdr *ms;
+static struct wpabuf * eap_mschapv2_success(struct eap_sm *sm,
+					    struct eap_mschapv2_data *data,
+					    struct eap_method_ret *ret,
+					    const struct eap_mschapv2_hdr *req,
+					    size_t req_len, u8 id)
+{
+	struct wpabuf *resp;
 	const u8 *pos;
 	u8 recv_response[20];
 	size_t len;
-	u8 *rpos;
 
 	wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received success");
 	len = req_len - sizeof(*req);
@@ -465,8 +457,8 @@
 
 	/* Note: Only op_code of the EAP-MSCHAPV2 header is included in success
 	 * message. */
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respDataLen,
-			     1, EAP_CODE_RESPONSE, id, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Failed to allocate "
 			   "buffer for success response");
@@ -474,8 +466,7 @@
 		return NULL;
 	}
 
-	ms = (struct eap_mschapv2_hdr *) rpos;
-	ms->op_code = MSCHAPV2_OP_SUCCESS;
+	wpabuf_put_u8(resp, MSCHAPV2_OP_SUCCESS); /* op_code */
 
 	ret->methodState = METHOD_DONE;
 	ret->decision = DECISION_UNCOND_SUCC;
@@ -485,7 +476,7 @@
 	if (data->prev_error == ERROR_PASSWD_EXPIRED)
 		eap_mschapv2_password_changed(sm, data);
 
-	return (u8 *) resp;
+	return resp;
 }
 
 
@@ -592,16 +583,13 @@
 }
 
 
-static u8 * eap_mschapv2_change_password(struct eap_sm *sm,
-					 struct eap_mschapv2_data *data,
-					 struct eap_method_ret *ret,
-					 const struct eap_mschapv2_hdr *req,
-					 u8 id, size_t *respDataLen)
-{
-	struct eap_hdr *resp;
+static struct wpabuf * eap_mschapv2_change_password(
+	struct eap_sm *sm, struct eap_mschapv2_data *data,
+	struct eap_method_ret *ret, const struct eap_mschapv2_hdr *req, u8 id)
+{
+	struct wpabuf *resp;
 	int ms_len;
 	const u8 *username, *password, *new_password;
-	u8 *pos;
 	size_t username_len, password_len, new_password_len;
 	struct eap_mschapv2_hdr *ms;
 	struct ms_change_password *cp;
@@ -622,16 +610,16 @@
 	ret->allowNotifications = TRUE;
 
 	ms_len = sizeof(*ms) + sizeof(*cp);
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respDataLen,
-			     ms_len, EAP_CODE_RESPONSE, id, &pos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	ms = (struct eap_mschapv2_hdr *) pos;
+	ms = wpabuf_put(resp, sizeof(*ms));
 	ms->op_code = MSCHAPV2_OP_CHANGE_PASSWORD;
 	ms->mschapv2_id = req->mschapv2_id + 1;
 	WPA_PUT_BE16(ms->ms_length, ms_len);
-	cp = (struct ms_change_password *) (ms + 1);
+	cp = wpabuf_put(resp, sizeof(*cp));
 
 	/* Encrypted-Password */
 	if (pwhash) {
@@ -660,7 +648,7 @@
 
 	/* Peer-Challenge */
 	if (os_get_random(cp->peer_challenge, MSCHAPV2_CHAL_LEN)) {
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 
@@ -703,9 +691,9 @@
 	os_memset(cp->flags, 0, 2);
 
 	wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: TX identifier %d mschapv2_id %d "
-		   "(change pw)", resp->identifier, ms->mschapv2_id);
-
-	return (u8 *) resp;
+		   "(change pw)", id, ms->mschapv2_id);
+
+	return resp;
 }
 
 
@@ -717,23 +705,20 @@
  * @req: Pointer to EAP-MSCHAPv2 header from the request
  * @req_len: Length of the EAP-MSCHAPv2 data
  * @id: EAP identifier used in th erequest
- * @respDataLen: Length of the returned EAP response
  * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
  * no reply available
  */
-static u8 * eap_mschapv2_failure(struct eap_sm *sm,
-				 struct eap_mschapv2_data *data,
-				 struct eap_method_ret *ret,
-				 const struct eap_mschapv2_hdr *req,
-				 size_t req_len, u8 id, size_t *respDataLen)
-{
-	struct eap_hdr *resp;
+static struct wpabuf * eap_mschapv2_failure(struct eap_sm *sm,
+					    struct eap_mschapv2_data *data,
+					    struct eap_method_ret *ret,
+					    const struct eap_mschapv2_hdr *req,
+					    size_t req_len, u8 id)
+{
+	struct wpabuf *resp;
 	const u8 *msdata = (const u8 *) (req + 1);
 	char *buf;
 	size_t len = req_len - sizeof(*req);
 	int retry = 0;
-	struct eap_mschapv2_hdr *ms;
-	u8 *pos;
 
 	wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Received failure");
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: Failure data",
@@ -761,7 +746,7 @@
 		struct wpa_ssid *config = eap_get_config(sm);
 		if (config && config->new_password)
 			return eap_mschapv2_change_password(sm, data, ret, req,
-							    id, respDataLen);
+							    id);
 		if (config && config->pending_req_new_password)
 			return NULL;
 	} else if (retry && data->prev_error == ERROR_AUTHENTICATION_FAILURE) {
@@ -773,15 +758,14 @@
 
 	/* Note: Only op_code of the EAP-MSCHAPV2 header is included in failure
 	 * message. */
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respDataLen,
-			     1, EAP_CODE_RESPONSE, id, &pos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, 1,
+			     EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
 
-	ms = (struct eap_mschapv2_hdr *) pos;
-	ms->op_code = MSCHAPV2_OP_FAILURE;
-
-	return (u8 *) resp;
+	wpabuf_put_u8(resp, MSCHAPV2_OP_FAILURE); /* op_code */
+
+	return resp;
 }
 
 
@@ -830,18 +814,14 @@
 
 
 static void eap_mschapv2_copy_challenge(struct eap_mschapv2_data *data,
-					const u8 *reqData, size_t reqDataLen)
+					const struct wpabuf *reqData)
 {
 	/*
 	 * Store a copy of the challenge message, so that it can be processed
 	 * again in case retry is allowed after a possible failure.
 	 */
-	os_free(data->prev_challenge);
-	data->prev_challenge = os_malloc(reqDataLen);
-	if (data->prev_challenge) {
-		data->prev_challenge_len = reqDataLen;
-		os_memcpy(data->prev_challenge, reqData, reqDataLen);
-	}
+	wpabuf_free(data->prev_challenge);
+	data->prev_challenge = wpabuf_dup(reqData);
 }
 
 
@@ -851,23 +831,20 @@
  * @priv: Pointer to private EAP method data from eap_mschapv2_init()
  * @ret: Return values from EAP request validation and processing
  * @reqData: EAP request to be processed (eapReqData)
- * @reqDataLen: Length of the EAP request
- * @respDataLen: Length of the returned EAP response
  * Returns: Pointer to allocated EAP response packet (eapRespData) or %NULL if
  * no reply available
  */
-static u8 * eap_mschapv2_process(struct eap_sm *sm, void *priv,
-				 struct eap_method_ret *ret,
-				 const u8 *reqData, size_t reqDataLen,
-				 size_t *respDataLen)
+static struct wpabuf * eap_mschapv2_process(struct eap_sm *sm, void *priv,
+					    struct eap_method_ret *ret,
+					    const struct wpabuf *reqData)
 {
 	struct eap_mschapv2_data *data = priv;
 	struct wpa_ssid *config = eap_get_config(sm);
-	const struct eap_hdr *req;
 	const struct eap_mschapv2_hdr *ms;
 	int using_prev_challenge = 0;
 	const u8 *pos;
 	size_t len;
+	u8 id;
 
 	if (eap_mschapv2_check_config(sm)) {
 		ret->ignore = TRUE;
@@ -880,13 +857,12 @@
 			   "with the previous challenge");
 
 		reqData = data->prev_challenge;
-		reqDataLen = data->prev_challenge_len;
 		using_prev_challenge = 1;
 		config->mschapv2_retry = 0;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqData,
+			       &len);
 	if (pos == NULL || len < sizeof(*ms) + 1) {
 		ret->ignore = TRUE;
 		return NULL;
@@ -898,22 +874,19 @@
 		return NULL;
 	}
 
-	req = (const struct eap_hdr *) reqData;
+	id = eap_get_id(reqData);
 	wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: RX identifier %d mschapv2_id %d",
-		   req->identifier, ms->mschapv2_id);
+		   id, ms->mschapv2_id);
 
 	switch (ms->op_code) {
 	case MSCHAPV2_OP_CHALLENGE:
 		if (!using_prev_challenge)
-			eap_mschapv2_copy_challenge(data, reqData, reqDataLen);
-		return eap_mschapv2_challenge(sm, data, ret, ms, len,
-					      req->identifier, respDataLen);
+			eap_mschapv2_copy_challenge(data, reqData);
+		return eap_mschapv2_challenge(sm, data, ret, ms, len, id);
 	case MSCHAPV2_OP_SUCCESS:
-		return eap_mschapv2_success(sm, data, ret, ms, len,
-					    req->identifier, respDataLen);
+		return eap_mschapv2_success(sm, data, ret, ms, len, id);
 	case MSCHAPV2_OP_FAILURE:
-		return eap_mschapv2_failure(sm, data, ret, ms, len,
-					    req->identifier, respDataLen);
+		return eap_mschapv2_failure(sm, data, ret, ms, len, id);
 	default:
 		wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Unknown op %d - ignored",
 			   ms->op_code);

Modified: wpasupplicant/trunk/src/eap_peer/eap_otp.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_otp.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_otp.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_otp.c Tue Dec 25 15:23:24 2007
@@ -31,25 +31,20 @@
 }
 
 
-static u8 * eap_otp_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+static struct wpabuf * eap_otp_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	const u8 *pos, *password;
-	u8 *rpos;
 	size_t password_len, len;
 	int otp;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_OTP, reqData, &len);
 	if (pos == NULL) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	req = (const struct eap_hdr *) reqData;
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-OTP: Request message",
 			  pos, len);
 
@@ -74,12 +69,11 @@
 	ret->decision = DECISION_COND_SUCC;
 	ret->allowNotifications = FALSE;
 
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, respDataLen,
-			     password_len, EAP_CODE_RESPONSE, req->identifier,
-			     &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_OTP, password_len,
+			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
-	os_memcpy(rpos, password, password_len);
+	wpabuf_put_data(resp, password, password_len);
 	wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-OTP: Response",
 			      password, password_len);
 
@@ -88,7 +82,7 @@
 		eap_clear_config_otp(sm);
 	}
 
-	return (u8 *) resp;
+	return resp;
 }
 
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_pax.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_pax.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_pax.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_pax.c Tue Dec 25 15:23:24 2007
@@ -107,40 +107,39 @@
 }
 
 
-static struct eap_pax_hdr * eap_pax_alloc_resp(const struct eap_pax_hdr *req,
-					       u16 resp_len, u8 op_code)
-{
-	struct eap_pax_hdr *resp;
-
-	resp = os_malloc(resp_len);
+static struct wpabuf * eap_pax_alloc_resp(const struct eap_pax_hdr *req,
+					  u8 id, u8 op_code, size_t plen)
+{
+	struct wpabuf *resp;
+	struct eap_pax_hdr *pax;
+
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PAX,
+			     sizeof(*pax) + plen, EAP_CODE_RESPONSE, id);
 	if (resp == NULL)
 		return NULL;
-	resp->code = EAP_CODE_RESPONSE;
-	resp->identifier = req->identifier;
-	resp->length = host_to_be16(resp_len);
-	resp->type = EAP_TYPE_PAX;
-	resp->op_code = op_code;
-	resp->flags = 0;
-	resp->mac_id = req->mac_id;
-	resp->dh_group_id = req->dh_group_id;
-	resp->public_key_id = req->public_key_id;
+
+	pax = wpabuf_put(resp, sizeof(*pax));
+	pax->op_code = op_code;
+	pax->flags = 0;
+	pax->mac_id = req->mac_id;
+	pax->dh_group_id = req->dh_group_id;
+	pax->public_key_id = req->public_key_id;
+
 	return resp;
 }
 
 
-static u8 * eap_pax_process_std_1(struct eap_pax_data *data,
-				  struct eap_method_ret *ret,
-				  const u8 *reqData, size_t reqDataLen,
-				  size_t *respDataLen)
-{
-	const struct eap_pax_hdr *req;
-	struct eap_pax_hdr *resp;
+static struct wpabuf * eap_pax_process_std_1(struct eap_pax_data *data,
+					     struct eap_method_ret *ret, u8 id,
+					     const struct eap_pax_hdr *req,
+					     size_t req_plen)
+{
+	struct wpabuf *resp;
 	const u8 *pos;
 	u8 *rpos;
-	size_t left;
+	size_t left, plen;
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (received)");
-	req = (const struct eap_pax_hdr *) reqData;
 
 	if (data->state != PAX_INIT) {
 		wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-1 received in "
@@ -156,7 +155,7 @@
 		return NULL;
 	}
 
-	left = reqDataLen - sizeof(*req);
+	left = req_plen - sizeof(*req);
 
 	if (left < 2 + EAP_PAX_RAND_LEN) {
 		wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-1 with too short "
@@ -204,66 +203,59 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-2 (sending)");
 
-	*respDataLen = sizeof(*resp) + 2 + EAP_PAX_RAND_LEN +
-		2 + data->cid_len + 2 + EAP_PAX_MAC_LEN + EAP_PAX_ICV_LEN;
-	resp = eap_pax_alloc_resp(req, *respDataLen, EAP_PAX_OP_STD_2);
+	plen = 2 + EAP_PAX_RAND_LEN + 2 + data->cid_len + 2 + EAP_PAX_MAC_LEN +
+		EAP_PAX_ICV_LEN;
+	resp = eap_pax_alloc_resp(req, id, EAP_PAX_OP_STD_2, plen);
 	if (resp == NULL)
 		return NULL;
 
-	rpos = (u8 *) (resp + 1);
-	*rpos++ = 0;
-	*rpos++ = EAP_PAX_RAND_LEN;
-	os_memcpy(rpos, data->rand.r.y, EAP_PAX_RAND_LEN);
+	wpabuf_put_be16(resp, EAP_PAX_RAND_LEN);
+	wpabuf_put_data(resp, data->rand.r.y, EAP_PAX_RAND_LEN);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: B = Y (client rand)",
-		    rpos, EAP_PAX_RAND_LEN);
-	rpos += EAP_PAX_RAND_LEN;
-
-	WPA_PUT_BE16(rpos, data->cid_len);
-	rpos += 2;
-	os_memcpy(rpos, data->cid, data->cid_len);
-	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PAX: CID", rpos, data->cid_len);
-	rpos += data->cid_len;
-
-	*rpos++ = 0;
-	*rpos++ = EAP_PAX_MAC_LEN;
+		    data->rand.r.y, EAP_PAX_RAND_LEN);
+
+	wpabuf_put_be16(resp, data->cid_len);
+	wpabuf_put_data(resp, data->cid, data->cid_len);
+	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PAX: CID",
+			  (u8 *) data->cid, data->cid_len);
+
+	wpabuf_put_be16(resp, EAP_PAX_MAC_LEN);
+	rpos = wpabuf_put(resp, EAP_PAX_MAC_LEN);
 	eap_pax_mac(req->mac_id, data->ck, EAP_PAX_CK_LEN,
 		    data->rand.r.x, EAP_PAX_RAND_LEN,
 		    data->rand.r.y, EAP_PAX_RAND_LEN,
 		    (u8 *) data->cid, data->cid_len, rpos);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: MAC_CK(A, B, CID)",
 		    rpos, EAP_PAX_MAC_LEN);
-	rpos += EAP_PAX_MAC_LEN;
 
 	/* Optional ADE could be added here, if needed */
 
+	rpos = wpabuf_put(resp, EAP_PAX_ICV_LEN);
 	eap_pax_mac(req->mac_id, data->ick, EAP_PAX_ICK_LEN,
-		    (u8 *) resp, *respDataLen - EAP_PAX_ICV_LEN,
+		    wpabuf_head(resp), wpabuf_len(resp) - EAP_PAX_ICV_LEN,
 		    NULL, 0, NULL, 0, rpos);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", rpos, EAP_PAX_ICV_LEN);
-	rpos += EAP_PAX_ICV_LEN;
 
 	data->state = PAX_STD_2_SENT;
 	data->mac_id = req->mac_id;
 	data->dh_group_id = req->dh_group_id;
 	data->public_key_id = req->public_key_id;
 
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_pax_process_std_3(struct eap_pax_data *data,
-				  struct eap_method_ret *ret,
-				  const u8 *reqData, size_t reqDataLen,
-				  size_t *respDataLen)
-{
-	const struct eap_pax_hdr *req;
-	struct eap_pax_hdr *resp;
+	return resp;
+}
+
+
+static struct wpabuf * eap_pax_process_std_3(struct eap_pax_data *data,
+					     struct eap_method_ret *ret, u8 id,
+					     const struct eap_pax_hdr *req,
+					     size_t req_plen)
+{
+	struct wpabuf *resp;
 	u8 *rpos, mac[EAP_PAX_MAC_LEN];
 	const u8 *pos;
 	size_t left;
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-3 (received)");
-	req = (const struct eap_pax_hdr *) reqData;
 
 	if (data->state != PAX_STD_2_SENT) {
 		wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-3 received in "
@@ -279,7 +271,7 @@
 		return NULL;
 	}
 
-	left = reqDataLen - sizeof(*req);
+	left = req_plen - sizeof(*req);
 
 	if (left < 2 + EAP_PAX_MAC_LEN) {
 		wpa_printf(MSG_INFO, "EAP-PAX: PAX_STD-3 with too short "
@@ -323,17 +315,15 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX-ACK (sending)");
 
-	*respDataLen = sizeof(*resp) + EAP_PAX_ICV_LEN;
-	resp = eap_pax_alloc_resp(req, *respDataLen, EAP_PAX_OP_ACK);
+	resp = eap_pax_alloc_resp(req, id, EAP_PAX_OP_ACK, EAP_PAX_ICV_LEN);
 	if (resp == NULL)
 		return NULL;
 
-	rpos = (u8 *) (resp + 1);
-
 	/* Optional ADE could be added here, if needed */
 
+	rpos = wpabuf_put(resp, EAP_PAX_ICV_LEN);
 	eap_pax_mac(data->mac_id, data->ick, EAP_PAX_ICK_LEN,
-		    (u8 *) resp, *respDataLen - EAP_PAX_ICV_LEN,
+		    wpabuf_head(resp), wpabuf_len(resp) - EAP_PAX_ICV_LEN,
 		    NULL, 0, NULL, 0, rpos);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", rpos, EAP_PAX_ICV_LEN);
 
@@ -342,30 +332,31 @@
 	ret->decision = DECISION_UNCOND_SUCC;
 	ret->allowNotifications = FALSE;
 
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_pax_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+	return resp;
+}
+
+
+static struct wpabuf * eap_pax_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_pax_data *data = priv;
 	const struct eap_pax_hdr *req;
-	u8 *resp, icvbuf[EAP_PAX_ICV_LEN];
+	struct wpabuf *resp;
+	u8 icvbuf[EAP_PAX_ICV_LEN], id;
 	const u8 *icv, *pos;
 	size_t len;
-	u16 flen;
-
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX,
-			       reqData, reqDataLen, &len);
+	u16 flen, mlen;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX, reqData, &len);
 	if (pos == NULL || len < EAP_PAX_ICV_LEN) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	req = (const struct eap_pax_hdr *) reqData;
-	flen = be_to_host16(req->length) - EAP_PAX_ICV_LEN;
+	id = eap_get_id(reqData);
+	req = (const struct eap_pax_hdr *) pos;
+	flen = len - EAP_PAX_ICV_LEN;
+	mlen = wpabuf_len(reqData) - EAP_PAX_ICV_LEN;
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: received frame: op_code 0x%x "
 		   "flags 0x%x mac_id 0x%x dh_group_id 0x%x "
@@ -434,10 +425,12 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", icv, EAP_PAX_ICV_LEN);
 	if (req->op_code == EAP_PAX_OP_STD_1) {
 		eap_pax_mac(req->mac_id, (u8 *) "", 0,
-			    reqData, flen, NULL, 0, NULL, 0, icvbuf);
+			    wpabuf_head(reqData), mlen, NULL, 0, NULL, 0,
+			    icvbuf);
 	} else {
 		eap_pax_mac(req->mac_id, data->ick, EAP_PAX_ICK_LEN,
-			    reqData, flen, NULL, 0, NULL, 0, icvbuf);
+			    wpabuf_head(reqData), mlen, NULL, 0, NULL, 0,
+			    icvbuf);
 	}
 	if (os_memcmp(icv, icvbuf, EAP_PAX_ICV_LEN) != 0) {
 		wpa_printf(MSG_DEBUG, "EAP-PAX: invalid ICV - ignoring the "
@@ -455,12 +448,10 @@
 
 	switch (req->op_code) {
 	case EAP_PAX_OP_STD_1:
-		resp = eap_pax_process_std_1(data, ret, reqData, flen,
-					     respDataLen);
+		resp = eap_pax_process_std_1(data, ret, id, req, flen);
 		break;
 	case EAP_PAX_OP_STD_3:
-		resp = eap_pax_process_std_3(data, ret, reqData, flen,
-					     respDataLen);
+		resp = eap_pax_process_std_3(data, ret, id, req, flen);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-PAX: ignoring message with unknown "

Modified: wpasupplicant/trunk/src/eap_peer/eap_peap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_peap.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_peap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_peap.c Tue Dec 25 15:23:24 2007
@@ -57,8 +57,7 @@
 	int resuming; /* starting a resumed session */
 	u8 *key_data;
 
-	u8 *pending_phase2_req;
-	size_t pending_phase2_req_len;
+	struct wpabuf *pending_phase2_req;
 };
 
 
@@ -148,7 +147,7 @@
 	os_free(data->phase2_types);
 	eap_peer_tls_ssl_deinit(sm, &data->ssl);
 	os_free(data->key_data);
-	os_free(data->pending_phase2_req);
+	wpabuf_free(data->pending_phase2_req);
 	os_free(data);
 }
 
@@ -156,9 +155,10 @@
 static int eap_peap_phase2_request(struct eap_sm *sm,
 				   struct eap_peap_data *data,
 				   struct eap_method_ret *ret,
-				   struct eap_hdr *hdr,
-				   u8 **resp, size_t *resp_len)
-{
+				   struct wpabuf *req,
+				   struct wpabuf **resp)
+{
+	struct eap_hdr *hdr = wpabuf_mhead(req);
 	size_t len = be_to_host16(hdr->length);
 	u8 *pos;
 	struct eap_method_ret iret;
@@ -173,11 +173,11 @@
 	wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Request: type=%d", *pos);
 	switch (*pos) {
 	case EAP_TYPE_IDENTITY:
-		*resp = eap_sm_buildIdentity(sm, hdr->identifier, resp_len, 1);
+		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
 		break;
 	case EAP_TYPE_TLV:
 		os_memset(&iret, 0, sizeof(iret));
-		if (eap_tlv_process(sm, &iret, hdr, resp, resp_len)) {
+		if (eap_tlv_process(sm, &iret, req, resp)) {
 			ret->methodState = METHOD_DONE;
 			ret->decision = DECISION_FAIL;
 			return -1;
@@ -214,7 +214,7 @@
 		    *pos == EAP_TYPE_NONE) {
 			if (eap_peer_tls_phase2_nak(data->phase2_types,
 						    data->num_phase2_types,
-						    hdr, resp, resp_len))
+						    hdr, resp))
 				return -1;
 			return 0;
 		}
@@ -239,8 +239,7 @@
 		}
 		os_memset(&iret, 0, sizeof(iret));
 		*resp = data->phase2_method->process(sm, data->phase2_priv,
-						     &iret, (u8 *) hdr, len,
-						     resp_len);
+						     &iret, req);
 		if ((iret.methodState == METHOD_DONE ||
 		     iret.methodState == METHOD_MAY_CONT) &&
 		    (iret.decision == DECISION_UNCOND_SUCC ||
@@ -253,12 +252,8 @@
 	if (*resp == NULL &&
 	    (config->pending_req_identity || config->pending_req_password ||
 	     config->pending_req_otp || config->pending_req_new_password)) {
-		os_free(data->pending_phase2_req);
-		data->pending_phase2_req = os_malloc(len);
-		if (data->pending_phase2_req) {
-			os_memcpy(data->pending_phase2_req, hdr, len);
-			data->pending_phase2_req_len = len;
-		}
+		wpabuf_free(data->pending_phase2_req);
+		data->pending_phase2_req = wpabuf_alloc_copy(hdr, len);
 	}
 
 	return 0;
@@ -268,17 +263,17 @@
 static int eap_peap_decrypt(struct eap_sm *sm, struct eap_peap_data *data,
 			    struct eap_method_ret *ret,
 			    const struct eap_hdr *req,
-			    const u8 *in_data, size_t in_len,
-			    u8 **out_data, size_t *out_len)
-{
-	u8 *in_decrypted;
+			    const struct wpabuf *in_data,
+			    struct wpabuf **out_data)
+{
+	struct wpabuf *in_decrypted = NULL;
 	int res, skip_change = 0;
 	struct eap_hdr *hdr, *rhdr;
-	u8 *resp = NULL;
-	size_t resp_len, len_decrypted, len;
+	struct wpabuf *resp = NULL;
+	size_t len;
 
 	wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for"
-		   " Phase 2", (unsigned long) in_len);
+		   " Phase 2", (unsigned long) wpabuf_len(in_data));
 
 	if (data->pending_phase2_req) {
 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Pending Phase 2 request - "
@@ -287,12 +282,12 @@
 		eap_peer_tls_reset_input(&data->ssl);
 		in_decrypted = data->pending_phase2_req;
 		data->pending_phase2_req = NULL;
-		len_decrypted = data->pending_phase2_req_len;
 		skip_change = 1;
 		goto continue_req;
 	}
 
-	if (in_len == 0 && sm->workaround && data->phase2_success) {
+	if (wpabuf_len(in_data) == 0 && sm->workaround &&
+	    data->phase2_success) {
 		/*
 		 * Cisco ACS seems to be using TLS ACK to terminate
 		 * EAP-PEAPv0/GTC. Try to reply with TLS ACK.
@@ -303,98 +298,84 @@
 		ret->decision = DECISION_COND_SUCC;
 		ret->methodState = METHOD_DONE;
 		return 1;
-	} else if (in_len == 0) {
+	} else if (wpabuf_len(in_data) == 0) {
 		/* Received TLS ACK - requesting more fragments */
 		return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_PEAP,
 					    data->peap_version,
-					    req->identifier, NULL, 0,
-					    out_data, out_len);
-	}
-
-	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, in_len,
-				   &in_decrypted, &len_decrypted);
+					    req->identifier, NULL, out_data);
+	}
+
+	res = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
 	if (res)
 		return res;
 
 continue_req:
-	wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP", in_decrypted,
-		    len_decrypted);
-
-	hdr = (struct eap_hdr *) in_decrypted;
-	if (len_decrypted == 5 && hdr->code == EAP_CODE_REQUEST &&
+	wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
+			in_decrypted);
+
+	hdr = wpabuf_mhead(in_decrypted);
+	if (wpabuf_len(in_decrypted) == 5 && hdr->code == EAP_CODE_REQUEST &&
 	    be_to_host16(hdr->length) == 5 &&
-	    in_decrypted[4] == EAP_TYPE_IDENTITY) {
+	    eap_get_type(in_decrypted) == EAP_TYPE_IDENTITY) {
 		/* At least FreeRADIUS seems to send full EAP header with
 		 * EAP Request Identity */
 		skip_change = 1;
 	}
-	if (len_decrypted >= 5 && hdr->code == EAP_CODE_REQUEST &&
-	    in_decrypted[4] == EAP_TYPE_TLV) {
+	if (wpabuf_len(in_decrypted) >= 5 && hdr->code == EAP_CODE_REQUEST &&
+	    eap_get_type(in_decrypted) == EAP_TYPE_TLV) {
 		skip_change = 1;
 	}
 
 	if (data->peap_version == 0 && !skip_change) {
-		struct eap_hdr *nhdr = os_malloc(sizeof(struct eap_hdr) +
-						 len_decrypted);
-		if (nhdr == NULL) {
-			os_free(in_decrypted);
+		struct eap_hdr *nhdr;
+		struct wpabuf *nmsg = wpabuf_alloc(sizeof(struct eap_hdr) +
+						   wpabuf_len(in_decrypted));
+		if (nmsg == NULL) {
+			wpabuf_free(in_decrypted);
 			return 0;
 		}
-		os_memcpy((u8 *) (nhdr + 1), in_decrypted, len_decrypted);
-		os_free(in_decrypted);
+		nhdr = wpabuf_put(nmsg, sizeof(*nhdr));
+		wpabuf_put_buf(nmsg, in_decrypted);
 		nhdr->code = req->code;
 		nhdr->identifier = req->identifier;
 		nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
-					    len_decrypted);
-
-		len_decrypted += sizeof(struct eap_hdr);
-		in_decrypted = (u8 *) nhdr;
-	}
-	hdr = (struct eap_hdr *) in_decrypted;
-	if (len_decrypted < sizeof(*hdr)) {
-		os_free(in_decrypted);
+					    wpabuf_len(in_decrypted));
+
+		wpabuf_free(in_decrypted);
+		in_decrypted = nmsg;
+	}
+	hdr = wpabuf_mhead(in_decrypted);
+	if (wpabuf_len(in_decrypted) < sizeof(*hdr)) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
 			   "EAP frame (len=%lu)",
-			   (unsigned long) len_decrypted);
+			   (unsigned long) wpabuf_len(in_decrypted));
+		wpabuf_free(in_decrypted);
 		return 0;
 	}
 	len = be_to_host16(hdr->length);
-	if (len > len_decrypted) {
-		os_free(in_decrypted);
+	if (len > wpabuf_len(in_decrypted)) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in "
 			   "Phase 2 EAP frame (len=%lu hdr->length=%lu)",
-			   (unsigned long) len_decrypted, (unsigned long) len);
+			   (unsigned long) wpabuf_len(in_decrypted),
+			   (unsigned long) len);
+		wpabuf_free(in_decrypted);
 		return 0;
 	}
-	if (len < len_decrypted) {
+	if (len < wpabuf_len(in_decrypted)) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Odd.. Phase 2 EAP header has "
 			   "shorter length than full decrypted data "
 			   "(%lu < %lu)",
-			   (unsigned long) len, (unsigned long) len_decrypted);
-		if (sm->workaround && len == 4 && len_decrypted == 5 &&
-		    in_decrypted[4] == EAP_TYPE_IDENTITY) {
-			/* Radiator 3.9 seems to set Phase 2 EAP header to use
-			 * incorrect length for the EAP-Request Identity
-			 * packet, so fix the inner header to interoperate..
-			 * This was fixed in 2004-06-23 patch for Radiator and
-			 * this workaround can be removed at some point. */
-			wpa_printf(MSG_INFO, "EAP-PEAP: workaround -> replace "
-				   "Phase 2 EAP header len (%lu) with real "
-				   "decrypted len (%lu)",
-				   (unsigned long) len,
-				   (unsigned long) len_decrypted);
-			len = len_decrypted;
-			hdr->length = host_to_be16(len);
-		}
+			   (unsigned long) len,
+			   (unsigned long) wpabuf_len(in_decrypted));
 	}
 	wpa_printf(MSG_DEBUG, "EAP-PEAP: received Phase 2: code=%d "
 		   "identifier=%d length=%lu", hdr->code, hdr->identifier,
 		   (unsigned long) len);
 	switch (hdr->code) {
 	case EAP_CODE_REQUEST:
-		if (eap_peap_phase2_request(sm, data, ret, hdr,
-					    &resp, &resp_len)) {
-			os_free(in_decrypted);
+		if (eap_peap_phase2_request(sm, data, ret, in_decrypted,
+					    &resp)) {
+			wpabuf_free(in_decrypted);
 			wpa_printf(MSG_INFO, "EAP-PEAP: Phase2 Request "
 				   "processing failed");
 			return 0;
@@ -413,20 +394,20 @@
 			ret->methodState = METHOD_DONE;
 			data->phase2_success = 1;
 			if (data->peap_outer_success == 2) {
-				os_free(in_decrypted);
+				wpabuf_free(in_decrypted);
 				wpa_printf(MSG_DEBUG, "EAP-PEAP: Use TLS ACK "
 					   "to finish authentication");
 				return 1;
 			} else if (data->peap_outer_success == 1) {
 				/* Reply with EAP-Success within the TLS
 				 * channel to complete the authentication. */
-				resp_len = sizeof(struct eap_hdr);
-				resp = os_zalloc(resp_len);
+				resp = wpabuf_alloc(sizeof(struct eap_hdr));
 				if (resp) {
-					rhdr = (struct eap_hdr *) resp;
+					rhdr = wpabuf_put(resp, sizeof(*rhdr));
 					rhdr->code = EAP_CODE_SUCCESS;
 					rhdr->identifier = hdr->identifier;
-					rhdr->length = host_to_be16(resp_len);
+					rhdr->length =
+						host_to_be16(sizeof(*rhdr));
 				}
 			} else {
 				/* No EAP-Success expected for Phase 1 (outer,
@@ -445,13 +426,12 @@
 		ret->allowNotifications = FALSE;
 		/* Reply with EAP-Failure within the TLS channel to complete
 		 * failure reporting. */
-		resp_len = sizeof(struct eap_hdr);
-		resp = os_zalloc(resp_len);
+		resp = wpabuf_alloc(sizeof(struct eap_hdr));
 		if (resp) {
-			rhdr = (struct eap_hdr *) resp;
+			rhdr = wpabuf_put(resp, sizeof(*rhdr));
 			rhdr->code = EAP_CODE_FAILURE;
 			rhdr->identifier = hdr->identifier;
-			rhdr->length = host_to_be16(resp_len);
+			rhdr->length = host_to_be16(sizeof(*rhdr));
 		}
 		break;
 	default:
@@ -460,58 +440,57 @@
 		break;
 	}
 
-	os_free(in_decrypted);
+	wpabuf_free(in_decrypted);
 
 	if (resp) {
-		u8 *resp_pos;
-		size_t resp_send_len;
 		int skip_change2 = 0;
-
-		wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
-				resp, resp_len);
+		struct wpabuf *rmsg, buf;
+
+		wpa_hexdump_buf_key(MSG_DEBUG,
+				    "EAP-PEAP: Encrypting Phase 2 data", resp);
 		/* PEAP version changes */
-		if (resp_len >= 5 && resp[0] == EAP_CODE_RESPONSE &&
-		    resp[4] == EAP_TYPE_TLV)
+		if (wpabuf_len(resp) >= 5 &&
+		    wpabuf_head_u8(resp)[0] == EAP_CODE_RESPONSE &&
+		    eap_get_type(resp) == EAP_TYPE_TLV)
 			skip_change2 = 1;
+		rmsg = resp;
 		if (data->peap_version == 0 && !skip_change2) {
-			resp_pos = resp + sizeof(struct eap_hdr);
-			resp_send_len = resp_len - sizeof(struct eap_hdr);
-		} else {
-			resp_pos = resp;
-			resp_send_len = resp_len;
+			wpabuf_set(&buf, wpabuf_head_u8(resp) +
+				   sizeof(struct eap_hdr),
+				   wpabuf_len(resp) - sizeof(struct eap_hdr));
+			rmsg = &buf;
 		}
 
 		if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_PEAP,
 					 data->peap_version, req->identifier,
-					 resp_pos, resp_send_len,
-					 out_data, out_len)) {
+					 rmsg, out_data)) {
 			wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt "
 				   "a Phase 2 frame");
 		}
-		os_free(resp);
+		wpabuf_free(resp);
 	}
 
 	return 0;
 }
 
 
-static u8 * eap_peap_process(struct eap_sm *sm, void *priv,
-			     struct eap_method_ret *ret,
-			     const u8 *reqData, size_t reqDataLen,
-			     size_t *respDataLen)
+static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
+					struct eap_method_ret *ret,
+					const struct wpabuf *reqData)
 {
 	const struct eap_hdr *req;
 	size_t left;
 	int res;
-	u8 flags, *resp, id;
+	u8 flags, id;
+	struct wpabuf *resp;
 	const u8 *pos;
 	struct eap_peap_data *data = priv;
 
 	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_PEAP, ret,
-					reqData, reqDataLen, &left, &flags);
+					reqData, &left, &flags);
 	if (pos == NULL)
 		return NULL;
-	req = (const struct eap_hdr *) reqData;
+	req = wpabuf_head(reqData);
 	id = req->identifier;
 
 	if (flags & EAP_TLS_FLAGS_START) {
@@ -539,13 +518,14 @@
 	resp = NULL;
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
 	    !data->resuming) {
-		res = eap_peap_decrypt(sm, data, ret, req, pos, left,
-				       &resp, respDataLen);
+		struct wpabuf msg;
+		wpabuf_set(&msg, pos, left);
+		res = eap_peap_decrypt(sm, data, ret, req, &msg, &resp);
 	} else {
 		res = eap_peer_tls_process_helper(sm, &data->ssl,
 						  EAP_TYPE_PEAP,
 						  data->peap_version, id, pos,
-						  left, &resp, respDataLen);
+						  left, &resp);
 
 		if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 			char *label;
@@ -600,16 +580,16 @@
 		}
 
 		if (res == 2) {
+			struct wpabuf msg;
 			/*
 			 * Application data included in the handshake message.
 			 */
-			os_free(data->pending_phase2_req);
+			wpabuf_free(data->pending_phase2_req);
 			data->pending_phase2_req = resp;
-			data->pending_phase2_req_len = *respDataLen;
 			resp = NULL;
-			*respDataLen = 0;
-			res = eap_peap_decrypt(sm, data, ret, req, pos, left,
-					       &resp, respDataLen);
+			wpabuf_set(&msg, pos, left);
+			res = eap_peap_decrypt(sm, data, ret, req, &msg,
+					       &resp);
 		}
 	}
 
@@ -618,8 +598,8 @@
 	}
 
 	if (res == 1) {
-		os_free(resp);
-		return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_PEAP,
+		wpabuf_free(resp);
+		return eap_peer_tls_build_ack(id, EAP_TYPE_PEAP,
 					      data->peap_version);
 	}
 
@@ -638,7 +618,7 @@
 static void eap_peap_deinit_for_reauth(struct eap_sm *sm, void *priv)
 {
 	struct eap_peap_data *data = priv;
-	os_free(data->pending_phase2_req);
+	wpabuf_free(data->pending_phase2_req);
 	data->pending_phase2_req = NULL;
 }
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_psk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_psk.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_psk.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_psk.c Tue Dec 25 15:23:24 2007
@@ -78,26 +78,25 @@
 }
 
 
-static u8 * eap_psk_process_1(struct eap_psk_data *data,
-			      struct eap_method_ret *ret,
-			      const u8 *reqData, size_t reqDataLen,
-			      size_t *respDataLen)
+static struct wpabuf * eap_psk_process_1(struct eap_psk_data *data,
+					 struct eap_method_ret *ret,
+					 const struct wpabuf *reqData)
 {
 	const struct eap_psk_hdr_1 *hdr1;
 	struct eap_psk_hdr_2 *hdr2;
-	u8 *resp, *buf, *pos;
-	size_t buflen;
+	struct wpabuf *resp;
+	u8 *buf, *pos;
+	size_t buflen, len;
+	const u8 *cpos;
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: in INIT state");
 
-	hdr1 = (const struct eap_psk_hdr_1 *) reqData;
-	if (reqDataLen < sizeof(*hdr1) ||
-	    be_to_host16(hdr1->length) < sizeof(*hdr1) ||
-	    be_to_host16(hdr1->length) > reqDataLen) {
+	cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
+	hdr1 = (const struct eap_psk_hdr_1 *) cpos;
+	if (cpos == NULL || len < sizeof(*hdr1)) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Invalid first message "
-			   "length (%lu %d; expected %lu or more)",
-			   (unsigned long) reqDataLen,
-			   be_to_host16(hdr1->length),
+			   "length (%lu; expected %lu or more)",
+			   (unsigned long) len,
 			   (unsigned long) sizeof(*hdr1));
 		ret->ignore = TRUE;
 		return NULL;
@@ -113,7 +112,7 @@
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr1->rand_s,
 		    EAP_PSK_RAND_LEN);
 	os_free(data->id_s);
-	data->id_s_len = be_to_host16(hdr1->length) - sizeof(*hdr1);
+	data->id_s_len = len - sizeof(*hdr1);
 	data->id_s = os_malloc(data->id_s_len);
 	if (data->id_s == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory for "
@@ -131,24 +130,21 @@
 		return NULL;
 	}
 
-	*respDataLen = sizeof(*hdr2) + data->id_p_len;
-	resp = os_malloc(*respDataLen);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
+			     sizeof(*hdr2) + data->id_p_len, EAP_CODE_RESPONSE,
+			     eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
-	hdr2 = (struct eap_psk_hdr_2 *) resp;
-	hdr2->code = EAP_CODE_RESPONSE;
-	hdr2->identifier = hdr1->identifier;
-	hdr2->length = host_to_be16(*respDataLen);
-	hdr2->type = EAP_TYPE_PSK;
+	hdr2 = wpabuf_put(resp, sizeof(*hdr2));
 	hdr2->flags = EAP_PSK_FLAGS_SET_T(1); /* T=1 */
 	os_memcpy(hdr2->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
 	os_memcpy(hdr2->rand_p, data->rand_p, EAP_PSK_RAND_LEN);
-	os_memcpy((u8 *) (hdr2 + 1), data->id_p, data->id_p_len);
+	wpabuf_put_data(resp, data->id_p, data->id_p_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 = os_malloc(buflen);
 	if (buf == NULL) {
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 	os_memcpy(buf, data->id_p, data->id_p_len);
@@ -164,7 +160,7 @@
 		    EAP_PSK_RAND_LEN);
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", hdr2->mac_p, EAP_PSK_MAC_LEN);
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_P",
-			  (u8 *) (hdr2 + 1), data->id_p_len);
+			  data->id_p, data->id_p_len);
 
 	data->state = PSK_MAC_SENT;
 
@@ -172,33 +168,34 @@
 }
 
 
-static u8 * eap_psk_process_3(struct eap_psk_data *data,
-			      struct eap_method_ret *ret,
-			      const u8 *reqData, size_t reqDataLen,
-			      size_t *respDataLen)
+static struct wpabuf * eap_psk_process_3(struct eap_psk_data *data,
+					 struct eap_method_ret *ret,
+					 const struct wpabuf *reqData)
 {
 	const struct eap_psk_hdr_3 *hdr3;
 	struct eap_psk_hdr_4 *hdr4;
-	u8 *resp, *buf, *rpchannel, nonce[16], *decrypted;
+	struct wpabuf *resp;
+	u8 *buf, *rpchannel, nonce[16], *decrypted;
 	const u8 *pchannel, *tag, *msg;
 	u8 mac[EAP_PSK_MAC_LEN];
-	size_t buflen, left, data_len;
+	size_t buflen, left, data_len, len, plen;
 	int failed = 0;
+	const u8 *pos;
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: in MAC_SENT state");
 
-	hdr3 = (const struct eap_psk_hdr_3 *) reqData;
-	left = be_to_host16(hdr3->length);
-	if (left < sizeof(*hdr3) || reqDataLen < left) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK,
+			       reqData, &len);
+	hdr3 = (const struct eap_psk_hdr_3 *) pos;
+	if (pos == NULL || len < sizeof(*hdr3)) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Invalid third message "
-			   "length (%lu %d; expected %lu)",
-			   (unsigned long) reqDataLen,
-			   be_to_host16(hdr3->length),
+			   "length (%lu; expected %lu or more)",
+			   (unsigned long) len,
 			   (unsigned long) sizeof(*hdr3));
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	left -= sizeof(*hdr3);
+	left = len - sizeof(*hdr3);
 	pchannel = (const u8 *) (hdr3 + 1);
 	wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr3->flags);
 	if (EAP_PSK_FLAGS_GET_T(hdr3->flags) != 2) {
@@ -258,7 +255,8 @@
 
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - nonce",
 		    nonce, sizeof(nonce));
-	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - hdr", reqData, 5);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - hdr",
+		    wpabuf_head(reqData), 5);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - cipher msg", msg, left);
 
 	decrypted = os_malloc(left);
@@ -270,7 +268,10 @@
 	os_memcpy(decrypted, msg, left);
 
 	if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
-				reqData, 22, decrypted, left, tag)) {
+				wpabuf_head(reqData),
+				sizeof(struct eap_hdr) + 1 +
+				sizeof(*hdr3) - EAP_PSK_MAC_LEN, decrypted,
+				left, tag)) {
 		wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
 		os_free(decrypted);
 		return NULL;
@@ -295,26 +296,25 @@
 		break;
 	}
 
-	*respDataLen = sizeof(*hdr4) + 4 + 16 + 1;
-	resp = os_malloc(*respDataLen + 1);
+	data_len = 1;
+	if ((decrypted[0] & EAP_PSK_E_FLAG) && left > 1)
+		data_len++;
+	plen = sizeof(*hdr4) + 4 + 16 + data_len;
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, plen,
+			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL) {
 		os_free(decrypted);
 		return NULL;
 	}
-	hdr4 = (struct eap_psk_hdr_4 *) resp;
-	hdr4->code = EAP_CODE_RESPONSE;
-	hdr4->identifier = hdr3->identifier;
-	hdr4->length = host_to_be16(*respDataLen);
-	hdr4->type = EAP_TYPE_PSK;
+	hdr4 = wpabuf_put(resp, sizeof(*hdr4));
 	hdr4->flags = EAP_PSK_FLAGS_SET_T(3); /* T=3 */
 	os_memcpy(hdr4->rand_s, hdr3->rand_s, EAP_PSK_RAND_LEN);
-	rpchannel = (u8 *) (hdr4 + 1);
+	rpchannel = wpabuf_put(resp, 4 + 16 + data_len);
 
 	/* nonce++ */
 	inc_byte_array(nonce, sizeof(nonce));
 	os_memcpy(rpchannel, nonce + 12, 4);
 
-	data_len = 1;
 	if (decrypted[0] & EAP_PSK_E_FLAG) {
 		wpa_printf(MSG_DEBUG, "EAP-PSK: Unsupported E (Ext) flag");
 		failed = 1;
@@ -322,10 +322,7 @@
 			EAP_PSK_E_FLAG;
 		if (left > 1) {
 			/* Add empty EXT_Payload with same EXT_Type */
-			(*respDataLen)++;
-			hdr4->length = host_to_be16(*respDataLen);
 			rpchannel[4 + 16 + 1] = decrypted[1];
-			data_len++;
 		}
 	} else if (failed)
 		rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_FAILURE << 6;
@@ -334,7 +331,8 @@
 
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (plaintext)",
 		    rpchannel + 4 + 16, data_len);
-	aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), resp, 22,
+	aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), wpabuf_head(resp),
+			    sizeof(struct eap_hdr) + 1 + sizeof(*hdr4),
 			    rpchannel + 4 + 16, data_len, rpchannel + 4);
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (PCHANNEL)",
 		    rpchannel, 4 + 16 + data_len);
@@ -351,23 +349,20 @@
 }
 
 
-static u8 * eap_psk_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+static struct wpabuf * eap_psk_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_psk_data *data = priv;
 	const u8 *pos;
-	u8 *resp = NULL;
+	struct wpabuf *resp = NULL;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
 	if (pos == NULL) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	len += sizeof(struct eap_hdr) + 1;
 
 	ret->ignore = FALSE;
 	ret->methodState = METHOD_MAY_CONT;
@@ -376,12 +371,10 @@
 
 	switch (data->state) {
 	case PSK_INIT:
-		resp = eap_psk_process_1(data, ret, reqData, len,
-					 respDataLen);
+		resp = eap_psk_process_1(data, ret, reqData);
 		break;
 	case PSK_MAC_SENT:
-		resp = eap_psk_process_3(data, ret, reqData, len,
-					 respDataLen);
+		resp = eap_psk_process_3(data, ret, reqData);
 		break;
 	case PSK_DONE:
 		wpa_printf(MSG_DEBUG, "EAP-PSK: in DONE state - ignore "

Modified: wpasupplicant/trunk/src/eap_peer/eap_sake.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_sake.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_sake.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_sake.c Tue Dec 25 15:23:24 2007
@@ -122,45 +122,41 @@
 }
 
 
-static u8 * eap_sake_build_msg(struct eap_sake_data *data, u8 **payload,
-			       int id, size_t *length, u8 subtype)
-{
-	struct eap_sake_hdr *req;
-	u8 *msg;
-
-	*length += sizeof(struct eap_sake_hdr);
-
-	msg = os_zalloc(*length);
+static struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data,
+					  int id, size_t length, u8 subtype)
+{
+	struct eap_sake_hdr *sake;
+	struct wpabuf *msg;
+	size_t plen;
+
+	plen = length + sizeof(struct eap_sake_hdr);
+
+	msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_SAKE, plen,
+			    EAP_CODE_RESPONSE, id);
 	if (msg == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to allocate memory "
 			   "request");
 		return NULL;
 	}
 
-	req = (struct eap_sake_hdr *) msg;
-	req->code = EAP_CODE_RESPONSE;
-	req->identifier = id;
-	req->length = host_to_be16((u16) *length);
-	req->type = EAP_TYPE_SAKE;
-	req->version = EAP_SAKE_VERSION;
-	req->session_id = data->session_id;
-	req->subtype = subtype;
-	*payload = (u8 *) (req + 1);
+	sake = wpabuf_put(msg, sizeof(*sake));
+	sake->version = EAP_SAKE_VERSION;
+	sake->session_id = data->session_id;
+	sake->subtype = subtype;
 
 	return msg;
 }
 
 
-static u8 * eap_sake_process_identity(struct eap_sm *sm,
-				      struct eap_sake_data *data,
-				      struct eap_method_ret *ret,
-				      const u8 *reqData, size_t reqDataLen,
-				      const u8 *payload, size_t payload_len,
-				      size_t *respDataLen)
+static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm,
+						 struct eap_sake_data *data,
+						 struct eap_method_ret *ret,
+						 const struct wpabuf *reqData,
+						 const u8 *payload,
+						 size_t payload_len)
 {
 	struct eap_sake_parse_attr attr;
-	u8 *resp, *rpos;
-	const struct eap_hdr *hdr = (const struct eap_hdr *) reqData;
+	struct wpabuf *resp;
 
 	if (data->state != IDENTITY) {
 		ret->ignore = TRUE;
@@ -180,17 +176,15 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Identity");
 
-	*respDataLen = 2 + data->peerid_len;
-	resp = eap_sake_build_msg(data, &rpos, hdr->identifier, respDataLen,
+	resp = eap_sake_build_msg(data, eap_get_id(reqData),
+				  2 + data->peerid_len,
 				  EAP_SAKE_SUBTYPE_IDENTITY);
 	if (resp == NULL)
 		return NULL;
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID");
-	*rpos++ = EAP_SAKE_AT_PEERID;
-	*rpos++ = 2 + data->peerid_len;
-	if (data->peerid)
-		os_memcpy(rpos, data->peerid, data->peerid_len);
+	eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID,
+			  data->peerid, data->peerid_len);
 
 	eap_sake_state(data, CHALLENGE);
 
@@ -198,16 +192,17 @@
 }
 
 
-static u8 * eap_sake_process_challenge(struct eap_sm *sm,
-				       struct eap_sake_data *data,
-				       struct eap_method_ret *ret,
-				       const u8 *reqData, size_t reqDataLen,
-				       const u8 *payload, size_t payload_len,
-				       size_t *respDataLen)
+static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm,
+						  struct eap_sake_data *data,
+						  struct eap_method_ret *ret,
+						  const struct wpabuf *reqData,
+						  const u8 *payload,
+						  size_t payload_len)
 {
 	struct eap_sake_parse_attr attr;
-	u8 *resp, *rpos;
-	const struct eap_hdr *hdr = (const struct eap_hdr *) reqData;
+	struct wpabuf *resp;
+	u8 *rpos;
+	size_t rlen;
 
 	if (data->state != IDENTITY && data->state != CHALLENGE) {
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge received "
@@ -259,37 +254,35 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Challenge");
 
-	*respDataLen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN;
+	rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN;
 	if (data->peerid)
-		*respDataLen += 2 + data->peerid_len;
-	resp = eap_sake_build_msg(data, &rpos, hdr->identifier, respDataLen,
+		rlen += 2 + data->peerid_len;
+	resp = eap_sake_build_msg(data, eap_get_id(reqData), rlen,
 				  EAP_SAKE_SUBTYPE_CHALLENGE);
 	if (resp == NULL)
 		return NULL;
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_P");
-	*rpos++ = EAP_SAKE_AT_RAND_P;
-	*rpos++ = 2 + EAP_SAKE_RAND_LEN;
-	os_memcpy(rpos, data->rand_p, EAP_SAKE_RAND_LEN);
-	rpos += EAP_SAKE_RAND_LEN;
+	eap_sake_add_attr(resp, EAP_SAKE_AT_RAND_P,
+			  data->rand_p, EAP_SAKE_RAND_LEN);
 
 	if (data->peerid) {
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID");
-		*rpos++ = EAP_SAKE_AT_PEERID;
-		*rpos++ = 2 + data->peerid_len;
-		os_memcpy(rpos, data->peerid, data->peerid_len);
-		rpos += data->peerid_len;
+		eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID,
+				  data->peerid, data->peerid_len);
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P");
-	*rpos++ = EAP_SAKE_AT_MIC_P;
-	*rpos++ = 2 + EAP_SAKE_MIC_LEN;
+	wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P);
+	wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN);
+	rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN);
 	if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
 				 data->serverid, data->serverid_len,
 				 data->peerid, data->peerid_len, 1,
-				 resp, *respDataLen, rpos, rpos)) {
+				 wpabuf_head(resp), wpabuf_len(resp), rpos,
+				 rpos)) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC");
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 
@@ -299,17 +292,17 @@
 }
 
 
-static u8 * eap_sake_process_confirm(struct eap_sm *sm,
-				     struct eap_sake_data *data,
-				     struct eap_method_ret *ret,
-				     const u8 *reqData, size_t reqDataLen,
-				     const u8 *payload, size_t payload_len,
-				     size_t *respDataLen)
+static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm,
+						struct eap_sake_data *data,
+						struct eap_method_ret *ret,
+						const struct wpabuf *reqData,
+						const u8 *payload,
+						size_t payload_len)
 {
 	struct eap_sake_parse_attr attr;
 	u8 mic_s[EAP_SAKE_MIC_LEN];
-	u8 *resp, *rpos;
-	const struct eap_hdr *hdr = (const struct eap_hdr *) reqData;
+	struct wpabuf *resp;
+	u8 *rpos;
 
 	if (data->state != CONFIRM) {
 		ret->ignore = TRUE;
@@ -330,38 +323,39 @@
 	eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
 			     data->serverid, data->serverid_len,
 			     data->peerid, data->peerid_len, 0,
-			     reqData, reqDataLen, attr.mic_s, mic_s);
+			     wpabuf_head(reqData), wpabuf_len(reqData),
+			     attr.mic_s, mic_s);
 	if (os_memcmp(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_S");
 		eap_sake_state(data, FAILURE);
 		ret->methodState = METHOD_DONE;
 		ret->decision = DECISION_FAIL;
 		ret->allowNotifications = FALSE;
-		*respDataLen = 0;
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending "
 			   "Response/Auth-Reject");
-		return eap_sake_build_msg(data, &rpos, hdr->identifier,
-					  respDataLen,
+		return eap_sake_build_msg(data, eap_get_id(reqData), 0,
 					  EAP_SAKE_SUBTYPE_AUTH_REJECT);
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Confirm");
 
-	*respDataLen = 2 + EAP_SAKE_MIC_LEN;
-	resp = eap_sake_build_msg(data, &rpos, hdr->identifier, respDataLen,
+	resp = eap_sake_build_msg(data, eap_get_id(reqData),
+				  2 + EAP_SAKE_MIC_LEN,
 				  EAP_SAKE_SUBTYPE_CONFIRM);
 	if (resp == NULL)
 		return NULL;
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P");
-	*rpos++ = EAP_SAKE_AT_MIC_P;
-	*rpos++ = 2 + EAP_SAKE_MIC_LEN;
+	wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P);
+	wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN);
+	rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN);
 	if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
 				 data->serverid, data->serverid_len,
 				 data->peerid, data->peerid_len, 1,
-				 resp, *respDataLen, rpos, rpos)) {
+				 wpabuf_head(resp), wpabuf_len(resp), rpos,
+				 rpos)) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC");
-		os_free(resp);
+		wpabuf_free(resp);
 		return NULL;
 	}
 
@@ -374,30 +368,28 @@
 }
 
 
-static u8 * eap_sake_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv,
+					struct eap_method_ret *ret,
+					const struct wpabuf *reqData)
 {
 	struct eap_sake_data *data = priv;
 	const struct eap_sake_hdr *req;
-	u8 *resp;
+	struct wpabuf *resp;
 	const u8 *pos, *end;
 	size_t len;
 	u8 subtype, session_id;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE,
-			       reqData, reqDataLen, &len);
-	if (pos == NULL || len < 3) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, reqData, &len);
+	if (pos == NULL || len < sizeof(struct eap_sake_hdr)) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
 
-	req = (const struct eap_sake_hdr *) reqData;
+	req = (const struct eap_sake_hdr *) pos;
+	end = pos + len;
 	subtype = req->subtype;
 	session_id = req->session_id;
 	pos = (const u8 *) (req + 1);
-	end = reqData + be_to_host16(req->length);
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received frame: subtype %d "
 		   "session_id %d", subtype, session_id);
@@ -421,18 +413,15 @@
 	switch (subtype) {
 	case EAP_SAKE_SUBTYPE_IDENTITY:
 		resp = eap_sake_process_identity(sm, data, ret, reqData,
-						 reqDataLen, pos, end - pos,
-						 respDataLen);
+						 pos, end - pos);
 		break;
 	case EAP_SAKE_SUBTYPE_CHALLENGE:
 		resp = eap_sake_process_challenge(sm, data, ret, reqData,
-						  reqDataLen, pos, end - pos,
-						  respDataLen);
+						  pos, end - pos);
 		break;
 	case EAP_SAKE_SUBTYPE_CONFIRM:
 		resp = eap_sake_process_confirm(sm, data, ret, reqData,
-						reqDataLen, pos, end - pos,
-						respDataLen);
+						pos, end - pos);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: Ignoring message with "

Modified: wpasupplicant/trunk/src/eap_peer/eap_sim.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_sim.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_sim.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_sim.c Tue Dec 25 15:23:24 2007
@@ -46,8 +46,41 @@
 	unsigned int counter, counter_too_small;
 	u8 *last_eap_identity;
 	size_t last_eap_identity_len;
-	enum { CONTINUE, SUCCESS, FAILURE } state;
+	enum {
+		CONTINUE, RESULT_SUCCESS, RESULT_FAILURE, SUCCESS, FAILURE
+	} state;
+	int result_ind, use_result_ind;
 };
+
+
+#ifndef CONFIG_NO_STDOUT_DEBUG
+static const char * eap_sim_state_txt(int state)
+{
+	switch (state) {
+	case CONTINUE:
+		return "CONTINUE";
+	case RESULT_SUCCESS:
+		return "RESULT_SUCCESS";
+	case RESULT_FAILURE:
+		return "RESULT_FAILURE";
+	case SUCCESS:
+		return "SUCCESS";
+	case FAILURE:
+		return "FAILURE";
+	default:
+		return "?";
+	}
+}
+#endif /* CONFIG_NO_STDOUT_DEBUG */
+
+
+static void eap_sim_state(struct eap_sim_data *data, int state)
+{
+	wpa_printf(MSG_DEBUG, "EAP-SIM: %s -> %s",
+		   eap_sim_state_txt(data->state),
+		   eap_sim_state_txt(state));
+	data->state = state;
+}
 
 
 static void * eap_sim_init(struct eap_sm *sm)
@@ -83,9 +116,12 @@
 				   "challenges to %lu",
 				   (unsigned long) data->min_num_chal);
 		}
-	}
-
-	data->state = CONTINUE;
+
+		data->result_ind = os_strstr(config->phase1, "result_ind=1") !=
+			NULL;
+	}
+
+	eap_sim_state(data, CONTINUE);
 
 	return data;
 }
@@ -228,28 +264,25 @@
 }
 
 
-static u8 * eap_sim_client_error(struct eap_sim_data *data,
-				 const struct eap_hdr *req,
-				 size_t *respDataLen, int err)
+static struct wpabuf * eap_sim_client_error(struct eap_sim_data *data, u8 id,
+					    int err)
 {
 	struct eap_sim_msg *msg;
 
-	data->state = FAILURE;
+	eap_sim_state(data, FAILURE);
 	data->num_id_req = 0;
 	data->num_notification = 0;
 
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CLIENT_ERROR);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
+			       EAP_SIM_SUBTYPE_CLIENT_ERROR);
 	eap_sim_msg_add(msg, EAP_SIM_AT_CLIENT_ERROR_CODE, err, NULL, 0);
-	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_sim_response_start(struct eap_sm *sm,
-				   struct eap_sim_data *data,
-				   const struct eap_hdr *req,
-				   size_t *respDataLen,
-				   enum eap_sim_id_req id_req)
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_sim_response_start(struct eap_sm *sm,
+					      struct eap_sim_data *data, u8 id,
+					      enum eap_sim_id_req id_req)
 {
 	const u8 *identity = NULL;
 	size_t identity_len = 0;
@@ -275,9 +308,8 @@
 	if (id_req != NO_ID_REQ)
 		eap_sim_clear_identities(data, CLEAR_EAP_ID);
 
-	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
+	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Start (id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
 			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_START);
 	wpa_hexdump(MSG_DEBUG, "   AT_NONCE_MT",
 		    data->nonce_mt, EAP_SIM_NONCE_MT_LEN);
@@ -295,39 +327,38 @@
 				identity, identity_len);
 	}
 
-	return eap_sim_msg_finish(msg, respDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_sim_response_challenge(struct eap_sim_data *data,
-				       const struct eap_hdr *req,
-				       size_t *respDataLen)
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
+}
+
+
+static struct wpabuf * eap_sim_response_challenge(struct eap_sim_data *data,
+						  u8 id)
 {
 	struct eap_sim_msg *msg;
 
-	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_CHALLENGE);
+	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Challenge (id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
+			       EAP_SIM_SUBTYPE_CHALLENGE);
+	if (data->use_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, respDataLen, data->k_aut,
-				  (u8 *) data->sres,
+	return eap_sim_msg_finish(msg, data->k_aut, (u8 *) data->sres,
 				  data->num_chal * EAP_SIM_SRES_LEN);
 }
 
 
-static u8 * eap_sim_response_reauth(struct eap_sim_data *data,
-				    const struct eap_hdr *req,
-				    size_t *respDataLen, int counter_too_small)
+static struct wpabuf * eap_sim_response_reauth(struct eap_sim_data *data,
+					       u8 id, int counter_too_small)
 {
 	struct eap_sim_msg *msg;
 	unsigned int counter;
 
 	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Reauthentication (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
-			       EAP_TYPE_SIM,
+		   id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id, EAP_TYPE_SIM,
 			       EAP_SIM_SUBTYPE_REAUTHENTICATION);
 	wpa_printf(MSG_DEBUG, "   AT_IV");
 	wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
@@ -349,24 +380,25 @@
 		eap_sim_msg_free(msg);
 		return NULL;
 	}
+	if (data->use_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, respDataLen, data->k_aut, data->nonce_s,
+	return eap_sim_msg_finish(msg, data->k_aut, data->nonce_s,
 				  EAP_SIM_NONCE_S_LEN);
 }
 
 
-static u8 * eap_sim_response_notification(struct eap_sim_data *data,
-					  const struct eap_hdr *req,
-					  size_t *respDataLen,
-					  u16 notification)
+static struct wpabuf * eap_sim_response_notification(struct eap_sim_data *data,
+						     u8 id, u16 notification)
 {
 	struct eap_sim_msg *msg;
 	u8 *k_aut = (notification & 0x4000) == 0 ? data->k_aut : NULL;
 
-	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)",
-		   req->identifier);
-	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, req->identifier,
+	wpa_printf(MSG_DEBUG, "Generating EAP-SIM Notification (id=%d)", id);
+	msg = eap_sim_msg_init(EAP_CODE_RESPONSE, id,
 			       EAP_TYPE_SIM, EAP_SIM_SUBTYPE_NOTIFICATION);
 	wpa_printf(MSG_DEBUG, "   AT_NOTIFICATION");
 	eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, notification, NULL, 0);
@@ -390,14 +422,13 @@
 		wpa_printf(MSG_DEBUG, "   AT_MAC");
 		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
 	}
-	return eap_sim_msg_finish(msg, respDataLen, k_aut, (u8 *) "", 0);
-}
-
-
-static u8 * eap_sim_process_start(struct eap_sm *sm, struct eap_sim_data *data,
-				  const struct eap_hdr *req,
-				  size_t *respDataLen,
-				  struct eap_sim_attrs *attr)
+	return eap_sim_msg_finish(msg, k_aut, (u8 *) "", 0);
+}
+
+
+static struct wpabuf * eap_sim_process_start(struct eap_sm *sm,
+					     struct eap_sim_data *data, u8 id,
+					     struct eap_sim_attrs *attr)
 {
 	int selected_version = -1, id_error;
 	size_t i;
@@ -407,7 +438,7 @@
 	if (attr->version_list == NULL) {
 		wpa_printf(MSG_INFO, "EAP-SIM: No AT_VERSION_LIST in "
 			   "SIM/Start");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNSUPPORTED_VERSION);
 	}
 
@@ -416,7 +447,7 @@
 	if (data->ver_list == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to allocate "
 			   "memory for version list");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 	os_memcpy(data->ver_list, attr->version_list, attr->version_list_len);
@@ -433,7 +464,7 @@
 	if (selected_version < 0) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Could not find a supported "
 			   "version");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNSUPPORTED_VERSION);
 	}
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Selected Version %d",
@@ -463,21 +494,19 @@
 	if (id_error) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Too many ID requests "
 			   "used within one authentication");
-		return eap_sim_client_error(data, req, respDataLen,
-					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
-	}
-
-	return eap_sim_response_start(sm, data, req, respDataLen,
-				      attr->id_req);
-}
-
-
-static u8 * eap_sim_process_challenge(struct eap_sm *sm,
-				      struct eap_sim_data *data,
-				      const struct eap_hdr *req,
-				      size_t reqDataLen,
-				      size_t *respDataLen,
-				      struct eap_sim_attrs *attr)
+		return eap_sim_client_error(data, id,
+					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
+	}
+
+	return eap_sim_response_start(sm, data, id, attr->id_req);
+}
+
+
+static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm,
+						 struct eap_sim_data *data,
+						 u8 id,
+						 const struct wpabuf *reqData,
+						 struct eap_sim_attrs *attr)
 {
 	const u8 *identity;
 	size_t identity_len;
@@ -490,7 +519,7 @@
 			   "did not include%s%s",
 			   !attr->mac ? " AT_MAC" : "",
 			   !attr->rand ? " AT_RAND" : "");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -499,13 +528,13 @@
 	if (attr->num_chal < data->min_num_chal) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Insufficient number of "
 			   "challenges (%lu)", (unsigned long) attr->num_chal);
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_INSUFFICIENT_NUM_OF_CHAL);
 	}
 	if (attr->num_chal > 3) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Too many challenges "
 			   "(%lu)", (unsigned long) attr->num_chal);
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -519,7 +548,7 @@
 			attr->rand + 2 * GSM_RAND_LEN,
 			GSM_RAND_LEN) == 0))) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Same RAND used multiple times");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_RAND_NOT_FRESH);
 	}
 
@@ -528,7 +557,7 @@
 		
 	if (eap_sim_gsm_auth(sm, data)) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 	if (data->last_eap_identity) {
@@ -547,12 +576,11 @@
 			  (const u8 *) data->kc, data->mk);
 	eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk,
 			    data->emsk);
-	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
-			       attr->mac, data->nonce_mt,
+	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, data->nonce_mt,
 			       EAP_SIM_NONCE_MT_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
 			   "used invalid AT_MAC");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -569,15 +597,19 @@
 					       &eattr, 0);
 		if (decrypted == NULL) {
 			return eap_sim_client_error(
-				data, req, respDataLen,
-				EAP_SIM_UNABLE_TO_PROCESS_PACKET);
+				data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 		}
 		eap_sim_learn_ids(data, &eattr);
 		os_free(decrypted);
 	}
 
-	if (data->state != FAILURE)
-		data->state = SUCCESS;
+	if (data->result_ind && attr->result_ind)
+		data->use_result_ind = 1;
+
+	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
+		eap_sim_state(data, data->use_result_ind ?
+			      RESULT_SUCCESS : SUCCESS);
+	}
 
 	data->num_id_req = 0;
 	data->num_notification = 0;
@@ -585,7 +617,7 @@
 	 * fullauth, but initializing it to zero makes it easier to implement
 	 * reauth verification. */
 	data->counter = 0;
-	return eap_sim_response_challenge(data, req, respDataLen);
+	return eap_sim_response_challenge(data, id);
 }
 
 
@@ -624,8 +656,7 @@
 
 
 static int eap_sim_process_notification_auth(struct eap_sim_data *data,
-					     const struct eap_hdr *req,
-					     size_t reqDataLen,
+					     const struct wpabuf *reqData,
 					     struct eap_sim_attrs *attr)
 {
 	if (attr->mac == NULL) {
@@ -634,8 +665,8 @@
 		return -1;
 	}
 
-	if (eap_sim_verify_mac(data->k_aut, (u8 *) req, reqDataLen, attr->mac,
-			       (u8 *) "", 0)) {
+	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
+	{
 		wpa_printf(MSG_WARNING, "EAP-SIM: Notification message "
 			   "used invalid AT_MAC");
 		return -1;
@@ -652,49 +683,44 @@
 }
 
 
-static u8 * eap_sim_process_notification(struct eap_sm *sm,
-					 struct eap_sim_data *data,
-					 const struct eap_hdr *req,
-					 size_t reqDataLen,
-					 size_t *respDataLen,
-					 struct eap_sim_attrs *attr)
+static struct wpabuf * eap_sim_process_notification(
+	struct eap_sm *sm, struct eap_sim_data *data, u8 id,
+	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Notification");
 	if (data->num_notification > 0) {
 		wpa_printf(MSG_INFO, "EAP-SIM: too many notification "
 			   "rounds (only one allowed)");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 	data->num_notification++;
 	if (attr->notification == -1) {
 		wpa_printf(MSG_INFO, "EAP-SIM: no AT_NOTIFICATION in "
 			   "Notification message");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	if ((attr->notification & 0x4000) == 0 &&
-	    eap_sim_process_notification_auth(data, req, reqDataLen, attr)) {
-		return eap_sim_client_error(data, req, respDataLen,
+	    eap_sim_process_notification_auth(data, reqData, attr)) {
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	eap_sim_report_notification(sm->msg_ctx, attr->notification, 0);
 	if (attr->notification >= 0 && attr->notification < 32768) {
-		data->state = FAILURE;
-	}
-	return eap_sim_response_notification(data, req, respDataLen,
-					     attr->notification);
-}
-
-
-static u8 * eap_sim_process_reauthentication(struct eap_sm *sm,
-					     struct eap_sim_data *data,
-					     const struct eap_hdr *req,
-					     size_t reqDataLen,
-					     size_t *respDataLen,
-					     struct eap_sim_attrs *attr)
+		eap_sim_state(data, FAILURE);
+	} else if (attr->notification == EAP_SIM_SUCCESS &&
+		   data->state == RESULT_SUCCESS)
+		eap_sim_state(data, SUCCESS);
+	return eap_sim_response_notification(data, id, attr->notification);
+}
+
+
+static struct wpabuf * eap_sim_process_reauthentication(
+	struct eap_sm *sm, struct eap_sim_data *data, u8 id,
+	const struct wpabuf *reqData, struct eap_sim_attrs *attr)
 {
 	struct eap_sim_attrs eattr;
 	u8 *decrypted;
@@ -704,23 +730,23 @@
 	if (data->reauth_id == NULL) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Server is trying "
 			   "reauthentication, but no reauth_id available");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	data->reauth = 1;
-	if (eap_sim_verify_mac(data->k_aut, (const u8 *) req, reqDataLen,
-			       attr->mac, (u8 *) "", 0)) {
+	if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0))
+	{
 		wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
 			   "did not have valid AT_MAC");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
 	if (attr->encr_data == NULL || attr->iv == NULL) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication "
 			   "message did not include encrypted data");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -730,7 +756,7 @@
 	if (decrypted == NULL) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted "
 			   "data from reauthentication message");
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -739,7 +765,7 @@
 			   !eattr.nonce_s ? " AT_NONCE_S" : "",
 			   eattr.counter < 0 ? " AT_COUNTER" : "");
 		os_free(decrypted);
-		return eap_sim_client_error(data, req, respDataLen,
+		return eap_sim_client_error(data, id,
 					    EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 	}
 
@@ -758,7 +784,7 @@
 		data->reauth_id = NULL;
 		data->reauth_id_len = 0;
 		os_free(decrypted);
-		return eap_sim_response_reauth(data, req, respDataLen, 1);
+		return eap_sim_response_reauth(data, id, 1);
 	}
 	data->counter = eattr.counter;
 
@@ -773,8 +799,13 @@
 	eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 	eap_sim_learn_ids(data, &eattr);
 
-	if (data->state != FAILURE)
-		data->state = SUCCESS;
+	if (data->result_ind && attr->result_ind)
+		data->use_result_ind = 1;
+
+	if (data->state != FAILURE && data->state != RESULT_FAILURE) {
+		eap_sim_state(data, data->use_result_ind ?
+			      RESULT_SUCCESS : SUCCESS);
+	}
 
 	data->num_id_req = 0;
 	data->num_notification = 0;
@@ -784,23 +815,23 @@
 		eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID);
 	}
 	os_free(decrypted);
-	return eap_sim_response_reauth(data, req, respDataLen, 0);
-}
-
-
-static u8 * eap_sim_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+	return eap_sim_response_reauth(data, id, 0);
+}
+
+
+static struct wpabuf * eap_sim_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_sim_data *data = priv;
 	const struct eap_hdr *req;
-	u8 subtype, *res;
+	u8 subtype, id;
+	struct wpabuf *res;
 	const u8 *pos;
 	struct eap_sim_attrs attr;
 	size_t len;
 
-	wpa_hexdump(MSG_DEBUG, "EAP-SIM: EAP data", reqData, reqDataLen);
+	wpa_hexdump_buf(MSG_DEBUG, "EAP-SIM: EAP data", reqData);
 	if (eap_get_config_identity(sm, &len) == NULL) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Identity not configured");
 		eap_sm_request_identity(sm);
@@ -808,13 +839,13 @@
 		return NULL;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, reqData, &len);
 	if (pos == NULL || len < 1) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
-	req = (const struct eap_hdr *) reqData;
+	req = wpabuf_head(reqData);
+	id = req->identifier;
 	len = be_to_host16(req->length);
 
 	ret->ignore = FALSE;
@@ -826,37 +857,36 @@
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Subtype=%d", subtype);
 	pos += 2; /* Reserved */
 
-	if (eap_sim_parse_attr(pos, reqData + len, &attr, 0, 0)) {
-		res = eap_sim_client_error(data, req, respDataLen,
+	if (eap_sim_parse_attr(pos, wpabuf_head_u8(reqData) + len, &attr, 0,
+			       0)) {
+		res = eap_sim_client_error(data, id,
 					   EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 		goto done;
 	}
 
 	switch (subtype) {
 	case EAP_SIM_SUBTYPE_START:
-		res = eap_sim_process_start(sm, data, req,
-					    respDataLen, &attr);
+		res = eap_sim_process_start(sm, data, id, &attr);
 		break;
 	case EAP_SIM_SUBTYPE_CHALLENGE:
-		res = eap_sim_process_challenge(sm, data, req, len,
-						respDataLen, &attr);
+		res = eap_sim_process_challenge(sm, data, id, reqData, &attr);
 		break;
 	case EAP_SIM_SUBTYPE_NOTIFICATION:
-		res = eap_sim_process_notification(sm, data, req, len,
-						   respDataLen, &attr);
+		res = eap_sim_process_notification(sm, data, id, reqData,
+						   &attr);
 		break;
 	case EAP_SIM_SUBTYPE_REAUTHENTICATION:
-		res = eap_sim_process_reauthentication(sm, data, req, len,
-						       respDataLen, &attr);
+		res = eap_sim_process_reauthentication(sm, data, id, reqData,
+						       &attr);
 		break;
 	case EAP_SIM_SUBTYPE_CLIENT_ERROR:
 		wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Client-Error");
-		res = eap_sim_client_error(data, req, respDataLen,
+		res = eap_sim_client_error(data, id,
 					   EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown subtype=%d", subtype);
-		res = eap_sim_client_error(data, req, respDataLen,
+		res = eap_sim_client_error(data, id,
 					   EAP_SIM_UNABLE_TO_PROCESS_PACKET);
 		break;
 	}
@@ -866,9 +896,14 @@
 		ret->decision = DECISION_FAIL;
 		ret->methodState = METHOD_DONE;
 	} else if (data->state == SUCCESS) {
-		ret->decision = DECISION_COND_SUCC;
-		ret->methodState = METHOD_DONE;
-	}
+		ret->decision = data->use_result_ind ?
+			DECISION_UNCOND_SUCC : DECISION_COND_SUCC;
+		ret->methodState = data->use_result_ind ?
+			METHOD_DONE : METHOD_MAY_CONT;
+	} else if (data->state == RESULT_FAILURE)
+		ret->methodState = METHOD_CONT;
+	else if (data->state == RESULT_SUCCESS)
+		ret->methodState = METHOD_CONT;
 
 	if (ret->methodState == METHOD_DONE) {
 		ret->allowNotifications = FALSE;
@@ -889,6 +924,7 @@
 {
 	struct eap_sim_data *data = priv;
 	eap_sim_clear_identities(data, CLEAR_EAP_ID);
+	data->use_result_ind = 0;
 }
 
 
@@ -903,7 +939,7 @@
 	}
 	data->num_id_req = 0;
 	data->num_notification = 0;
-	data->state = CONTINUE;
+	eap_sim_state(data, CONTINUE);
 	return priv;
 }
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_tls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tls.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tls.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tls.c Tue Dec 25 15:23:24 2007
@@ -78,9 +78,10 @@
 }
 
 
-static u8 * eap_tls_failure(struct eap_sm *sm, struct eap_tls_data *data,
-			    struct eap_method_ret *ret, int res, u8 *resp,
-			    u8 id, size_t *respDataLen)
+static struct wpabuf * eap_tls_failure(struct eap_sm *sm,
+				       struct eap_tls_data *data,
+				       struct eap_method_ret *ret, int res,
+				       struct wpabuf *resp, u8 id)
 {
 	wpa_printf(MSG_DEBUG, "EAP-TLS: TLS processing failed");
 
@@ -109,7 +110,7 @@
 		return resp;
 	}
 
-	return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_TLS, 0);
+	return eap_peer_tls_build_ack(id, EAP_TYPE_TLS, 0);
 }
 
 
@@ -138,24 +139,22 @@
 }
 
 
-static u8 * eap_tls_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
-{
-	const struct eap_hdr *req;
+static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
+{
 	size_t left;
 	int res;
-	u8 flags, *resp, id;
+	struct wpabuf *resp;
+	u8 flags, id;
 	const u8 *pos;
 	struct eap_tls_data *data = priv;
 
 	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TLS, ret,
-					reqData, reqDataLen, &left, &flags);
+					reqData, &left, &flags);
 	if (pos == NULL)
 		return NULL;
-	req = (const struct eap_hdr *) reqData;
-	id = req->identifier;
+	id = eap_get_id(reqData);
 
 	if (flags & EAP_TLS_FLAGS_START) {
 		wpa_printf(MSG_DEBUG, "EAP-TLS: Start");
@@ -165,20 +164,18 @@
 
 	resp = NULL;
 	res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TLS, 0, id,
-					  pos, left, &resp, respDataLen);
+					  pos, left, &resp);
 
 	if (res < 0) {
-		return eap_tls_failure(sm, data, ret, res, resp, id,
-				       respDataLen);
+		return eap_tls_failure(sm, data, ret, res, resp, id);
 	}
 
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn))
 		eap_tls_success(sm, data, ret);
 
 	if (res == 1) {
-		os_free(resp);
-		return eap_peer_tls_build_ack(respDataLen, id, EAP_TYPE_TLS,
-					      0);
+		wpabuf_free(resp);
+		return eap_peer_tls_build_ack(id, EAP_TYPE_TLS, 0);
 	}
 
 	return resp;

Modified: wpasupplicant/trunk/src/eap_peer/eap_tls_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tls_common.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tls_common.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tls_common.c Tue Dec 25 15:23:24 2007
@@ -400,13 +400,12 @@
  * @in_data: Message received from the server
  * @in_len: Length of in_data
  * @out_data: Buffer for returning a pointer to application data (if available)
- * @out_len: Buffer for returning the length of the application data
  * Returns: 0 on success, 1 if more input data is needed, 2 if application data
  * is available, -1 on failure
  */
 static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
 				 const u8 *in_data, size_t in_len,
-				 u8 **out_data, size_t *out_len)
+				 struct wpabuf **out_data)
 {
 	const u8 *msg;
 	size_t msg_len;
@@ -440,8 +439,11 @@
 	    !tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
 		wpa_hexdump_key(MSG_MSGDUMP, "SSL: Application data",
 				appl_data, appl_data_len);
-		*out_data = appl_data;
-		*out_len = appl_data_len;
+		*out_data = wpabuf_alloc_ext_data(appl_data, appl_data_len);
+		if (*out_data == NULL) {
+			os_free(appl_data);
+			return -1;
+		}
 		return 2;
 	}
 
@@ -459,15 +461,14 @@
  * @id: EAP identifier for the response
  * @ret: Return value to use on success
  * @out_data: Buffer for returning the allocated output buffer
- * @out_len: Buffer for returning the length of the output buffer
  * Returns: ret (0 or 1) on success, -1 on failure
  */
 static int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type,
 				  int peap_version, u8 id, int ret,
-				  u8 **out_data, size_t *out_len)
+				  struct wpabuf **out_data)
 {
 	size_t len;
-	u8 *pos, *flags;
+	u8 *flags;
 	int more_fragments, length_included;
 	
 	len = data->tls_out_len - data->tls_out_pos;
@@ -491,24 +492,22 @@
 		(data->tls_out_len > data->tls_out_limit ||
 		 data->include_tls_length);
 
-	*out_data = (u8 *)
-		eap_msg_alloc(EAP_VENDOR_IETF, eap_type, out_len,
-			      1 + length_included * 4 + len, EAP_CODE_RESPONSE,
-			      id, &pos);
+	*out_data = eap_msg_alloc(EAP_VENDOR_IETF, eap_type,
+				  1 + length_included * 4 + len,
+				  EAP_CODE_RESPONSE, id);
 	if (*out_data == NULL)
 		return -1;
 
-	flags = pos++;
+	flags = wpabuf_put(*out_data, 1);
 	*flags = peap_version;
 	if (more_fragments)
 		*flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS;
 	if (length_included) {
 		*flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
-		WPA_PUT_BE32(pos, data->tls_out_len);
-		pos += 4;
-	}
-
-	os_memcpy(pos, &data->tls_out[data->tls_out_pos], len);
+		wpabuf_put_be32(*out_data, data->tls_out_len);
+	}
+
+	wpabuf_put_data(*out_data, &data->tls_out[data->tls_out_pos], len);
 	data->tls_out_pos += len;
 
 	if (!more_fragments)
@@ -528,7 +527,6 @@
  * @in_data: Message received from the server
  * @in_len: Length of in_data
  * @out_data: Buffer for returning a pointer to the response message
- * @out_len: Buffer for returning the length of the response message
  * Returns: 0 on success, 1 if more input data is needed, 2 if application data
  * is available, or -1 on failure
  *
@@ -551,11 +549,10 @@
 int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
 				EapType eap_type, int peap_version,
 				u8 id, const u8 *in_data, size_t in_len,
-				u8 **out_data, size_t *out_len)
+				struct wpabuf **out_data)
 {
 	int ret = 0;
 
-	*out_len = 0;
 	*out_data = NULL;
 
 	if (data->tls_out_len > 0 && in_len > 0) {
@@ -570,7 +567,7 @@
 		 * the AS.
 		 */
 		int res = eap_tls_process_input(sm, data, in_data, in_len,
-						out_data, out_len);
+						out_data);
 		if (res) {
 			/*
 			 * Input processing failed (res = -1) or more data is
@@ -617,32 +614,30 @@
 
 	/* Send the pending message (in fragments, if needed). */
 	return eap_tls_process_output(data, eap_type, peap_version, id, ret,
-				      out_data, out_len);
+				      out_data);
 }
 
 
 /**
  * eap_peer_tls_build_ack - Build a TLS ACK frame
- * @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(size_t *respDataLen, u8 id, EapType eap_type,
-			    int peap_version)
-{
-	struct eap_hdr *resp;
-	u8 *pos;
-
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, respDataLen,
-			     1, EAP_CODE_RESPONSE, id, &pos);
+struct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type,
+				       int peap_version)
+{
+	struct wpabuf *resp;
+
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_RESPONSE,
+			     id);
 	if (resp == NULL)
 		return NULL;
 	wpa_printf(MSG_DEBUG, "SSL: Building ACK (type=%d id=%d ver=%d)",
 		   (int) eap_type, id, peap_version);
-	*pos = peap_version; /* Flags */
-	return (u8 *) resp;
+	wpabuf_put_u8(resp, peap_version); /* Flags */
+	return resp;
 }
 
 
@@ -694,10 +689,9 @@
  * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...)
  * @ret: Return values from EAP request validation and processing
  * @reqData: EAP request to be processed (eapReqData)
- * @reqDataLen: Length of the EAP request
  * @len: Buffer for returning length of the remaining payload
  * @flags: Buffer for returning TLS flags
- * Returns: Buffer to payload after TLS flags and length or %NULL on failure
+ * Returns: Pointer to payload after TLS flags and length or %NULL on failure
  *
  * This function validates the EAP header and processes the optional TLS
  * Message Length field. If this is the first fragment of a TLS message, the
@@ -716,7 +710,7 @@
 				     struct eap_ssl_data *data,
 				     EapType eap_type,
 				     struct eap_method_ret *ret,
-				     const u8 *reqData, size_t reqDataLen,
+				     const struct wpabuf *reqData,
 				     size_t *len, u8 *flags)
 {
 	const u8 *pos;
@@ -729,8 +723,7 @@
 		return NULL;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, reqDataLen,
-			       &left);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, &left);
 	if (pos == NULL) {
 		ret->ignore = TRUE;
 		return NULL;
@@ -738,7 +731,8 @@
 	*flags = *pos++;
 	left--;
 	wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - "
-		   "Flags 0x%02x", (unsigned long) reqDataLen, *flags);
+		   "Flags 0x%02x", (unsigned long) wpabuf_len(reqData),
+		   *flags);
 	if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
 		if (left < 4) {
 			wpa_printf(MSG_INFO, "SSL: Short frame with TLS "
@@ -806,29 +800,28 @@
  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
  * @data: Data for TLS processing
  * @in_data: Message received from the server
- * @in_len: Length of in_data
  * @in_decrypted: Buffer for returning a pointer to the decrypted message
- * @len_decrypted: Buffer for returning the length of the decrypted message
  * Returns: 0 on success, 1 if more input data is needed, or -1 on failure
  */
 int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
-			 const u8 *in_data, size_t in_len,
-			 u8 **in_decrypted, size_t *len_decrypted)
+			 const struct wpabuf *in_data,
+			 struct wpabuf **in_decrypted)
 {
 	int res;
 	const u8 *msg;
 	size_t msg_len, buf_len;
 	int need_more_input;
 
-	msg = eap_peer_tls_data_reassemble(data, in_data, in_len, &msg_len,
+	msg = eap_peer_tls_data_reassemble(data, wpabuf_head(in_data),
+					   wpabuf_len(in_data), &msg_len,
 					   &need_more_input);
 	if (msg == NULL)
 		return need_more_input ? 1 : -1;
 
-	buf_len = in_len;
+	buf_len = wpabuf_len(in_data);
 	if (data->tls_in_total > buf_len)
 		buf_len = data->tls_in_total;
-	*in_decrypted = os_malloc(buf_len ? buf_len : 1);
+	*in_decrypted = wpabuf_alloc(buf_len ? buf_len : 1);
 	if (*in_decrypted == NULL) {
 		eap_peer_tls_reset_input(data);
 		wpa_printf(MSG_WARNING, "SSL: Failed to allocate memory for "
@@ -837,13 +830,13 @@
 	}
 
 	res = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg, msg_len,
-				     *in_decrypted, buf_len);
+				     wpabuf_mhead(*in_decrypted), buf_len);
 	eap_peer_tls_reset_input(data);
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data");
 		return -1;
 	}
-	*len_decrypted = res;
+	wpabuf_put(*in_decrypted, res);
 	return 0;
 }
 
@@ -856,32 +849,32 @@
  * @peap_version: Version number for EAP-PEAP/TTLS
  * @id: EAP identifier for the response
  * @in_data: Plaintext phase 2 data to encrypt or %NULL to continue fragments
- * @in_len: Length of in_data
  * @out_data: Buffer for returning a pointer to the encrypted response message
- * @out_len: Buffer for returning the length of the encrypted response message
  * Returns: 0 on success, -1 on failure
  */
 int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
 			 EapType eap_type, int peap_version, u8 id,
-			 const u8 *in_data, size_t in_len,
-			 u8 **out_data, size_t *out_len)
+			 const struct wpabuf *in_data,
+			 struct wpabuf **out_data)
 {
 	int res;
 	size_t len;
 
 	if (in_data) {
 		eap_peer_tls_reset_output(data);
-		len = in_len + 100;
+		len = wpabuf_len(in_data) + 100;
 		data->tls_out = os_malloc(len);
 		if (data->tls_out == NULL)
 			return -1;
 
-		res = tls_connection_encrypt(sm->ssl_ctx, data->conn, in_data,
-					     in_len, data->tls_out, len);
+		res = tls_connection_encrypt(sm->ssl_ctx, data->conn,
+					     wpabuf_head(in_data),
+					     wpabuf_len(in_data),
+					     data->tls_out, len);
 		if (res < 0) {
 			wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 "
 				   "data (in_len=%lu)",
-				   (unsigned long) in_len);
+				   (unsigned long) wpabuf_len(in_data));
 			eap_peer_tls_reset_output(data);
 			return -1;
 		}
@@ -890,7 +883,7 @@
 	}
 
 	return eap_tls_process_output(data, eap_type, peap_version, id, 0,
-				      out_data, out_len);
+				      out_data);
 }
 
 
@@ -985,13 +978,11 @@
  * @num_types: Buffer for returning number of allocated EAP methods
  * @hdr: EAP-Request header (and the following EAP type octet)
  * @resp: Buffer for returning the EAP-Nak message
- * @resp_len: Buffer for returning the length of the EAP-Nak message
  * Returns: 0 on success, -1 on failure
  */
 int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types,
-			    struct eap_hdr *hdr, u8 **resp, size_t *resp_len)
-{
-	struct eap_hdr *resp_hdr;
+			    struct eap_hdr *hdr, struct wpabuf **resp)
+{
 	u8 *pos = (u8 *) (hdr + 1);
 	size_t i;
 
@@ -999,24 +990,18 @@
 	wpa_printf(MSG_DEBUG, "TLS: Phase 2 Request: Nak type=%d", *pos);
 	wpa_hexdump(MSG_DEBUG, "TLS: Allowed Phase2 EAP types",
 		    (u8 *) types, num_types * sizeof(struct eap_method_type));
-	*resp_len = sizeof(struct eap_hdr) + 1;
-	*resp = os_malloc(*resp_len + num_types);
+	*resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, num_types,
+			      EAP_CODE_RESPONSE, hdr->identifier);
 	if (*resp == NULL)
 		return -1;
 
-	resp_hdr = (struct eap_hdr *) (*resp);
-	resp_hdr->code = EAP_CODE_RESPONSE;
-	resp_hdr->identifier = hdr->identifier;
-	pos = (u8 *) (resp_hdr + 1);
-	*pos++ = EAP_TYPE_NAK;
 	for (i = 0; i < num_types; i++) {
 		if (types[i].vendor == EAP_VENDOR_IETF &&
-		    types[i].method < 256) {
-			(*resp_len)++;
-			*pos++ = types[i].method;
-		}
-	}
-	resp_hdr->length = host_to_be16(*resp_len);
+		    types[i].method < 256)
+			wpabuf_put_u8(*resp, types[i].method);
+	}
+
+	eap_update_len(*resp);
 
 	return 0;
 }

Modified: wpasupplicant/trunk/src/eap_peer/eap_tls_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tls_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tls_common.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tls_common.h Tue Dec 25 15:23:24 2007
@@ -108,9 +108,9 @@
 int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
 				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(size_t *respDataLen, u8 id, EapType eap_type,
-			    int peap_version);
+				struct wpabuf **out_data);
+struct wpabuf * eap_peer_tls_build_ack(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);
@@ -118,21 +118,21 @@
 				     struct eap_ssl_data *data,
 				     EapType eap_type,
 				     struct eap_method_ret *ret,
-				     const u8 *reqData, size_t reqDataLen,
+				     const struct wpabuf *reqData,
 				     size_t *len, u8 *flags);
 void eap_peer_tls_reset_input(struct eap_ssl_data *data);
 void eap_peer_tls_reset_output(struct eap_ssl_data *data);
 int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
-			 const u8 *in_data, size_t in_len,
-			 u8 **in_decrypted, size_t *len_decrypted);
+			 const struct wpabuf *in_data,
+			 struct wpabuf **in_decrypted);
 int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
 			 EapType eap_type, int peap_version, u8 id,
-			 const u8 *in_data, size_t in_len,
-			 u8 **out_data, size_t *out_len);
+			 const struct wpabuf *in_data,
+			 struct wpabuf **out_data);
 int eap_peer_select_phase2_methods(struct wpa_ssid *config, const char *prefix,
 				   struct eap_method_type **types,
 				   size_t *num_types);
 int eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types,
-			    struct eap_hdr *hdr, u8 **resp, size_t *resp_len);
+			    struct eap_hdr *hdr, struct wpabuf **resp);
 
 #endif /* EAP_TLS_COMMON_H */

Modified: wpasupplicant/trunk/src/eap_peer/eap_tlv.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tlv.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tlv.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tlv.c Tue Dec 25 15:23:24 2007
@@ -23,36 +23,27 @@
  * eap_tlv_build_nak - Build EAP-TLV NAK message
  * @id: EAP identifier for the header
  * @nak_type: TLV type (EAP_TLV_*)
- * @resp_len: Buffer for returning the response length
  * Returns: Buffer to the allocated EAP-TLV NAK message or %NULL on failure
  *
  * This funtion builds an EAP-TLV NAK message. The caller is responsible for
  * freeing the returned buffer.
  */
-u8 * eap_tlv_build_nak(int id, u16 nak_type, size_t *resp_len)
+struct wpabuf * eap_tlv_build_nak(int id, u16 nak_type)
 {
-	struct eap_hdr *hdr;
-	u8 *pos;
+	struct wpabuf *msg;
 
-	hdr = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, resp_len,
-			    10, EAP_CODE_RESPONSE, id, &pos);
-	if (hdr == NULL)
+	msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, 10,
+			    EAP_CODE_RESPONSE, id);
+	if (msg == NULL)
 		return NULL;
 
-	*pos++ = 0x80; /* Mandatory */
-	*pos++ = EAP_TLV_NAK_TLV;
-	/* Length */
-	*pos++ = 0;
-	*pos++ = 6;
-	/* Vendor-Id */
-	*pos++ = 0;
-	*pos++ = 0;
-	*pos++ = 0;
-	*pos++ = 0;
-	/* NAK-Type */
-	WPA_PUT_BE16(pos, nak_type);
+	wpabuf_put_u8(msg, 0x80); /* Mandatory */
+	wpabuf_put_u8(msg, EAP_TLV_NAK_TLV);
+	wpabuf_put_be16(msg, 6); /* Length */
+	wpabuf_put_be32(msg, 0); /* Vendor-Id */
+	wpabuf_put_be16(msg, nak_type); /* NAK-Type */
 
-	return (u8 *) hdr;
+	return msg;
 }
 
 
@@ -60,31 +51,26 @@
  * eap_tlv_build_result - Build EAP-TLV Result message
  * @id: EAP identifier for the header
  * @status: Status (EAP_TLV_RESULT_SUCCESS or EAP_TLV_RESULT_FAILURE)
- * @resp_len: Buffer for returning the response length
  * Returns: Buffer to the allocated EAP-TLV Result message or %NULL on failure
  *
  * This funtion builds an EAP-TLV Result message. The caller is responsible for
  * freeing the returned buffer.
  */
-u8 * eap_tlv_build_result(int id, u16 status, size_t *resp_len)
+struct wpabuf * eap_tlv_build_result(int id, u16 status)
 {
-	struct eap_hdr *hdr;
-	u8 *pos;
+	struct wpabuf *msg;
 
-	hdr = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, resp_len,
-			    6, EAP_CODE_RESPONSE, id, &pos);
-	if (hdr == NULL)
+	msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, 6,
+			    EAP_CODE_RESPONSE, id);
+	if (msg == NULL)
 		return NULL;
 
-	*pos++ = 0x80; /* Mandatory */
-	*pos++ = EAP_TLV_RESULT_TLV;
-	/* Length */
-	*pos++ = 0;
-	*pos++ = 2;
-	/* Status */
-	WPA_PUT_BE16(pos, status);
+	wpabuf_put_u8(msg, 0x80); /* Mandatory */
+	wpabuf_put_u8(msg, EAP_TLV_RESULT_TLV);
+	wpabuf_put_be16(msg, 2); /* Length */
+	wpabuf_put_be16(msg, status); /* Status */
 
-	return (u8 *) hdr;
+	return msg;
 }
 
 
@@ -92,18 +78,17 @@
  * eap_tlv_process - Process a received EAP-TLV message and generate a response
  * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
  * @ret: Return values from EAP request validation and processing
- * @hdr: EAP-TLV request to be processed. The caller must have validated that
+ * @req: EAP-TLV request to be processed. The caller must have validated that
  * the buffer is large enough to contain full request (hdr->length bytes) and
  * that the EAP type is EAP_TYPE_TLV.
  * @resp: Buffer to return a pointer to the allocated response message. This
  * field should be initialized to %NULL before the call. The value will be
  * updated if a response message is generated. The caller is responsible for
  * freeing the allocated message.
- * @resp_len: Buffer for returning the response length
  * Returns: 0 on success, -1 on failure
  */
 int eap_tlv_process(struct eap_sm *sm, struct eap_method_ret *ret,
-		    const struct eap_hdr *hdr, u8 **resp, size_t *resp_len)
+		    const struct wpabuf *req, struct wpabuf **resp)
 {
 	size_t left, tlv_len;
 	const u8 *pos;
@@ -112,9 +97,9 @@
 	int tlv_type, mandatory;
 
 	/* Parse TLVs */
-	left = be_to_host16(hdr->length) - sizeof(struct eap_hdr) - 1;
-	pos = (const u8 *) (hdr + 1);
-	pos++;
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLV, req, &left);
+	if (pos == NULL)
+		return -1;
 	wpa_hexdump(MSG_DEBUG, "EAP-TLV: Received TLVs", pos, left);
 	while (left >= 4) {
 		mandatory = !!(pos[0] & 0x80);
@@ -142,8 +127,8 @@
 			if (mandatory) {
 				/* NAK TLV and ignore all TLVs in this packet.
 				 */
-				*resp = eap_tlv_build_nak(hdr->identifier,
-							  tlv_type, resp_len);
+				*resp = eap_tlv_build_nak(eap_get_id(req),
+							  tlv_type);
 				return *resp == NULL ? -1 : 0;
 			}
 			/* Ignore this TLV, but process other TLVs */
@@ -188,8 +173,7 @@
 		}
 		ret->methodState = METHOD_DONE;
 
-		*resp = eap_tlv_build_result(hdr->identifier, resp_status,
-					     resp_len);
+		*resp = eap_tlv_build_result(eap_get_id(req), resp_status);
 	}
 
 	return 0;

Modified: wpasupplicant/trunk/src/eap_peer/eap_tlv.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tlv.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tlv.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tlv.h Tue Dec 25 15:23:24 2007
@@ -17,9 +17,9 @@
 
 #include "eap_common/eap_tlv_common.h"
 
-u8 * eap_tlv_build_nak(int id, u16 nak_type, size_t *resp_len);
-u8 * eap_tlv_build_result(int id, u16 status, size_t *resp_len);
+struct wpabuf * eap_tlv_build_nak(int id, u16 nak_type);
+struct wpabuf * eap_tlv_build_result(int id, u16 status);
 int eap_tlv_process(struct eap_sm *sm, struct eap_method_ret *ret,
-		    const struct eap_hdr *hdr, u8 **resp, size_t *resp_len);
+		    const struct wpabuf *req, struct wpabuf **resp);
 
 #endif /* EAP_TLV_H */

Modified: wpasupplicant/trunk/src/eap_peer/eap_tnc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tnc.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tnc.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tnc.c Tue Dec 25 15:23:24 2007
@@ -62,24 +62,21 @@
 }
 
 
-static u8 * eap_tnc_process(struct eap_sm *sm, void *priv,
-			    struct eap_method_ret *ret,
-			    const u8 *reqData, size_t reqDataLen,
-			    size_t *respDataLen)
+static struct wpabuf * eap_tnc_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_tnc_data *data = priv;
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	const u8 *pos;
-	u8 *rpos, *start;
+	u8 *rpos, *rpos1, *start;
 	size_t len, rlen;
 	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);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TNC, reqData, &len);
 	if (pos == NULL || len == 0) {
 		wpa_printf(MSG_INFO, "EAP-TNC: Invalid frame (pos=%p len=%lu)",
 			   pos, (unsigned long) len);
@@ -87,7 +84,6 @@
 		return NULL;
 	}
 
-	req = (const struct eap_hdr *) reqData;
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Received payload", pos, len);
 
 	if ((*pos & EAP_TNC_VERSION_MASK) != EAP_TNC_VERSION) {
@@ -152,16 +148,15 @@
 	ret->allowNotifications = TRUE;
 
 	if (tncs_done) {
-		resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC,
-				     respDataLen, 1, EAP_CODE_RESPONSE,
-				     req->identifier, &rpos);
+		resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, 1,
+				     EAP_CODE_RESPONSE, eap_get_id(reqData));
 		if (resp == NULL)
 			return NULL;
 
-		*rpos = EAP_TNC_VERSION;
+		wpabuf_put_u8(resp, EAP_TNC_VERSION);
 		wpa_printf(MSG_DEBUG, "EAP-TNC: TNCS done - reply with an "
 			   "empty ACK message");
-		return (u8 *) resp;
+		return resp;
 	}
 
 	imc_len = tncc_total_send_len(data->tncc);
@@ -178,29 +173,29 @@
 	end_len = os_strlen(end_buf);
 
 	rlen = 1 + start_len + imc_len + end_len;
-	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, respDataLen,
-			     rlen, EAP_CODE_RESPONSE,
-			     req->identifier, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TNC, rlen,
+			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL) {
 		os_free(start_buf);
 		os_free(end_buf);
 		return NULL;
 	}
 
-	start = rpos;
-	*rpos++ = EAP_TNC_VERSION;
-	os_memcpy(rpos, start_buf, start_len);
+	start = wpabuf_put(resp, 0);
+	wpabuf_put_u8(resp, EAP_TNC_VERSION);
+	wpabuf_put_data(resp, start_buf, start_len);
 	os_free(start_buf);
-	rpos += start_len;
-
-	rpos = tncc_copy_send_buf(data->tncc, rpos);
-
-	os_memcpy(rpos, end_buf, end_len);
+
+	rpos1 = wpabuf_put(resp, 0);
+	rpos = tncc_copy_send_buf(data->tncc, rpos1);
+	wpabuf_put(resp, rpos - rpos1);
+
+	wpabuf_put_data(resp, end_buf, end_len);
 	os_free(end_buf);
 
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TNC: Response", start, rlen);
 
-	return (u8 *) resp;
+	return resp;
 }
 
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_ttls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_ttls.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_ttls.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_ttls.c Tue Dec 25 15:23:24 2007
@@ -20,7 +20,7 @@
 #include "config_ssid.h"
 #include "ms_funcs.h"
 #include "sha1.h"
-#include "crypto.h"
+#include "eap_common/chap.h"
 #include "tls.h"
 #include "eap_common/eap_ttls.h"
 
@@ -69,8 +69,7 @@
 	int reauth; /* reauthentication */
 	u8 *key_data;
 
-	u8 *pending_phase2_req;
-	size_t pending_phase2_req_len;
+	struct wpabuf *pending_phase2_req;
 
 #ifdef EAP_TNC
 	int ready_for_tnc;
@@ -167,7 +166,7 @@
 	if (data->ssl_initialized)
 		eap_peer_tls_ssl_deinit(sm, &data->ssl);
 	os_free(data->key_data);
-	os_free(data->pending_phase2_req);
+	wpabuf_free(data->pending_phase2_req);
 	os_free(data);
 }
 
@@ -209,26 +208,27 @@
 }
 
 
-static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
+static int eap_ttls_avp_encapsulate(struct wpabuf **resp, u32 avp_code,
 				    int mandatory)
 {
+	struct wpabuf *msg;
 	u8 *avp, *pos;
 
-	avp = os_malloc(sizeof(struct ttls_avp) + *resp_len + 4);
-	if (avp == NULL) {
-		os_free(*resp);
+	msg = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(*resp) + 4);
+	if (msg == NULL) {
+		wpabuf_free(*resp);
 		*resp = NULL;
-		*resp_len = 0;
-		return -1;
-	}
-
-	pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
-	os_memcpy(pos, *resp, *resp_len);
-	pos += *resp_len;
+		return -1;
+	}
+
+	avp = wpabuf_mhead(msg);
+	pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, wpabuf_len(*resp));
+	os_memcpy(pos, wpabuf_head(*resp), wpabuf_len(*resp));
+	pos += wpabuf_len(*resp);
 	AVP_PAD(avp, pos);
-	os_free(*resp);
-	*resp = avp;
-	*resp_len = pos - avp;
+	wpabuf_free(*resp);
+	wpabuf_put(msg, pos - avp);
+	*resp = msg;
 	return 0;
 }
 
@@ -464,10 +464,10 @@
 					      struct eap_ttls_data *data,
 					      struct eap_method_ret *ret,
 					      struct eap_hdr *hdr, size_t len,
-					      u8 method,
-					      u8 **resp, size_t *resp_len)
+					      u8 method, struct wpabuf **resp)
 {
 	struct eap_method_ret iret;
+	struct wpabuf msg;
 
 #ifdef EAP_TNC
 	if (data->tnc_started && data->phase2_method &&
@@ -516,7 +516,7 @@
 	{
 		if (eap_peer_tls_phase2_nak(data->phase2_eap_types,
 					    data->num_phase2_eap_types,
-					    hdr, resp, resp_len))
+					    hdr, resp))
 			return -1;
 		return 0;
 	}
@@ -546,9 +546,9 @@
 process:
 #endif /* EAP_TNC */
 	os_memset(&iret, 0, sizeof(iret));
-	*resp = data->phase2_method->process(sm, data->phase2_priv,
-					     &iret, (u8 *) hdr, len,
-					     resp_len);
+	wpabuf_set(&msg, hdr, len);
+	*resp = data->phase2_method->process(sm, data->phase2_priv, &iret,
+					     &msg);
 	if ((iret.methodState == METHOD_DONE ||
 	     iret.methodState == METHOD_MAY_CONT) &&
 	    (iret.decision == DECISION_UNCOND_SUCC ||
@@ -567,7 +567,7 @@
 				       struct eap_ttls_data *data,
 				       struct eap_method_ret *ret,
 				       struct eap_hdr *hdr,
-				       u8 **resp, size_t *resp_len)
+				       struct wpabuf **resp)
 {
 	size_t len = be_to_host16(hdr->length);
 	u8 *pos;
@@ -582,12 +582,11 @@
 	wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 EAP Request: type=%d", *pos);
 	switch (*pos) {
 	case EAP_TYPE_IDENTITY:
-		*resp = eap_sm_buildIdentity(sm, hdr->identifier, resp_len, 1);
+		*resp = eap_sm_buildIdentity(sm, hdr->identifier, 1);
 		break;
 	default:
 		if (eap_ttls_phase2_request_eap_method(sm, data, ret, hdr, len,
-						       *pos, resp, resp_len) <
-		    0)
+						       *pos, resp) < 0)
 			return -1;
 		break;
 	}
@@ -601,10 +600,9 @@
 	if (*resp == NULL)
 		return -1;
 
-	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
-		    *resp, *resp_len);
-	return eap_ttls_avp_encapsulate(resp, resp_len,
-					RADIUS_ATTR_EAP_MESSAGE, 1);
+	wpa_hexdump_buf(MSG_DEBUG, "EAP-TTLS: AVP encapsulate EAP Response",
+			*resp);
+	return eap_ttls_avp_encapsulate(resp, RADIUS_ATTR_EAP_MESSAGE, 1);
 }
 
 
@@ -646,8 +644,9 @@
 static int eap_ttls_phase2_request_mschapv2(struct eap_sm *sm,
 					    struct eap_ttls_data *data,
 					    struct eap_method_ret *ret,
-					    u8 **resp, size_t *resp_len)
-{
+					    struct wpabuf **resp)
+{
+	struct wpabuf *msg;
 	u8 *buf, *pos, *challenge, *peer_challenge;
 	const u8 *identity, *username, *password;
 	size_t identity_len, password_len, username_len, i;
@@ -672,12 +671,13 @@
 		}
 	}
 
-	pos = buf = os_malloc(identity_len + 1000);
-	if (buf == NULL) {
+	msg = wpabuf_alloc(identity_len + 1000);
+	if (msg == NULL) {
 		wpa_printf(MSG_ERROR,
 			   "EAP-TTLS/MSCHAPV2: Failed to allocate memory");
 		return -1;
 	}
+	pos = buf = wpabuf_mhead(msg);
 
 	/* User-Name */
 	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
@@ -687,7 +687,7 @@
 	challenge = eap_ttls_implicit_challenge(
 		sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN * 2 + 1);
 	if (challenge == NULL) {
-		os_free(buf);
+		wpabuf_free(msg);
 		wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAPV2: Failed to derive "
 			   "implicit challenge");
 		return -1;
@@ -745,8 +745,8 @@
 	os_free(challenge);
 	AVP_PAD(buf, pos);
 
-	*resp = buf;
-	*resp_len = pos - buf;
+	wpabuf_put(msg, pos - buf);
+	*resp = msg;
 
 	if (sm->workaround && data->ttls_version == 0) {
 		/* At least FreeRADIUS seems to be terminating
@@ -765,8 +765,9 @@
 static int eap_ttls_phase2_request_mschap(struct eap_sm *sm,
 					  struct eap_ttls_data *data,
 					  struct eap_method_ret *ret,
-					  u8 **resp, size_t *resp_len)
-{
+					  struct wpabuf **resp)
+{
+	struct wpabuf *msg;
 	u8 *buf, *pos, *challenge;
 	const u8 *identity, *password;
 	size_t identity_len, password_len;
@@ -779,12 +780,13 @@
 	if (identity == NULL || password == NULL)
 		return -1;
 
-	pos = buf = os_malloc(identity_len + 1000);
-	if (buf == NULL) {
+	msg = wpabuf_alloc(identity_len + 1000);
+	if (msg == NULL) {
 		wpa_printf(MSG_ERROR,
 			   "EAP-TTLS/MSCHAP: Failed to allocate memory");
 		return -1;
 	}
+	pos = buf = wpabuf_mhead(msg);
 
 	/* User-Name */
 	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
@@ -793,7 +795,7 @@
 	/* MS-CHAP-Challenge */
 	challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
 	if (challenge == NULL) {
-		os_free(buf);
+		wpabuf_free(msg);
 		wpa_printf(MSG_ERROR, "EAP-TTLS/MSCHAP: Failed to derive "
 			   "implicit challenge");
 		return -1;
@@ -829,8 +831,8 @@
 	os_free(challenge);
 	AVP_PAD(buf, pos);
 
-	*resp = buf;
-	*resp_len = pos - buf;
+	wpabuf_put(msg, pos - buf);
+	*resp = msg;
 
 	if (data->ttls_version > 0) {
 		/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
@@ -851,8 +853,9 @@
 static int eap_ttls_phase2_request_pap(struct eap_sm *sm,
 				       struct eap_ttls_data *data,
 				       struct eap_method_ret *ret,
-				       u8 **resp, size_t *resp_len)
-{
+				       struct wpabuf **resp)
+{
+	struct wpabuf *msg;
 	u8 *buf, *pos;
 	size_t pad;
 	const u8 *identity, *password;
@@ -865,12 +868,13 @@
 	if (identity == NULL || password == NULL)
 		return -1;
 
-	pos = buf = os_malloc(identity_len + password_len + 100);
-	if (buf == NULL) {
+	msg = wpabuf_alloc(identity_len + password_len + 100);
+	if (msg == NULL) {
 		wpa_printf(MSG_ERROR,
 			   "EAP-TTLS/PAP: Failed to allocate memory");
 		return -1;
 	}
+	pos = buf = wpabuf_mhead(msg);
 
 	/* User-Name */
 	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
@@ -888,8 +892,8 @@
 	pos += pad;
 	AVP_PAD(buf, pos);
 
-	*resp = buf;
-	*resp_len = pos - buf;
+	wpabuf_put(msg, pos - buf);
+	*resp = msg;
 
 	if (data->ttls_version > 0) {
 		/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
@@ -910,11 +914,10 @@
 static int eap_ttls_phase2_request_chap(struct eap_sm *sm,
 					struct eap_ttls_data *data,
 					struct eap_method_ret *ret,
-					u8 **resp, size_t *resp_len)
-{
+					struct wpabuf **resp)
+{
+	struct wpabuf *msg;
 	u8 *buf, *pos, *challenge;
-	const u8 *addr[3];
-	size_t len[3];
 	const u8 *identity, *password;
 	size_t identity_len, password_len;
 
@@ -925,12 +928,13 @@
 	if (identity == NULL || password == NULL)
 		return -1;
 
-	pos = buf = os_malloc(identity_len + 1000);
-	if (buf == NULL) {
+	msg = wpabuf_alloc(identity_len + 1000);
+	if (msg == NULL) {
 		wpa_printf(MSG_ERROR,
 			   "EAP-TTLS/CHAP: Failed to allocate memory");
 		return -1;
 	}
+	pos = buf = wpabuf_mhead(msg);
 
 	/* User-Name */
 	pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
@@ -939,7 +943,7 @@
 	/* CHAP-Challenge */
 	challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
 	if (challenge == NULL) {
-		os_free(buf);
+		wpabuf_free(msg);
 		wpa_printf(MSG_ERROR, "EAP-TTLS/CHAP: Failed to derive "
 			   "implicit challenge");
 		return -1;
@@ -955,13 +959,8 @@
 	*pos++ = data->ident;
 
 	/* MD5(Ident + Password + Challenge) */
-	addr[0] = &data->ident;
-	len[0] = 1;
-	addr[1] = password;
-	len[1] = password_len;
-	addr[2] = challenge;
-	len[2] = EAP_TTLS_CHAP_CHALLENGE_LEN;
-	md5_vector(3, addr, len, pos);
+	chap_md5(data->ident, password, password_len, challenge,
+		 EAP_TTLS_CHAP_CHALLENGE_LEN, pos);
 
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
 			  identity, identity_len);
@@ -975,8 +974,8 @@
 	os_free(challenge);
 	AVP_PAD(buf, pos);
 
-	*resp = buf;
-	*resp_len = pos - buf;
+	wpabuf_put(msg, pos - buf);
+	*resp = msg;
 
 	if (data->ttls_version > 0) {
 		/* EAP-TTLSv1 uses TLS/IA FinalPhaseFinished to report success,
@@ -998,7 +997,7 @@
 				   struct eap_ttls_data *data,
 				   struct eap_method_ret *ret,
 				   struct eap_hdr *hdr,
-				   u8 **resp, size_t *resp_len)
+				   struct wpabuf **resp)
 {
 	int res = 0;
 	size_t len;
@@ -1027,32 +1026,26 @@
 #ifdef EAP_TNC
 	if (data->tnc_started) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Processing TNC");
-		res = eap_ttls_phase2_request_eap(sm, data, ret, hdr,
-						  resp, resp_len);
+		res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);
 		goto done;
 	}
 #endif /* EAP_TNC */
 
 	switch (data->phase2_type) {
 	case EAP_TTLS_PHASE2_EAP:
-		res = eap_ttls_phase2_request_eap(sm, data, ret, hdr,
-						  resp, resp_len);
+		res = eap_ttls_phase2_request_eap(sm, data, ret, hdr, resp);
 		break;
 	case EAP_TTLS_PHASE2_MSCHAPV2:
-		res = eap_ttls_phase2_request_mschapv2(sm, data, ret,
-						       resp, resp_len);
+		res = eap_ttls_phase2_request_mschapv2(sm, data, ret, resp);
 		break;
 	case EAP_TTLS_PHASE2_MSCHAP:
-		res = eap_ttls_phase2_request_mschap(sm, data, ret,
-						     resp, resp_len);
+		res = eap_ttls_phase2_request_mschap(sm, data, ret, resp);
 		break;
 	case EAP_TTLS_PHASE2_PAP:
-		res = eap_ttls_phase2_request_pap(sm, data, ret,
-						  resp, resp_len);
+		res = eap_ttls_phase2_request_pap(sm, data, ret, resp);
 		break;
 	case EAP_TTLS_PHASE2_CHAP:
-		res = eap_ttls_phase2_request_chap(sm, data, ret,
-						   resp, resp_len);
+		res = eap_ttls_phase2_request_chap(sm, data, ret, resp);
 		break;
 	default:
 		wpa_printf(MSG_ERROR, "EAP-TTLS: Phase 2 - Unknown");
@@ -1074,40 +1067,33 @@
 
 
 #if EAP_TTLS_VERSION > 0
-static u8 * eap_ttls_build_phase_finished(struct eap_sm *sm,
-					  struct eap_ttls_data *data,
-					  int id, int final,
-					  size_t *reqDataLen)
+static struct wpabuf * eap_ttls_build_phase_finished(
+	struct eap_sm *sm, struct eap_ttls_data *data, int id, int final)
 {
 	int len;
-	struct eap_hdr *req;
+	struct wpabuf *req;
 	u8 *pos;
 	const int max_len = 300;
 
-	len = sizeof(struct eap_hdr) + 2 + max_len;
-	req = os_malloc(len);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1 + max_len,
+			    EAP_CODE_RESPONSE, id);
 	if (req == NULL)
 		return NULL;
 
-	req->code = EAP_CODE_RESPONSE;
-	req->identifier = id;
-
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_TTLS;
-	*pos++ = data->ttls_version;
-
+	wpabuf_put_u8(req, data->ttls_version);
+
+	pos = wpabuf_put(req, 0);
 	len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
 						    data->ssl.conn,
 						    final, pos, max_len);
 	if (len < 0) {
-		os_free(req);
+		wpabuf_free(req);
 		return NULL;
 	}
-
-	*reqDataLen = sizeof(struct eap_hdr) + 2 + len;
-	req->length = host_to_be16(*reqDataLen);
-
-	return (u8 *) req;
+	wpabuf_put(req, len);
+	eap_update_len(req);
+
+	return req;
 }
 #endif /* EAP_TTLS_VERSION */
 
@@ -1236,27 +1222,25 @@
 }
 
 
-static int eap_ttls_parse_avps(u8 *in_decrypted, size_t len_decrypted,
+static int eap_ttls_parse_avps(struct wpabuf *in_decrypted,
 			       struct ttls_parse_avp *parse)
 {
 	u8 *pos;
 	size_t left, pad;
 	int avp_length;
 
-	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs",
-		    in_decrypted, len_decrypted);
-	if (len_decrypted < sizeof(struct ttls_avp)) {
+	pos = wpabuf_mhead(in_decrypted);
+	left = wpabuf_len(in_decrypted);
+	wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 AVPs", pos, left);
+	if (left < sizeof(struct ttls_avp)) {
 		wpa_printf(MSG_WARNING, "EAP-TTLS: Too short Phase 2 AVP frame"
 			   " len=%lu expected %lu or more - dropped",
-			   (unsigned long) len_decrypted,
+			   (unsigned long) left,
 			   (unsigned long) sizeof(struct ttls_avp));
 		return -1;
 	}
 
 	/* Parse AVPs */
-	pos = in_decrypted;
-	left = len_decrypted;
-
 	os_memset(parse, 0, sizeof(*parse));
 
 	while (left > 0) {
@@ -1302,23 +1286,22 @@
 
 static int eap_ttls_encrypt_response(struct eap_sm *sm,
 				     struct eap_ttls_data *data,
-				     u8 *resp, size_t resp_len,
-				     u8 identifier,
-				     u8 **out_data, size_t *out_len)
+				     struct wpabuf *resp, u8 identifier,
+				     struct wpabuf **out_data)
 {
 	if (resp == NULL)
 		return 0;
 
-	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
-			resp, resp_len);
+	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Encrypting Phase 2 data",
+			    resp);
 	if (eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
 				 data->ttls_version, identifier,
-				 resp, resp_len, out_data, out_len)) {
+				 resp, out_data)) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt a Phase 2 "
 			   "frame");
 		return -1;
 	}
-	os_free(resp);
+	wpabuf_free(resp);
 
 	return 0;
 }
@@ -1328,7 +1311,7 @@
 				       struct eap_ttls_data *data,
 				       struct eap_method_ret *ret,
 				       struct ttls_parse_avp *parse,
-				       u8 **resp, size_t *resp_len)
+				       struct wpabuf **resp)
 {
 	struct eap_hdr *hdr;
 	size_t len;
@@ -1364,8 +1347,7 @@
 		   hdr->code, hdr->identifier, (unsigned long) len);
 	switch (hdr->code) {
 	case EAP_CODE_REQUEST:
-		if (eap_ttls_phase2_request(sm, data, ret, hdr, resp,
-					    resp_len)) {
+		if (eap_ttls_phase2_request(sm, data, ret, hdr, resp)) {
 			wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
 				   "processing failed");
 			return -1;
@@ -1446,7 +1428,7 @@
 				      struct eap_ttls_data *data,
 				      struct eap_method_ret *ret,
 				      struct ttls_parse_avp *parse,
-				      u8 **resp, size_t *resp_len)
+				      struct wpabuf **resp)
 {
 	/* TNC uses inner EAP method after non-EAP TTLS phase 2. */
 	if (parse->eapdata == NULL) {
@@ -1465,8 +1447,7 @@
 		   "non-EAP method");
 	data->tnc_started = 1;
 
-	if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp,
-					resp_len) < 0)
+	if (eap_ttls_process_phase2_eap(sm, data, ret, parse, resp) < 0)
 		return -1;
 
 	return 0;
@@ -1479,18 +1460,17 @@
 				      struct eap_method_ret *ret,
 				      u8 identifier,
 				      struct ttls_parse_avp *parse,
-				      u8 *in_decrypted, size_t len_decrypted,
-				      u8 **out_data, size_t *out_len)
-{
-	u8 *resp = NULL;
-	size_t resp_len;
+				      struct wpabuf *in_decrypted,
+				      struct wpabuf **out_data)
+{
+	struct wpabuf *resp = NULL;
 	struct wpa_ssid *config = eap_get_config(sm);
 	int res;
 
 	switch (data->phase2_type) {
 	case EAP_TTLS_PHASE2_EAP:
-		if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp,
-						&resp_len) < 0)
+		if (eap_ttls_process_phase2_eap(sm, data, ret, parse, &resp) <
+		    0)
 			return -1;
 		break;
 	case EAP_TTLS_PHASE2_MSCHAPV2:
@@ -1506,7 +1486,7 @@
 			ret->methodState = METHOD_MAY_CONT;
 			data->ready_for_tnc = 1;
 			if (eap_ttls_process_tnc_start(sm, data, ret, parse,
-						       &resp, &resp_len) == 0)
+						       &resp) == 0)
 				break;
 		}
 #endif /* EAP_TNC */
@@ -1515,8 +1495,8 @@
 	case EAP_TTLS_PHASE2_PAP:
 	case EAP_TTLS_PHASE2_CHAP:
 #ifdef EAP_TNC
-		if (eap_ttls_process_tnc_start(sm, data, ret, parse,
-					       &resp, &resp_len) < 0)
+		if (eap_ttls_process_tnc_start(sm, data, ret, parse, &resp) <
+		    0)
 			return -1;
 		break;
 #else /* EAP_TNC */
@@ -1529,21 +1509,15 @@
 	}
 
 	if (resp) {
-		if (eap_ttls_encrypt_response(sm, data, resp, resp_len,
-					      identifier,
-					      out_data, out_len) < 0)
+		if (eap_ttls_encrypt_response(sm, data, resp, identifier,
+					      out_data) < 0)
 			return -1;
 	} else if (config->pending_req_identity ||
 		   config->pending_req_password ||
 		   config->pending_req_otp ||
 		   config->pending_req_new_password) {
-		os_free(data->pending_phase2_req);
-		data->pending_phase2_req = os_malloc(len_decrypted);
-		if (data->pending_phase2_req) {
-			os_memcpy(data->pending_phase2_req, in_decrypted,
-				  len_decrypted);
-			data->pending_phase2_req_len = len_decrypted;
-		}
+		wpabuf_free(data->pending_phase2_req);
+		data->pending_phase2_req = wpabuf_dup(in_decrypted);
 	}
 
 	return 0;
@@ -1555,15 +1529,14 @@
 					  struct eap_ttls_data *data,
 					  struct eap_method_ret *ret,
 					  u8 identifier,
-					  u8 **out_data, size_t *out_len)
+					  struct wpabuf **out_data)
 {
 	wpa_printf(MSG_DEBUG, "EAP-TTLS: FinalPhaseFinished received");
 	wpa_printf(MSG_INFO, "EAP-TTLS: TLS/IA authentication succeeded");
 	ret->methodState = METHOD_DONE;
 	ret->decision = DECISION_UNCOND_SUCC;
 	data->phase2_success = 1;
-	*out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1,
-						  out_len);
+	*out_data = eap_ttls_build_phase_finished(sm, data, identifier, 1);
 	eap_ttls_v1_derive_key(sm, data);
 }
 #endif /* EAP_TTLS_VERSION */
@@ -1573,12 +1546,11 @@
 					      struct eap_ttls_data *data,
 					      struct eap_method_ret *ret,
 					      u8 identifier,
-					      u8 **out_data, size_t *out_len)
+					      struct wpabuf **out_data)
 {
 	int retval = 0;
 	struct eap_hdr *hdr;
-	u8 *resp;
-	size_t resp_len;
+	struct wpabuf *resp;
 
 	hdr = (struct eap_hdr *) eap_ttls_fake_identity_request();
 	if (hdr == NULL) {
@@ -1588,14 +1560,13 @@
 	}
 
 	resp = NULL;
-	if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp, &resp_len)) {
+	if (eap_ttls_phase2_request(sm, data, ret, hdr, &resp)) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: Phase2 Request "
 			   "processing failed");
 		retval = -1;
 	} else {
-		retval = eap_ttls_encrypt_response(sm, data, resp, resp_len,
-						   identifier, out_data,
-						   out_len);
+		retval = eap_ttls_encrypt_response(sm, data, resp, identifier,
+						   out_data);
 	}
 
 	os_free(hdr);
@@ -1611,7 +1582,7 @@
 
 static int eap_ttls_phase2_start(struct eap_sm *sm, struct eap_ttls_data *data,
 				 struct eap_method_ret *ret, u8 identifier,
-				 u8 **out_data, size_t *out_len)
+				 struct wpabuf **out_data)
 {
 	data->phase2_start = 0;
 
@@ -1626,8 +1597,7 @@
 	    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(out_len, identifier,
-						   EAP_TYPE_TTLS,
+		*out_data = eap_peer_tls_build_ack(identifier, EAP_TYPE_TTLS,
 						   data->ttls_version);
 		ret->methodState = METHOD_DONE;
 		ret->decision = DECISION_UNCOND_SUCC;
@@ -1636,25 +1606,24 @@
 	}
 
 	return eap_ttls_implicit_identity_request(sm, data, ret, identifier,
-						  out_data, out_len);
+						  out_data);
 }
 
 
 static int eap_ttls_decrypt(struct eap_sm *sm, struct eap_ttls_data *data,
-			    struct eap_method_ret *ret,
-			    u8 identifier,
-			    const u8 *in_data, size_t in_len,
-			    u8 **out_data, size_t *out_len)
-{
-	u8 *in_decrypted = NULL;
+			    struct eap_method_ret *ret, u8 identifier,
+			    const struct wpabuf *in_data,
+			    struct wpabuf **out_data)
+{
+	struct wpabuf *in_decrypted = NULL;
 	int retval = 0;
-	size_t len_decrypted = 0;
 	struct ttls_parse_avp parse;
 
 	os_memset(&parse, 0, sizeof(parse));
 
 	wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
-		   " Phase 2", (unsigned long) in_len);
+		   " Phase 2",
+		   in_data ? (unsigned long) wpabuf_len(in_data) : 0);
 
 	if (data->pending_phase2_req) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 request - "
@@ -1664,40 +1633,38 @@
 
 		in_decrypted = data->pending_phase2_req;
 		data->pending_phase2_req = NULL;
-		len_decrypted = data->pending_phase2_req_len;
-		if (data->pending_phase2_req_len == 0) {
-			os_free(in_decrypted);
+		if (wpabuf_len(in_decrypted) == 0) {
+			wpabuf_free(in_decrypted);
 			return eap_ttls_implicit_identity_request(
-				sm, data, ret, identifier, out_data,
-				out_len);
+				sm, data, ret, identifier, out_data);
 		}
 		goto continue_req;
 	}
 
-	if (in_len == 0 && data->phase2_start) {
+	if ((in_data == NULL || wpabuf_len(in_data) == 0) &&
+	    data->phase2_start) {
 		return eap_ttls_phase2_start(sm, data, ret, identifier,
-					     out_data, out_len);
-	}
-
-	if (in_len == 0) {
+					     out_data);
+	}
+
+	if (in_data == NULL || wpabuf_len(in_data) == 0) {
 		/* Received TLS ACK - requesting more fragments */
 		return eap_peer_tls_encrypt(sm, &data->ssl, EAP_TYPE_TTLS,
 					    data->ttls_version,
-					    identifier, NULL, 0,
-					    out_data, out_len);
-	}
-
-	retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, in_len,
-				      &in_decrypted, &len_decrypted);
+					    identifier, NULL, out_data);
+	}
+
+	retval = eap_peer_tls_decrypt(sm, &data->ssl, in_data, &in_decrypted);
 	if (retval)
 		goto done;
 
 #if EAP_TTLS_VERSION > 0
-	if (data->ttls_version > 0 && len_decrypted == 0 &&
+	if (data->ttls_version > 0 &&
+	    (in_decrypted == NULL || wpabuf_len(in_decrypted) == 0) &&
 	    tls_connection_ia_final_phase_finished(sm->ssl_ctx,
 						   data->ssl.conn)) {
 		eap_ttls_final_phase_finished(sm, data, ret, identifier,
-					      out_data, out_len);
+					      out_data);
 		goto done;
 	}
 #endif /* EAP_TTLS_VERSION */
@@ -1705,18 +1672,16 @@
 continue_req:
 	data->phase2_start = 0;
 
-	if (eap_ttls_parse_avps(in_decrypted, len_decrypted, &parse) < 0) {
+	if (eap_ttls_parse_avps(in_decrypted, &parse) < 0) {
 		retval = -1;
 		goto done;
 	}
 
 	retval = eap_ttls_process_decrypted(sm, data, ret, identifier,
-					    &parse,
-					    in_decrypted, len_decrypted,
-					    out_data, out_len);
+					    &parse, in_decrypted, out_data);
 
 done:
-	os_free(in_decrypted);
+	wpabuf_free(in_decrypted);
 	os_free(parse.eapdata);
 
 	if (retval < 0) {
@@ -1773,13 +1738,13 @@
 				      struct eap_method_ret *ret,
 				      u8 identifier,
 				      const u8 *in_data, size_t in_len,
-				      u8 **out_data, size_t *out_len)
+				      struct wpabuf **out_data)
 {
 	int res;
 
 	res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS,
 					  data->ttls_version, identifier,
-					  in_data, in_len, out_data, out_len);
+					  in_data, in_len, out_data);
 
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to "
@@ -1794,9 +1759,9 @@
 		if (data->ttls_version == 0)
 			eap_ttls_v0_derive_key(sm, data);
 
-		if (*out_len == 0) {
+		if (*out_data == NULL || wpabuf_len(*out_data) == 0) {
 			if (eap_ttls_decrypt(sm, data, ret, identifier,
-					     NULL, 0, out_data, out_len)) {
+					     NULL, out_data)) {
 				wpa_printf(MSG_WARNING, "EAP-TTLS: "
 					   "failed to process early "
 					   "start for Phase 2");
@@ -1807,16 +1772,16 @@
 	}
 
 	if (res == 2) {
+		struct wpabuf msg;
 		/*
 		 * Application data included in the handshake message.
 		 */
-		os_free(data->pending_phase2_req);
+		wpabuf_free(data->pending_phase2_req);
 		data->pending_phase2_req = *out_data;
-		data->pending_phase2_req_len = *out_len;
 		*out_data = NULL;
-		*out_len = 0;
-		res = eap_ttls_decrypt(sm, data, ret, identifier,
-				       in_data, in_len, out_data, out_len);
+		wpabuf_set(&msg, in_data, in_len);
+		res = eap_ttls_decrypt(sm, data, ret, identifier, &msg,
+				       out_data);
 	}
 
 	return res;
@@ -1856,23 +1821,22 @@
 }
 
 
-static u8 * eap_ttls_process(struct eap_sm *sm, void *priv,
-			     struct eap_method_ret *ret,
-			     const u8 *reqData, size_t reqDataLen,
-			     size_t *respDataLen)
-{
-	const struct eap_hdr *req;
+static struct wpabuf * eap_ttls_process(struct eap_sm *sm, void *priv,
+					struct eap_method_ret *ret,
+					const struct wpabuf *reqData)
+{
 	size_t left;
 	int res;
-	u8 flags, *resp;
+	u8 flags, id;
+	struct wpabuf *resp;
 	const u8 *pos;
 	struct eap_ttls_data *data = priv;
 
 	pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TTLS, ret,
-					reqData, reqDataLen, &left, &flags);
+					reqData, &left, &flags);
 	if (pos == NULL)
 		return NULL;
-	req = (const struct eap_hdr *) reqData;
+	id = eap_get_id(reqData);
 
 	if (flags & EAP_TLS_FLAGS_START) {
 		if (eap_ttls_process_start(sm, data, flags, ret) < 0)
@@ -1896,12 +1860,12 @@
 	resp = NULL;
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
 	    !data->resuming) {
-		res = eap_ttls_decrypt(sm, data, ret, req->identifier,
-				       pos, left, &resp, respDataLen);
+		struct wpabuf msg;
+		wpabuf_set(&msg, pos, left);
+		res = eap_ttls_decrypt(sm, data, ret, id, &msg, &resp);
 	} else {
-		res = eap_ttls_process_handshake(sm, data, ret,
-						 req->identifier, pos, left,
-						 &resp, respDataLen);
+		res = eap_ttls_process_handshake(sm, data, ret, id,
+						 pos, left, &resp);
 	}
 
 	eap_ttls_check_auth_status(sm, data, ret);
@@ -1909,9 +1873,8 @@
 	/* FIX: what about res == -1? Could just move all error processing into
 	 * the other functions and get rid of this res==1 case here. */
 	if (res == 1) {
-		os_free(resp);
-		return eap_peer_tls_build_ack(respDataLen, req->identifier,
-					      EAP_TYPE_TTLS,
+		wpabuf_free(resp);
+		return eap_peer_tls_build_ack(id, EAP_TYPE_TTLS,
 					      data->ttls_version);
 	}
 	return resp;
@@ -1929,7 +1892,7 @@
 static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv)
 {
 	struct eap_ttls_data *data = priv;
-	os_free(data->pending_phase2_req);
+	wpabuf_free(data->pending_phase2_req);
 	data->pending_phase2_req = NULL;
 #ifdef EAP_TNC
 	data->ready_for_tnc = 0;

Modified: wpasupplicant/trunk/src/eap_peer/eap_vendor_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_vendor_test.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_vendor_test.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_vendor_test.c Tue Dec 25 15:23:24 2007
@@ -67,20 +67,16 @@
 #endif /* TEST_PENDING_REQUEST */
 
 
-static u8 * eap_vendor_test_process(struct eap_sm *sm, void *priv,
-				    struct eap_method_ret *ret,
-				    const u8 *reqData, size_t reqDataLen,
-				    size_t *respDataLen)
+static struct wpabuf * eap_vendor_test_process(struct eap_sm *sm, void *priv,
+					       struct eap_method_ret *ret,
+					       const struct wpabuf *reqData)
 {
 	struct eap_vendor_test_data *data = priv;
-	const struct eap_hdr *req;
-	struct eap_hdr *resp;
+	struct wpabuf *resp;
 	const u8 *pos;
-	u8 *rpos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, reqData, &len);
 	if (pos == NULL || len < 1) {
 		ret->ignore = TRUE;
 		return NULL;
@@ -122,29 +118,28 @@
 	}
 
 	ret->ignore = FALSE;
-	req = (const struct eap_hdr *) reqData;
 
 	wpa_printf(MSG_DEBUG, "EAP-VENDOR-TEST: Generating Response");
 	ret->allowNotifications = TRUE;
 
-	resp = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respDataLen, 1,
-			     EAP_CODE_RESPONSE, req->identifier, &rpos);
+	resp = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1,
+			     EAP_CODE_RESPONSE, eap_get_id(reqData));
 	if (resp == NULL)
 		return NULL;
 
 	if (data->state == INIT) {
-		*rpos = 2;
+		wpabuf_put_u8(resp, 2);
 		data->state = CONFIRM;
 		ret->methodState = METHOD_CONT;
 		ret->decision = DECISION_FAIL;
 	} else {
-		*rpos = 4;
+		wpabuf_put_u8(resp, 4);
 		data->state = SUCCESS;
 		ret->methodState = METHOD_DONE;
 		ret->decision = DECISION_UNCOND_SUCC;
 	}
 
-	return (u8 *) resp;
+	return resp;
 }
 
 

Modified: wpasupplicant/trunk/src/eap_peer/eap_wsc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_wsc.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_wsc.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_wsc.c Tue Dec 25 15:23:24 2007
@@ -216,12 +216,11 @@
 }
 
 
-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;
+static struct wpabuf * eap_wsc_build_msg(struct eap_wsc_data *data,
+					 struct eap_method_ret *ret, u8 id)
+{
+	struct wpabuf *resp;
+	u8 flags;
 	size_t send_len, plen;
 
 	ret->ignore = FALSE;
@@ -241,19 +240,17 @@
 	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);
+	resp = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, plen,
+			     EAP_CODE_RESPONSE, id);
 	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);
+	wpabuf_put_u8(resp, data->out_op_code); /* Op-Code */
+	wpabuf_put_u8(resp, flags); /* Flags */
+	if (flags & WSC_FLAGS_LF)
+		wpabuf_put_be16(resp, data->out_len);
+
+	wpabuf_put_data(resp, data->out_buf + data->out_used, send_len);
 	data->out_used += send_len;
 
 	ret->methodState = METHOD_MAY_CONT;
@@ -279,17 +276,15 @@
 		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)
+	return resp;
+}
+
+
+static struct wpabuf * eap_wsc_process(struct eap_sm *sm, void *priv,
+				       struct eap_method_ret *ret,
+				       const struct wpabuf *reqData)
 {
 	struct eap_wsc_data *data = priv;
-	const struct eap_hdr *req;
 	const u8 *start, *pos, *end;
 	size_t len;
 	u8 op_code, flags, id;
@@ -298,15 +293,14 @@
 	size_t msg_len;
 	enum wps_process_res res;
 
-	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
-			       reqData, reqDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, reqData,
+			       &len);
 	if (pos == NULL || len < 2) {
 		ret->ignore = TRUE;
 		return NULL;
 	}
 
-	req = (const struct eap_hdr *) reqData;
-	id = req->identifier;
+	id = eap_get_id(reqData);
 
 	start = pos;
 	end = start + len;
@@ -343,7 +337,7 @@
 		}
 		wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment acknowledged");
 		eap_wsc_state(data, MSG);
-		return eap_wsc_build_msg(data, ret, id, respDataLen);
+		return eap_wsc_build_msg(data, ret, id);
 	}
 
 	if (op_code != WSC_ACK && op_code != WSC_NACK && op_code != WSC_MSG &&
@@ -422,8 +416,7 @@
 				   data->in_len - data->in_used);
 		}
 
-		return eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE,
-					      respDataLen);
+		return eap_wsc_build_frag_ack(id, EAP_CODE_RESPONSE);
 	}
 
 	if (data->in_buf) {
@@ -470,7 +463,7 @@
 	}
 
 	eap_wsc_state(data, MSG);
-	return eap_wsc_build_msg(data, ret, id, respDataLen);
+	return eap_wsc_build_msg(data, ret, id);
 }
 
 

Modified: wpasupplicant/trunk/src/eap_server/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap.c Tue Dec 25 15:23:24 2007
@@ -37,15 +37,27 @@
 static int eap_sm_calculateTimeout(struct eap_sm *sm, int retransCount,
 				   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 void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp);
+static int eap_sm_getId(const struct wpabuf *data);
+static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id);
+static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id);
 static int eap_sm_nextId(struct eap_sm *sm, int id);
-static void eap_sm_Policy_update(struct eap_sm *sm, u8 *nak_list, size_t len);
+static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
+				 size_t len);
 static EapType eap_sm_Policy_getNextMethod(struct eap_sm *sm, int *vendor);
 static int eap_sm_Policy_getDecision(struct eap_sm *sm);
 static Boolean eap_sm_Policy_doPickUp(struct eap_sm *sm, EapType method);
+
+
+static int eap_copy_buf(struct wpabuf **dst, const struct wpabuf *src)
+{
+	if (src == NULL)
+		return -1;
+
+	wpabuf_free(*dst);
+	*dst = wpabuf_dup(src);
+	return *dst ? 0 : -1;
+}
 
 
 static int eap_copy_data(u8 **dst, size_t *dst_len,
@@ -148,8 +160,7 @@
 	if (sm->backend_auth) {
 		sm->currentMethod = EAP_TYPE_NONE;
 		/* parse rxResp, respId, respMethod */
-		eap_sm_parseEapResp(sm, sm->eap_if.eapRespData,
-				    sm->eap_if.eapRespDataLen);
+		eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
 		if (sm->rxResp) {
 			sm->currentId = sm->respId;
 		}
@@ -204,7 +215,7 @@
 
 	sm->retransCount++;
 	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
-		if (EAP_COPY(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
+		if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
 			sm->eap_if.eapReq = TRUE;
 	}
 }
@@ -215,8 +226,7 @@
 	SM_ENTRY(EAP, RECEIVED);
 
 	/* parse rxResp, respId, respMethod */
-	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData,
-			    sm->eap_if.eapRespDataLen);
+	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
 	sm->num_rounds++;
 }
 
@@ -235,7 +245,8 @@
 
 	sm->retransCount = 0;
 	if (sm->eap_if.eapReqData) {
-		if (EAP_COPY(&sm->lastReqData, sm->eap_if.eapReqData) == 0) {
+		if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
+		{
 			sm->eap_if.eapResp = FALSE;
 			sm->eap_if.eapReq = TRUE;
 		} else {
@@ -257,8 +268,7 @@
 
 	if (sm->m->check) {
 		sm->ignore = sm->m->check(sm, sm->eap_method_priv,
-					  sm->eap_if.eapRespData,
-					  sm->eap_if.eapRespDataLen);
+					  sm->eap_if.eapRespData);
 	}
 }
 
@@ -276,10 +286,9 @@
 	wpa_printf(MSG_DEBUG, "EAP: building EAP-Request: Identifier %d",
 		   sm->currentId);
 	sm->lastId = sm->currentId;
-	os_free(sm->eap_if.eapReqData);
+	wpabuf_free(sm->eap_if.eapReqData);
 	sm->eap_if.eapReqData = sm->m->buildReq(sm, sm->eap_method_priv,
-						sm->currentId,
-						&sm->eap_if.eapReqDataLen);
+						sm->currentId);
 	if (sm->m->getTimeout)
 		sm->methodTimeout = sm->m->getTimeout(sm, sm->eap_method_priv);
 	else
@@ -291,8 +300,7 @@
 {
 	SM_ENTRY(EAP, METHOD_RESPONSE);
 
-	sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData,
-		       sm->eap_if.eapRespDataLen);
+	sm->m->process(sm, sm->eap_method_priv, sm->eap_if.eapRespData);
 	if (sm->m->isDone(sm, sm->eap_method_priv)) {
 		eap_sm_Policy_update(sm, NULL, 0);
 		os_free(sm->eap_if.eapKeyData);
@@ -347,9 +355,10 @@
 
 SM_STATE(EAP, NAK)
 {
-	struct eap_hdr *nak;
+	const struct eap_hdr *nak;
 	size_t len = 0;
-	u8 *pos, *nak_list = NULL;
+	const u8 *pos;
+	const u8 *nak_list = NULL;
 
 	SM_ENTRY(EAP, NAK);
 
@@ -359,12 +368,12 @@
 	}
 	sm->m = NULL;
 
-	nak = (struct eap_hdr *) sm->eap_if.eapRespData;
-	if (nak && sm->eap_if.eapRespDataLen > sizeof(*nak)) {
+	nak = wpabuf_head(sm->eap_if.eapRespData);
+	if (nak && wpabuf_len(sm->eap_if.eapRespData) > sizeof(*nak)) {
 		len = be_to_host16(nak->length);
-		if (len > sm->eap_if.eapRespDataLen)
-			len = sm->eap_if.eapRespDataLen;
-		pos = (u8 *) (nak + 1);
+		if (len > wpabuf_len(sm->eap_if.eapRespData))
+			len = wpabuf_len(sm->eap_if.eapRespData);
+		pos = (const u8 *) (nak + 1);
 		len -= sizeof(*nak);
 		if (*pos == EAP_TYPE_NAK) {
 			pos++;
@@ -396,12 +405,10 @@
 {
 	SM_ENTRY(EAP, FAILURE);
 
-	os_free(sm->eap_if.eapReqData);
-	sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId,
-						    &sm->eap_if.eapReqDataLen);
-	os_free(sm->lastReqData);
+	wpabuf_free(sm->eap_if.eapReqData);
+	sm->eap_if.eapReqData = eap_sm_buildFailure(sm, sm->currentId);
+	wpabuf_free(sm->lastReqData);
 	sm->lastReqData = NULL;
-	sm->lastReqDataLen = 0;
 	sm->eap_if.eapFail = TRUE;
 }
 
@@ -410,12 +417,10 @@
 {
 	SM_ENTRY(EAP, SUCCESS);
 
-	os_free(sm->eap_if.eapReqData);
-	sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId,
-						    &sm->eap_if.eapReqDataLen);
-	os_free(sm->lastReqData);
+	wpabuf_free(sm->eap_if.eapReqData);
+	sm->eap_if.eapReqData = eap_sm_buildSuccess(sm, sm->currentId);
+	wpabuf_free(sm->lastReqData);
 	sm->lastReqData = NULL;
-	sm->lastReqDataLen = 0;
 	if (sm->eap_if.eapKeyData)
 		sm->eap_if.eapKeyAvailable = TRUE;
 	sm->eap_if.eapSuccess = TRUE;
@@ -426,9 +431,8 @@
 {
 	SM_ENTRY(EAP, INITIALIZE_PASSTHROUGH);
 
-	os_free(sm->eap_if.aaaEapRespData);
+	wpabuf_free(sm->eap_if.aaaEapRespData);
 	sm->eap_if.aaaEapRespData = NULL;
-	sm->eap_if.aaaEapRespDataLen = 0;
 }
 
 
@@ -448,7 +452,7 @@
 
 	sm->retransCount++;
 	if (sm->retransCount <= sm->MaxRetrans && sm->lastReqData) {
-		if (EAP_COPY(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
+		if (eap_copy_buf(&sm->eap_if.eapReqData, sm->lastReqData) == 0)
 			sm->eap_if.eapReq = TRUE;
 	}
 }
@@ -459,8 +463,7 @@
 	SM_ENTRY(EAP, RECEIVED2);
 
 	/* parse rxResp, respId, respMethod */
-	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData,
-			    sm->eap_if.eapRespDataLen);
+	eap_sm_parseEapResp(sm, sm->eap_if.eapRespData);
 }
 
 
@@ -478,7 +481,8 @@
 
 	sm->retransCount = 0;
 	if (sm->eap_if.eapReqData) {
-		if (EAP_COPY(&sm->lastReqData, sm->eap_if.eapReqData) == 0) {
+		if (eap_copy_buf(&sm->lastReqData, sm->eap_if.eapReqData) == 0)
+		{
 			sm->eap_if.eapResp = FALSE;
 			sm->eap_if.eapReq = TRUE;
 		} else {
@@ -510,7 +514,7 @@
 	 * stores the identity into sm->identity.
 	 */
 
-	EAP_COPY(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);
+	eap_copy_buf(&sm->eap_if.aaaEapRespData, sm->eap_if.eapRespData);
 }
 
 
@@ -518,9 +522,8 @@
 {
 	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);
+	eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
+	sm->currentId = eap_sm_getId(sm->eap_if.eapReqData);
 	sm->methodTimeout = sm->eap_if.aaaMethodTimeout;
 }
 
@@ -549,7 +552,7 @@
 {
 	SM_ENTRY(EAP, FAILURE2);
 
-	EAP_COPY(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
+	eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
 	sm->eap_if.eapFail = TRUE;
 }
 
@@ -558,7 +561,7 @@
 {
 	SM_ENTRY(EAP, SUCCESS2);
 
-	EAP_COPY(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
+	eap_copy_buf(&sm->eap_if.eapReqData, sm->eap_if.aaaEapReqData);
 
 	sm->eap_if.eapKeyAvailable = sm->eap_if.aaaEapKeyAvailable;
 	if (sm->eap_if.aaaEapKeyAvailable) {
@@ -796,9 +799,9 @@
 }
 
 
-static void eap_sm_parseEapResp(struct eap_sm *sm, u8 *resp, size_t len)
-{
-	struct eap_hdr *hdr;
+static void eap_sm_parseEapResp(struct eap_sm *sm, const struct wpabuf *resp)
+{
+	const struct eap_hdr *hdr;
 	size_t plen;
 
 	/* parse rxResp, respId, respMethod */
@@ -808,17 +811,19 @@
 	sm->respVendor = EAP_VENDOR_IETF;
 	sm->respVendorMethod = EAP_TYPE_NONE;
 
-	if (resp == NULL || len < sizeof(*hdr)) {
+	if (resp == NULL || wpabuf_len(resp) < sizeof(*hdr)) {
 		wpa_printf(MSG_DEBUG, "EAP: parseEapResp: invalid resp=%p "
-			   "len=%lu", resp, (unsigned long) len);
+			   "len=%lu", resp,
+			   resp ? (unsigned long) wpabuf_len(resp) : 0);
 		return;
 	}
 
-	hdr = (struct eap_hdr *) resp;
+	hdr = wpabuf_head(resp);
 	plen = be_to_host16(hdr->length);
-	if (plen > len) {
+	if (plen > wpabuf_len(resp)) {
 		wpa_printf(MSG_DEBUG, "EAP: Ignored truncated EAP-Packet "
-			   "(len=%lu plen=%lu)", (unsigned long) len,
+			   "(len=%lu plen=%lu)",
+			   (unsigned long) wpabuf_len(resp),
 			   (unsigned long) plen);
 		return;
 	}
@@ -851,50 +856,52 @@
 }
 
 
-static int eap_sm_getId(const u8 *data, size_t len)
+static int eap_sm_getId(const struct wpabuf *data)
 {
 	const struct eap_hdr *hdr;
 
-	if (data == NULL || len < sizeof(*hdr))
+	if (data == NULL || wpabuf_len(data) < sizeof(*hdr))
 		return -1;
 
-	hdr = (const struct eap_hdr *) data;
+	hdr = wpabuf_head(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)
-{
+static struct wpabuf * eap_sm_buildSuccess(struct eap_sm *sm, u8 id)
+{
+	struct wpabuf *msg;
 	struct eap_hdr *resp;
 	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Success (id=%d)", id);
 
-	*len = sizeof(*resp);
-	resp = os_malloc(*len);
-	if (resp == NULL)
+	msg = wpabuf_alloc(sizeof(*resp));
+	if (msg == NULL)
 		return NULL;
+	resp = wpabuf_put(msg, sizeof(*resp));
 	resp->code = EAP_CODE_SUCCESS;
 	resp->identifier = id;
-	resp->length = host_to_be16(*len);
-
-	return (u8 *) resp;
-}
-
-
-static u8 * eap_sm_buildFailure(struct eap_sm *sm, int id, size_t *len)
-{
+	resp->length = host_to_be16(sizeof(*resp));
+
+	return msg;
+}
+
+
+static struct wpabuf * eap_sm_buildFailure(struct eap_sm *sm, u8 id)
+{
+	struct wpabuf *msg;
 	struct eap_hdr *resp;
 	wpa_printf(MSG_DEBUG, "EAP: Building EAP-Failure (id=%d)", id);
 
-	*len = sizeof(*resp);
-	resp = os_malloc(*len);
-	if (resp == NULL)
+	msg = wpabuf_alloc(sizeof(*resp));
+	if (msg == NULL)
 		return NULL;
+	resp = wpabuf_put(msg, sizeof(*resp));
 	resp->code = EAP_CODE_FAILURE;
 	resp->identifier = id;
-	resp->length = host_to_be16(*len);
-
-	return (u8 *) resp;
+	resp->length = host_to_be16(sizeof(*resp));
+
+	return msg;
 }
 
 
@@ -920,7 +927,7 @@
  * This function is called when EAP-Response/Nak is received from the
  * supplicant. This can happen for both phase 1 and phase 2 authentications.
  */
-void eap_sm_process_nak(struct eap_sm *sm, u8 *nak_list, size_t len)
+void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len)
 {
 	int i;
 	size_t j;
@@ -971,7 +978,8 @@
 }
 
 
-static void eap_sm_Policy_update(struct eap_sm *sm, u8 *nak_list, size_t len)
+static void eap_sm_Policy_update(struct eap_sm *sm, const u8 *nak_list,
+				 size_t len)
 {
 	if (nak_list == NULL || sm == NULL || sm->user == NULL)
 		return;
@@ -1145,6 +1153,7 @@
 	}
 	if (conf->eap_fast_a_id)
 		sm->eap_fast_a_id = os_strdup(conf->eap_fast_a_id);
+	sm->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
 
 	wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
 
@@ -1166,15 +1175,15 @@
 	wpa_printf(MSG_DEBUG, "EAP: Server state machine removed");
 	if (sm->m && sm->eap_method_priv)
 		sm->m->reset(sm, sm->eap_method_priv);
-	os_free(sm->eap_if.eapReqData);
+	wpabuf_free(sm->eap_if.eapReqData);
 	os_free(sm->eap_if.eapKeyData);
 	os_free(sm->lastReqData);
-	os_free(sm->eap_if.eapRespData);
+	wpabuf_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);
+	wpabuf_free(sm->eap_if.aaaEapReqData);
+	wpabuf_free(sm->eap_if.aaaEapRespData);
 	os_free(sm->eap_if.aaaEapKeyData);
 	eap_user_free(sm->user);
 	os_free(sm);

Modified: wpasupplicant/trunk/src/eap_server/eap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap.h Tue Dec 25 15:23:24 2007
@@ -18,10 +18,17 @@
 #include "defs.h"
 #include "eap_common/eap_defs.h"
 #include "eap_server/eap_methods.h"
+#include "wpabuf.h"
 
 struct eap_sm;
 
 #define EAP_MAX_METHODS 8
+
+#define EAP_TTLS_AUTH_PAP 1
+#define EAP_TTLS_AUTH_CHAP 2
+#define EAP_TTLS_AUTH_MSCHAP 4
+#define EAP_TTLS_AUTH_MSCHAPV2 8
+
 struct eap_user {
 	struct {
 		int vendor;
@@ -33,13 +40,14 @@
 			    * nt_password_hash() */
 	int phase2;
 	int force_version;
+	int ttls_auth; /* bitfield of
+			* EAP_TTLS_AUTH_{PAP,CHAP,MSCHAP,MSCHAPV2} */
 };
 
 struct eap_eapol_interface {
 	/* Lower layer to full authenticator variables */
 	Boolean eapResp; /* shared with EAPOL Backend Authentication */
-	u8 *eapRespData;
-	size_t eapRespDataLen;
+	struct wpabuf *eapRespData;
 	Boolean portEnabled;
 	int retransWhile;
 	Boolean eapRestart; /* shared with EAPOL Authenticator PAE */
@@ -52,8 +60,7 @@
 	Boolean eapSuccess;
 	Boolean eapFail;
 	Boolean eapTimeout;
-	u8 *eapReqData;
-	size_t eapReqDataLen;
+	struct wpabuf *eapReqData;
 	u8 *eapKeyData;
 	size_t eapKeyDataLen;
 	Boolean eapKeyAvailable; /* called keyAvailable in IEEE 802.1X-2004 */
@@ -63,8 +70,7 @@
 	Boolean aaaEapNoReq;
 	Boolean aaaSuccess;
 	Boolean aaaFail;
-	u8 *aaaEapReqData;
-	size_t aaaEapReqDataLen;
+	struct wpabuf *aaaEapReqData;
 	u8 *aaaEapKeyData;
 	size_t aaaEapKeyDataLen;
 	Boolean aaaEapKeyAvailable;
@@ -72,8 +78,7 @@
 
 	/* Full authenticator to AAA interface variables */
 	Boolean aaaEapResp;
-	u8 *aaaEapRespData;
-	size_t aaaEapRespDataLen;
+	struct wpabuf *aaaEapRespData;
 	/* aaaIdentity -> eap_get_identity() */
 	Boolean aaaTimeout;
 };
@@ -91,6 +96,7 @@
 	int eap_server;
 	u8 *pac_opaque_encr_key;
 	char *eap_fast_a_id;
+	int eap_sim_aka_result_ind;
 };
 
 

Modified: wpasupplicant/trunk/src/eap_server/eap_aka.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_aka.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_aka.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_aka.c Tue Dec 25 15:23:24 2007
@@ -18,6 +18,8 @@
 #include "eap_server/eap_i.h"
 #include "eap_common/eap_sim_common.h"
 #include "eap_server/eap_sim_db.h"
+#include "sha1.h"
+#include "crypto.h"
 
 
 struct eap_aka_data {
@@ -43,6 +45,10 @@
 	int auts_reported; /* whether the current AUTS has been reported to the
 			    * eap_sim_db */
 	u16 notification;
+	int use_result_ind;
+
+	struct wpabuf *id_msgs;
+	int pending_id;
 };
 
 
@@ -95,6 +101,7 @@
 		return NULL;
 	data->state = IDENTITY;
 	eap_aka_determine_identity(sm, data, 1, 0);
+	data->pending_id = -1;
 
 	return data;
 }
@@ -105,15 +112,105 @@
 	struct eap_aka_data *data = priv;
 	os_free(data->next_pseudonym);
 	os_free(data->next_reauth_id);
+	wpabuf_free(data->id_msgs);
 	os_free(data);
 }
 
 
-static u8 * eap_aka_build_identity(struct eap_sm *sm,
-				   struct eap_aka_data *data,
-				   int id, size_t *reqDataLen)
+static int eap_aka_add_id_msg(struct eap_aka_data *data,
+			      const struct wpabuf *msg)
+{
+	if (msg == NULL)
+		return -1;
+
+	if (data->id_msgs == NULL) {
+		data->id_msgs = wpabuf_dup(msg);
+		return data->id_msgs == NULL ? -1 : 0;
+	}
+
+	if (wpabuf_resize(&data->id_msgs, wpabuf_len(msg)) < 0)
+		return -1;
+	wpabuf_put_buf(data->id_msgs, msg);
+
+	return 0;
+}
+
+
+static void eap_aka_add_checkcode(struct eap_aka_data *data,
+				  struct eap_sim_msg *msg)
+{
+	const u8 *addr;
+	size_t len;
+	u8 hash[SHA1_MAC_LEN];
+
+	wpa_printf(MSG_DEBUG, "   AT_CHECKCODE");
+
+	if (data->id_msgs == NULL) {
+		/*
+		 * No EAP-AKA/Identity packets were exchanged - send empty
+		 * checkcode.
+		 */
+		eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, NULL, 0);
+		return;
+	}
+
+	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	addr = wpabuf_head(data->id_msgs);
+	len = wpabuf_len(data->id_msgs);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-AKA: AT_CHECKCODE data", addr, len);
+	sha1_vector(1, &addr, &len, hash);
+
+	eap_sim_msg_add(msg, EAP_SIM_AT_CHECKCODE, 0, hash,
+			EAP_AKA_CHECKCODE_LEN);
+}
+
+
+static int eap_aka_verify_checkcode(struct eap_aka_data *data,
+				    const u8 *checkcode, size_t checkcode_len)
+{
+	const u8 *addr;
+	size_t len;
+	u8 hash[SHA1_MAC_LEN];
+
+	if (checkcode == NULL)
+		return -1;
+
+	if (data->id_msgs == NULL) {
+		if (checkcode_len != 0) {
+			wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from peer "
+				   "indicates that AKA/Identity messages were "
+				   "used, but they were not");
+			return -1;
+		}
+		return 0;
+	}
+
+	if (checkcode_len != EAP_AKA_CHECKCODE_LEN) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: Checkcode from peer indicates "
+			   "that AKA/Identity message were not used, but they "
+			   "were");
+		return -1;
+	}
+
+	/* Checkcode is SHA1 hash over all EAP-AKA/Identity packets. */
+	addr = wpabuf_head(data->id_msgs);
+	len = wpabuf_len(data->id_msgs);
+	sha1_vector(1, &addr, &len, hash);
+
+	if (os_memcmp(hash, checkcode, EAP_AKA_CHECKCODE_LEN) != 0) {
+		wpa_printf(MSG_DEBUG, "EAP-AKA: Mismatch in AT_CHECKCODE");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static struct wpabuf * eap_aka_build_identity(struct eap_sm *sm,
+					      struct eap_aka_data *data, u8 id)
 {
 	struct eap_sim_msg *msg;
+	struct wpabuf *buf;
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Generating Identity");
 	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_AKA,
@@ -123,7 +220,13 @@
 		wpa_printf(MSG_DEBUG, "   AT_PERMANENT_ID_REQ");
 		eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
 	}
-	return eap_sim_msg_finish(msg, reqDataLen, NULL, NULL, 0);
+	buf = eap_sim_msg_finish(msg, NULL, NULL, 0);
+	if (eap_aka_add_id_msg(data, buf) < 0) {
+		wpabuf_free(buf);
+		return NULL;
+	}
+	data->pending_id = id;
+	return buf;
 }
 
 
@@ -191,9 +294,9 @@
 }
 
 
-static u8 * eap_aka_build_challenge(struct eap_sm *sm,
-				    struct eap_aka_data *data,
-				    int id, size_t *reqDataLen)
+static struct wpabuf * eap_aka_build_challenge(struct eap_sm *sm,
+					       struct eap_aka_data *data,
+					       u8 id)
 {
 	struct eap_sim_msg *msg;
 
@@ -209,15 +312,21 @@
 		return NULL;
 	}
 
+	eap_aka_add_checkcode(data, msg);
+
+	if (sm->eap_sim_aka_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
+
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, reqDataLen, data->k_aut, NULL, 0);
-}
-
-
-static u8 * eap_aka_build_reauth(struct eap_sm *sm,
-				 struct eap_aka_data *data,
-				 int id, size_t *reqDataLen)
+	return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_build_reauth(struct eap_sm *sm,
+					    struct eap_aka_data *data, u8 id)
 {
 	struct eap_sim_msg *msg;
 
@@ -242,15 +351,22 @@
 		return NULL;
 	}
 
+	eap_aka_add_checkcode(data, msg);
+
+	if (sm->eap_sim_aka_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
+
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, reqDataLen, data->k_aut, NULL, 0);
-}
-
-
-static u8 * eap_aka_build_notification(struct eap_sm *sm,
-				       struct eap_aka_data *data,
-				       int id, size_t *reqDataLen)
+	return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_build_notification(struct eap_sm *sm,
+						  struct eap_aka_data *data,
+						  u8 id)
 {
 	struct eap_sim_msg *msg;
 
@@ -260,25 +376,44 @@
 	wpa_printf(MSG_DEBUG, "   AT_NOTIFICATION");
 	eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification,
 			NULL, 0);
-	return eap_sim_msg_finish(msg, reqDataLen, NULL, NULL, 0);
-}
-
-
-static u8 * eap_aka_buildReq(struct eap_sm *sm, void *priv, int id,
-			     size_t *reqDataLen)
+	if (data->use_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_IV");
+		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
+		eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
+					   EAP_SIM_AT_ENCR_DATA);
+		wpa_printf(MSG_DEBUG, "   *AT_COUNTER (%u)", data->counter);
+		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, NULL,
+				0);
+
+		if (eap_sim_msg_add_encr_end(msg, data->k_encr,
+					     EAP_SIM_AT_PADDING)) {
+			wpa_printf(MSG_WARNING, "EAP-AKA: Failed to encrypt "
+				   "AT_ENCR_DATA");
+			eap_sim_msg_free(msg);
+			return NULL;
+		}
+
+		wpa_printf(MSG_DEBUG, "   AT_MAC");
+		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
+	}
+	return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
+}
+
+
+static struct wpabuf * eap_aka_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_aka_data *data = priv;
 
 	data->auts_reported = 0;
 	switch (data->state) {
 	case IDENTITY:
-		return eap_aka_build_identity(sm, data, id, reqDataLen);
+		return eap_aka_build_identity(sm, data, id);
 	case CHALLENGE:
-		return eap_aka_build_challenge(sm, data, id, reqDataLen);
+		return eap_aka_build_challenge(sm, data, id);
 	case REAUTH:
-		return eap_aka_build_reauth(sm, data, id, reqDataLen);
+		return eap_aka_build_reauth(sm, data, id);
 	case NOTIFICATION:
-		return eap_aka_build_notification(sm, data, id, reqDataLen);
+		return eap_aka_build_notification(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in "
 			   "buildReq", data->state);
@@ -289,13 +424,12 @@
 
 
 static Boolean eap_aka_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, respData, &len);
 	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-AKA: Invalid frame");
 		return TRUE;
@@ -456,7 +590,7 @@
 
 static void eap_aka_process_identity(struct eap_sm *sm,
 				     struct eap_aka_data *data,
-				     u8 *respData, size_t respDataLen,
+				     struct wpabuf *respData,
 				     struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Identity");
@@ -480,12 +614,16 @@
 	}
 
 	eap_aka_determine_identity(sm, data, 0, 0);
+	if (eap_get_id(respData) == data->pending_id) {
+		data->pending_id = -1;
+		eap_aka_add_id_msg(data, respData);
+	}
 }
 
 
 static void eap_aka_process_challenge(struct eap_sm *sm,
 				      struct eap_aka_data *data,
-				      u8 *respData, size_t respDataLen,
+				      struct wpabuf *respData,
 				      struct eap_sim_attrs *attr)
 {
 	const u8 *identity;
@@ -493,9 +631,17 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Challenge");
 
+	if (attr->checkcode &&
+	    eap_aka_verify_checkcode(data, attr->checkcode,
+				     attr->checkcode_len)) {
+		wpa_printf(MSG_WARNING, "EAP-AKA: Invalid AT_CHECKCODE in the "
+			   "message");
+		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
+		eap_aka_state(data, NOTIFICATION);
+		return;
+	}
 	if (attr->mac == NULL ||
-	    eap_sim_verify_mac(data->k_aut, respData, respDataLen, attr->mac,
-			       NULL, 0)) {
+	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, NULL, 0)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Challenge message "
 			   "did not include valid AT_MAC");
 		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
@@ -514,7 +660,12 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Challenge response includes the "
 		   "correct AT_MAC");
-	eap_aka_state(data, SUCCESS);
+	if (sm->eap_sim_aka_result_ind && attr->result_ind) {
+		data->use_result_ind = 1;
+		data->notification = EAP_SIM_SUCCESS;
+		eap_aka_state(data, NOTIFICATION);
+	} else
+		eap_aka_state(data, SUCCESS);
 
 	identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity,
 					    sm->identity_len, &identity_len);
@@ -541,7 +692,7 @@
 
 static void eap_aka_process_sync_failure(struct eap_sm *sm,
 					 struct eap_aka_data *data,
-					 u8 *respData, size_t respDataLen,
+					 struct wpabuf *respData,
 					 struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Synchronization-Failure");
@@ -575,7 +726,7 @@
 
 static void eap_aka_process_reauth(struct eap_sm *sm,
 				   struct eap_aka_data *data,
-				   u8 *respData, size_t respDataLen,
+				   struct wpabuf *respData,
 				   struct eap_sim_attrs *attr)
 {
 	struct eap_sim_attrs eattr;
@@ -586,8 +737,8 @@
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Processing Reauthentication");
 
 	if (attr->mac == NULL ||
-	    eap_sim_verify_mac(data->k_aut, respData, respDataLen, attr->mac,
-			       data->nonce_s, EAP_SIM_NONCE_S_LEN)) {
+	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,
+			       EAP_SIM_NONCE_S_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-AKA: Re-authentication message "
 			   "did not include valid AT_MAC");
 		goto fail;
@@ -628,7 +779,12 @@
 		return;
 	}
 
-	eap_aka_state(data, SUCCESS);
+	if (sm->eap_sim_aka_result_ind && attr->result_ind) {
+		data->use_result_ind = 1;
+		data->notification = EAP_SIM_SUCCESS;
+		eap_aka_state(data, NOTIFICATION);
+	} else
+		eap_aka_state(data, SUCCESS);
 
 	if (data->reauth) {
 		identity = data->reauth->identity;
@@ -673,7 +829,7 @@
 
 static void eap_aka_process_client_error(struct eap_sm *sm,
 					 struct eap_aka_data *data,
-					 u8 *respData, size_t respDataLen,
+					 struct wpabuf *respData,
 					 struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Client reported error %d",
@@ -684,7 +840,7 @@
 
 static void eap_aka_process_authentication_reject(
 	struct eap_sm *sm, struct eap_aka_data *data,
-	u8 *respData, size_t respDataLen, struct eap_sim_attrs *attr)
+	struct wpabuf *respData, struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Client rejected authentication");
 	eap_aka_state(data, FAILURE);
@@ -693,26 +849,33 @@
 
 static void eap_aka_process_notification(struct eap_sm *sm,
 					 struct eap_aka_data *data,
-					 u8 *respData, size_t respDataLen,
+					 struct wpabuf *respData,
 					 struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-AKA: Client replied to notification");
-	eap_aka_state(data, FAILURE);
+	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)
+		eap_aka_state(data, SUCCESS);
+	else
+		eap_aka_state(data, FAILURE);
 }
 
 
 static void eap_aka_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
+			    struct wpabuf *respData)
 {
 	struct eap_aka_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, subtype;
+	const u8 *pos, *end;
+	u8 subtype;
 	size_t len;
 	struct eap_sim_attrs attr;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	subtype = pos[1];
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_AKA, respData, &len);
+	if (pos == NULL || len < 3)
+		return;
+
+	end = pos + len;
+	subtype = *pos;
+	pos += 3;
 
 	if (eap_aka_subtype_ok(data, subtype)) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Unrecognized or unexpected "
@@ -722,10 +885,7 @@
 		return;
 	}
 
-	len = be_to_host16(resp->length);
-	pos += 4;
-
-	if (eap_sim_parse_attr(pos, respData + len, &attr, 1, 0)) {
+	if (eap_sim_parse_attr(pos, end, &attr, 1, 0)) {
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Failed to parse attributes");
 		data->notification = EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH;
 		eap_aka_state(data, NOTIFICATION);
@@ -733,34 +893,33 @@
 	}
 
 	if (subtype == EAP_AKA_SUBTYPE_CLIENT_ERROR) {
-		eap_aka_process_client_error(sm, data, respData, len, &attr);
+		eap_aka_process_client_error(sm, data, respData, &attr);
 		return;
 	}
 
 	if (subtype == EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT) {
-		eap_aka_process_authentication_reject(sm, data, respData, len,
+		eap_aka_process_authentication_reject(sm, data, respData,
 						      &attr);
 		return;
 	}
 
 	switch (data->state) {
 	case IDENTITY:
-		eap_aka_process_identity(sm, data, respData, len, &attr);
+		eap_aka_process_identity(sm, data, respData, &attr);
 		break;
 	case CHALLENGE:
 		if (subtype == EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE) {
-			eap_aka_process_sync_failure(sm, data, respData, len,
+			eap_aka_process_sync_failure(sm, data, respData,
 						     &attr);
 		} else {
-			eap_aka_process_challenge(sm, data, respData, len,
-						  &attr);
+			eap_aka_process_challenge(sm, data, respData, &attr);
 		}
 		break;
 	case REAUTH:
-		eap_aka_process_reauth(sm, data, respData, len, &attr);
+		eap_aka_process_reauth(sm, data, respData, &attr);
 		break;
 	case NOTIFICATION:
-		eap_aka_process_notification(sm, data, respData, len, &attr);
+		eap_aka_process_notification(sm, data, respData, &attr);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-AKA: Unknown state %d in "

Modified: wpasupplicant/trunk/src/eap_server/eap_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_fast.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_fast.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_fast.c Tue Dec 25 15:23:24 2007
@@ -514,20 +514,21 @@
 		data->phase2_method->reset(sm, data->phase2_priv);
 	eap_server_tls_ssl_deinit(sm, &data->ssl);
 	os_free(data->srv_id);
+	os_free(data->key_block_p);
 	os_free(data);
 }
 
 
-static u8 * eap_fast_build_start(struct eap_sm *sm, struct eap_fast_data *data,
-				 int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
-	u8 *pos;
+static struct wpabuf * eap_fast_build_start(struct eap_sm *sm,
+					    struct eap_fast_data *data, u8 id)
+{
+	struct wpabuf *req;
 	struct pac_tlv_hdr *a_id;
 	size_t srv_id_len = os_strlen(data->srv_id);
 
-	*reqDataLen = sizeof(*req) + 2 + sizeof(*a_id) + srv_id_len;
-	req = os_malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST,
+			    1 + sizeof(*a_id) + srv_id_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-FAST: Failed to allocate memory for"
 			   " request");
@@ -535,21 +536,15 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_FAST;
-	*pos++ = EAP_TLS_FLAGS_START | data->fast_version;
-	a_id = (struct pac_tlv_hdr *) pos;
+	wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->fast_version);
+	a_id = wpabuf_put(req, sizeof(*a_id));
 	a_id->type = host_to_be16(PAC_TYPE_A_ID);
 	a_id->len = host_to_be16(srv_id_len);
-	pos = (u8 *) (a_id + 1);
-	os_memcpy(pos, data->srv_id, srv_id_len);
+	wpabuf_put_data(req, data->srv_id, srv_id_len);
 
 	eap_fast_state(data, PHASE1);
 
-	return (u8 *) req;
+	return req;
 }
 
 
@@ -580,15 +575,14 @@
 }
 
 
-static u8 * eap_fast_build_req(struct eap_sm *sm, struct eap_fast_data *data,
-			       int id, size_t *reqDataLen)
+static struct wpabuf * eap_fast_build_req(struct eap_sm *sm,
+					  struct eap_fast_data *data, u8 id)
 {
 	int res;
-	u8 *req;
+	struct wpabuf *req;
 
 	res = eap_server_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_FAST,
-					     data->fast_version, id, &req,
-					     reqDataLen);
+					     data->fast_version, id, &req);
 
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 		if (eap_fast_phase1_done(sm, data) < 0) {
@@ -598,51 +592,49 @@
 	}
 
 	if (res == 1)
-		return eap_server_tls_build_ack(reqDataLen, id, EAP_TYPE_FAST,
+		return eap_server_tls_build_ack(id, EAP_TYPE_FAST,
 						data->fast_version);
 	return req;
 }
 
 
-static u8 * eap_fast_encrypt(struct eap_sm *sm, struct eap_fast_data *data,
-			     int id, u8 *plain, size_t plain_len,
-			     size_t *out_len)
+static struct wpabuf * eap_fast_encrypt(struct eap_sm *sm,
+					struct eap_fast_data *data,
+					u8 id, u8 *plain, size_t plain_len)
 {
 	int res;
-	u8 *pos;
-	struct eap_hdr *req;
+	struct wpabuf *buf;
 
 	/* TODO: add support for fragmentation, if needed. This will need to
 	 * add TLS Message Length field, if the frame is fragmented. */
-	req = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
-	if (req == NULL)
-		return NULL;
-
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_FAST;
-	*pos++ = data->fast_version;
+	buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_FAST,
+			    1 + data->ssl.tls_out_limit,
+			    EAP_CODE_REQUEST, id);
+	if (buf == NULL)
+		return NULL;
+
+	wpabuf_put_u8(buf, data->fast_version);
 
 	res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
-				     plain, plain_len,
-				     pos, data->ssl.tls_out_limit);
+				     plain, plain_len, wpabuf_put(buf, 0),
+				     data->ssl.tls_out_limit);
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Failed to encrypt Phase 2 "
 			   "data");
-		os_free(req);
-		return NULL;
-	}
-
-	*out_len = sizeof(struct eap_hdr) + 2 + res;
-	req->length = host_to_be16(*out_len);
-	return (u8 *) req;
-}
-
-
-static u8 * eap_fast_tlv_eap_payload(u8 *buf, size_t *len)
-{
+		wpabuf_free(buf);
+		return NULL;
+	}
+
+	wpabuf_put(buf, res);
+	eap_update_len(buf);
+
+	return buf;
+}
+
+
+static struct wpabuf * eap_fast_tlv_eap_payload(struct wpabuf *buf)
+{
+	struct wpabuf *e;
 	struct eap_tlv_hdr *tlv;
 
 	if (buf == NULL)
@@ -650,54 +642,49 @@
 
 	/* Encapsulate EAP packet in EAP-Payload TLV */
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Add EAP-Payload TLV");
-	tlv = os_malloc(sizeof(*tlv) + *len);
-	if (tlv == NULL) {
-		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to "
-			   "allocate memory for TLV "
-			   "encapsulation");
-		os_free(buf);
-		return NULL;
-	}
+	e = wpabuf_alloc(sizeof(*tlv) + wpabuf_len(buf));
+	if (e == NULL) {
+		wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to allocate memory "
+			   "for TLV encapsulation");
+		wpabuf_free(buf);
+		return NULL;
+	}
+	tlv = wpabuf_put(e, sizeof(*tlv));
 	tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 				     EAP_TLV_EAP_PAYLOAD_TLV);
-	tlv->length = host_to_be16(*len);
-	os_memcpy(tlv + 1, buf, *len);
-	os_free(buf);
-	*len += sizeof(*tlv);
-	return (u8 *) tlv;
-}
-
-
-static u8 * eap_fast_build_phase2_req(struct eap_sm *sm,
-				      struct eap_fast_data *data,
-				      int id, size_t *req_len)
-{
-	u8 *req;
-
-	req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
-					    req_len);
+	tlv->length = host_to_be16(wpabuf_len(buf));
+	wpabuf_put_buf(e, buf);
+	wpabuf_free(buf);
+	return e;
+}
+
+
+static struct wpabuf * eap_fast_build_phase2_req(struct eap_sm *sm,
+						 struct eap_fast_data *data,
+						 u8 id)
+{
+	struct wpabuf *req;
+
+	req = data->phase2_method->buildReq(sm, data->phase2_priv, id);
 	if (req == NULL)
 		return NULL;
 
-	wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: Phase 2 EAP-Request",
-			req, *req_len);
-	return eap_fast_tlv_eap_payload(req, req_len);
-}
-
-
-static u8 * eap_fast_build_crypto_binding(struct eap_sm *sm,
-					  struct eap_fast_data *data,
-					  size_t *req_len)
-{
+	wpa_hexdump_buf_key(MSG_MSGDUMP, "EAP-FAST: Phase 2 EAP-Request", req);
+	return eap_fast_tlv_eap_payload(req);
+}
+
+
+static struct wpabuf * eap_fast_build_crypto_binding(
+	struct eap_sm *sm, struct eap_fast_data *data)
+{
+	struct wpabuf *buf;
 	struct eap_tlv_result_tlv *result;
 	struct eap_tlv_crypto_binding__tlv *binding;
 	int type;
 
-	*req_len = sizeof(*result) + sizeof(*binding);
-	result = os_zalloc(*req_len);
-	if (result == NULL)
-		return NULL;
-	binding = (struct eap_tlv_crypto_binding__tlv *) (result + 1);
+	buf = wpabuf_alloc(sizeof(*result) + sizeof(*binding));
+	if (buf == NULL)
+		return NULL;
 
 	if (data->send_new_pac || data->anon_provisioning) {
 		type = EAP_TLV_INTERMEDIATE_RESULT_TLV;
@@ -709,11 +696,13 @@
 
 	/* Result TLV */
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV (status=SUCCESS)");
+	result = wpabuf_put(buf, sizeof(*result));
 	result->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY | type);
 	result->length = host_to_be16(2);
 	result->status = host_to_be16(EAP_TLV_RESULT_SUCCESS);
 
 	/* Crypto-Binding TLV */
+	binding = wpabuf_put(buf, sizeof(*binding));
 	binding->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 					 EAP_TLV_CRYPTO_BINDING_TLV_);
 	binding->length = host_to_be16(sizeof(*binding) -
@@ -722,7 +711,7 @@
 	binding->received_version = data->peer_version;
 	binding->subtype = EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST;
 	if (os_get_random(binding->nonce, sizeof(binding->nonce)) < 0) {
-		os_free(result);
+		wpabuf_free(buf);
 		return NULL;
 	}
 
@@ -753,17 +742,17 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: Compound MAC",
 		    binding->compound_mac, sizeof(binding->compound_mac));
 
-	return (u8 *) result;
-}
-
-
-static u8 * eap_fast_build_pac(struct eap_sm *sm,
-			       struct eap_fast_data *data,
-			       size_t *reqDataLen)
+	return buf;
+}
+
+
+static struct wpabuf * eap_fast_build_pac(struct eap_sm *sm,
+					  struct eap_fast_data *data)
 {
 	u8 pac_key[2 + EAP_FAST_PAC_KEY_LEN + 6];
 	u8 pac_opaque[8 + EAP_FAST_PAC_KEY_LEN + 8];
-	u8 *buf, *pos;
+	struct wpabuf *buf;
+	u8 *pos;
 	size_t buf_len, srv_id_len;
 	struct eap_tlv_hdr *pac_tlv;
 	struct pac_tlv_hdr *hdr, *pac_info;
@@ -796,116 +785,97 @@
 		sizeof(*hdr) + EAP_FAST_PAC_KEY_LEN +
 		sizeof(*hdr) + sizeof(pac_opaque) +
 		2 * srv_id_len + 100 + sizeof(*result);
-	buf = os_zalloc(buf_len);
+	buf = wpabuf_alloc(buf_len);
 	if (buf == NULL)
 		return NULL;
-
-	pos = buf;
 
 	/* PAC TLV */
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Add PAC TLV");
-	pac_tlv = (struct eap_tlv_hdr *) pos;
+	pac_tlv = wpabuf_put(buf, sizeof(*pac_tlv));
 	pac_tlv->tlv_type = host_to_be16(EAP_TLV_TYPE_MANDATORY |
 					 EAP_TLV_PAC_TLV);
-	pos = (u8 *) (pac_tlv + 1);
 
 	/* PAC-Key */
-	hdr = (struct pac_tlv_hdr *) pos;
+	hdr = wpabuf_put(buf, sizeof(*hdr));
 	hdr->type = host_to_be16(PAC_TYPE_PAC_KEY);
 	hdr->len = host_to_be16(EAP_FAST_PAC_KEY_LEN);
-	pos = (u8 *) (hdr + 1);
-	os_memcpy(pos, pac_key + 2, EAP_FAST_PAC_KEY_LEN);
-	pos += EAP_FAST_PAC_KEY_LEN;
+	wpabuf_put_data(buf, pac_key + 2, EAP_FAST_PAC_KEY_LEN);
 
 	/* PAC-Opaque */
-	hdr = (struct pac_tlv_hdr *) pos;
+	hdr = wpabuf_put(buf, sizeof(*hdr));
 	hdr->type = host_to_be16(PAC_TYPE_PAC_OPAQUE);
 	hdr->len = host_to_be16(sizeof(pac_opaque));
-	pos = (u8 *) (hdr + 1);
-	os_memcpy(pos, pac_opaque, sizeof(pac_opaque));
-	pos += sizeof(pac_opaque);
+	wpabuf_put_data(buf, pac_opaque, sizeof(pac_opaque));
 
 	/* PAC-Info */
-	pac_info = (struct pac_tlv_hdr *) pos;
+	pac_info = wpabuf_put(buf, sizeof(*pac_info));
 	pac_info->type = host_to_be16(PAC_TYPE_PAC_INFO);
-	pos = (u8 *) (pac_info + 1);
 
 	/* PAC-Lifetime (inside PAC-Info) */
-	hdr = (struct pac_tlv_hdr *) pos;
+	hdr = wpabuf_put(buf, sizeof(*hdr));
 	hdr->type = host_to_be16(PAC_TYPE_CRED_LIFETIME);
 	hdr->len = host_to_be16(4);
-	pos = (u8 *) (hdr + 1);
-	WPA_PUT_BE32(pos, now.sec + PAC_KEY_LIFETIME);
-	pos += 4;
+	wpabuf_put_be32(buf, now.sec + PAC_KEY_LIFETIME);
 
 	/* A-ID (inside PAC-Info) */
-	hdr = (struct pac_tlv_hdr *) pos;
+	hdr = wpabuf_put(buf, sizeof(*hdr));
 	hdr->type = host_to_be16(PAC_TYPE_A_ID);
 	hdr->len = host_to_be16(srv_id_len);
-	pos = (u8 *) (hdr + 1);
-	os_memcpy(pos, data->srv_id, srv_id_len);
-	pos += srv_id_len;
+	wpabuf_put_data(buf, data->srv_id, srv_id_len);
 	
 	/* Note: headers may be misaligned after A-ID */
 
 	/* A-ID-Info (inside PAC-Info) */
-	hdr = (struct pac_tlv_hdr *) pos;
+	hdr = wpabuf_put(buf, sizeof(*hdr));
 	WPA_PUT_BE16((u8 *) &hdr->type, PAC_TYPE_A_ID_INFO);
 	WPA_PUT_BE16((u8 *) &hdr->len, srv_id_len);
-	pos = (u8 *) (hdr + 1);
-	os_memcpy(pos, data->srv_id, srv_id_len);
-	pos += srv_id_len;
+	wpabuf_put_data(buf, data->srv_id, srv_id_len);
 
 	/* PAC-Type (inside PAC-Info) */
-	hdr = (struct pac_tlv_hdr *) pos;
+	hdr = wpabuf_put(buf, sizeof(*hdr));
 	WPA_PUT_BE16((u8 *) &hdr->type, PAC_TYPE_PAC_TYPE);
 	WPA_PUT_BE16((u8 *) &hdr->len, 2);
-	pos = (u8 *) (hdr + 1);
-	WPA_PUT_BE16(pos, PAC_TYPE_TUNNEL_PAC);
-	pos += 2;
+	wpabuf_put_be16(buf, PAC_TYPE_TUNNEL_PAC);
 
 	/* Update PAC-Info and PAC TLV Length fields */
+	pos = wpabuf_put(buf, 0);
 	pac_info->len = host_to_be16(pos - (u8 *) (pac_info + 1));
 	pac_tlv->length = host_to_be16(pos - (u8 *) (pac_tlv + 1));
 
 	/* Result TLV */
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Add Result TLV (status=SUCCESS)");
-	result = (struct eap_tlv_result_tlv *) pos;
+	result = wpabuf_put(buf, sizeof(*result));
 	WPA_PUT_BE16((u8 *) &result->tlv_type,
 		     EAP_TLV_TYPE_MANDATORY | EAP_TLV_RESULT_TLV);
 	WPA_PUT_BE16((u8 *) &result->length, 2);
 	WPA_PUT_BE16((u8 *) &result->status, EAP_TLV_RESULT_SUCCESS);
-	pos = (u8 *) (result + 1);
-
-	*reqDataLen = pos - buf;
 
 	return buf;
 }
 
 
-static u8 * eap_fast_buildReq(struct eap_sm *sm, void *priv, int id,
-			      size_t *reqDataLen)
+static struct wpabuf * eap_fast_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_fast_data *data = priv;
-	u8 *req, *encr;
-	size_t req_len;
+	struct wpabuf *req;
+	struct wpabuf *encr;
 
 	if (data->state == START)
-		return eap_fast_build_start(sm, data, id, reqDataLen);
+		return eap_fast_build_start(sm, data, id);
 
 	if (data->state == PHASE1)
-		return eap_fast_build_req(sm, data, id, reqDataLen);
+		return eap_fast_build_req(sm, data, id);
 
 	switch (data->state) {
 	case PHASE2_ID:
 	case PHASE2_METHOD:
-		req = eap_fast_build_phase2_req(sm, data, id, &req_len);
+		req = eap_fast_build_phase2_req(sm, data, id);
 		break;
 	case CRYPTO_BINDING:
-		req = eap_fast_build_crypto_binding(sm, data, &req_len);
+		req = eap_fast_build_crypto_binding(sm, data);
 		break;
 	case REQUEST_PAC:
-		req = eap_fast_build_pac(sm, data, &req_len);
+		req = eap_fast_build_pac(sm, data);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-FAST: %s - unexpected state %d",
@@ -916,25 +886,24 @@
 	if (req == NULL)
 		return NULL;
 
-	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);
-	os_free(req);
+	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-FAST: Encrypting Phase 2 TLVs",
+			    req);
+	encr = eap_fast_encrypt(sm, data, id, wpabuf_mhead(req),
+				wpabuf_len(req));
+	wpabuf_free(req);
 
 	return encr;
 }
 
 
 static Boolean eap_fast_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) + 2 || *pos != EAP_TYPE_FAST ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+			      struct wpabuf *respData)
+{
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData, &len);
+	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-FAST: Invalid frame");
 		return TRUE;
 	}
@@ -978,8 +947,11 @@
 	struct eap_hdr *hdr;
 	u8 *pos;
 	size_t left;
-
-	if (data->phase2_priv == NULL) {
+	struct wpabuf buf;
+	const struct eap_method *m = data->phase2_method;
+	void *priv = data->phase2_priv;
+
+	if (priv == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: %s - Phase2 not "
 			   "initialized?!", __func__);
 		return;
@@ -1007,20 +979,21 @@
 		return;
 	}
 
-	if (data->phase2_method->check(sm, data->phase2_priv, in_data,
-				       in_len)) {
+	wpabuf_set(&buf, in_data, in_len);
+
+	if (m->check(sm, priv, &buf)) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 check() asked to "
 			   "ignore the packet");
 		next_type = eap_fast_req_failure(sm, data);
 		return;
 	}
 
-	data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
-
-	if (!data->phase2_method->isDone(sm, data->phase2_priv))
-		return;
-
-	if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
+	m->process(sm, priv, &buf);
+
+	if (!m->isDone(sm, priv))
+		return;
+
+	if (!m->isSuccess(sm, priv)) {
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Phase2 method failed");
 		next_type = eap_fast_req_failure(sm, data);
 		eap_fast_phase2_init(sm, data, next_type);
@@ -1465,8 +1438,7 @@
 
 static void eap_fast_process_phase2(struct eap_sm *sm,
 				    struct eap_fast_data *data,
-				    struct eap_hdr *resp,
-				    u8 *in_data, size_t in_len)
+				    const u8 *in_data, size_t in_len)
 {
 	u8 *in_decrypted;
 	int len_decrypted, res;
@@ -1475,7 +1447,8 @@
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Received %lu bytes encrypted data for"
 		   " Phase 2", (unsigned long) in_len);
 
-	res = eap_server_tls_data_reassemble(sm, &data->ssl, &in_data,
+	/* FIX: get rid of const -> non-const typecast */
+	res = eap_server_tls_data_reassemble(sm, &data->ssl, (u8 **) &in_data,
 					     &in_len);
 	if (res < 0 || res == 1)
 		return;
@@ -1517,22 +1490,24 @@
 
 
 static void eap_fast_process(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_fast_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, flags;
-	int left;
+	const u8 *pos;
+	u8 flags;
+	size_t left;
 	unsigned int tls_msg_len;
 	int peer_version;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	pos++;
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_FAST, respData,
+			       &left);
+	if (pos == NULL || left < 1)
+		return;
 	flags = *pos++;
-	left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 2;
+	left--;
 	wpa_printf(MSG_DEBUG, "EAP-FAST: Received packet(len=%lu) - "
-		   "Flags 0x%02x", (unsigned long) respDataLen, flags);
+		   "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
+		   flags);
 	data->peer_version = peer_version = flags & EAP_PEAP_VERSION_MASK;
 	if (data->force_version >= 0 && peer_version != data->force_version) {
 		wpa_printf(MSG_INFO, "EAP-FAST: peer did not select the forced"
@@ -1600,7 +1575,7 @@
 	case PHASE2_METHOD:
 	case CRYPTO_BINDING:
 	case REQUEST_PAC:
-		eap_fast_process_phase2(sm, data, resp, pos, left);
+		eap_fast_process_phase2(sm, data, pos, left);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-FAST: Unexpected state %d in %s",

Modified: wpasupplicant/trunk/src/eap_server/eap_gpsk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_gpsk.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_gpsk.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_gpsk.c Tue Dec 25 15:23:24 2007
@@ -112,13 +112,11 @@
 }
 
 
-static u8 * eap_gpsk_build_gpsk_1(struct eap_sm *sm,
-				  struct eap_gpsk_data *data,
-				  int id, size_t *reqDataLen)
-{
-	u8 *pos;
+static struct wpabuf * eap_gpsk_build_gpsk_1(struct eap_sm *sm,
+					     struct eap_gpsk_data *data, u8 id)
+{
 	size_t len;
-	struct eap_hdr *req;
+	struct wpabuf *req;
 
 	wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-1");
 
@@ -132,8 +130,8 @@
 
 	len = 1 + 2 + data->id_server_len + EAP_GPSK_RAND_LEN + 2 +
 		data->csuite_count * sizeof(struct eap_gpsk_csuite);
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, reqDataLen,
-			    len, EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
 			   "for request/GPSK-1");
@@ -141,42 +139,34 @@
 		return NULL;
 	}
 
-	*pos++ = EAP_GPSK_OPCODE_GPSK_1;
-
-	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;
-
-	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;
-	os_memcpy(pos, data->csuite_list,
-		  data->csuite_count * sizeof(struct eap_gpsk_csuite));
-
-	return (u8 *) req;
-}
-
-
-static u8 * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
-				  struct eap_gpsk_data *data,
-				  int id, size_t *reqDataLen)
+	wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_1);
+	wpabuf_put_be16(req, data->id_server_len);
+	wpabuf_put_data(req, data->id_server, data->id_server_len);
+	wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
+	wpabuf_put_be16(req,
+			data->csuite_count * sizeof(struct eap_gpsk_csuite));
+	wpabuf_put_data(req, data->csuite_list,
+			data->csuite_count * sizeof(struct eap_gpsk_csuite));
+
+	return req;
+}
+
+
+static struct wpabuf * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
+					     struct eap_gpsk_data *data, u8 id)
 {
 	u8 *pos, *start;
 	size_t len, miclen;
 	struct eap_gpsk_csuite *csuite;
-	struct eap_hdr *req;
+	struct wpabuf *req;
 
 	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 + 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);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
 			   "for request/GPSK-3");
@@ -184,27 +174,21 @@
 		return NULL;
 	}
 
-	*pos++ = EAP_GPSK_OPCODE_GPSK_3;
-	start = pos;
-
-	os_memcpy(pos, data->rand_peer, EAP_GPSK_RAND_LEN);
-	pos += 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;
+	wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_3);
+	start = wpabuf_put(req, 0);
+
+	wpabuf_put_data(req, data->rand_peer, EAP_GPSK_RAND_LEN);
+	wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
+	wpabuf_put_be16(req, data->id_server_len);
+	wpabuf_put_data(req, data->id_server, data->id_server_len);
+	csuite = wpabuf_put(req, sizeof(*csuite));
 	WPA_PUT_BE32(csuite->vendor, data->vendor);
 	WPA_PUT_BE16(csuite->specifier, data->specifier);
-	pos += sizeof(*csuite);
 
 	/* no PD_Payload_2 */
-	WPA_PUT_BE16(pos, 0);
-	pos += 2;
-
+	wpabuf_put_be16(req, 0);
+
+	pos = wpabuf_put(req, miclen);
 	if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
 				 data->specifier, start, pos - start, pos) < 0)
 	{
@@ -213,20 +197,19 @@
 		return NULL;
 	}
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_gpsk_buildReq(struct eap_sm *sm, void *priv, int id,
-			      size_t *reqDataLen)
+	return req;
+}
+
+
+static struct wpabuf * eap_gpsk_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_gpsk_data *data = priv;
 
 	switch (data->state) {
 	case GPSK_1:
-		return eap_gpsk_build_gpsk_1(sm, data, id, reqDataLen);
+		return eap_gpsk_build_gpsk_1(sm, data, id);
 	case GPSK_3:
-		return eap_gpsk_build_gpsk_3(sm, data, id, reqDataLen);
+		return eap_gpsk_build_gpsk_3(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown state %d in buildReq",
 			   data->state);
@@ -237,14 +220,13 @@
 
 
 static Boolean eap_gpsk_check(struct eap_sm *sm, void *priv,
-			      u8 *respData, size_t respDataLen)
+			      struct wpabuf *respData)
 {
 	struct eap_gpsk_data *data = priv;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
 	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-GPSK: Invalid frame");
 		return TRUE;
@@ -267,7 +249,6 @@
 
 static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
 				    struct eap_gpsk_data *data,
-				    u8 *respData, size_t respDataLen,
 				    const u8 *payload, size_t payloadlen)
 {
 	const u8 *pos, *end;
@@ -483,7 +464,6 @@
 
 static void eap_gpsk_process_gpsk_4(struct eap_sm *sm,
 				    struct eap_gpsk_data *data,
-				    u8 *respData, size_t respDataLen,
 				    const u8 *payload, size_t payloadlen)
 {
 	const u8 *pos, *end;
@@ -549,25 +529,22 @@
 
 
 static void eap_gpsk_process(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_gpsk_data *data = priv;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
 	if (pos == NULL || len < 1)
 		return;
 
 	switch (*pos) {
 	case EAP_GPSK_OPCODE_GPSK_2:
-		eap_gpsk_process_gpsk_2(sm, data, respData, respDataLen,
-					pos + 1, len - 1);
+		eap_gpsk_process_gpsk_2(sm, data, pos + 1, len - 1);
 		break;
 	case EAP_GPSK_OPCODE_GPSK_4:
-		eap_gpsk_process_gpsk_4(sm, data, respData, respDataLen,
-					pos + 1, len - 1);
+		eap_gpsk_process_gpsk_4(sm, data, pos + 1, len - 1);
 		break;
 	}
 }

Modified: wpasupplicant/trunk/src/eap_server/eap_gtc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_gtc.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_gtc.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_gtc.c Tue Dec 25 15:23:24 2007
@@ -53,20 +53,18 @@
 }
 
 
-static u8 * eap_gtc_buildReq(struct eap_sm *sm, void *priv, int id,
-			     size_t *reqDataLen)
-{
-	struct eap_gtc_data *data = priv;
-	struct eap_hdr *req;
-	u8 *pos;
+static struct wpabuf * eap_gtc_buildReq(struct eap_sm *sm, void *priv, u8 id)
+{
+	struct eap_gtc_data *data = priv;
+	struct wpabuf *req;
 	char *msg;
 	size_t msg_len;
 
 	msg = data->prefix ? "CHALLENGE=Password" : "Password";
 
 	msg_len = os_strlen(msg);
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqDataLen,
-			    msg_len, EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, msg_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-GTC: Failed to allocate memory for "
 			   "request");
@@ -74,22 +72,21 @@
 		return NULL;
 	}
 
-	os_memcpy(pos, msg, msg_len);
+	wpabuf_put_data(req, msg, msg_len);
 
 	data->state = CONTINUE;
 
-	return (u8 *) req;
+	return req;
 }
 
 
 static Boolean eap_gtc_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &len);
 	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-GTC: Invalid frame");
 		return TRUE;
@@ -100,14 +97,13 @@
 
 
 static void eap_gtc_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
+			    struct wpabuf *respData)
 {
 	struct eap_gtc_data *data = priv;
 	const u8 *pos;
 	size_t rlen;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
-			       respData, respDataLen, &rlen);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &rlen);
 	if (pos == NULL || rlen < 1)
 		return; /* Should not happen - frame already validated */
 

Modified: wpasupplicant/trunk/src/eap_server/eap_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_i.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_i.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap_i.h Tue Dec 25 15:23:24 2007
@@ -15,6 +15,7 @@
 #ifndef EAP_I_H
 #define EAP_I_H
 
+#include "wpabuf.h"
 #include "eap_server/eap.h"
 #include "eap_common/eap_common.h"
 
@@ -35,13 +36,12 @@
 	void * (*initPickUp)(struct eap_sm *sm);
 	void (*reset)(struct eap_sm *sm, void *priv);
 
-	u8 * (*buildReq)(struct eap_sm *sm, void *priv, int id,
-			 size_t *reqDataLen);
+	struct wpabuf * (*buildReq)(struct eap_sm *sm, void *priv, u8 id);
 	int (*getTimeout)(struct eap_sm *sm, void *priv);
 	Boolean (*check)(struct eap_sm *sm, void *priv,
-			 u8 *respData, size_t respDataLen);
+			 struct wpabuf *respData);
 	void (*process)(struct eap_sm *sm, void *priv,
-			u8 *respData, size_t respDataLen);
+			struct wpabuf *respData);
 	Boolean (*isDone)(struct eap_sm *sm, void *priv);
 	u8 * (*getKey)(struct eap_sm *sm, void *priv, size_t *len);
 	/* isSuccess is not specified in draft-ietf-eap-statemachine-05.txt,
@@ -126,8 +126,7 @@
 		METHOD_PROPOSED, METHOD_CONTINUE, METHOD_END
 	} methodState;
 	int retransCount;
-	u8 *lastReqData;
-	size_t lastReqDataLen;
+	struct wpabuf *lastReqData;
 	int methodTimeout;
 
 	/* Short-term (not maintained between packets) */
@@ -172,10 +171,11 @@
 
 	u8 *pac_opaque_encr_key;
 	char *eap_fast_a_id;
+	int eap_sim_aka_result_ind;
 };
 
 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
 		 int phase2);
-void eap_sm_process_nak(struct eap_sm *sm, u8 *nak_list, size_t len);
+void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len);
 
 #endif /* EAP_I_H */

Modified: wpasupplicant/trunk/src/eap_server/eap_identity.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_identity.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_identity.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_identity.c Tue Dec 25 15:23:24 2007
@@ -55,12 +55,11 @@
 }
 
 
-static u8 * eap_identity_buildReq(struct eap_sm *sm, void *priv, int id,
-				  size_t *reqDataLen)
+static struct wpabuf * eap_identity_buildReq(struct eap_sm *sm, void *priv,
+					     u8 id)
 {
 	struct eap_identity_data *data = priv;
-	struct eap_hdr *req;
-	u8 *pos;
+	struct wpabuf *req;
 	const char *req_data;
 	size_t req_data_len;
 
@@ -71,8 +70,8 @@
 		req_data = NULL;
 		req_data_len = 0;
 	}
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, reqDataLen,
-			    req_data_len, EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY, req_data_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-Identity: Failed to allocate "
 			   "memory for request");
@@ -80,21 +79,20 @@
 		return NULL;
 	}
 
-	if (req_data)
-		os_memcpy(pos, req_data, req_data_len);
+	wpabuf_put_data(req, req_data, req_data_len);
 
-	return (u8 *) req;
+	return req;
 }
 
 
 static Boolean eap_identity_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+				  struct wpabuf *respData)
 {
 	const u8 *pos;
 	size_t len;
 
 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
-			       respData, respDataLen, &len);
+			       respData, &len);
 	if (pos == NULL) {
 		wpa_printf(MSG_INFO, "EAP-Identity: Invalid frame");
 		return TRUE;
@@ -105,14 +103,14 @@
 
 
 static void eap_identity_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
+				 struct wpabuf *respData)
 {
 	struct eap_identity_data *data = priv;
 	const u8 *pos;
 	size_t len;
 
 	if (data->pick_up) {
-		if (eap_identity_check(sm, data, respData, respDataLen)) {
+		if (eap_identity_check(sm, data, respData)) {
 			wpa_printf(MSG_DEBUG, "EAP-Identity: failed to pick "
 				   "up already started negotiation");
 			data->state = FAILURE;
@@ -122,7 +120,7 @@
 	}
 
 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_IDENTITY,
-			       respData, respDataLen, &len);
+			       respData, &len);
 	if (pos == NULL)
 		return; /* Should not happen - frame already validated */
 

Modified: wpasupplicant/trunk/src/eap_server/eap_md5.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_md5.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_md5.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_md5.c Tue Dec 25 15:23:24 2007
@@ -1,6 +1,6 @@
 /*
  * hostapd / EAP-MD5 server
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * 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
@@ -16,8 +16,7 @@
 
 #include "common.h"
 #include "eap_i.h"
-#include "md5.h"
-#include "crypto.h"
+#include "eap_common/chap.h"
 
 
 #define CHALLENGE_LEN 16
@@ -48,12 +47,10 @@
 }
 
 
-static u8 * eap_md5_buildReq(struct eap_sm *sm, void *priv, int id,
-			     size_t *reqDataLen)
+static struct wpabuf * eap_md5_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_md5_data *data = priv;
-	struct eap_hdr *req;
-	u8 *pos;
+	struct wpabuf *req;
 
 	if (os_get_random(data->challenge, CHALLENGE_LEN)) {
 		wpa_printf(MSG_ERROR, "EAP-MD5: Failed to get random data");
@@ -61,8 +58,8 @@
 		return NULL;
 	}
 
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, reqDataLen,
-			    1 + CHALLENGE_LEN, EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MD5, 1 + CHALLENGE_LEN,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-MD5: Failed to allocate memory for "
 			   "request");
@@ -70,29 +67,29 @@
 		return NULL;
 	}
 
-	*pos++ = CHALLENGE_LEN;
-	os_memcpy(pos, data->challenge, CHALLENGE_LEN);
-	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", pos, CHALLENGE_LEN);
+	wpabuf_put_u8(req, CHALLENGE_LEN);
+	wpabuf_put_data(req, data->challenge, CHALLENGE_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Challenge", data->challenge,
+		    CHALLENGE_LEN);
 
 	data->state = CONTINUE;
 
-	return (u8 *) req;
+	return req;
 }
 
 
 static Boolean eap_md5_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, respData, &len);
 	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-MD5: Invalid frame");
 		return TRUE;
 	}
-	if (*pos != MD5_MAC_LEN || 1 + MD5_MAC_LEN > len) {
+	if (*pos != CHAP_MD5_LEN || 1 + CHAP_MD5_LEN > len) {
 		wpa_printf(MSG_INFO, "EAP-MD5: Invalid response "
 			   "(response_len=%d payload_len=%lu",
 			   *pos, (unsigned long) len);
@@ -104,14 +101,12 @@
 
 
 static void eap_md5_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
+			    struct wpabuf *respData)
 {
 	struct eap_md5_data *data = priv;
-	struct eap_hdr *resp;
 	const u8 *pos;
-	const u8 *addr[3];
-	size_t len[3], plen;
-	u8 hash[MD5_MAC_LEN];
+	size_t plen;
+	u8 hash[CHAP_MD5_LEN], id;
 
 	if (sm->user == NULL || sm->user->password == NULL ||
 	    sm->user->password_hash) {
@@ -121,24 +116,18 @@
 		return;
 	}
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5,
-			       respData, respDataLen, &plen);
-	if (pos == NULL || *pos != MD5_MAC_LEN || plen < 1 + MD5_MAC_LEN)
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MD5, respData, &plen);
+	if (pos == NULL || *pos != CHAP_MD5_LEN || plen < 1 + CHAP_MD5_LEN)
 		return; /* Should not happen - frame already validated */
 
 	pos++; /* Skip response len */
-	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", pos, MD5_MAC_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-MD5: Response", pos, CHAP_MD5_LEN);
 
-	resp = (struct eap_hdr *) respData;
-	addr[0] = &resp->identifier;
-	len[0] = 1;
-	addr[1] = sm->user->password;
-	len[1] = sm->user->password_len;
-	addr[2] = data->challenge;
-	len[2] = CHALLENGE_LEN;
-	md5_vector(3, addr, len, hash);
+	id = eap_get_id(respData);
+	chap_md5(id, sm->user->password, sm->user->password_len,
+		 data->challenge, CHALLENGE_LEN, hash);
 
-	if (os_memcmp(hash, pos, MD5_MAC_LEN) == 0) {
+	if (os_memcmp(hash, pos, CHAP_MD5_LEN) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-MD5: Done - Success");
 		data->state = SUCCESS;
 	} else {

Modified: wpasupplicant/trunk/src/eap_server/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_mschapv2.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_mschapv2.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_mschapv2.c Tue Dec 25 15:23:24 2007
@@ -100,13 +100,11 @@
 }
 
 
-static u8 * eap_mschapv2_build_challenge(struct eap_sm *sm,
-					 struct eap_mschapv2_data *data,
-					 int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
+static struct wpabuf * eap_mschapv2_build_challenge(
+	struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id)
+{
+	struct wpabuf *req;
 	struct eap_mschapv2_hdr *ms;
-	u8 *pos;
 	char *name = "hostapd"; /* TODO: make this configurable */
 	size_t ms_len;
 
@@ -119,8 +117,8 @@
 	}
 
 	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);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory"
 			   " for request");
@@ -128,38 +126,37 @@
 		return NULL;
 	}
 
-	ms = (struct eap_mschapv2_hdr *) pos;
+	ms = wpabuf_put(req, sizeof(*ms));
 	ms->op_code = MSCHAPV2_OP_CHALLENGE;
 	ms->mschapv2_id = id;
 	WPA_PUT_BE16(ms->ms_length, ms_len);
 
-	pos = (u8 *) (ms + 1);
-	*pos++ = CHALLENGE_LEN;
+	wpabuf_put_u8(req, CHALLENGE_LEN);
 	if (!data->auth_challenge_from_tls)
-		os_memcpy(pos, data->auth_challenge, CHALLENGE_LEN);
-	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge", pos,
-		    CHALLENGE_LEN);
-	pos += CHALLENGE_LEN;
-	os_memcpy(pos, name, os_strlen(name));
-
-	return (u8 *) req;
-}
-
-
-static u8 * eap_mschapv2_build_success_req(struct eap_sm *sm,
-					   struct eap_mschapv2_data *data,
-					   int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
+		wpabuf_put_data(req, data->auth_challenge, CHALLENGE_LEN);
+	else
+		wpabuf_put(req, CHALLENGE_LEN);
+	wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge",
+		    data->auth_challenge, CHALLENGE_LEN);
+	wpabuf_put_data(req, name, os_strlen(name));
+
+	return req;
+}
+
+
+static struct wpabuf * eap_mschapv2_build_success_req(
+	struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id)
+{
+	struct wpabuf *req;
 	struct eap_mschapv2_hdr *ms;
-	u8 *pos, *msg;
+	u8 *msg;
 	char *message = "OK";
 	size_t ms_len;
 
 	ms_len = sizeof(*ms) + 2 + 2 * sizeof(data->auth_response) + 1 + 2 +
 		os_strlen(message);
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, reqDataLen,
-			    ms_len, EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory"
 			   " for request");
@@ -167,44 +164,42 @@
 		return NULL;
 	}
 
-	ms = (struct eap_mschapv2_hdr *) pos;
+	ms = wpabuf_put(req, sizeof(*ms));
 	ms->op_code = MSCHAPV2_OP_SUCCESS;
 	ms->mschapv2_id = data->resp_mschapv2_id;
 	WPA_PUT_BE16(ms->ms_length, ms_len);
-
-	msg = pos = (u8 *) (ms + 1);
-	*pos++ = 'S';
-	*pos++ = '=';
-	pos += wpa_snprintf_hex_uppercase((char *) pos,
-					  sizeof(data->auth_response) * 2 + 1,
-					  data->auth_response,
-					  sizeof(data->auth_response));
-	*pos++ = ' ';
-	*pos++ = 'M';
-	*pos++ = '=';
-	os_memcpy(pos, message, os_strlen(message));
+	msg = (u8 *) (ms + 1);
+
+	wpabuf_put_u8(req, 'S');
+	wpabuf_put_u8(req, '=');
+	wpa_snprintf_hex_uppercase(
+		wpabuf_put(req, sizeof(data->auth_response) * 2),
+		sizeof(data->auth_response) * 2 + 1,
+		data->auth_response, sizeof(data->auth_response));
+	wpabuf_put_u8(req, ' ');
+	wpabuf_put_u8(req, 'M');
+	wpabuf_put_u8(req, '=');
+	wpabuf_put_data(req, message, os_strlen(message));
 
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Success Request Message",
 			  msg, ms_len - sizeof(*ms));
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_mschapv2_build_failure_req(struct eap_sm *sm,
-					   struct eap_mschapv2_data *data,
-					   int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
+	return req;
+}
+
+
+static struct wpabuf * eap_mschapv2_build_failure_req(
+	struct eap_sm *sm, struct eap_mschapv2_data *data, u8 id)
+{
+	struct wpabuf *req;
 	struct eap_mschapv2_hdr *ms;
-	u8 *pos;
 	char *message = "E=691 R=0 C=00000000000000000000000000000000 V=3 "
 		"M=FAILED";
 	size_t ms_len;
 
 	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);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, ms_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to allocate memory"
 			   " for request");
@@ -212,34 +207,32 @@
 		return NULL;
 	}
 
-	ms = (struct eap_mschapv2_hdr *) pos;
+	ms = wpabuf_put(req, sizeof(*ms));
 	ms->op_code = MSCHAPV2_OP_FAILURE;
 	ms->mschapv2_id = data->resp_mschapv2_id;
 	WPA_PUT_BE16(ms->ms_length, ms_len);
 
-	os_memcpy((u8 *) (ms + 1), message, os_strlen(message));
+	wpabuf_put_data(req, message, os_strlen(message));
 
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Failure Request Message",
 			  (u8 *) message, os_strlen(message));
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_mschapv2_buildReq(struct eap_sm *sm, void *priv, int id,
-				  size_t *reqDataLen)
+	return req;
+}
+
+
+static struct wpabuf * eap_mschapv2_buildReq(struct eap_sm *sm, void *priv,
+					     u8 id)
 {
 	struct eap_mschapv2_data *data = priv;
 
 	switch (data->state) {
 	case CHALLENGE:
-		return eap_mschapv2_build_challenge(sm, data, id, reqDataLen);
+		return eap_mschapv2_build_challenge(sm, data, id);
 	case SUCCESS_REQ:
-		return eap_mschapv2_build_success_req(sm, data, id,
-						      reqDataLen);
+		return eap_mschapv2_build_success_req(sm, data, id);
 	case FAILURE_REQ:
-		return eap_mschapv2_build_failure_req(sm, data, id,
-						      reqDataLen);
+		return eap_mschapv2_build_failure_req(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Unknown state %d in "
 			   "buildReq", data->state);
@@ -250,15 +243,15 @@
 
 
 static Boolean eap_mschapv2_check(struct eap_sm *sm, void *priv,
-				  u8 *respData, size_t respDataLen)
+				  struct wpabuf *respData)
 {
 	struct eap_mschapv2_data *data = priv;
 	struct eap_mschapv2_hdr *resp;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
+			       &len);
 	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-MSCHAPV2: Invalid frame");
 		return TRUE;
@@ -293,7 +286,7 @@
 
 static void eap_mschapv2_process_response(struct eap_sm *sm,
 					  struct eap_mschapv2_data *data,
-					  u8 *respData, size_t respDataLen)
+					  struct wpabuf *respData)
 {
 	struct eap_mschapv2_hdr *resp;
 	const u8 *pos, *end, *peer_challenge, *nt_response, *name;
@@ -303,8 +296,8 @@
 	const u8 *username, *user;
 	size_t username_len, user_len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
+			       &len);
 	if (pos == NULL || len < 1)
 		return; /* Should not happen - frame already validated */
 
@@ -315,8 +308,8 @@
 	if (len < sizeof(*resp) + 1 + 49 ||
 	    resp->op_code != MSCHAPV2_OP_RESPONSE ||
 	    pos[0] != 49) {
-		wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: Invalid response",
-			    respData, respDataLen);
+		wpa_hexdump_buf(MSG_DEBUG, "EAP-MSCHAPV2: Invalid response",
+				respData);
 		data->state = FAILURE;
 		return;
 	}
@@ -438,14 +431,14 @@
 
 static void eap_mschapv2_process_success_resp(struct eap_sm *sm,
 					      struct eap_mschapv2_data *data,
-					      u8 *respData, size_t respDataLen)
+					      struct wpabuf *respData)
 {
 	struct eap_mschapv2_hdr *resp;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
+			       &len);
 	if (pos == NULL || len < 1)
 		return; /* Should not happen - frame already validated */
 
@@ -465,14 +458,14 @@
 
 static void eap_mschapv2_process_failure_resp(struct eap_sm *sm,
 					      struct eap_mschapv2_data *data,
-					      u8 *respData, size_t respDataLen)
+					      struct wpabuf *respData)
 {
 	struct eap_mschapv2_hdr *resp;
 	const u8 *pos;
 	size_t len;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
+			       &len);
 	if (pos == NULL || len < 1)
 		return; /* Should not happen - frame already validated */
 
@@ -491,7 +484,7 @@
 
 
 static void eap_mschapv2_process(struct eap_sm *sm, void *priv,
-				 u8 *respData, size_t respDataLen)
+				 struct wpabuf *respData)
 {
 	struct eap_mschapv2_data *data = priv;
 
@@ -503,15 +496,13 @@
 
 	switch (data->state) {
 	case CHALLENGE:
-		eap_mschapv2_process_response(sm, data, respData, respDataLen);
+		eap_mschapv2_process_response(sm, data, respData);
 		break;
 	case SUCCESS_REQ:
-		eap_mschapv2_process_success_resp(sm, data, respData,
-						  respDataLen);
+		eap_mschapv2_process_success_resp(sm, data, respData);
 		break;
 	case FAILURE_REQ:
-		eap_mschapv2_process_failure_resp(sm, data, respData,
-						  respDataLen);
+		eap_mschapv2_process_failure_resp(sm, data, respData);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Unknown state %d in "

Modified: wpasupplicant/trunk/src/eap_server/eap_pax.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_pax.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_pax.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_pax.c Tue Dec 25 15:23:24 2007
@@ -73,11 +73,11 @@
 }
 
 
-static u8 * eap_pax_build_std_1(struct eap_sm *sm,
-				struct eap_pax_data *data,
-				int id, size_t *reqDataLen)
-{
-	struct eap_pax_hdr *req;
+static struct wpabuf * eap_pax_build_std_1(struct eap_sm *sm,
+					   struct eap_pax_data *data, u8 id)
+{
+	struct wpabuf *req;
+	struct eap_pax_hdr *pax;
 	u8 *pos;
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-1 (sending)");
@@ -88,8 +88,9 @@
 		return NULL;
 	}
 
-	*reqDataLen = sizeof(*req) + 2 + EAP_PAX_RAND_LEN + EAP_PAX_ICV_LEN;
-	req = os_malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PAX,
+			    sizeof(*pax) + 2 + EAP_PAX_RAND_LEN +
+			    EAP_PAX_ICV_LEN, EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory "
 			   "request");
@@ -97,44 +98,40 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	req->type = EAP_TYPE_PAX;
-	req->op_code = EAP_PAX_OP_STD_1;
-	req->flags = 0;
-	req->mac_id = data->mac_id;
-	req->dh_group_id = EAP_PAX_DH_GROUP_NONE;
-	req->public_key_id = EAP_PAX_PUBLIC_KEY_NONE;
-	pos = (u8 *) (req + 1);
-	*pos++ = 0;
-	*pos++ = EAP_PAX_RAND_LEN;
-	os_memcpy(pos, data->rand.r.x, EAP_PAX_RAND_LEN);
+	pax = wpabuf_put(req, sizeof(*pax));
+	pax->op_code = EAP_PAX_OP_STD_1;
+	pax->flags = 0;
+	pax->mac_id = data->mac_id;
+	pax->dh_group_id = EAP_PAX_DH_GROUP_NONE;
+	pax->public_key_id = EAP_PAX_PUBLIC_KEY_NONE;
+
+	wpabuf_put_be16(req, EAP_PAX_RAND_LEN);
+	wpabuf_put_data(req, 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;
-
+		    data->rand.r.x, EAP_PAX_RAND_LEN);
+
+	pos = wpabuf_put(req, EAP_PAX_MAC_LEN);
 	eap_pax_mac(data->mac_id, (u8 *) "", 0,
-		    (u8 *) req, *reqDataLen - EAP_PAX_ICV_LEN,
+		    wpabuf_mhead(req), wpabuf_len(req) - EAP_PAX_ICV_LEN,
 		    NULL, 0, NULL, 0, pos);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN);
-	pos += EAP_PAX_ICV_LEN;
-
-	return (u8 *) req;
-}
-
-
-static u8 * eap_pax_build_std_3(struct eap_sm *sm,
-				struct eap_pax_data *data,
-				int id, size_t *reqDataLen)
-{
-	struct eap_pax_hdr *req;
+
+	return req;
+}
+
+
+static struct wpabuf * eap_pax_build_std_3(struct eap_sm *sm,
+					   struct eap_pax_data *data, u8 id)
+{
+	struct wpabuf *req;
+	struct eap_pax_hdr *pax;
 	u8 *pos;
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: PAX_STD-3 (sending)");
 
-	*reqDataLen = sizeof(*req) + 2 + EAP_PAX_MAC_LEN + EAP_PAX_ICV_LEN;
-	req = os_malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PAX,
+			    sizeof(*pax) + 2 + EAP_PAX_MAC_LEN +
+			    EAP_PAX_ICV_LEN, EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PAX: Failed to allocate memory "
 			   "request");
@@ -142,18 +139,15 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	req->type = EAP_TYPE_PAX;
-	req->op_code = EAP_PAX_OP_STD_3;
-	req->flags = 0;
-	req->mac_id = data->mac_id;
-	req->dh_group_id = EAP_PAX_DH_GROUP_NONE;
-	req->public_key_id = EAP_PAX_PUBLIC_KEY_NONE;
-	pos = (u8 *) (req + 1);
-	*pos++ = 0;
-	*pos++ = EAP_PAX_MAC_LEN;
+	pax = wpabuf_put(req, sizeof(*pax));
+	pax->op_code = EAP_PAX_OP_STD_3;
+	pax->flags = 0;
+	pax->mac_id = data->mac_id;
+	pax->dh_group_id = EAP_PAX_DH_GROUP_NONE;
+	pax->public_key_id = EAP_PAX_PUBLIC_KEY_NONE;
+
+	wpabuf_put_be16(req, EAP_PAX_MAC_LEN);
+	pos = wpabuf_put(req, EAP_PAX_MAC_LEN);
 	eap_pax_mac(data->mac_id, data->ck, EAP_PAX_CK_LEN,
 		    data->rand.r.y, EAP_PAX_RAND_LEN,
 		    (u8 *) data->cid, data->cid_len, NULL, 0, pos);
@@ -163,26 +157,25 @@
 
 	/* Optional ADE could be added here, if needed */
 
+	pos = wpabuf_put(req, EAP_PAX_MAC_LEN);
 	eap_pax_mac(data->mac_id, data->ick, EAP_PAX_ICK_LEN,
-		    (u8 *) req, *reqDataLen - EAP_PAX_ICV_LEN,
+		    wpabuf_mhead(req), wpabuf_len(req) - EAP_PAX_ICV_LEN,
 		    NULL, 0, NULL, 0, pos);
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", pos, EAP_PAX_ICV_LEN);
-	pos += EAP_PAX_ICV_LEN;
-
-	return (u8 *) req;
-}
-
-
-static u8 * eap_pax_buildReq(struct eap_sm *sm, void *priv, int id,
-				  size_t *reqDataLen)
+
+	return req;
+}
+
+
+static struct wpabuf * eap_pax_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_pax_data *data = priv;
 
 	switch (data->state) {
 	case PAX_STD_1:
-		return eap_pax_build_std_1(sm, data, id, reqDataLen);
+		return eap_pax_build_std_1(sm, data, id);
 	case PAX_STD_3:
-		return eap_pax_build_std_3(sm, data, id, reqDataLen);
+		return eap_pax_build_std_3(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-PAX: Unknown state %d in buildReq",
 			   data->state);
@@ -193,20 +186,22 @@
 
 
 static Boolean eap_pax_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_pax_data *data = priv;
 	struct eap_pax_hdr *resp;
-	size_t len;
+	const u8 *pos;
+	size_t len, mlen;
 	u8 icvbuf[EAP_PAX_ICV_LEN], *icv;
 
-	resp = (struct eap_pax_hdr *) respData;
-	if (respDataLen < sizeof(*resp) || resp->type != EAP_TYPE_PAX ||
-	    (len = be_to_host16(resp->length)) > respDataLen ||
-	    len < sizeof(*resp) + EAP_PAX_ICV_LEN) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX, respData, &len);
+	if (pos == NULL || len < sizeof(*resp)) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Invalid frame");
 		return TRUE;
 	}
+
+	mlen = sizeof(struct eap_hdr) + 1 + len;
+	resp = (struct eap_pax_hdr *) pos;
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: received frame: op_code 0x%x "
 		   "flags 0x%x mac_id 0x%x dh_group_id 0x%x "
@@ -272,11 +267,12 @@
 			wpa_printf(MSG_INFO, "EAP-PAX: No ICV in the packet");
 			return TRUE;
 		}
-		icv = respData + len - EAP_PAX_ICV_LEN;
+		icv = wpabuf_mhead_u8(respData) + mlen - EAP_PAX_ICV_LEN;
 		wpa_hexdump(MSG_MSGDUMP, "EAP-PAX: ICV", icv, 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);
+			    wpabuf_mhead(respData),
+			    wpabuf_len(respData) - EAP_PAX_ICV_LEN,
+			    NULL, 0, NULL, 0, icvbuf);
 		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",
@@ -291,10 +287,11 @@
 
 static void eap_pax_process_std_2(struct eap_sm *sm,
 				  struct eap_pax_data *data,
-				  u8 *respData, size_t respDataLen)
+				  struct wpabuf *respData)
 {
 	struct eap_pax_hdr *resp;
-	u8 *pos, mac[EAP_PAX_MAC_LEN], icvbuf[EAP_PAX_ICV_LEN];
+	u8 mac[EAP_PAX_MAC_LEN], icvbuf[EAP_PAX_ICV_LEN];
+	const u8 *pos;
 	size_t len, left;
 	int i;
 
@@ -303,8 +300,11 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-PAX: Received PAX_STD-2");
 
-	resp = (struct eap_pax_hdr *) respData;
-	len = be_to_host16(resp->length);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX, respData, &len);
+	if (pos == NULL || len < sizeof(*resp) + EAP_PAX_ICV_LEN)
+		return;
+
+	resp = (struct eap_pax_hdr *) pos;
 	pos = (u8 *) (resp + 1);
 	left = len - sizeof(*resp);
 
@@ -419,7 +419,9 @@
 	}
 	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);
+		    wpabuf_head(respData),
+		    wpabuf_len(respData) - EAP_PAX_ICV_LEN, NULL, 0, NULL, 0,
+		    icvbuf);
 	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",
@@ -440,7 +442,7 @@
 
 static void eap_pax_process_ack(struct eap_sm *sm,
 				struct eap_pax_data *data,
-				u8 *respData, size_t respDataLen)
+				struct wpabuf *respData)
 {
 	if (data->state != PAX_STD_3)
 		return;
@@ -452,10 +454,12 @@
 
 
 static void eap_pax_process(struct eap_sm *sm, void *priv,
-				 u8 *respData, size_t respDataLen)
+			    struct wpabuf *respData)
 {
 	struct eap_pax_data *data = priv;
 	struct eap_pax_hdr *resp;
+	const u8 *pos;
+	size_t len;
 
 	if (sm->user == NULL || sm->user->password == NULL) {
 		wpa_printf(MSG_INFO, "EAP-PAX: Plaintext password not "
@@ -464,14 +468,18 @@
 		return;
 	}
 
-	resp = (struct eap_pax_hdr *) respData;
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PAX, respData, &len);
+	if (pos == NULL || len < sizeof(*resp))
+		return;
+
+	resp = (struct eap_pax_hdr *) pos;
 
 	switch (resp->op_code) {
 	case EAP_PAX_OP_STD_2:
-		eap_pax_process_std_2(sm, data, respData, respDataLen);
+		eap_pax_process_std_2(sm, data, respData);
 		break;
 	case EAP_PAX_OP_ACK:
-		eap_pax_process_ack(sm, data, respData, respDataLen);
+		eap_pax_process_ack(sm, data, respData);
 		break;
 	}
 }

Modified: wpasupplicant/trunk/src/eap_server/eap_peap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_peap.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_peap.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_peap.c Tue Dec 25 15:23:24 2007
@@ -163,14 +163,13 @@
 }
 
 
-static u8 * eap_peap_build_start(struct eap_sm *sm, struct eap_peap_data *data,
-				 int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
-	u8 *pos;
-
-	*reqDataLen = sizeof(*req) + 2;
-	req = os_malloc(*reqDataLen);
+static struct wpabuf * eap_peap_build_start(struct eap_sm *sm,
+					    struct eap_peap_data *data, u8 id)
+{
+	struct wpabuf *req;
+
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PEAP, 1,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PEAP: Failed to allocate memory for"
 			   " request");
@@ -178,28 +177,22 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_PEAP;
-	*pos = EAP_TLS_FLAGS_START | data->peap_version;
+	wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->peap_version);
 
 	eap_peap_state(data, PHASE1);
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_peap_build_req(struct eap_sm *sm, struct eap_peap_data *data,
-			       int id, size_t *reqDataLen)
+	return req;
+}
+
+
+static struct wpabuf * eap_peap_build_req(struct eap_sm *sm,
+					  struct eap_peap_data *data, u8 id)
 {
 	int res;
-	u8 *req;
+	struct wpabuf *req;
 
 	res = eap_server_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_PEAP,
-					     data->peap_version, id, &req,
-					     reqDataLen);
+					     data->peap_version, id, &req);
 
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase1 done, starting "
@@ -208,61 +201,61 @@
 	}
 
 	if (res == 1)
-		return eap_server_tls_build_ack(reqDataLen, id, EAP_TYPE_PEAP,
+		return eap_server_tls_build_ack(id, EAP_TYPE_PEAP,
 						data->peap_version);
 	return req;
 }
 
 
-static u8 * eap_peap_encrypt(struct eap_sm *sm, struct eap_peap_data *data,
-			     int id, u8 *plain, size_t plain_len,
-			     size_t *out_len)
+static struct wpabuf * eap_peap_encrypt(struct eap_sm *sm,
+					struct eap_peap_data *data,
+					u8 id, const u8 *plain,
+					size_t plain_len)
 {
 	int res;
-	u8 *pos;
-	struct eap_hdr *req;
+	struct wpabuf *buf;
 
 	/* TODO: add support for fragmentation, if needed. This will need to
 	 * add TLS Message Length field, if the frame is fragmented. */
-	req = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
-	if (req == NULL)
-		return NULL;
-
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_PEAP;
-	*pos++ = data->peap_version;
+	buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PEAP,
+			    1 + data->ssl.tls_out_limit,
+			    EAP_CODE_REQUEST, id);
+	if (buf == NULL)
+		return NULL;
+
+	wpabuf_put_u8(buf, data->peap_version);
 
 	res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
-				     plain, plain_len,
-				     pos, data->ssl.tls_out_limit);
+				     plain, plain_len, wpabuf_put(buf, 0),
+				     data->ssl.tls_out_limit);
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt Phase 2 "
 			   "data");
-		os_free(req);
-		return NULL;
-	}
-
-	*out_len = sizeof(struct eap_hdr) + 2 + res;
-	req->length = host_to_be16(*out_len);
-	return (u8 *) req;
-}
-
-
-static u8 * eap_peap_build_phase2_req(struct eap_sm *sm,
-				      struct eap_peap_data *data,
-				      int id, size_t *reqDataLen)
-{
-	u8 *req, *buf, *encr_req;
+		wpabuf_free(buf);
+		return NULL;
+	}
+
+	wpabuf_put(buf, res);
+	eap_update_len(buf);
+
+	return buf;
+}
+
+
+static struct wpabuf * eap_peap_build_phase2_req(struct eap_sm *sm,
+						 struct eap_peap_data *data,
+						 u8 id)
+{
+	struct wpabuf *buf, *encr_req;
+	const u8 *req;
 	size_t req_len;
 
-	buf = req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
-						  &req_len);
-	if (req == NULL)
-		return NULL;
-
+	buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
+	if (buf == NULL)
+		return NULL;
+
+	req = wpabuf_head(buf);
+	req_len = wpabuf_len(buf);
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
 			req, req_len);
 
@@ -272,18 +265,18 @@
 		req_len -= sizeof(struct eap_hdr);
 	}
 
-	encr_req = eap_peap_encrypt(sm, data, id, req, req_len, reqDataLen);
-	os_free(buf);
+	encr_req = eap_peap_encrypt(sm, data, id, req, req_len);
+	wpabuf_free(buf);
 
 	return encr_req;
 }
 
 
-static u8 * eap_peap_build_phase2_term(struct eap_sm *sm,
-				       struct eap_peap_data *data,
-				       int id, size_t *reqDataLen, int success)
-{
-	u8 *encr_req;
+static struct wpabuf * eap_peap_build_phase2_term(struct eap_sm *sm,
+						  struct eap_peap_data *data,
+						  u8 id, int success)
+{
+	struct wpabuf *encr_req;
 	size_t req_len;
 	struct eap_hdr *hdr;
 
@@ -299,32 +292,30 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Encrypting Phase 2 data",
 			(u8 *) hdr, req_len);
 
-	encr_req = eap_peap_encrypt(sm, data, id, (u8 *) hdr, req_len,
-				    reqDataLen);
+	encr_req = eap_peap_encrypt(sm, data, id, (u8 *) hdr, req_len);
 	os_free(hdr);
 
 	return encr_req;
 }
 
 
-static u8 * eap_peap_buildReq(struct eap_sm *sm, void *priv, int id,
-			      size_t *reqDataLen)
+static struct wpabuf * eap_peap_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_peap_data *data = priv;
 
 	switch (data->state) {
 	case START:
-		return eap_peap_build_start(sm, data, id, reqDataLen);
+		return eap_peap_build_start(sm, data, id);
 	case PHASE1:
-		return eap_peap_build_req(sm, data, id, reqDataLen);
+		return eap_peap_build_req(sm, data, id);
 	case PHASE2_ID:
 	case PHASE2_METHOD:
 	case PHASE2_TLV:
-		return eap_peap_build_phase2_req(sm, data, id, reqDataLen);
+		return eap_peap_build_phase2_req(sm, data, id);
 	case SUCCESS_REQ:
-		return eap_peap_build_phase2_term(sm, data, id, reqDataLen, 1);
+		return eap_peap_build_phase2_term(sm, data, id, 1);
 	case FAILURE_REQ:
-		return eap_peap_build_phase2_term(sm, data, id, reqDataLen, 0);
+		return eap_peap_build_phase2_term(sm, data, id, 0);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-PEAP: %s - unexpected state %d",
 			   __func__, data->state);
@@ -334,15 +325,13 @@
 
 
 static Boolean eap_peap_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) + 2 || *pos != EAP_TYPE_PEAP ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+			      struct wpabuf *respData)
+{
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PEAP, respData, &len);
+	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: Invalid frame");
 		return TRUE;
 	}
@@ -373,11 +362,11 @@
 
 static void eap_peap_process_phase2_response(struct eap_sm *sm,
 					     struct eap_peap_data *data,
-					     u8 *in_data, size_t in_len)
+					     struct wpabuf *in_data)
 {
 	u8 next_type = EAP_TYPE_NONE;
-	struct eap_hdr *hdr;
-	u8 *pos;
+	const struct eap_hdr *hdr;
+	const u8 *pos;
 	size_t left;
 
 	if (data->phase2_priv == NULL) {
@@ -386,11 +375,11 @@
 		return;
 	}
 
-	hdr = (struct eap_hdr *) in_data;
-	pos = (u8 *) (hdr + 1);
-
-	if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
-		left = in_len - sizeof(*hdr);
+	hdr = wpabuf_head(in_data);
+	pos = (const u8 *) (hdr + 1);
+
+	if (wpabuf_len(in_data) > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
+		left = wpabuf_len(in_data) - sizeof(*hdr);
 		wpa_hexdump(MSG_DEBUG, "EAP-PEAP: Phase2 type Nak'ed; "
 			    "allowed types", pos + 1, left - 1);
 		eap_sm_process_nak(sm, pos + 1, left - 1);
@@ -408,14 +397,13 @@
 		return;
 	}
 
-	if (data->phase2_method->check(sm, data->phase2_priv, in_data,
-				       in_len)) {
+	if (data->phase2_method->check(sm, data->phase2_priv, in_data)) {
 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 check() asked to "
 			   "ignore the packet");
 		return;
 	}
 
-	data->phase2_method->process(sm, data->phase2_priv, in_data, in_len);
+	data->phase2_method->process(sm, data->phase2_priv, in_data);
 
 	if (!data->phase2_method->isDone(sm, data->phase2_priv))
 		return;
@@ -469,18 +457,19 @@
 
 static void eap_peap_process_phase2(struct eap_sm *sm,
 				    struct eap_peap_data *data,
-				    struct eap_hdr *resp,
-				    u8 *in_data, size_t in_len)
-{
-	u8 *in_decrypted;
-	int len_decrypted, len, res;
-	struct eap_hdr *hdr;
-	size_t buf_len;
+				    const struct wpabuf *respData,
+				    const u8 *in_data, size_t in_len)
+{
+	struct wpabuf *in_decrypted;
+	int len_decrypted, res;
+	const struct eap_hdr *hdr;
+	size_t buf_len, len;
 
 	wpa_printf(MSG_DEBUG, "EAP-PEAP: received %lu bytes encrypted data for"
 		   " Phase 2", (unsigned long) in_len);
 
-	res = eap_server_tls_data_reassemble(sm, &data->ssl, &in_data,
+	/* FIX: get rid of const -> non-const typecast */
+	res = eap_server_tls_data_reassemble(sm, &data->ssl, (u8 **) &in_data,
 					     &in_len);
 	if (res < 0 || res == 1)
 		return;
@@ -488,7 +477,7 @@
 	buf_len = in_len;
 	if (data->ssl.tls_in_total > buf_len)
 		buf_len = data->ssl.tls_in_total;
-	in_decrypted = os_malloc(buf_len);
+	in_decrypted = wpabuf_alloc(buf_len);
 	if (in_decrypted == NULL) {
 		os_free(data->ssl.tls_in);
 		data->ssl.tls_in = NULL;
@@ -500,54 +489,61 @@
 
 	len_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
 					       in_data, in_len,
-					       in_decrypted, buf_len);
+					       wpabuf_mhead(in_decrypted),
+					       buf_len);
 	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");
-		os_free(in_decrypted);
+		wpabuf_free(in_decrypted);
 		eap_peap_state(data, FAILURE);
 		return;
 	}
-
-	wpa_hexdump_key(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
-			in_decrypted, len_decrypted);
-
-	hdr = (struct eap_hdr *) in_decrypted;
+	wpabuf_put(in_decrypted, len_decrypted);
+
+	wpa_hexdump_buf_key(MSG_DEBUG, "EAP-PEAP: Decrypted Phase 2 EAP",
+			    in_decrypted);
+
+	hdr = wpabuf_head(in_decrypted);
 
 	if (data->peap_version == 0 && data->state != PHASE2_TLV) {
-		struct eap_hdr *nhdr = os_malloc(sizeof(struct eap_hdr) +
-						 len_decrypted);
-		if (nhdr == NULL) {
-			os_free(in_decrypted);
+		const struct eap_hdr *resp;
+		struct eap_hdr *nhdr;
+		struct wpabuf *nbuf =
+			wpabuf_alloc(sizeof(struct eap_hdr) +
+				     wpabuf_len(in_decrypted));
+		if (nbuf == NULL) {
+			wpabuf_free(in_decrypted);
 			return;
 		}
-		os_memcpy((u8 *) (nhdr + 1), in_decrypted, len_decrypted);
-		os_free(in_decrypted);
+
+		resp = wpabuf_head(respData);
+		nhdr = wpabuf_put(nbuf, sizeof(*nhdr));
 		nhdr->code = resp->code;
 		nhdr->identifier = resp->identifier;
 		nhdr->length = host_to_be16(sizeof(struct eap_hdr) +
-					    len_decrypted);
-
-		len_decrypted += sizeof(struct eap_hdr);
-		in_decrypted = (u8 *) nhdr;
-	}
-	hdr = (struct eap_hdr *) in_decrypted;
-	if (len_decrypted < (int) sizeof(*hdr)) {
-		os_free(in_decrypted);
+					    wpabuf_len(in_decrypted));
+		wpabuf_put_buf(nbuf, in_decrypted);
+		wpabuf_free(in_decrypted);
+
+		in_decrypted = nbuf;
+	}
+	hdr = wpabuf_head(in_decrypted);
+	if (wpabuf_len(in_decrypted) < (int) sizeof(*hdr)) {
+		wpabuf_free(in_decrypted);
 		wpa_printf(MSG_INFO, "EAP-PEAP: Too short Phase 2 "
-			   "EAP frame (len=%d)", len_decrypted);
+			   "EAP frame (len=%d)", wpabuf_len(in_decrypted));
 		eap_peap_req_failure(sm, data);
 		return;
 	}
 	len = be_to_host16(hdr->length);
-	if (len > len_decrypted) {
-		os_free(in_decrypted);
+	if (len > wpabuf_len(in_decrypted)) {
+		wpabuf_free(in_decrypted);
 		wpa_printf(MSG_INFO, "EAP-PEAP: Length mismatch in "
 			   "Phase 2 EAP frame (len=%d hdr->length=%d)",
-			   len_decrypted, len);
+			   wpabuf_len(in_decrypted), len);
 		eap_peap_req_failure(sm, data);
 		return;
 	}
@@ -555,7 +551,7 @@
 		   "identifier=%d length=%d", hdr->code, hdr->identifier, len);
 	switch (hdr->code) {
 	case EAP_CODE_RESPONSE:
-		eap_peap_process_phase2_response(sm, data, (u8 *) hdr, len);
+		eap_peap_process_phase2_response(sm, data, in_decrypted);
 		break;
 	case EAP_CODE_SUCCESS:
 		wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 Success");
@@ -574,26 +570,28 @@
 	}
 
 	os_free(in_decrypted);
- }
+}
 
 
 static void eap_peap_process(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_peap_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, flags;
-	int left;
+	const u8 *pos;
+	u8 flags;
+	size_t left;
 	unsigned int tls_msg_len;
 	int peer_version;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	pos++;
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PEAP, respData,
+			       &left);
+	if (pos == NULL || left < 1)
+		return;
 	flags = *pos++;
-	left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 2;
+	left--;
 	wpa_printf(MSG_DEBUG, "EAP-PEAP: Received packet(len=%lu) - "
-		   "Flags 0x%02x", (unsigned long) respDataLen, flags);
+		   "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
+		   flags);
 	peer_version = flags & EAP_PEAP_VERSION_MASK;
 	if (data->force_version >= 0 && peer_version != data->force_version) {
 		wpa_printf(MSG_INFO, "EAP-PEAP: peer did not select the forced"
@@ -645,7 +643,7 @@
 	case PHASE2_ID:
 	case PHASE2_METHOD:
 	case PHASE2_TLV:
-		eap_peap_process_phase2(sm, data, resp, pos, left);
+		eap_peap_process_phase2(sm, data, respData, pos, left);
 		break;
 	case SUCCESS_REQ:
 		eap_peap_state(data, SUCCESS);

Modified: wpasupplicant/trunk/src/eap_server/eap_psk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_psk.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_psk.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_psk.c Tue Dec 25 15:23:24 2007
@@ -58,10 +58,11 @@
 }
 
 
-static u8 * eap_psk_build_1(struct eap_sm *sm, struct eap_psk_data *data,
-			    int id, size_t *reqDataLen)
-{
-	struct eap_psk_hdr_1 *req;
+static struct wpabuf * eap_psk_build_1(struct eap_sm *sm,
+				       struct eap_psk_data *data, u8 id)
+{
+	struct wpabuf *req;
+	struct eap_psk_hdr_1 *psk;
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-1 (sending)");
 
@@ -73,8 +74,9 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_S (server rand)",
 		    data->rand_s, EAP_PSK_RAND_LEN);
 
-	*reqDataLen = sizeof(*req) + data->id_s_len;
-	req = os_malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
+			    sizeof(*psk) + data->id_s_len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
 			   "request");
@@ -82,29 +84,27 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	req->type = EAP_TYPE_PSK;
-	req->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */
-	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;
-}
-
-
-static u8 * eap_psk_build_3(struct eap_sm *sm, struct eap_psk_data *data,
-			    int id, size_t *reqDataLen)
-{
-	struct eap_psk_hdr_3 *req;
+	psk = wpabuf_put(req, sizeof(*psk));
+	psk->flags = EAP_PSK_FLAGS_SET_T(0); /* T=0 */
+	os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
+	wpabuf_put_data(req, data->id_s, data->id_s_len);
+
+	return req;
+}
+
+
+static struct wpabuf * eap_psk_build_3(struct eap_sm *sm,
+				       struct eap_psk_data *data, u8 id)
+{
+	struct wpabuf *req;
+	struct eap_psk_hdr_3 *psk;
 	u8 *buf, *pchannel, nonce[16];
 	size_t buflen;
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-3 (sending)");
 
-	*reqDataLen = sizeof(*req) + 4 + 16 + 1;
-	req = os_malloc(*reqDataLen);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
+			    sizeof(*psk) + 4 + 16 + 1, EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory "
 			   "request");
@@ -112,24 +112,21 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	req->type = EAP_TYPE_PSK;
-	req->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */
-	os_memcpy(req->rand_s, data->rand_s, EAP_PSK_RAND_LEN);
+	psk = wpabuf_put(req, sizeof(*psk));
+	psk->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */
+	os_memcpy(psk->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 = os_malloc(buflen);
 	if (buf == NULL) {
-		os_free(req);
+		wpabuf_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);
+	omac1_aes_128(data->ak, buf, buflen, psk->mac_s);
 	os_free(buf);
 
 	eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk,
@@ -139,31 +136,31 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN);
 
 	os_memset(nonce, 0, sizeof(nonce));
-	pchannel = (u8 *) (req + 1);
+	pchannel = wpabuf_put(req, 4 + 16 + 1);
 	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);
-	aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), (u8 *) req, 22,
+	aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce),
+			    wpabuf_head(req), 22,
 			    pchannel + 4 + 16, 1, pchannel + 4);
 	wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (encrypted)",
 		    pchannel, 4 + 16 + 1);
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_psk_buildReq(struct eap_sm *sm, void *priv, int id,
-				  size_t *reqDataLen)
+	return req;
+}
+
+
+static struct wpabuf * eap_psk_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_psk_data *data = priv;
 
 	switch (data->state) {
 	case PSK_1:
-		return eap_psk_build_1(sm, data, id, reqDataLen);
+		return eap_psk_build_1(sm, data, id);
 	case PSK_3:
-		return eap_psk_build_3(sm, data, id, reqDataLen);
+		return eap_psk_build_3(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-PSK: Unknown state %d in buildReq",
 			   data->state);
@@ -174,21 +171,19 @@
 
 
 static Boolean eap_psk_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
-{
-	struct eap_psk_data *data = priv;
-	struct eap_psk_hdr *resp;
+			     struct wpabuf *respData)
+{
+	struct eap_psk_data *data = priv;
 	size_t len;
 	u8 t;
-
-	resp = (struct eap_psk_hdr *) respData;
-	if (respDataLen < sizeof(*resp) || resp->type != EAP_TYPE_PSK ||
-	    (len = ntohs(resp->length)) > respDataLen ||
-	    len < sizeof(*resp)) {
+	const u8 *pos;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &len);
+	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame");
 		return TRUE;
 	}
-	t = EAP_PSK_FLAGS_GET_T(resp->flags);
+	t = EAP_PSK_FLAGS_GET_T(*pos);
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: received frame: T=%d", t);
 
@@ -216,22 +211,28 @@
 
 static void eap_psk_process_2(struct eap_sm *sm,
 			      struct eap_psk_data *data,
-			      u8 *respData, size_t respDataLen)
-{
-	struct eap_psk_hdr_2 *resp;
+			      struct wpabuf *respData)
+{
+	const struct eap_psk_hdr_2 *resp;
 	u8 *pos, mac[EAP_PSK_MAC_LEN], *buf;
-	size_t len, left, buflen;
+	size_t left, buflen;
 	int i;
+	const u8 *cpos;
 
 	if (data->state != PSK_1)
 		return;
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-2");
 
-	resp = (struct eap_psk_hdr_2 *) respData;
-	len = be_to_host16(resp->length);
-	pos = (u8 *) (resp + 1);
-	left = len - sizeof(*resp);
+	cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData,
+				&left);
+	if (cpos == NULL || left < sizeof(*resp)) {
+		wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame");
+		return;
+	}
+	resp = (const struct eap_psk_hdr_2 *) cpos;
+	cpos = (const u8 *) (resp + 1);
+	left -= sizeof(*resp);
 
 	os_free(data->id_p);
 	data->id_p = os_malloc(left);
@@ -240,7 +241,7 @@
 			   "ID_P");
 		return;
 	}
-	os_memcpy(data->id_p, pos, left);
+	os_memcpy(data->id_p, cpos, left);
 	data->id_p_len = left;
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P",
 			  data->id_p, data->id_p_len);
@@ -319,20 +320,26 @@
 
 static void eap_psk_process_4(struct eap_sm *sm,
 			      struct eap_psk_data *data,
-			      u8 *respData, size_t respDataLen)
-{
-	struct eap_psk_hdr_4 *resp;
-	u8 *pos, *decrypted, nonce[16], *tag;
+			      struct wpabuf *respData)
+{
+	const struct eap_psk_hdr_4 *resp;
+	u8 *decrypted, nonce[16];
 	size_t left;
+	const u8 *pos, *tag;
 
 	if (data->state != PSK_3)
 		return;
 
 	wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-4");
 
-	resp = (struct eap_psk_hdr_4 *) respData;
-	pos = (u8 *) (resp + 1);
-	left = be_to_host16(resp->length) - sizeof(*resp);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &left);
+	if (pos == NULL || left < sizeof(*resp)) {
+		wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame");
+		return;
+	}
+	resp = (const struct eap_psk_hdr_4 *) pos;
+	pos = (const u8 *) (resp + 1);
+	left -= sizeof(*resp);
 
 	wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Encrypted PCHANNEL", pos, left);
 
@@ -362,7 +369,8 @@
 	os_memcpy(decrypted, pos, left);
 
 	if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
-				respData, 22, decrypted, left, tag)) {
+				wpabuf_head(respData), 22, decrypted, left,
+				tag)) {
 		wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
 		os_free(decrypted);
 		data->state = FAILURE;
@@ -391,10 +399,11 @@
 
 
 static void eap_psk_process(struct eap_sm *sm, void *priv,
-				 u8 *respData, size_t respDataLen)
-{
-	struct eap_psk_data *data = priv;
-	struct eap_psk_hdr *resp;
+			    struct wpabuf *respData)
+{
+	struct eap_psk_data *data = priv;
+	const u8 *pos;
+	size_t len;
 
 	if (sm->user == NULL || sm->user->password == NULL) {
 		wpa_printf(MSG_INFO, "EAP-PSK: Plaintext password not "
@@ -403,14 +412,16 @@
 		return;
 	}
 
-	resp = (struct eap_psk_hdr *) respData;
-
-	switch (EAP_PSK_FLAGS_GET_T(resp->flags)) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &len);
+	if (pos == NULL || len < 1)
+		return;
+
+	switch (EAP_PSK_FLAGS_GET_T(*pos)) {
 	case 1:
-		eap_psk_process_2(sm, data, respData, respDataLen);
+		eap_psk_process_2(sm, data, respData);
 		break;
 	case 3:
-		eap_psk_process_4(sm, data, respData, respDataLen);
+		eap_psk_process_4(sm, data, respData);
 		break;
 	}
 }

Modified: wpasupplicant/trunk/src/eap_server/eap_sake.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_sake.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_sake.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_sake.c Tue Dec 25 15:23:24 2007
@@ -100,75 +100,69 @@
 }
 
 
-static u8 * eap_sake_build_msg(struct eap_sake_data *data, u8 **payload,
-			       int id, size_t *length, u8 subtype)
-{
-	struct eap_sake_hdr *req;
-	u8 *msg;
-
-	*length += sizeof(struct eap_sake_hdr);
-
-	msg = os_zalloc(*length);
+static struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data,
+					  u8 id, size_t length, u8 subtype)
+{
+	struct eap_sake_hdr *sake;
+	struct wpabuf *msg;
+	size_t plen;
+
+	plen = sizeof(struct eap_sake_hdr) + length;
+
+	msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_SAKE, plen,
+			    EAP_CODE_REQUEST, id);
 	if (msg == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to allocate memory "
 			   "request");
 		return NULL;
 	}
 
-	req = (struct eap_sake_hdr *) msg;
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16((u16) *length);
-	req->type = EAP_TYPE_SAKE;
-	req->version = EAP_SAKE_VERSION;
-	req->session_id = data->session_id;
-	req->subtype = subtype;
-	*payload = (u8 *) (req + 1);
+	sake = wpabuf_put(msg, sizeof(*sake));
+	sake->version = EAP_SAKE_VERSION;
+	sake->session_id = data->session_id;
+	sake->subtype = subtype;
 
 	return msg;
 }
 
 
-static u8 * eap_sake_build_identity(struct eap_sm *sm,
-				    struct eap_sake_data *data,
-				    int id, size_t *reqDataLen)
-{
-	u8 *msg, *pos;
+static struct wpabuf * eap_sake_build_identity(struct eap_sm *sm,
+					       struct eap_sake_data *data,
+					       u8 id)
+{
+	struct wpabuf *msg;
+	size_t plen;
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Identity");
 
-	*reqDataLen = 4;
+	plen = 4;
 	if (data->serverid)
-		*reqDataLen += 2 + data->serverid_len;
-	msg = eap_sake_build_msg(data, &pos, id, reqDataLen,
-				 EAP_SAKE_SUBTYPE_IDENTITY);
+		plen += 2 + data->serverid_len;
+	msg = eap_sake_build_msg(data, id, plen, EAP_SAKE_SUBTYPE_IDENTITY);
 	if (msg == NULL) {
 		data->state = FAILURE;
 		return NULL;
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PERM_ID_REQ");
-	*pos++ = EAP_SAKE_AT_PERM_ID_REQ;
-	*pos++ = 4;
-	*pos++ = 0;
-	*pos++ = 0;
+	eap_sake_add_attr(msg, EAP_SAKE_AT_PERM_ID_REQ, NULL, 2);
 
 	if (data->serverid) {
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_SERVERID");
-		*pos++ = EAP_SAKE_AT_SERVERID;
-		*pos++ = 2 + data->serverid_len;
-		os_memcpy(pos, data->serverid, data->serverid_len);
+		eap_sake_add_attr(msg, EAP_SAKE_AT_SERVERID,
+				  data->serverid, data->serverid_len);
 	}
 
 	return msg;
 }
 
 
-static u8 * eap_sake_build_challenge(struct eap_sm *sm,
-				     struct eap_sake_data *data,
-				     int id, size_t *reqDataLen)
-{
-	u8 *msg, *pos;
+static struct wpabuf * eap_sake_build_challenge(struct eap_sm *sm,
+						struct eap_sake_data *data,
+						u8 id)
+{
+	struct wpabuf *msg;
+	size_t plen;
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge");
 
@@ -180,43 +174,39 @@
 	wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)",
 		    data->rand_s, EAP_SAKE_RAND_LEN);
 
-	*reqDataLen = 2 + EAP_SAKE_RAND_LEN;
+	plen = 2 + EAP_SAKE_RAND_LEN;
 	if (data->serverid)
-		*reqDataLen += 2 + data->serverid_len;
-	msg = eap_sake_build_msg(data, &pos, id, reqDataLen,
-				 EAP_SAKE_SUBTYPE_CHALLENGE);
+		plen += 2 + data->serverid_len;
+	msg = eap_sake_build_msg(data, id, plen, EAP_SAKE_SUBTYPE_CHALLENGE);
 	if (msg == NULL) {
 		data->state = FAILURE;
 		return NULL;
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_S");
-	*pos++ = EAP_SAKE_AT_RAND_S;
-	*pos++ = 2 + EAP_SAKE_RAND_LEN;
-	os_memcpy(pos, data->rand_s, EAP_SAKE_RAND_LEN);
-	pos += EAP_SAKE_RAND_LEN;
+	eap_sake_add_attr(msg, EAP_SAKE_AT_RAND_S,
+			  data->rand_s, EAP_SAKE_RAND_LEN);
 
 	if (data->serverid) {
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_SERVERID");
-		*pos++ = EAP_SAKE_AT_SERVERID;
-		*pos++ = 2 + data->serverid_len;
-		os_memcpy(pos, data->serverid, data->serverid_len);
+		eap_sake_add_attr(msg, EAP_SAKE_AT_SERVERID,
+				  data->serverid, data->serverid_len);
 	}
 
 	return msg;
 }
 
 
-static u8 * eap_sake_build_confirm(struct eap_sm *sm,
-				   struct eap_sake_data *data,
-				   int id, size_t *reqDataLen)
-{
-	u8 *msg, *pos;
+static struct wpabuf * eap_sake_build_confirm(struct eap_sm *sm,
+					      struct eap_sake_data *data,
+					      u8 id)
+{
+	struct wpabuf *msg;
+	u8 *mic;
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Confirm");
 
-	*reqDataLen = 2 + EAP_SAKE_MIC_LEN;
-	msg = eap_sake_build_msg(data, &pos, id, reqDataLen,
+	msg = eap_sake_build_msg(data, id, 2 + EAP_SAKE_MIC_LEN,
 				 EAP_SAKE_SUBTYPE_CONFIRM);
 	if (msg == NULL) {
 		data->state = FAILURE;
@@ -224,12 +214,14 @@
 	}
 
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_S");
-	*pos++ = EAP_SAKE_AT_MIC_S;
-	*pos++ = 2 + EAP_SAKE_MIC_LEN;
+	wpabuf_put_u8(msg, EAP_SAKE_AT_MIC_S);
+	wpabuf_put_u8(msg, 2 + EAP_SAKE_MIC_LEN);
+	mic = wpabuf_put(msg, EAP_SAKE_MIC_LEN);
 	if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
 				 data->serverid, data->serverid_len,
 				 data->peerid, data->peerid_len, 0,
-				 msg, *reqDataLen, pos, pos)) {
+				 wpabuf_head(msg), wpabuf_len(msg), mic, mic))
+	{
 		wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC");
 		data->state = FAILURE;
 		os_free(msg);
@@ -240,18 +232,17 @@
 }
 
 
-static u8 * eap_sake_buildReq(struct eap_sm *sm, void *priv, int id,
-			      size_t *reqDataLen)
+static struct wpabuf * eap_sake_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_sake_data *data = priv;
 
 	switch (data->state) {
 	case IDENTITY:
-		return eap_sake_build_identity(sm, data, id, reqDataLen);
+		return eap_sake_build_identity(sm, data, id);
 	case CHALLENGE:
-		return eap_sake_build_challenge(sm, data, id, reqDataLen);
+		return eap_sake_build_challenge(sm, data, id);
 	case CONFIRM:
-		return eap_sake_build_confirm(sm, data, id, reqDataLen);
+		return eap_sake_build_confirm(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-SAKE: Unknown state %d in buildReq",
 			   data->state);
@@ -262,21 +253,21 @@
 
 
 static Boolean eap_sake_check(struct eap_sm *sm, void *priv,
-			      u8 *respData, size_t respDataLen)
+			      struct wpabuf *respData)
 {
 	struct eap_sake_data *data = priv;
 	struct eap_sake_hdr *resp;
 	size_t len;
 	u8 version, session_id, subtype;
-
-	resp = (struct eap_sake_hdr *) respData;
-	if (respDataLen < sizeof(*resp) ||
-	    resp->type != EAP_TYPE_SAKE ||
-	    (len = be_to_host16(resp->length)) > respDataLen ||
-	    len < sizeof(*resp)) {
+	const u8 *pos;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, respData, &len);
+	if (pos == NULL || len < sizeof(struct eap_sake_hdr)) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Invalid frame");
 		return TRUE;
 	}
+
+	resp = (struct eap_sake_hdr *) pos;
 	version = resp->version;
 	session_id = resp->session_id;
 	subtype = resp->subtype;
@@ -315,8 +306,8 @@
 
 static void eap_sake_process_identity(struct eap_sm *sm,
 				      struct eap_sake_data *data,
-				      u8 *respData, size_t respDataLen,
-				      u8 *payload, size_t payloadlen)
+				      const struct wpabuf *respData,
+				      const u8 *payload, size_t payloadlen)
 {
 	if (data->state != IDENTITY)
 		return;
@@ -329,8 +320,8 @@
 
 static void eap_sake_process_challenge(struct eap_sm *sm,
 				       struct eap_sake_data *data,
-				       u8 *respData, size_t respDataLen,
-				       u8 *payload, size_t payloadlen)
+				       const struct wpabuf *respData,
+				       const u8 *payload, size_t payloadlen)
 {
 	struct eap_sake_parse_attr attr;
 	u8 mic_p[EAP_SAKE_MIC_LEN];
@@ -378,7 +369,8 @@
 	eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
 			     data->serverid, data->serverid_len,
 			     data->peerid, data->peerid_len, 1,
-			     respData, respDataLen, attr.mic_p, mic_p);
+			     wpabuf_head(respData), wpabuf_len(respData),
+			     attr.mic_p, mic_p);
 	if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P");
 		eap_sake_state(data, FAILURE);
@@ -391,8 +383,8 @@
 
 static void eap_sake_process_confirm(struct eap_sm *sm,
 				     struct eap_sake_data *data,
-				     u8 *respData, size_t respDataLen,
-				     u8 *payload, size_t payloadlen)
+				     const struct wpabuf *respData,
+				     const u8 *payload, size_t payloadlen)
 {
 	struct eap_sake_parse_attr attr;
 	u8 mic_p[EAP_SAKE_MIC_LEN];
@@ -414,7 +406,8 @@
 	eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
 			     data->serverid, data->serverid_len,
 			     data->peerid, data->peerid_len, 1,
-			     respData, respDataLen, attr.mic_p, mic_p);
+			     wpabuf_head(respData), wpabuf_len(respData),
+			     attr.mic_p, mic_p);
 	if (os_memcmp(attr.mic_p, mic_p, EAP_SAKE_MIC_LEN) != 0) {
 		wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_P");
 		eap_sake_state(data, FAILURE);
@@ -425,8 +418,8 @@
 
 static void eap_sake_process_auth_reject(struct eap_sm *sm,
 					 struct eap_sake_data *data,
-					 u8 *respData, size_t respDataLen,
-					 u8 *payload, size_t payloadlen)
+					 const struct wpabuf *respData,
+					 const u8 *payload, size_t payloadlen)
 {
 	wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Response/Auth-Reject");
 	eap_sake_state(data, FAILURE);
@@ -434,36 +427,39 @@
 
 
 static void eap_sake_process(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_sake_data *data = priv;
 	struct eap_sake_hdr *resp;
-	u8 subtype, *pos, *end;
-
-	resp = (struct eap_sake_hdr *) respData;
+	u8 subtype;
+	size_t len;
+	const u8 *pos, *end;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, respData, &len);
+	if (pos == NULL || len < sizeof(struct eap_sake_hdr))
+		return;
+
+	resp = (struct eap_sake_hdr *) pos;
+	end = pos + len;
 	subtype = resp->subtype;
 	pos = (u8 *) (resp + 1);
-	end = respData + be_to_host16(resp->length);
 
 	wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Received attributes",
 		    pos, end - pos);
 
 	switch (subtype) {
 	case EAP_SAKE_SUBTYPE_IDENTITY:
-		eap_sake_process_identity(sm, data, respData, respDataLen, pos,
-					  end - pos);
+		eap_sake_process_identity(sm, data, respData, pos, end - pos);
 		break;
 	case EAP_SAKE_SUBTYPE_CHALLENGE:
-		eap_sake_process_challenge(sm, data, respData, respDataLen,
-					   pos, end - pos);
+		eap_sake_process_challenge(sm, data, respData, pos, end - pos);
 		break;
 	case EAP_SAKE_SUBTYPE_CONFIRM:
-		eap_sake_process_confirm(sm, data, respData, respDataLen, pos,
-					 end - pos);
+		eap_sake_process_confirm(sm, data, respData, pos, end - pos);
 		break;
 	case EAP_SAKE_SUBTYPE_AUTH_REJECT:
-		eap_sake_process_auth_reject(sm, data, respData, respDataLen,
-					     pos, end - pos);
+		eap_sake_process_auth_reject(sm, data, respData, pos,
+					     end - pos);
 		break;
 	}
 }

Modified: wpasupplicant/trunk/src/eap_server/eap_sim.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_sim.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_sim.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_sim.c Tue Dec 25 15:23:24 2007
@@ -32,11 +32,15 @@
 	u8 sres[EAP_SIM_MAX_CHAL][EAP_SIM_SRES_LEN];
 	u8 rand[EAP_SIM_MAX_CHAL][GSM_RAND_LEN];
 	int num_chal;
-	enum { START, CHALLENGE, REAUTH, SUCCESS, FAILURE } state;
+	enum {
+		START, CHALLENGE, REAUTH, NOTIFICATION, SUCCESS, FAILURE
+	} state;
 	char *next_pseudonym;
 	char *next_reauth_id;
 	u16 counter;
 	struct eap_sim_reauth *reauth;
+	u16 notification;
+	int use_result_ind;
 };
 
 
@@ -53,6 +57,8 @@
 		return "SUCCESS";
 	case FAILURE:
 		return "FAILURE";
+	case NOTIFICATION:
+		return "NOTIFICATION";
 	default:
 		return "Unknown?!";
 	}
@@ -95,8 +101,8 @@
 }
 
 
-static u8 * eap_sim_build_start(struct eap_sm *sm, struct eap_sim_data *data,
-				int id, size_t *reqDataLen)
+static struct wpabuf * eap_sim_build_start(struct eap_sm *sm,
+					   struct eap_sim_data *data, u8 id)
 {
 	struct eap_sim_msg *msg;
 	u8 ver[2];
@@ -114,7 +120,7 @@
 	ver[1] = EAP_SIM_VERSION;
 	eap_sim_msg_add(msg, EAP_SIM_AT_VERSION_LIST, sizeof(ver),
 			ver, sizeof(ver));
-	return eap_sim_msg_finish(msg, reqDataLen, NULL, NULL, 0);
+	return eap_sim_msg_finish(msg, NULL, NULL, 0);
 }
 
 
@@ -182,9 +188,9 @@
 }
 
 
-static u8 * eap_sim_build_challenge(struct eap_sm *sm,
-				    struct eap_sim_data *data,
-				    int id, size_t *reqDataLen)
+static struct wpabuf * eap_sim_build_challenge(struct eap_sm *sm,
+					       struct eap_sim_data *data,
+					       u8 id)
 {
 	struct eap_sim_msg *msg;
 
@@ -200,16 +206,20 @@
 		return NULL;
 	}
 
+	if (sm->eap_sim_aka_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
+
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, reqDataLen, data->k_aut, data->nonce_mt,
+	return eap_sim_msg_finish(msg, data->k_aut, data->nonce_mt,
 				  EAP_SIM_NONCE_MT_LEN);
 }
 
 
-static u8 * eap_sim_build_reauth(struct eap_sm *sm,
-				 struct eap_sim_data *data,
-				 int id, size_t *reqDataLen)
+static struct wpabuf * eap_sim_build_reauth(struct eap_sm *sm,
+					    struct eap_sim_data *data, u8 id)
 {
 	struct eap_sim_msg *msg;
 
@@ -234,24 +244,66 @@
 		return NULL;
 	}
 
+	if (sm->eap_sim_aka_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_RESULT_IND");
+		eap_sim_msg_add(msg, EAP_SIM_AT_RESULT_IND, 0, NULL, 0);
+	}
+
 	wpa_printf(MSG_DEBUG, "   AT_MAC");
 	eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
-	return eap_sim_msg_finish(msg, reqDataLen, data->k_aut, NULL, 0);
-}
-
-
-static u8 * eap_sim_buildReq(struct eap_sm *sm, void *priv, int id,
-			     size_t *reqDataLen)
+	return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
+}
+
+
+static struct wpabuf * eap_sim_build_notification(struct eap_sm *sm,
+						  struct eap_sim_data *data,
+						  u8 id)
+{
+	struct eap_sim_msg *msg;
+
+	wpa_printf(MSG_DEBUG, "EAP-SIM: Generating Notification");
+	msg = eap_sim_msg_init(EAP_CODE_REQUEST, id, EAP_TYPE_SIM,
+			       EAP_SIM_SUBTYPE_NOTIFICATION);
+	wpa_printf(MSG_DEBUG, "   AT_NOTIFICATION");
+	eap_sim_msg_add(msg, EAP_SIM_AT_NOTIFICATION, data->notification,
+			NULL, 0);
+	if (data->use_result_ind) {
+		wpa_printf(MSG_DEBUG, "   AT_IV");
+		wpa_printf(MSG_DEBUG, "   AT_ENCR_DATA");
+		eap_sim_msg_add_encr_start(msg, EAP_SIM_AT_IV,
+					   EAP_SIM_AT_ENCR_DATA);
+		wpa_printf(MSG_DEBUG, "   *AT_COUNTER (%u)", data->counter);
+		eap_sim_msg_add(msg, EAP_SIM_AT_COUNTER, data->counter, NULL,
+				0);
+
+		if (eap_sim_msg_add_encr_end(msg, data->k_encr,
+					     EAP_SIM_AT_PADDING)) {
+			wpa_printf(MSG_WARNING, "EAP-SIM: Failed to encrypt "
+				   "AT_ENCR_DATA");
+			eap_sim_msg_free(msg);
+			return NULL;
+		}
+
+		wpa_printf(MSG_DEBUG, "   AT_MAC");
+		eap_sim_msg_add_mac(msg, EAP_SIM_AT_MAC);
+	}
+	return eap_sim_msg_finish(msg, data->k_aut, NULL, 0);
+}
+
+
+static struct wpabuf * eap_sim_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_sim_data *data = priv;
 
 	switch (data->state) {
 	case START:
-		return eap_sim_build_start(sm, data, id, reqDataLen);
+		return eap_sim_build_start(sm, data, id);
 	case CHALLENGE:
-		return eap_sim_build_challenge(sm, data, id, reqDataLen);
+		return eap_sim_build_challenge(sm, data, id);
 	case REAUTH:
-		return eap_sim_build_reauth(sm, data, id, reqDataLen);
+		return eap_sim_build_reauth(sm, data, id);
+	case NOTIFICATION:
+		return eap_sim_build_notification(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "
 			   "buildReq", data->state);
@@ -262,15 +314,14 @@
 
 
 static Boolean eap_sim_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_sim_data *data = priv;
 	const u8 *pos;
 	size_t len;
 	u8 subtype;
 
-	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM,
-			       respData, respDataLen, &len);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, respData, &len);
 	if (pos == NULL || len < 3) {
 		wpa_printf(MSG_INFO, "EAP-SIM: Invalid frame");
 		return TRUE;
@@ -302,6 +353,13 @@
 			return TRUE;
 		}
 		break;
+	case NOTIFICATION:
+		if (subtype != EAP_SIM_SUBTYPE_NOTIFICATION) {
+			wpa_printf(MSG_INFO, "EAP-SIM: Unexpected response "
+				   "subtype %d", subtype);
+			return TRUE;
+		}
+		break;
 	default:
 		wpa_printf(MSG_INFO, "EAP-SIM: Unexpected state (%d) for "
 			   "processing a response", data->state);
@@ -320,7 +378,7 @@
 
 static void eap_sim_process_start(struct eap_sm *sm,
 				  struct eap_sim_data *data,
-				  u8 *respData, size_t respDataLen,
+				  struct wpabuf *respData,
 				  struct eap_sim_attrs *attr)
 {
 	const u8 *identity;
@@ -433,14 +491,14 @@
 
 static void eap_sim_process_challenge(struct eap_sm *sm,
 				      struct eap_sim_data *data,
-				      u8 *respData, size_t respDataLen,
+				      struct wpabuf *respData,
 				      struct eap_sim_attrs *attr)
 {
 	const u8 *identity;
 	size_t identity_len;
 
 	if (attr->mac == NULL ||
-	    eap_sim_verify_mac(data->k_aut, respData, respDataLen, attr->mac,
+	    eap_sim_verify_mac(data->k_aut, respData, attr->mac,
 			       (u8 *) data->sres,
 			       data->num_chal * EAP_SIM_SRES_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message "
@@ -451,7 +509,12 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Challenge response includes the "
 		   "correct AT_MAC");
-	eap_sim_state(data, SUCCESS);
+	if (sm->eap_sim_aka_result_ind && attr->result_ind) {
+		data->use_result_ind = 1;
+		data->notification = EAP_SIM_SUCCESS;
+		eap_sim_state(data, NOTIFICATION);
+	} else
+		eap_sim_state(data, SUCCESS);
 
 	identity = eap_sim_db_get_permanent(sm->eap_sim_db_priv, sm->identity,
 					    sm->identity_len, &identity_len);
@@ -478,7 +541,7 @@
 
 static void eap_sim_process_reauth(struct eap_sm *sm,
 				   struct eap_sim_data *data,
-				   u8 *respData, size_t respDataLen,
+				   struct wpabuf *respData,
 				   struct eap_sim_attrs *attr)
 {
 	struct eap_sim_attrs eattr;
@@ -487,8 +550,8 @@
 	size_t identity_len, id2_len;
 
 	if (attr->mac == NULL ||
-	    eap_sim_verify_mac(data->k_aut, respData, respDataLen, attr->mac,
-			       data->nonce_s, EAP_SIM_NONCE_S_LEN)) {
+	    eap_sim_verify_mac(data->k_aut, respData, attr->mac, data->nonce_s,
+			       EAP_SIM_NONCE_S_LEN)) {
 		wpa_printf(MSG_WARNING, "EAP-SIM: Re-authentication message "
 			   "did not include valid AT_MAC");
 		goto fail;
@@ -520,7 +583,12 @@
 
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Re-authentication response includes "
 		   "the correct AT_MAC");
-	eap_sim_state(data, SUCCESS);
+	if (sm->eap_sim_aka_result_ind && attr->result_ind) {
+		data->use_result_ind = 1;
+		data->notification = EAP_SIM_SUCCESS;
+		eap_sim_state(data, NOTIFICATION);
+	} else
+		eap_sim_state(data, SUCCESS);
 
 	if (data->reauth) {
 		identity = data->reauth->identity;
@@ -564,7 +632,7 @@
 
 static void eap_sim_process_client_error(struct eap_sm *sm,
 					 struct eap_sim_data *data,
-					 u8 *respData, size_t respDataLen,
+					 struct wpabuf *respData,
 					 struct eap_sim_attrs *attr)
 {
 	wpa_printf(MSG_DEBUG, "EAP-SIM: Client reported error %d",
@@ -573,41 +641,59 @@
 }
 
 
+static void eap_sim_process_notification(struct eap_sm *sm,
+					 struct eap_sim_data *data,
+					 struct wpabuf *respData,
+					 struct eap_sim_attrs *attr)
+{
+	wpa_printf(MSG_DEBUG, "EAP-SIM: Client replied to notification");
+	if (data->notification == EAP_SIM_SUCCESS && data->use_result_ind)
+		eap_sim_state(data, SUCCESS);
+	else
+		eap_sim_state(data, FAILURE);
+}
+
+
 static void eap_sim_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
+			    struct wpabuf *respData)
 {
 	struct eap_sim_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, subtype;
+	const u8 *pos, *end;
+	u8 subtype;
 	size_t len;
 	struct eap_sim_attrs attr;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	subtype = pos[1];
-	len = be_to_host16(resp->length);
-	pos += 4;
-
-	if (eap_sim_parse_attr(pos, respData + len, &attr, 0, 0)) {
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SIM, respData, &len);
+	if (pos == NULL || len < 3)
+		return;
+
+	end = pos + len;
+	subtype = *pos;
+	pos += 3;
+
+	if (eap_sim_parse_attr(pos, end, &attr, 0, 0)) {
 		wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to parse attributes");
 		eap_sim_state(data, FAILURE);
 		return;
 	}
 
 	if (subtype == EAP_SIM_SUBTYPE_CLIENT_ERROR) {
-		eap_sim_process_client_error(sm, data, respData, len, &attr);
+		eap_sim_process_client_error(sm, data, respData, &attr);
 		return;
 	}
 
 	switch (data->state) {
 	case START:
-		eap_sim_process_start(sm, data, respData, len, &attr);
+		eap_sim_process_start(sm, data, respData, &attr);
 		break;
 	case CHALLENGE:
-		eap_sim_process_challenge(sm, data, respData, len, &attr);
+		eap_sim_process_challenge(sm, data, respData, &attr);
 		break;
 	case REAUTH:
-		eap_sim_process_reauth(sm, data, respData, len, &attr);
+		eap_sim_process_reauth(sm, data, respData, &attr);
+		break;
+	case NOTIFICATION:
+		eap_sim_process_notification(sm, data, respData, &attr);
 		break;
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-SIM: Unknown state %d in "

Modified: wpasupplicant/trunk/src/eap_server/eap_tls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_tls.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_tls.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_tls.c Tue Dec 25 15:23:24 2007
@@ -58,14 +58,13 @@
 }
 
 
-static u8 * eap_tls_build_start(struct eap_sm *sm, struct eap_tls_data *data,
-				int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
-	u8 *pos;
-
-	*reqDataLen = sizeof(*req) + 2;
-	req = os_malloc(*reqDataLen);
+static struct wpabuf * eap_tls_build_start(struct eap_sm *sm,
+					   struct eap_tls_data *data, u8 id)
+{
+	struct wpabuf *req;
+
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLS, 1, EAP_CODE_REQUEST,
+			    id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-TLS: Failed to allocate memory for "
 			   "request");
@@ -73,27 +72,22 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_TLS;
-	*pos = EAP_TLS_FLAGS_START;
+	wpabuf_put_u8(req, EAP_TLS_FLAGS_START);
 
 	data->state = CONTINUE;
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_tls_build_req(struct eap_sm *sm, struct eap_tls_data *data,
-			      int id, size_t *reqDataLen)
+	return req;
+}
+
+
+static struct wpabuf * eap_tls_build_req(struct eap_sm *sm,
+					 struct eap_tls_data *data, u8 id)
 {
 	int res;
-	u8 *req;
+	struct wpabuf *req;
 
 	res = eap_server_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TLS, 0,
-					     id, &req, reqDataLen);
+					     id, &req);
 
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 		wpa_printf(MSG_DEBUG, "EAP-TLS: Done");
@@ -101,22 +95,20 @@
 	}
 
 	if (res == 1)
-		return eap_server_tls_build_ack(reqDataLen, id, EAP_TYPE_TLS,
-						0);
+		return eap_server_tls_build_ack(id, EAP_TYPE_TLS, 0);
 	return req;
 }
 
 
-static u8 * eap_tls_buildReq(struct eap_sm *sm, void *priv, int id,
-			     size_t *reqDataLen)
+static struct wpabuf * eap_tls_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_tls_data *data = priv;
 
 	switch (data->state) {
 	case START:
-		return eap_tls_build_start(sm, data, id, reqDataLen);
+		return eap_tls_build_start(sm, data, id);
 	case CONTINUE:
-		return eap_tls_build_req(sm, data, id, reqDataLen);
+		return eap_tls_build_req(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-TLS: %s - unexpected state %d",
 			   __func__, data->state);
@@ -126,15 +118,13 @@
 
 
 static Boolean eap_tls_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) + 2 || *pos != EAP_TYPE_TLS ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+			     struct wpabuf *respData)
+{
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLS, respData, &len);
+	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-TLS: Invalid frame");
 		return TRUE;
 	}
@@ -144,21 +134,23 @@
 
 
 static void eap_tls_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
-{
-	struct eap_tls_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, flags;
-	int left;
+			    struct wpabuf *respData)
+{
+	struct eap_tls_data *data = priv;
+	const u8 *pos;
+	u8 flags;
+	size_t left;
 	unsigned int tls_msg_len;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	pos++;
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLS, respData, &left);
+	if (pos == NULL || left < 1)
+		return; /* Should not happen - frame already validated */
+
 	flags = *pos++;
-	left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 2;
+	left--;
 	wpa_printf(MSG_DEBUG, "EAP-TLS: Received packet(len=%lu) - "
-		   "Flags 0x%02x", (unsigned long) respDataLen, flags);
+		   "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
+		   flags);
 	if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) {
 		if (left < 4) {
 			wpa_printf(MSG_INFO, "EAP-TLS: Short frame with TLS "

Modified: wpasupplicant/trunk/src/eap_server/eap_tls_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_tls_common.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_tls_common.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_tls_common.c Tue Dec 25 15:23:24 2007
@@ -1,5 +1,5 @@
 /*
- * hostapd / EAP-TLS/PEAP/TTLS common functions
+ * hostapd / EAP-TLS/PEAP/TTLS/FAST common functions
  * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -112,12 +112,12 @@
 {
 	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 (*in_len == 0) {
+			wpa_printf(MSG_INFO, "SSL: Empty fragment when trying "
+				   "to reassemble");
+			return -1;
+		}
 		if (data->tls_in_len + *in_len > 65536) {
 			/* Limit length to avoid rogue peers from causing large
 			 * memory allocations. */
@@ -163,14 +163,16 @@
 
 
 int eap_server_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
-				  u8 *in_data, size_t in_len)
+				  const u8 *in_data, size_t in_len)
 {
 	WPA_ASSERT(data->tls_out_len == 0 || in_len == 0);
 
 	if (data->tls_out_len == 0) {
+		u8 *_in_data = (u8 *) in_data; /* FIX: get rid of the typecast
+						*/
 		/* No more data to send out - expect to receive more data from
 		 * the peer. */
-		int res = eap_server_tls_data_reassemble(sm, data, &in_data,
+		int res = eap_server_tls_data_reassemble(sm, data, &_in_data,
 							 &in_len);
 		if (res < 0 || res == 1) {
 			wpa_printf(MSG_DEBUG, "SSL: data reassembly failed");
@@ -187,7 +189,7 @@
 			WPA_ASSERT(data->tls_out == NULL);
 		}
 		data->tls_out = tls_connection_server_handshake(
-			sm->ssl_ctx, data->conn, in_data, in_len,
+			sm->ssl_ctx, data->conn, _in_data, in_len,
 			&data->tls_out_len);
 
 		/* Clear reassembled input data (if the buffer was needed). */
@@ -230,30 +232,27 @@
 int eap_server_tls_buildReq_helper(struct eap_sm *sm,
 				   struct eap_ssl_data *data,
 				   int eap_type, int peap_version, u8 id,
-				   u8 **out_data, size_t *out_len)
+				   struct wpabuf **out_data)
 {
 	size_t len;
-	u8 *pos, *flags;
-	struct eap_hdr *req;
-
-	*out_len = 0;
-
-	req = os_malloc(sizeof(struct eap_hdr) + 2 + 4 + data->tls_out_limit);
+	u8 *flags;
+	struct wpabuf *req;
+	int incl_len;
+
+	incl_len = data->tls_out_pos == 0 &&
+		data->tls_out_len > data->tls_out_limit;
+	req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type,
+			    1 + (incl_len ? 4 : 0) + data->tls_out_limit,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		*out_data = NULL;
 		return -1;
 	}
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	pos = (u8 *) (req + 1);
-	*pos++ = eap_type;
-	flags = pos++;
+	flags = wpabuf_put(req, 1);
 	*flags = peap_version;
-	if (data->tls_out_pos == 0 &&
-	    data->tls_out_len > data->tls_out_limit) {
+	if (incl_len) {
 		*flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED;
-		WPA_PUT_BE32(pos, data->tls_out_len);
-		pos += 4;
+		wpabuf_put_be32(req, data->tls_out_len);
 	}
 
 	len = data->tls_out_len - data->tls_out_pos;
@@ -263,11 +262,11 @@
 		wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments "
 			   "will follow", (unsigned long) len);
 	}
-	os_memcpy(pos, &data->tls_out[data->tls_out_pos], len);
+	wpabuf_put_data(req, &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);
-	*out_data = (u8 *) req;
+
+	eap_update_len(req);
+	*out_data = req;
 
 	if (!(*flags & EAP_TLS_FLAGS_MORE_FRAGMENTS)) {
 		data->tls_out_len = 0;
@@ -280,17 +279,15 @@
 }
 
 
-u8 * eap_server_tls_build_ack(size_t *reqDataLen, u8 id, int eap_type,
-			      int peap_version)
-{
-	struct eap_hdr *req;
-	u8 *pos;
-
-	req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, reqDataLen, 1,
-			    EAP_CODE_REQUEST, id, &pos);
+struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int peap_version)
+{
+	struct wpabuf *req;
+
+	req = eap_msg_alloc(EAP_VENDOR_IETF, eap_type, 1, EAP_CODE_REQUEST,
+			    id);
 	if (req == NULL)
 		return NULL;
 	wpa_printf(MSG_DEBUG, "SSL: Building ACK");
-	*pos = peap_version; /* Flags */
-	return (u8 *) req;
-}
+	wpabuf_put_u8(req, peap_version); /* Flags */
+	return req;
+}

Modified: wpasupplicant/trunk/src/eap_server/eap_tls_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_tls_common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_tls_common.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap_tls_common.h Tue Dec 25 15:23:24 2007
@@ -1,6 +1,6 @@
 /*
- * hostapd / EAP-TLS/PEAP/TTLS common functions
- * Copyright (c) 2004-2005, Jouni Malinen <j at w1.fi>
+ * hostapd / EAP-TLS/PEAP/TTLS/FAST common functions
+ * 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
@@ -52,12 +52,12 @@
 				   struct eap_ssl_data *data,
 				   u8 **in_data, size_t *in_len);
 int eap_server_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
-				  u8 *in_data, size_t in_len);
+				  const u8 *in_data, size_t in_len);
 int eap_server_tls_buildReq_helper(struct eap_sm *sm,
 				   struct eap_ssl_data *data,
 				   int eap_type, int peap_version, u8 id,
-				   u8 **out_data, size_t *out_len);
-u8 * eap_server_tls_build_ack(size_t *reqDataLen, u8 id, int eap_type,
-			      int peap_version);
+				   struct wpabuf **out_data);
+struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type,
+					 int peap_version);
 
 #endif /* EAP_TLS_COMMON_H */

Modified: wpasupplicant/trunk/src/eap_server/eap_tlv.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_tlv.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_tlv.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_tlv.c Tue Dec 25 15:23:24 2007
@@ -44,11 +44,9 @@
 }
 
 
-static u8 * eap_tlv_buildReq(struct eap_sm *sm, void *priv, int id,
-			     size_t *reqDataLen)
-{
-	struct eap_hdr *req;
-	u8 *pos;
+static struct wpabuf * eap_tlv_buildReq(struct eap_sm *sm, void *priv, u8 id)
+{
+	struct wpabuf *req;
 	u16 status;
 
 	if (sm->tlv_request == TLV_REQ_SUCCESS) {
@@ -57,33 +55,30 @@
 		status = EAP_TLV_RESULT_FAILURE;
 	}
 
-	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, reqDataLen, 6,
-			    EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TLV, 6,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL)
 		return NULL;
 
-	*pos++ = 0x80; /* Mandatory */
-	*pos++ = EAP_TLV_RESULT_TLV;
+	wpabuf_put_u8(req, 0x80); /* Mandatory */
+	wpabuf_put_u8(req, EAP_TLV_RESULT_TLV);
 	/* Length */
-	*pos++ = 0;
-	*pos++ = 2;
+	wpabuf_put_be16(req, 2);
 	/* Status */
-	WPA_PUT_BE16(pos, status);
-
-	return (u8 *) req;
+	wpabuf_put_be16(req, status);
+
+	return req;
 }
 
 
 static Boolean eap_tlv_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) + 1 || *pos != EAP_TYPE_TLV ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+			     struct wpabuf *respData)
+{
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLV, respData, &len);
+	if (pos == NULL) {
 		wpa_printf(MSG_INFO, "EAP-TLV: Invalid frame");
 		return TRUE;
 	}
@@ -93,23 +88,20 @@
 
 
 static void eap_tlv_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
-{
-	struct eap_tlv_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos;
+			    struct wpabuf *respData)
+{
+	struct eap_tlv_data *data = priv;
+	const u8 *pos;
 	size_t left;
-	u8 *result_tlv = NULL;
+	const u8 *result_tlv = NULL;
 	size_t result_tlv_len = 0;
 	int tlv_type, mandatory, tlv_len;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TLV, respData, &left);
+	if (pos == NULL)
+		return;
 
 	/* Parse TLVs */
-	left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 1;
-	pos = (u8 *) (resp + 1);
-	pos++;
 	wpa_hexdump(MSG_DEBUG, "EAP-TLV: Received TLVs", pos, left);
 	while (left >= 4) {
 		mandatory = !!(pos[0] & 0x80);

Modified: wpasupplicant/trunk/src/eap_server/eap_ttls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_ttls.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_ttls.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_ttls.c Tue Dec 25 15:23:24 2007
@@ -18,9 +18,8 @@
 #include "eap_server/eap_i.h"
 #include "eap_server/eap_tls_common.h"
 #include "ms_funcs.h"
-#include "md5.h"
 #include "sha1.h"
-#include "crypto.h"
+#include "eap_common/chap.h"
 #include "tls.h"
 #include "eap_common/eap_ttls.h"
 
@@ -116,26 +115,26 @@
 }
 
 
-static int eap_ttls_avp_encapsulate(u8 **resp, size_t *resp_len, u32 avp_code,
-				    int mandatory)
-{
-	u8 *avp, *pos;
-
-	avp = os_malloc(sizeof(struct ttls_avp) + *resp_len + 4);
+static struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp,
+						u32 avp_code, int mandatory)
+{
+	struct wpabuf *avp;
+	u8 *pos;
+
+	avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4);
 	if (avp == NULL) {
-		os_free(*resp);
-		*resp_len = 0;
-		return -1;
-	}
-
-	pos = eap_ttls_avp_hdr(avp, avp_code, 0, mandatory, *resp_len);
-	os_memcpy(pos, *resp, *resp_len);
-	pos += *resp_len;
-	AVP_PAD(avp, pos);
-	os_free(*resp);
-	*resp = avp;
-	*resp_len = pos - avp;
-	return 0;
+		wpabuf_free(resp);
+		return NULL;
+	}
+
+	pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory,
+			       wpabuf_len(resp));
+	os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp));
+	pos += wpabuf_len(resp);
+	AVP_PAD((const u8 *) wpabuf_head(avp), pos);
+	wpabuf_free(resp);
+	wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp));
+	return avp;
 }
 
 
@@ -421,14 +420,13 @@
 }
 
 
-static u8 * eap_ttls_build_start(struct eap_sm *sm, struct eap_ttls_data *data,
-				 int id, size_t *reqDataLen)
-{
-	struct eap_hdr *req;
-	u8 *pos;
-
-	*reqDataLen = sizeof(*req) + 2;
-	req = os_malloc(*reqDataLen);
+static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm,
+					    struct eap_ttls_data *data, u8 id)
+{	
+	struct wpabuf *req;
+
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
 			   " request");
@@ -436,28 +434,22 @@
 		return NULL;
 	}
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-	req->length = host_to_be16(*reqDataLen);
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_TTLS;
-	*pos = EAP_TLS_FLAGS_START | data->ttls_version;
+	wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version);
 
 	eap_ttls_state(data, PHASE1);
 
-	return (u8 *) req;
-}
-
-
-static u8 * eap_ttls_build_req(struct eap_sm *sm, struct eap_ttls_data *data,
-			       int id, size_t *reqDataLen)
+	return req;
+}
+
+
+static struct wpabuf * eap_ttls_build_req(struct eap_sm *sm,
+					  struct eap_ttls_data *data, u8 id)
 {
 	int res;
-	u8 *req;
+	struct wpabuf *req;
 
 	res = eap_server_tls_buildReq_helper(sm, &data->ssl, EAP_TYPE_TTLS,
-					     data->ttls_version, id, &req,
-					     reqDataLen);
+					     data->ttls_version, id, &req);
 
 	if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, starting "
@@ -466,87 +458,85 @@
 	}
 
 	if (res == 1)
-		return eap_server_tls_build_ack(reqDataLen, id, EAP_TYPE_TTLS,
+		return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,
 						data->ttls_version);
 	return req;
 }
 
 
-static u8 * eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data,
-			     int id, u8 *plain, size_t plain_len,
-			     size_t *out_len)
+static struct wpabuf * eap_ttls_encrypt(struct eap_sm *sm,
+					struct eap_ttls_data *data,
+					u8 id, u8 *plain, size_t plain_len)
 {
 	int res;
-	u8 *pos;
-	struct eap_hdr *req;
+	struct wpabuf *buf;
 
 	/* TODO: add support for fragmentation, if needed. This will need to
 	 * add TLS Message Length field, if the frame is fragmented. */
-	req = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit);
-	if (req == NULL)
-		return NULL;
-
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_TTLS;
-	*pos++ = data->ttls_version;
+	buf = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS,
+			    1 + data->ssl.tls_out_limit,
+			    EAP_CODE_REQUEST, id);
+	if (buf == NULL)
+		return NULL;
+
+	wpabuf_put_u8(buf, data->ttls_version);
 
 	res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn,
-				     plain, plain_len,
-				     pos, data->ssl.tls_out_limit);
+				     plain, plain_len, wpabuf_put(buf, 0),
+				     data->ssl.tls_out_limit);
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 "
 			   "data");
-		os_free(req);
-		return NULL;
-	}
-
-	*out_len = sizeof(struct eap_hdr) + 2 + res;
-	req->length = host_to_be16(*out_len);
-	return (u8 *) req;
-}
-
-
-static u8 * eap_ttls_build_phase2_eap_req(struct eap_sm *sm,
-					  struct eap_ttls_data *data,
-					  int id, size_t *reqDataLen)
-{
-	u8 *req, *encr_req;
+		wpabuf_free(buf);
+		return NULL;
+	}
+
+	wpabuf_put(buf, res);
+	eap_update_len(buf);
+
+	return buf;
+}
+
+
+static struct wpabuf * eap_ttls_build_phase2_eap_req(
+	struct eap_sm *sm, struct eap_ttls_data *data, u8 id)
+{
+	struct wpabuf *buf, *encr_req;
+	u8 *req;
 	size_t req_len;
 
 
-	req = data->phase2_method->buildReq(sm, data->phase2_priv, id,
-					    &req_len);
-	if (req == NULL)
-		return NULL;
-
-	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encapsulate Phase 2 data",
-			req, req_len);
-
-	if (eap_ttls_avp_encapsulate(&req, &req_len, RADIUS_ATTR_EAP_MESSAGE,
-				     1) < 0) {
+	buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
+	if (buf == NULL)
+		return NULL;
+
+	wpa_hexdump_buf_key(MSG_DEBUG,
+			    "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf);
+
+	buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1);
+	if (buf == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
 			   "packet");
 		return NULL;
 	}
 
+	req = wpabuf_mhead(buf);
+	req_len = wpabuf_len(buf);
 	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated Phase "
 			"2 data", req, req_len);
 
-	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
-	os_free(req);
+	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len);
+	wpabuf_free(buf);
 
 	return encr_req;
 }
 
 
-static u8 * eap_ttls_build_phase2_mschapv2(struct eap_sm *sm,
-					   struct eap_ttls_data *data,
-					   int id, size_t *reqDataLen)
-{
-	u8 *req, *encr_req, *pos, *end;
+static struct wpabuf * eap_ttls_build_phase2_mschapv2(
+	struct eap_sm *sm, struct eap_ttls_data *data, u8 id)
+{
+	struct wpabuf *encr_req;
+	u8 *req, *pos, *end;
 	int ret;
 	size_t req_len;
 
@@ -577,68 +567,58 @@
 	wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
 			"data", req, req_len);
 
-	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len, reqDataLen);
+	encr_req = eap_ttls_encrypt(sm, data, id, req, req_len);
 	os_free(req);
 
 	return encr_req;
 }
 
 
-static u8 * eap_ttls_build_phase_finished(struct eap_sm *sm,
-					  struct eap_ttls_data *data,
-					  int id, int final,
-					  size_t *reqDataLen)
+static struct wpabuf * eap_ttls_build_phase_finished(
+	struct eap_sm *sm, struct eap_ttls_data *data, u8 id, int final)
 {
 	int len;
-	struct eap_hdr *req;
-	u8 *pos;
+	struct wpabuf *req;
 	const int max_len = 300;
 
-	len = sizeof(struct eap_hdr) + 2 + max_len;
-	req = os_malloc(len);
+	len = 1 + max_len;
+	req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, len,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL)
 		return NULL;
 
-	req->code = EAP_CODE_REQUEST;
-	req->identifier = id;
-
-	pos = (u8 *) (req + 1);
-	*pos++ = EAP_TYPE_TTLS;
-	*pos++ = data->ttls_version;
+	wpabuf_put_u8(req, data->ttls_version);
 
 	len = tls_connection_ia_send_phase_finished(sm->ssl_ctx,
-						    data->ssl.conn,
-						    final, pos, max_len);
+						    data->ssl.conn, final,
+						    wpabuf_mhead(req),
+						    max_len);
 	if (len < 0) {
-		os_free(req);
-		return NULL;
-	}
-
-	*reqDataLen = sizeof(struct eap_hdr) + 2 + len;
-	req->length = host_to_be16(*reqDataLen);
-
-	return (u8 *) req;
-}
-
-
-static u8 * eap_ttls_buildReq(struct eap_sm *sm, void *priv, int id,
-			      size_t *reqDataLen)
+		wpabuf_free(req);
+		return NULL;
+	}
+	wpabuf_put(req, len);
+	eap_update_len(req);
+
+	return req;
+}
+
+
+static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_ttls_data *data = priv;
 
 	switch (data->state) {
 	case START:
-		return eap_ttls_build_start(sm, data, id, reqDataLen);
+		return eap_ttls_build_start(sm, data, id);
 	case PHASE1:
-		return eap_ttls_build_req(sm, data, id, reqDataLen);
+		return eap_ttls_build_req(sm, data, id);
 	case PHASE2_METHOD:
-		return eap_ttls_build_phase2_eap_req(sm, data, id, reqDataLen);
+		return eap_ttls_build_phase2_eap_req(sm, data, id);
 	case PHASE2_MSCHAPV2_RESP:
-		return eap_ttls_build_phase2_mschapv2(sm, data, id,
-						      reqDataLen);
+		return eap_ttls_build_phase2_mschapv2(sm, data, id);
 	case PHASE_FINISHED:
-		return eap_ttls_build_phase_finished(sm, data, id, 1,
-						     reqDataLen);
+		return eap_ttls_build_phase_finished(sm, data, id, 1);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
 			   __func__, data->state);
@@ -648,15 +628,13 @@
 
 
 static Boolean eap_ttls_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) + 2 || *pos != EAP_TYPE_TTLS ||
-	    (be_to_host16(resp->length)) > respDataLen) {
+			      struct wpabuf *respData)
+{
+	const u8 *pos;
+	size_t len;
+
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len);
+	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
 		return TRUE;
 	}
@@ -701,9 +679,8 @@
 					const u8 *user_password,
 					size_t user_password_len)
 {
-	/* TODO: add support for verifying that the user entry accepts
-	 * EAP-TTLS/PAP. */
-	if (!sm->user || !sm->user->password || sm->user->password_hash) {
+	if (!sm->user || !sm->user->password || sm->user->password_hash ||
+	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "
 			   "password configured");
 		eap_ttls_state(data, FAILURE);
@@ -731,9 +708,7 @@
 					 const u8 *password,
 					 size_t password_len)
 {
-	u8 *chal, hash[MD5_MAC_LEN];
-	const u8 *addr[3];
-	size_t len[3];
+	u8 *chal, hash[CHAP_MD5_LEN];
 
 	if (challenge == NULL || password == NULL ||
 	    challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
@@ -746,9 +721,8 @@
 		return;
 	}
 
-	/* TODO: add support for verifying that the user entry accepts
-	 * EAP-TTLS/CHAP. */
-	if (!sm->user || !sm->user->password || sm->user->password_hash) {
+	if (!sm->user || !sm->user->password || sm->user->password_hash ||
+	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "
 			   "password configured");
 		eap_ttls_state(data, FAILURE);
@@ -774,13 +748,8 @@
 	os_free(chal);
 
 	/* MD5(Ident + Password + Challenge) */
-	addr[0] = password;
-	len[0] = 1;
-	addr[1] = sm->user->password;
-	len[1] = sm->user->password_len;
-	addr[2] = challenge;
-	len[2] = challenge_len;
-	md5_vector(3, addr, len, hash);
+	chap_md5(password[0], sm->user->password, sm->user->password_len,
+		 challenge, challenge_len, hash);
 
 	if (os_memcmp(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) == 0) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
@@ -811,9 +780,8 @@
 		return;
 	}
 
-	/* TODO: add support for verifying that the user entry accepts
-	 * EAP-TTLS/MSCHAP. */
-	if (!sm->user || !sm->user->password) {
+	if (!sm->user || !sm->user->password ||
+	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
 			   "configured");
 		eap_ttls_state(data, FAILURE);
@@ -880,9 +848,8 @@
 		return;
 	}
 
-	/* TODO: add support for verifying that the user entry accepts
-	 * EAP-TTLS/MSCHAPV2. */
-	if (!sm->user || !sm->user->password) {
+	if (!sm->user || !sm->user->password ||
+	    !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
 			   "configured");
 		eap_ttls_state(data, FAILURE);
@@ -1029,10 +996,11 @@
 	struct eap_hdr *hdr;
 	u8 *pos;
 	size_t left;
+	struct wpabuf buf;
 	const struct eap_method *m = data->phase2_method;
 	void *priv = data->phase2_priv;
 
-	if (data->phase2_priv == NULL) {
+	if (priv == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
 			   "initialized?!", __func__);
 		return;
@@ -1060,13 +1028,15 @@
 		return;
 	}
 
-	if (m->check(sm, priv, in_data, in_len)) {
+	wpabuf_set(&buf, in_data, in_len);
+
+	if (m->check(sm, priv, &buf)) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
 			   "ignore the packet");
 		return;
 	}
 
-	m->process(sm, priv, in_data, in_len);
+	m->process(sm, priv, &buf);
 
 	if (!m->isDone(sm, priv))
 		return;
@@ -1168,7 +1138,6 @@
 
 static void eap_ttls_process_phase2(struct eap_sm *sm,
 				    struct eap_ttls_data *data,
-				    struct eap_hdr *resp,
 				    u8 *in_data, size_t in_len)
 {
 	u8 *in_decrypted;
@@ -1284,26 +1253,28 @@
 done:
 	os_free(in_decrypted);
 	os_free(parse.eap);
- }
+}
 
 
 static void eap_ttls_process(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	struct eap_ttls_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos, flags;
-	int left;
+	const u8 *pos;
+	u8 flags;
+	size_t left;
 	unsigned int tls_msg_len;
 	int peer_version;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	pos++;
+	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData,
+			       &left);
+	if (pos == NULL || left < 1)
+		return;
 	flags = *pos++;
-	left = be_to_host16(resp->length) - sizeof(struct eap_hdr) - 2;
+	left--;
 	wpa_printf(MSG_DEBUG, "EAP-TTLS: Received packet(len=%lu) - "
-		   "Flags 0x%02x", (unsigned long) respDataLen, flags);
+		   "Flags 0x%02x", (unsigned long) wpabuf_len(respData),
+		   flags);
 	peer_version = flags & EAP_PEAP_VERSION_MASK;
 	if (peer_version < data->ttls_version) {
 		wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
@@ -1355,7 +1326,8 @@
 	case PHASE2_START:
 	case PHASE2_METHOD:
 	case PHASE_FINISHED:
-		eap_ttls_process_phase2(sm, data, resp, pos, left);
+		/* FIX: get rid of const->non-const typecast */
+		eap_ttls_process_phase2(sm, data, (u8 *) pos, left);
 		break;
 	case PHASE2_MSCHAPV2_RESP:
 		if (data->mschapv2_resp_ok && left == 0) {

Modified: wpasupplicant/trunk/src/eap_server/eap_vendor_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_vendor_test.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_vendor_test.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_vendor_test.c Tue Dec 25 15:23:24 2007
@@ -74,72 +74,52 @@
 }
 
 
-static u8 * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv, int id,
-				     size_t *reqDataLen)
+static struct wpabuf * eap_vendor_test_buildReq(struct eap_sm *sm, void *priv,
+						u8 id)
 {
 	struct eap_vendor_test_data *data = priv;
-	struct eap_hdr *req;
-	u8 *pos;
+	struct wpabuf *req;
 
-	req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, reqDataLen, 1,
-			    EAP_CODE_REQUEST, id, &pos);
+	req = eap_msg_alloc(EAP_VENDOR_ID, EAP_VENDOR_TYPE, 1,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-VENDOR-TEST: Failed to allocate "
 			   "memory for request");
 		return NULL;
 	}
 
-	*pos = data->state == INIT ? 1 : 3;
+	wpabuf_put_u8(req, data->state == INIT ? 1 : 3);
 
-	return (u8 *) req;
+	return req;
 }
 
 
 static Boolean eap_vendor_test_check(struct eap_sm *sm, void *priv,
-				     u8 *respData, size_t respDataLen)
+				     struct wpabuf *respData)
 {
-	struct eap_hdr *resp;
-	u8 *pos;
+	const u8 *pos;
 	size_t len;
-	int vendor;
-	u32 method;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	if (respDataLen < sizeof(*resp))
-		return TRUE;
-	len = be_to_host16(resp->length);
-	if (len > respDataLen)
-		return TRUE;
-
-	if (len < sizeof(*resp) + 8 || *pos != EAP_TYPE_EXPANDED) {
+	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len);
+	if (pos == NULL || len < 1) {
 		wpa_printf(MSG_INFO, "EAP-VENDOR-TEST: Invalid frame");
 		return TRUE;
 	}
-	pos++;
-
-	vendor = WPA_GET_BE24(pos);
-	pos += 3;
-	method = WPA_GET_BE32(pos);
-	pos++;
-
-	if (vendor != EAP_VENDOR_ID || method != EAP_VENDOR_TYPE)
-		return TRUE;
 
 	return FALSE;
 }
 
 
 static void eap_vendor_test_process(struct eap_sm *sm, void *priv,
-				    u8 *respData, size_t respDataLen)
+				    struct wpabuf *respData)
 {
 	struct eap_vendor_test_data *data = priv;
-	struct eap_hdr *resp;
-	u8 *pos;
+	const u8 *pos;
+	size_t len;
 
-	resp = (struct eap_hdr *) respData;
-	pos = (u8 *) (resp + 1);
-	pos += 8; /* Skip expanded header */
+	pos = eap_hdr_validate(EAP_VENDOR_ID, EAP_VENDOR_TYPE, respData, &len);
+	if (pos == NULL || len < 1)
+		return;
 
 	if (data->state == INIT) {
 		if (*pos == 2)

Modified: wpasupplicant/trunk/src/eap_server/eap_wsc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_wsc.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_wsc.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_wsc.c Tue Dec 25 15:23:24 2007
@@ -228,14 +228,13 @@
 }
 
 
-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);
+static struct wpabuf * eap_wsc_build_start(struct eap_sm *sm,
+					   struct eap_wsc_data *data, u8 id)
+{
+	struct wpabuf *req;
+
+	req = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, 2,
+			    EAP_CODE_REQUEST, id);
 	if (req == NULL) {
 		wpa_printf(MSG_ERROR, "EAP-WSC: Failed to allocate memory for "
 			   "request");
@@ -243,18 +242,18 @@
 	}
 
 	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;
+	wpabuf_put_u8(req, WSC_Start); /* Op-Code */
+	wpabuf_put_u8(req, 0); /* Flags */
+
+	return req;
+}
+
+
+static struct wpabuf * eap_wsc_build_msg(struct eap_sm *sm,
+					 struct eap_wsc_data *data, u8 id)
+{
+	struct wpabuf *req;
+	u8 flags;
 	size_t send_len, plen;
 
 	if (data->out_buf == NULL) {
@@ -280,22 +279,20 @@
 	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);
+	req = eap_msg_alloc(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC, plen,
+			    EAP_CODE_REQUEST, id);
 	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);
+	wpabuf_put_u8(req, data->out_op_code); /* Op-Code */
+	wpabuf_put_u8(req, flags); /* Flags */
+	if (flags & WSC_FLAGS_LF)
+		wpabuf_put_be16(req, data->out_len);
+
+	wpabuf_put_data(req, data->out_buf + data->out_used, send_len);
 	data->out_used += send_len;
 
 	if (data->out_used == data->out_len) {
@@ -312,23 +309,21 @@
 		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)
+	return req;
+}
+
+
+static struct wpabuf * eap_wsc_buildReq(struct eap_sm *sm, void *priv, u8 id)
 {
 	struct eap_wsc_data *data = priv;
 
 	switch (data->state) {
 	case START:
-		return eap_wsc_build_start(sm, data, id, reqDataLen);
+		return eap_wsc_build_start(sm, data, id);
 	case FRAG_ACK:
-		return eap_wsc_build_frag_ack(id, EAP_CODE_REQUEST,
-					      reqDataLen);
+		return eap_wsc_build_frag_ack(id, EAP_CODE_REQUEST);
 	case MSG:
-		return eap_wsc_build_msg(sm, data, id, reqDataLen);
+		return eap_wsc_build_msg(sm, data, id);
 	default:
 		wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected state %d in "
 			   "buildReq", data->state);
@@ -338,13 +333,13 @@
 
 
 static Boolean eap_wsc_check(struct eap_sm *sm, void *priv,
-			     u8 *respData, size_t respDataLen)
+			     struct wpabuf *respData)
 {
 	const u8 *pos;
 	size_t len;
 
 	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
-			       respData, respDataLen, &len);
+			       respData, &len);
 	if (pos == NULL || len < 2) {
 		wpa_printf(MSG_INFO, "EAP-WSC: Invalid frame");
 		return TRUE;
@@ -355,7 +350,7 @@
 
 
 static void eap_wsc_process(struct eap_sm *sm, void *priv,
-			    u8 *respData, size_t respDataLen)
+			    struct wpabuf *respData)
 {
 	struct eap_wsc_data *data = priv;
 	const u8 *start, *pos, *end;
@@ -367,7 +362,7 @@
 	enum wps_process_res res;
 
 	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
-			       respData, respDataLen, &len);
+			       respData, &len);
 	if (pos == NULL || len < 2)
 		return; /* Should not happen; message already verified */
 

Modified: wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c (original)
+++ wpasupplicant/trunk/src/eapol_supp/eapol_supp_sm.c Tue Dec 25 15:23:24 2007
@@ -22,6 +22,7 @@
 #include "md5.h"
 #include "rc4.h"
 #include "state_machine.h"
+#include "wpabuf.h"
 
 #define STATE_MACHINE_DATA struct eapol_sm
 #define STATE_MACHINE_DEBUG_PREFIX "EAPOL"
@@ -38,6 +39,7 @@
 	unsigned int heldWhile;
 	unsigned int startWhen;
 	unsigned int idleWhile; /* for EAP state machine */
+	int timer_tick_enabled;
 
 	/* Global variables */
 	Boolean eapFail;
@@ -128,8 +130,7 @@
 	Boolean initial_req;
 	u8 *last_rx_key;
 	size_t last_rx_key_len;
-	u8 *eapReqData; /* for EAP */
-	size_t eapReqDataLen; /* for EAP */
+	struct wpabuf *eapReqData; /* for EAP */
 	Boolean altAccept; /* for EAP */
 	Boolean altReject; /* for EAP */
 	Boolean replay_counter_valid;
@@ -221,8 +222,25 @@
 			wpa_printf(MSG_DEBUG, "EAPOL: idleWhile --> 0");
 	}
 
-	eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx, sm);
+	if (sm->authWhile | sm->heldWhile | sm->startWhen | sm->idleWhile) {
+		eloop_register_timeout(1, 0, eapol_port_timers_tick, eloop_ctx,
+				       sm);
+	} else {
+		wpa_printf(MSG_DEBUG, "EAPOL: disable timer tick");
+		sm->timer_tick_enabled = 0;
+	}
 	eapol_sm_step(sm);
+}
+
+
+static void eapol_enable_timer_tick(struct eapol_sm *sm)
+{
+	if (sm->timer_tick_enabled)
+		return;
+	wpa_printf(MSG_DEBUG, "EAPOL: enable timer tick");
+	sm->timer_tick_enabled = 1;
+	eloop_cancel_timeout(eapol_port_timers_tick, NULL, sm);
+	eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
 }
 
 
@@ -266,6 +284,7 @@
 		 */
 		sm->startWhen = 3;
 	}
+	eapol_enable_timer_tick(sm);
 	sm->eapolEap = FALSE;
 	if (send_start)
 		eapol_sm_txStart(sm);
@@ -289,6 +308,7 @@
 {
 	SM_ENTRY(SUPP_PAE, HELD);
 	sm->heldWhile = sm->heldPeriod;
+	eapol_enable_timer_tick(sm);
 	sm->suppPortStatus = Unauthorized;
 	sm->cb_status = EAPOL_CB_FAILURE;
 }
@@ -509,6 +529,7 @@
 {
 	SM_ENTRY(SUPP_BE, RECEIVE);
 	sm->authWhile = sm->authPeriod;
+	eapol_enable_timer_tick(sm);
 	sm->eapolEap = FALSE;
 	sm->eapNoResp = FALSE;
 	sm->initial_req = FALSE;
@@ -791,11 +812,10 @@
 
 static void eapol_sm_txSuppRsp(struct eapol_sm *sm)
 {
-	u8 *resp;
-	size_t resp_len;
+	struct wpabuf *resp;
 
 	wpa_printf(MSG_DEBUG, "EAPOL: txSuppRsp");
-	resp = eap_get_eapRespData(sm->eap, &resp_len);
+	resp = eap_get_eapRespData(sm->eap);
 	if (resp == NULL) {
 		wpa_printf(MSG_WARNING, "EAPOL: txSuppRsp - EAP response data "
 			   "not available");
@@ -804,10 +824,11 @@
 
 	/* 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);
+			    IEEE802_1X_TYPE_EAP_PACKET, wpabuf_head(resp),
+			    wpabuf_len(resp));
 
 	/* eapRespData is not used anymore, so free it here */
-	os_free(resp);
+	wpabuf_free(resp);
 
 	if (sm->initial_req)
 		sm->dot1xSuppEapolReqIdFramesRx++;
@@ -824,7 +845,7 @@
 	 * authentication session */
 	os_free(sm->last_rx_key);
 	sm->last_rx_key = NULL;
-	os_free(sm->eapReqData);
+	wpabuf_free(sm->eapReqData);
 	sm->eapReqData = NULL;
 	eap_sm_abort(sm->eap);
 }
@@ -1155,14 +1176,11 @@
 			 */
 			eapol_sm_abort_cached(sm);
 		}
-		os_free(sm->eapReqData);
-		sm->eapReqDataLen = plen;
-		sm->eapReqData = os_malloc(sm->eapReqDataLen);
+		wpabuf_free(sm->eapReqData);
+		sm->eapReqData = wpabuf_alloc_copy(hdr + 1, plen);
 		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);
 		}
@@ -1213,7 +1231,7 @@
  * 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
+ * Notify EAPOL state 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)
@@ -1228,7 +1246,7 @@
  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
  * @enabled: New portEnabled value
  *
- * Notify EAPOL station machine about new portEnabled value.
+ * Notify EAPOL state machine about new portEnabled value.
  */
 void eapol_sm_notify_portEnabled(struct eapol_sm *sm, Boolean enabled)
 {
@@ -1246,7 +1264,7 @@
  * @sm: Pointer to EAPOL state machine allocated with eapol_sm_init()
  * @valid: New portValid value
  *
- * Notify EAPOL station machine about new portValid value.
+ * Notify EAPOL state machine about new portValid value.
  */
 void eapol_sm_notify_portValid(struct eapol_sm *sm, Boolean valid)
 {
@@ -1289,7 +1307,7 @@
  * @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
+ * Notify EAPOL state 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)
@@ -1310,7 +1328,7 @@
  * @config: Pointer to current network configuration
  * @conf: Pointer to EAPOL configuration data
  *
- * Notify EAPOL station machine that configuration has changed. config will be
+ * Notify EAPOL state 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
@@ -1396,6 +1414,7 @@
 	sm->SUPP_PAE_state = SUPP_PAE_AUTHENTICATED;
 	sm->suppPortStatus = Authorized;
 	eap_notify_success(sm->eap);
+	eapol_sm_step(sm);
 }
 
 
@@ -1433,6 +1452,7 @@
 	/* Make sure we do not start sending EAPOL-Start frames first, but
 	 * instead move to RESTART state to start EAPOL authentication. */
 	sm->startWhen = 3;
+	eapol_enable_timer_tick(sm);
 
 	if (sm->ctx->aborted_cached)
 		sm->ctx->aborted_cached(sm->ctx->ctx);
@@ -1539,6 +1559,7 @@
 	if (sm == NULL)
 		return;
 	eap_notify_lower_layer_success(sm->eap);
+	eapol_sm_step(sm);
 }
 
 
@@ -1560,15 +1581,12 @@
 }
 
 
-static u8 * eapol_sm_get_eapReqData(void *ctx, size_t *len)
+static struct wpabuf * eapol_sm_get_eapReqData(void *ctx)
 {
 	struct eapol_sm *sm = ctx;
-	if (sm == NULL || sm->eapReqData == NULL) {
-		*len = 0;
+	if (sm == NULL || sm->eapReqData == NULL)
 		return NULL;
-	}
-
-	*len = sm->eapReqDataLen;
+
 	return sm->eapReqData;
 }
 
@@ -1662,6 +1680,7 @@
 	switch (variable) {
 	case EAPOL_idleWhile:
 		sm->idleWhile = value;
+		eapol_enable_timer_tick(sm);
 		break;
 	}
 }
@@ -1767,6 +1786,7 @@
 	sm->initialize = FALSE;
 	eapol_sm_step(sm);
 
+	sm->timer_tick_enabled = 1;
 	eloop_register_timeout(1, 0, eapol_port_timers_tick, NULL, sm);
 
 	return sm;
@@ -1787,7 +1807,7 @@
 	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);
+	wpabuf_free(sm->eapReqData);
 	os_free(sm->ctx);
 	os_free(sm);
 }

Modified: wpasupplicant/trunk/src/radius/radius_server.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_server.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_server.c (original)
+++ wpasupplicant/trunk/src/radius/radius_server.c Tue Dec 25 15:23:24 2007
@@ -86,6 +86,7 @@
 	void *ssl_ctx;
 	u8 *pac_opaque_encr_key;
 	char *eap_fast_a_id;
+	int eap_sim_aka_result_ind;
 	int ipv6;
 	struct os_time start_time;
 	struct radius_server_counters counters;
@@ -309,6 +310,7 @@
 	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;
+	eap_conf.eap_sim_aka_result_ind = data->eap_sim_aka_result_ind;
 	sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
 				       &eap_conf);
 	if (sess->eap == NULL) {
@@ -362,8 +364,8 @@
 	}
 
 	if (sess->eap_if->eapReqData &&
-	    !radius_msg_add_eap(msg, sess->eap_if->eapReqData,
-				sess->eap_if->eapReqDataLen)) {
+	    !radius_msg_add_eap(msg, wpabuf_head(sess->eap_if->eapReqData),
+				wpabuf_len(sess->eap_if->eapReqData))) {
 		RADIUS_DEBUG("Failed to add EAP-Message attribute");
 	}
 
@@ -458,11 +460,10 @@
 	u8 *eap = NULL;
 	size_t eap_len;
 	int res, state_included = 0;
-	u8 statebuf[4], resp_id;
+	u8 statebuf[4];
 	unsigned int state;
 	struct radius_session *sess;
 	struct radius_msg *reply;
-	struct eap_hdr *hdr;
 
 	if (force_sess)
 		sess = force_sess;
@@ -528,12 +529,6 @@
 	}
 
 	RADIUS_DUMP("Received EAP data", eap, eap_len);
-	if (eap_len >= sizeof(*hdr)) {
-		hdr = (struct eap_hdr *) eap;
-		resp_id = hdr->identifier;
-	} else {
-		resp_id = 0;
-	}
 
 	/* FIX: if Code is Request, Success, or Failure, send Access-Reject;
 	 * RFC3579 Sect. 2.6.2.
@@ -542,9 +537,10 @@
 	 * If code is not 1-4, discard the packet silently.
 	 * Or is this already done by the EAP state machine? */
 
-	os_free(sess->eap_if->eapRespData);
-	sess->eap_if->eapRespData = eap;
-	sess->eap_if->eapRespDataLen = eap_len;
+	wpabuf_free(sess->eap_if->eapRespData);
+	sess->eap_if->eapRespData = wpabuf_alloc_ext_data(eap, eap_len);
+	if (sess->eap_if->eapRespData == NULL)
+		os_free(eap);
 	eap = NULL;
 	sess->eap_if->eapResp = TRUE;
 	eap_server_sm_step(sess->eap);
@@ -552,8 +548,8 @@
 	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->eap_if->eapReqData,
-			    sess->eap_if->eapReqDataLen);
+			    wpabuf_head(sess->eap_if->eapReqData),
+			    wpabuf_len(sess->eap_if->eapReqData));
 	} else if (sess->eap_if->eapFail) {
 		RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
 			     "set");
@@ -1006,6 +1002,7 @@
 	if (conf->eap_fast_a_id)
 		data->eap_fast_a_id = os_strdup(conf->eap_fast_a_id);
 	data->get_eap_user = conf->get_eap_user;
+	data->eap_sim_aka_result_ind = conf->eap_sim_aka_result_ind;
 
 	data->clients = radius_server_read_clients(conf->client_file,
 						   conf->ipv6);
@@ -1050,6 +1047,8 @@
 
 	radius_server_free_clients(data, data->clients);
 
+	os_free(data->pac_opaque_encr_key);
+	os_free(data->eap_fast_a_id);
 	os_free(data);
 }
 

Modified: wpasupplicant/trunk/src/radius/radius_server.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_server.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_server.h (original)
+++ wpasupplicant/trunk/src/radius/radius_server.h Tue Dec 25 15:23:24 2007
@@ -26,6 +26,7 @@
 	void *ssl_ctx;
 	u8 *pac_opaque_encr_key;
 	char *eap_fast_a_id;
+	int eap_sim_aka_result_ind;
 	int ipv6;
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);

Modified: wpasupplicant/trunk/src/utils/common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/common.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/common.h (original)
+++ wpasupplicant/trunk/src/utils/common.h Tue Dec 25 15:23:24 2007
@@ -402,13 +402,6 @@
 typedef u64 __bitwise be64;
 typedef u64 __bitwise le64;
 
-typedef u16 __bitwise __be16;
-typedef u32 __bitwise __be32;
-typedef u64 __bitwise __be64;
-typedef u16 __bitwise __le16;
-typedef u32 __bitwise __le32;
-typedef u64 __bitwise __le64;
-
 
 int hwaddr_aton(const char *txt, u8 *addr);
 int hexstr2bin(const char *hex, u8 *buf, size_t len);

Modified: wpasupplicant/trunk/src/utils/wpa_debug.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/wpa_debug.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/wpa_debug.h (original)
+++ wpasupplicant/trunk/src/utils/wpa_debug.h Tue Dec 25 15:23:24 2007
@@ -15,6 +15,8 @@
 #ifndef WPA_DEBUG_H
 #define WPA_DEBUG_H
 
+#include "wpabuf.h"
+
 /* Debugging function - conditional printf and hex dump. Driver wrappers can
  * use these for debugging purposes. */
 
@@ -25,7 +27,9 @@
 #define wpa_debug_print_timestamp() do { } while (0)
 #define wpa_printf(args...) do { } while (0)
 #define wpa_hexdump(l,t,b,le) do { } while (0)
+#define wpa_hexdump_buf(l,t,b) do { } while (0)
 #define wpa_hexdump_key(l,t,b,le) do { } while (0)
+#define wpa_hexdump_buf_key(l,t,b) do { } while (0)
 #define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
 #define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
 #define wpa_debug_open_file() do { } while (0)
@@ -72,6 +76,12 @@
  */
 void wpa_hexdump(int level, const char *title, const u8 *buf, size_t len);
 
+static inline void wpa_hexdump_buf(int level, const char *title,
+				   const struct wpabuf *buf)
+{
+	wpa_hexdump(level, title, wpabuf_head(buf), wpabuf_len(buf));
+}
+
 /**
  * wpa_hexdump_key - conditional hex dump, hide keys
  * @level: priority level (MSG_*) of the message
@@ -86,6 +96,12 @@
  * etc.) in debug output.
  */
 void wpa_hexdump_key(int level, const char *title, const u8 *buf, size_t len);
+
+static inline void wpa_hexdump_buf_key(int level, const char *title,
+				       const struct wpabuf *buf)
+{
+	wpa_hexdump_key(level, title, wpabuf_head(buf), wpabuf_len(buf));
+}
 
 /**
  * wpa_hexdump_ascii - conditional hex dump

Modified: wpasupplicant/trunk/wpa_supplicant/ChangeLog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ChangeLog?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ChangeLog (original)
+++ wpasupplicant/trunk/wpa_supplicant/ChangeLog Tue Dec 25 15:23:24 2007
@@ -3,6 +3,26 @@
 ????-??-?? - 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)
+	* fixed EAP-SIM and EAP-AKA message parser to validate attribute
+	  lengths properly to avoid potential crash caused by invalid messages
+	* added data structure for storing allocated buffers (struct wpabuf);
+	  this does not affect wpa_supplicant usage, but many of the APIs
+	  changed and various interfaces (e.g., EAP) is not compatible with old
+	  versions
+	* added support for protecting EAP-AKA/Identity messages with
+	  AT_CHECKCODE (optional feature in RFC 4187)
+	* added support for protected result indication with AT_RESULT_IND for
+	  EAP-SIM and EAP-AKA (phase1="result_ind=1")
+	* added driver_wext workaround for race condition between scanning and
+	  association with drivers that take very long time to scan all
+	  channels (e.g., madwifi with dual-band cards); wpa_supplicant is now
+	  using a longer hardcoded timeout for the scan if the driver supports
+	  notifications for scan completion (SIOCGIWSCAN event); this helps,
+	  e.g., in cases where wpa_supplicant and madwifi driver ended up in
+	  loop where the driver did not even try to associate
+	* stop EAPOL timer tick when no timers are in use in order to reduce
+	  power consumption (no need to wake up the process once per second)
+	  [Bug 237]
 
 2007-11-24 - v0.6.1
 	* added support for configuring password as NtPasswordHash

Modified: wpasupplicant/trunk/wpa_supplicant/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/Makefile?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/Makefile (original)
+++ wpasupplicant/trunk/wpa_supplicant/Makefile Tue Dec 25 15:23:24 2007
@@ -42,6 +42,7 @@
 OBJS = config.o
 OBJS += ../src/utils/common.o
 OBJS += ../src/utils/wpa_debug.o
+OBJS += ../src/utils/wpabuf.o
 OBJS += ../src/crypto/md5.o
 OBJS += ../src/crypto/rc4.o
 OBJS += ../src/crypto/md4.o
@@ -283,6 +284,7 @@
 endif
 MS_FUNCS=y
 TLS_FUNCS=y
+CHAP=y
 CONFIG_IEEE8021X_EAPOL=y
 endif
 
@@ -296,6 +298,7 @@
 OBJS += ../src/eap_peer/eap_md5.o
 OBJS_h += ../src/eap_server/eap_md5.o
 endif
+CHAP=y
 CONFIG_IEEE8021X_EAPOL=y
 endif
 
@@ -656,6 +659,10 @@
 NEED_CRYPTO=y
 endif
 
+ifdef CHAP
+OBJS += ../src/eap_common/chap.o
+endif
+
 ifdef NEED_CRYPTO
 ifndef TLS_FUNCS
 ifeq ($(CONFIG_TLS), openssl)
@@ -1077,7 +1084,7 @@
 docs-pics: doc/wpa_supplicant.png doc/wpa_supplicant.eps
 
 docs: docs-pics
-	doxygen doc/doxygen.full
+	(cd ..; doxygen wpa_supplicant/doc/doxygen.full; cd wpa_supplicant)
 	$(MAKE) -C doc/latex
 	cp doc/latex/refman.pdf wpa_supplicant-devel.pdf
 

Modified: wpasupplicant/trunk/wpa_supplicant/config_ssid.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config_ssid.h?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config_ssid.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/config_ssid.h Tue Dec 25 15:23:24 2007
@@ -504,6 +504,9 @@
 	 * sim_min_num_chal=3 can be used to configure EAP-SIM to require three
 	 * challenges (by default, it accepts 2 or 3).
 	 *
+	 * result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use
+	 * protected result indication.
+	 *
 	 * fast_provisioning option can be used to enable in-line provisioning
 	 * of EAP-FAST credentials (PAC):
 	 * 0 = disabled,

Modified: wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/ctrl_iface_dbus.c Tue Dec 25 15:23:24 2007
@@ -644,6 +644,7 @@
 		return;
 	}
 	dbus_connection_send(iface->con, _signal, NULL);
+	dbus_message_unref(_signal);
 }
 
 
@@ -661,7 +662,7 @@
 					     wpa_states old_state)
 {
 	struct ctrl_iface_dbus_priv *iface;
-	DBusMessage *_signal;
+	DBusMessage *_signal = NULL;
 	const char *path;
 	const char *new_state_str, *old_state_str;
 
@@ -706,7 +707,7 @@
 		wpa_printf(MSG_ERROR,
 		           "wpa_supplicant_dbus_notify_state_change[dbus]: "
 		           "couldn't convert state strings.");
-		return;
+		goto out;
 	}
 
 	if (!dbus_message_append_args(_signal,
@@ -719,8 +720,13 @@
 		           "wpa_supplicant_dbus_notify_state_change[dbus]: "
 		           "not enough memory to construct state change "
 		           "signal.");
-	}
+		goto out;
+	}
+
 	dbus_connection_send(iface->con, _signal, NULL);
+
+out:
+	dbus_message_unref(_signal);
 }
 
 

Modified: wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/code_structure.doxygen Tue Dec 25 15:23:24 2007
@@ -4,6 +4,7 @@
 [ \ref wpa_supplicant_core "wpa_supplicant core functionality" |
 \ref generic_helper_func "Generic helper functions" |
 \ref crypto_func "Cryptographic functions" |
+\ref tls_func "TLS library" |
 \ref configuration "Configuration" |
 \ref ctrl_iface "Control interface" |
 \ref wpa_code "WPA supplicant" |
@@ -103,6 +104,9 @@
 	T-PRF (for EAP-FAST)
 	TLS-PRF (RFC 2246)
 
+sha256.c and sha256.h
+	SHA-256 (replaced with a crypto library if TLS support is included)
+
 aes_wrap.c, aes_wrap.h, aes.c
 	AES (replaced with a crypto library if TLS support is included),
 	AES Key Wrap Algorithm with 128-bit KEK, RFC3394 (broadcast/default
@@ -115,8 +119,11 @@
 crypto.h
 	Definition of crypto library wrapper
 
-crypto.c
+crypto_openssl.c
 	Wrapper functions for libcrypto (OpenSSL)
+
+crypto_internal.c
+	Wrapper functions for internal crypto implementation
 
 crypto_gnutls.c
 	Wrapper functions for libgcrypt (used by GnuTLS)
@@ -134,10 +141,49 @@
 tls_openssl.c
 	TLS library wrapper for openssl
 
+tls_internal.c
+	TLS library for internal TLS implementation
+
 tls_gnutls.c
 	TLS library wrapper for GnuTLS
 
 
+\section crypto_func Cryptographic functions
+
+asn1.c and asn1.h
+	ASN.1 DER parsing
+
+bignum.c and bignum.h
+	Big number math
+
+rsa.c and rsa.h
+	RSA
+
+x509v3.c and x509v3.h
+	X.509v3 certificate parsing and processing
+
+tlsv1_client.c, tlsv1_client.h
+	TLSv1 client (RFC 2246)
+
+tlsv1_client_i.h
+	Internal structures for TLSv1 client
+
+tlsv1_client_read.c
+	TLSv1 client: read handshake messages
+
+tlsv1_client_write.c
+	TLSv1 client: write handshake messages
+
+tlsv1_common.c and tlsv1_common.h
+	Common TLSv1 routines and definitions
+
+tlsv1_cred.c and tlsv1_cred.h
+	TLSv1 credentials
+
+tlsv1_record.c and tlsv1_record.h
+	TLSv1 record protocol
+
+
 \section configuration Configuration
 
 config_ssid.h
@@ -151,6 +197,9 @@
 
 config_file.c
 	Configuration backend for text files (e.g., wpa_supplicant.conf)
+
+config_winreg.c
+	Configuration backend for Windows registry
 
 
 \section ctrl_iface Control interface
@@ -164,6 +213,15 @@
 ctrl_iface.c and ctrl_iface.h
 	%wpa_supplicant-side of the control interface
 
+ctrl_iface_unix.c
+	UNIX domain sockets -based control interface backend
+
+ctrl_iface_udp.c
+	UDP sockets -based control interface backend
+
+ctrl_iface_named_pipe.c
+	Windows named pipes -based control interface backend
+
 wpa_ctrl.c and wpa_ctrl.h
 	Library functions for external programs to provide access to the
 	%wpa_supplicant control interface
@@ -229,15 +287,15 @@
 
 \section eapol_supp EAPOL supplicant
 
-eapol_sm.c and eapol_sm.h
+eapol_supp_sm.c and eapol_supp_sm.h
 	EAPOL supplicant state machine and IEEE 802.1X processing
 
 
 \section win_port Windows port
 
-ndis_events.cpp
-	External program for receiving NdisMIndicateStatus() events and
-	delivering them to %wpa_supplicant in more easier to use form
+ndis_events.c
+	Code for receiving NdisMIndicateStatus() events and delivering them to
+	%wpa_supplicant driver_ndis.c in more easier to use form
 
 win_if_list.c
 	External program for listing current network interface
@@ -250,9 +308,6 @@
 
 radius.c and radius.h
 	RADIUS message processing for eapol_test
-
-config_types.h and hostapd.h
-	Minimal version of hostapd header files for eapol_test
 
 eapol_test.c
 	Standalone EAP testing tool with integrated RADIUS authentication

Modified: wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/doxygen.full Tue Dec 25 15:23:24 2007
@@ -4,8 +4,8 @@
 # Project related configuration options
 #---------------------------------------------------------------------------
 PROJECT_NAME           = wpa_supplicant
-PROJECT_NUMBER         = 0.5.x
-OUTPUT_DIRECTORY       = doc
+PROJECT_NUMBER         = 0.6.x
+OUTPUT_DIRECTORY       = wpa_supplicant/doc
 CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
 USE_WINDOWS_ENCODING   = NO
@@ -24,7 +24,7 @@
                          the
 ALWAYS_DETAILED_SEC    = NO
 INLINE_INHERITED_MEMB  = NO
-FULL_PATH_NAMES        = YES
+FULL_PATH_NAMES        = NO
 STRIP_FROM_PATH        =
 STRIP_FROM_INC_PATH    = 
 SHORT_NAMES            = NO
@@ -65,7 +65,7 @@
 ENABLED_SECTIONS       = 
 MAX_INITIALIZER_LINES  = 30
 SHOW_USED_FILES        = YES
-SHOW_DIRECTORIES       = NO
+SHOW_DIRECTORIES       = YES
 FILE_VERSION_FILTER    = 
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
@@ -80,8 +80,18 @@
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
-INPUT                  = .
-FILE_PATTERNS          = *.c *.h *.doxygen
+INPUT                  = wpa_supplicant \
+	src/common \
+	src/crypto \
+	src/drivers \
+	src/eap_common \
+	src/eapol_supp \
+	src/eap_peer \
+	src/l2_packet \
+	src/rsn_supp \
+	src/tls \
+	src/utils
+FILE_PATTERNS          = *.c *.h *.cpp *.m *.doxygen
 RECURSIVE              = YES
 EXCLUDE                = 
 EXCLUDE_SYMLINKS       = NO

Modified: wpasupplicant/trunk/wpa_supplicant/doc/eap.doxygen
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/eap.doxygen?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/eap.doxygen (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/eap.doxygen Tue Dec 25 15:23:24 2007
@@ -53,4 +53,35 @@
 eap_vendor_test.c for an example of an EAP method implementation that
 is implemented as an expanded type.
 
+
+\section used_eap_library Using EAP implementation as a library
+
+The Git repository has an eap_example directory that contains an
+example showing how EAP peer and server code from %wpa_supplicant and
+hostapd can be used as a library. The example program initializes both
+an EAP server and an EAP peer entities and then runs through an
+EAP-PEAP/MSCHAPv2 authentication.
+
+eap_example_peer.c shows the initialization and glue code needed to
+control the EAP peer implementation. eap_example_server.c does the
+same for EAP server. eap_example.c is an example that ties in both the
+EAP server and client parts to allow an EAP authentication to be
+shown.
+
+In this example, the EAP messages are passed between the server and
+the peer are passed by direct function calls within the same process.
+In practice, server and peer functionalities would likely reside in
+separate devices and the EAP messages would be transmitted between the
+devices based on an external protocol. For example, in IEEE 802.11
+uses IEEE 802.1X EAPOL state machines to control the transmission of
+EAP messages and WiMax supports optional PMK EAP authentication
+mechanism that transmits EAP messages as defined in IEEE 802.16e.
+
+The EAP library links in number of helper functions from src/utils and
+src/crypto directories. Most of these are suitable as-is, but it may
+be desirable to replace the debug output code in src/utils/wpa_debug.c
+by dropping this file from the library and re-implementing the
+functions there in a way that better fits in with the main
+application.
+
 */

Modified: wpasupplicant/trunk/wpa_supplicant/doc/mainpage.doxygen
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/mainpage.doxygen?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/mainpage.doxygen (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/mainpage.doxygen Tue Dec 25 15:23:24 2007
@@ -1,5 +1,5 @@
 /**
-\mainpage Developers' documentation for %wpa_supplicant
+\mainpage Developers' documentation for wpa_supplicant
 
 %wpa_supplicant is a WPA Supplicant for Linux, BSD and Windows with
 support for WPA and WPA2 (IEEE 802.11i / RSN). Supplicant is the IEEE
@@ -19,11 +19,11 @@
 license, GPLv2 or BSD at user's choice. All contributions to
 %wpa_supplicant are expected to use compatible licensing terms.
 
-The source code and read-only access to %wpa_supplicant CVS repository
+The source code and read-only access to %wpa_supplicant Git repository
 is available from the project home page at
-http://hostap.epitest.fi/wpa_supplicant/. This developers' documentation
+http://w1.fi/wpa_supplicant/. This developers' documentation
 is also available as a PDF file from
-http://hostap.epitest.fi/wpa_supplicant/wpa_supplicant-devel.pdf .
+http://w1.fi/wpa_supplicant/wpa_supplicant-devel.pdf .
 
 The design goal for %wpa_supplicant was to use hardware, driver, and
 OS independent, portable C code for all WPA functionality. The source

Modified: wpasupplicant/trunk/wpa_supplicant/eap_testing.txt
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/eap_testing.txt?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/eap_testing.txt (original)
+++ wpasupplicant/trunk/wpa_supplicant/eap_testing.txt Tue Dec 25 15:23:24 2007
@@ -58,12 +58,20 @@
 EAP-PEAPv0/GTC		+   -   +   -   +   +   +   +   -   -   +   +
 EAP-PEAPv0/OTP		-   -   -   -   -   +   -   -   -   -   -   -
 EAP-PEAPv0/MD5		+   -   -   +   +   +   +   +   -   -   +   -
-EAP-PEAPv0/TLS		-   +   -   +   +   +   F   +   -   -   -   -
+EAP-PEAPv0/TLS		+   +   -   +   +   +   F   +   -   -   -   -
+EAP-PEAPv0/PSK		-   -   -   -   -   -   -   -   -   -   +   -
+EAP-PEAPv0/PAX		-   -   -   -   -   -   -   -   -   -   +   -
+EAP-PEAPv0/SAKE		-   -   -   -   -   -   -   -   -   -   +   -
+EAP-PEAPv0/GPSK		-   -   -   -   -   -   -   -   -   -   +   -
 EAP-PEAPv1/MSCHAPv2	-   -   +   +   +   +1  +   +5  +8  -   +   +
 EAP-PEAPv1/GTC		-   -   +   +   +   +1  +   +5  +8  -   +   +
 EAP-PEAPv1/OTP		-   -   -   -   -   +1  -   -   -   -   -   -
 EAP-PEAPv1/MD5		-   -   -   +   +   +1  +   +5  -   -   +   -
 EAP-PEAPv1/TLS		-   -   -   +   +   +1  F   +5  -   -   -   -
+EAP-PEAPv1/PSK		-   -   -   -   -   -   -   -   -   -   +   -
+EAP-PEAPv1/PAX		-   -   -   -   -   -   -   -   -   -   +   -
+EAP-PEAPv1/SAKE		-   -   -   -   -   -   -   -   -   -   +   -
+EAP-PEAPv1/GPSK		-   -   -   -   -   -   -   -   -   -   +   -
 EAP-TTLS/CHAP		+   -   +2  +   +   +   +   +   +   -   +   -
 EAP-TTLS/MSCHAP		+   -   +   +   +   +   +   +   +   -   +   -
 EAP-TTLS/MSCHAPv2	+   -   +   +   +   +   +   +   +   -   +   -
@@ -72,8 +80,12 @@
 EAP-TTLS/EAP-GTC	+   -   +2  ?   +   +   +   +   -   -   +   -
 EAP-TTLS/EAP-OTP	-   -   -   -   -   +   -   -   -   -   -   -
 EAP-TTLS/EAP-MSCHAPv2	+   -   +2  +   +   +   +   +   +   -   +   -
-EAP-TTLS/EAP-TLS	-   -   +2  +   F   +   +   +   -   -   -   -
-EAP-SIM			+3  -   -   ?   -   +   -   ?   -   -   +   -
+EAP-TTLS/EAP-TLS	+   -   +2  +   F   +   +   +   -   -   -   -
+EAP-TTLS/EAP-PSK	-   -   -   -   -   -   -   -   -   -   +   -
+EAP-TTLS/EAP-PAX	-   -   -   -   -   -   -   -   -   -   +   -
+EAP-TTLS/EAP-SAKE	-   -   -   -   -   -   -   -   -   -   +   -
+EAP-TTLS/EAP-GPSK	-   -   -   -   -   -   -   -   -   -   +   -
+EAP-SIM			+   -   -   ?   -   +   -   ?   -   -   +   -
 EAP-AKA			-   -   -   -   -   +   -   -   -   -   +   -
 EAP-PSK			+7  -   -   -   -   +   -   -   -   -   +   -
 EAP-PAX			-   -   -   -   -   +   -   -   -   -   +   -
@@ -87,47 +99,47 @@
 EAP-FAST/MSCHAPv2(auth)	-   -   -   -   -   -   -   -   -   -   +   +
 EAP-FAST/TLS(auth)	-   -   -   -   -   -   -   -   -   -   -   +
 LEAP			+   -   +   +   +   +   F   +6  -   +   -   +
-EAP-TNC			-   -   -   -   -   +   -   -   -   -   -   -
+EAP-TNC			+9  -   -   -   -   +   -   -   -   -   -   -
 
 1) PEAPv1 required new label, "client PEAP encryption" instead of "client EAP
    encryption", during key derivation (requires phase1="peaplabel=1" in the
    network configuration in wpa_supplicant.conf)
 2) used FreeRADIUS as inner auth server
-3) required a patch to FreeRADIUS to fix EAP-SIM
 5) PEAPv1 required termination of negotiation on tunneled EAP-Success and new
    label in key deriviation
    (phase1="peap_outer_success=0 peaplabel=1") (in "IETF Draft 5" mode)
 6) Authenticator simulator required patching for handling Access-Accept within
    negotiation (for the first EAP-Success of LEAP)
-7) EAP-PSK is not included in FreeRADIUS distribution; used external
-   rlm_eap_psk implementation from
-   http://perso.rd.francetelecom.fr/bersani/EAP_PSK/
-	EAP-PSKWindowsimplementations.html
+7) tested only with an older (incompatible) draft of EAP-PSK; FreeRADIUS does
+   not support the current EAP-PSK (RFC) specification
 8) PEAPv1 used non-standard version negotiation (client had to force v1 even
    though server reported v0 as the highest supported version)
+9) only EAP-TTLS/EAP-TNC tested, i.e., test did not include proper sequence of
+   client authentication followed by TNC inside the tunnel
 
 
 Automated tests:
 
-FreeRADIUS (1.0pre and CVS snapshot)
-- EAP-MD5-Challenge
-- EAP-GTC
-- EAP-MSCHAPv2
-- EAP-TLS
-- EAP-PEAPv0 / MSCHAPv2
-- EAP-PEAPv0 / GTC
-- EAP-PEAPv0 / MD5-Challenge
-- EAP-TTLS / EAP-MD5-Challenge
-- EAP-TTLS / EAP-GTC
-- EAP-TTLS / EAP-MSCHAPv2
-- EAP-TTLS / CHAP
-- EAP-TTLS / PAP
-- EAP-TTLS / MSCHAP
-- EAP-TTLS / MSCHAPv2
+FreeRADIUS (2.0-beta/CVS snapshot)
+- EAP-MD5-Challenge
+- EAP-GTC
+- EAP-MSCHAPv2
+- EAP-TLS
+- EAP-PEAPv0 / MSCHAPv2
+- EAP-PEAPv0 / GTC
+- EAP-PEAPv0 / MD5-Challenge
+- EAP-PEAPv0 / TLS
+- EAP-TTLS / EAP-MD5-Challenge
+- EAP-TTLS / EAP-GTC
+- EAP-TTLS / EAP-MSCHAPv2
+- EAP-TTLS / EAP-TLS
+- EAP-TTLS / CHAP
+- EAP-TTLS / PAP
+- EAP-TTLS / MSCHAP
+- EAP-TTLS / MSCHAPv2
+- EAP-TTLS / EAP-TNC (partial support; no authentication sequence)
 - EAP-SIM
-* not supported in FreeRADIUS
-  - EAP-PEAP / TLS (Unable to tunnel TLS inside of TLS)
-  - EAP-TTLS / EAP-TLS (Unable to tunnel TLS inside of TLS)
+- LEAP
 
 Microsoft Windows Server 2003 / IAS
 - EAP-TLS

Modified: wpasupplicant/trunk/wpa_supplicant/nmake.mak
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/nmake.mak?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/nmake.mak (original)
+++ wpasupplicant/trunk/wpa_supplicant/nmake.mak Tue Dec 25 15:23:24 2007
@@ -69,6 +69,7 @@
 	$(OBJDIR)\aes_wrap.obj \
 	$(OBJDIR)\common.obj \
 	$(OBJDIR)\wpa_debug.obj \
+	$(OBJDIR)\wpabuf.obj \
 	$(OBJDIR)\wpa_supplicant.obj \
 	$(OBJDIR)\wpa.obj \
 	$(OBJDIR)\wpa_common.obj \

Modified: wpasupplicant/trunk/wpa_supplicant/todo.txt
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/todo.txt?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/todo.txt (original)
+++ wpasupplicant/trunk/wpa_supplicant/todo.txt Tue Dec 25 15:23:24 2007
@@ -15,8 +15,6 @@
   authentication has been completed (cache scard data based on serial#(?)
   and try to optimize next connection if the same card is present for next
   auth)
-- EAP-AKA: AT_CHECKCODE
-- EAP-SIM/AKA: AT_RESULT_IND
 - on disconnect event, could try to associate with another AP if one is
   present in scan results; would need to update scan results periodically..
 - if driver/hw is not WPA2 capable, must remove WPA_PROTO_RSN flag from
@@ -44,22 +42,12 @@
 - test wait-for-interface and daemonize combinations with number of driver
   interfaces
   * 'test' worked with WPA-PSK
-- EAP-POTP/RSA SecurID profile (draft-nystrom-eap-potp-03.txt)
+- EAP-POTP/RSA SecurID profile (RFC 4793)
 - document wpa_gui build and consider adding it to 'make install'
 - test madwifi with pairwise=TKIP group=WEP104
 - possibility to link in WPA Authenticator state machine to wpa_supplicant
-  (new STAKey handshake, WPA2 IBSS)
+  (new PeerKey handshake, WPA2/IEEE 802.11 (RSN) IBSS)
 - consider merging hostapd and wpa_supplicant PMKSA cache implementations
-- consider adding generic buffer functionality that could be used in number
-  of places
-  * allocate buffer (with default max size), allow reserving head room to
-    make it possible to add a header without having to reallocate buffer
-  * reallocate buffer (add head and/or tail room)
-  * ref count and free when count=0 ?
-  * add data (to tail): re-alloc more tailroom if needed and copy new data
-  * error flag so that caller can do multiple add()s and only in the end
-    check whether something has failed; this should make error handling
-    simpler
 - consider redesigning pending EAP requests (identity/password/otp from
   ctrl_iface) by moving the retrying of the previous request into EAP
   state machine so that EAPOL state machine is not needed for this
@@ -80,7 +68,7 @@
   really needed for all cases, reading IMSI and generating Identity string
   could very well be done before EAP has been started
 - test all allowed EAP Phase 2 methods (i.e., anything else than PEAP, TTLS,
-  FAST): SIM AKA PAX PSK LEAP; if these work, include in eap_testing.txt; if
+  FAST): SIM AKA LEAP; if these work, include in eap_testing.txt; if
   not, either fix or make eap_allowed_phase2_type reject
   (EAP-TTLS/EAP-AKA and EAP-TTLS/EAP-SIM worked fine in wpa_supplicant, but
   hostapd did not support this due to pending data from hlr_auth_gw

Modified: wpasupplicant/trunk/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj (original)
+++ wpasupplicant/trunk/wpa_supplicant/vs2005/eapol_test/eapol_test.vcproj Tue Dec 25 15:23:24 2007
@@ -387,6 +387,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\..\src\utils\wpabuf.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\wpas_glue.c"
 				>
 			</File>

Modified: wpasupplicant/trunk/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj (original)
+++ wpasupplicant/trunk/wpa_supplicant/vs2005/wpa_supplicant/wpa_supplicant.vcproj Tue Dec 25 15:23:24 2007
@@ -383,6 +383,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\..\src\utils\wpabuf.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\wpas_glue.c"
 				>
 			</File>

Modified: wpasupplicant/trunk/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj (original)
+++ wpasupplicant/trunk/wpa_supplicant/vs2005/wpasvc/wpasvc.vcproj Tue Dec 25 15:23:24 2007
@@ -383,6 +383,10 @@
 				>
 			</File>
 			<File
+				RelativePath="..\..\..\src\utils\wpabuf.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\wpas_glue.c"
 				>
 			</File>

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c Tue Dec 25 15:23:24 2007
@@ -1762,7 +1762,7 @@
  *
  * This function can be used to dynamically remove network interfaces from
  * %wpa_supplicant, e.g., when a hotplug network adapter is ejected. In
- * addition, this function is used to remove all remaining interdaces when
+ * addition, this function is used to remove all remaining interfaces when
  * %wpa_supplicant is terminated.
  */
 int wpa_supplicant_remove_iface(struct wpa_global *global,

Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf?rev=923&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf Tue Dec 25 15:23:24 2007
@@ -380,6 +380,8 @@
 #	fragmented.
 #	sim_min_num_chal=3 can be used to configure EAP-SIM to require three
 #	challenges (by default, it accepts 2 or 3)
+#	result_ind=1 can be used to enable EAP-SIM and EAP-AKA to use
+#	protected result indication.
 # phase2: Phase2 (inner authentication with TLS tunnel) parameters
 #	(string with field-value pairs, e.g., "auth=MSCHAPV2" for EAP-PEAP or
 #	"autheap=MSCHAPV2 autheap=MD5" for EAP-TTLS)




More information about the Pkg-wpa-devel mailing list