wpa_supplicant: Update to 07-Jul-2012 TOT

commit a5ed45586c63ffd8f9d2b44e27c251d7bacbeaf4
Author: Jouni Malinen <j@w1.fi>
Date:   Sat Jul 7 13:01:45 2012 +0300

    WPS SSDP: Fix socket leaks on error paths

Change-Id: I0864aac7fc88fa2a60f5cca7d524b94363410c85
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 6a88589..8b43be4 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -1,6 +1,6 @@
 /*
  * EAP peer state machines (RFC 4137)
- * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -81,6 +81,16 @@
 }
 
 
+static void eap_notify_status(struct eap_sm *sm, const char *status,
+				      const char *parameter)
+{
+	wpa_printf(MSG_DEBUG, "EAP: Status notification: %s (param=%s)",
+		   status, parameter);
+	if (sm->eapol_cb->notify_status)
+		sm->eapol_cb->notify_status(sm->eapol_ctx, status, parameter);
+}
+
+
 static void eap_deinit_prev_method(struct eap_sm *sm, const char *txt)
 {
 	if (sm->m == NULL || sm->eap_method_priv == NULL)
@@ -213,6 +223,7 @@
 {
 	int reinit;
 	EapType method;
+	const struct eap_method *eap_method;
 
 	SM_ENTRY(EAP, GET_METHOD);
 
@@ -221,18 +232,24 @@
 	else
 		method = sm->reqMethod;
 
+	eap_method = eap_peer_get_eap_method(sm->reqVendor, method);
+
 	if (!eap_sm_allowMethod(sm, sm->reqVendor, method)) {
 		wpa_printf(MSG_DEBUG, "EAP: vendor %u method %u not allowed",
 			   sm->reqVendor, method);
 		wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
 			"vendor=%u method=%u -> NAK",
 			sm->reqVendor, method);
+		eap_notify_status(sm, "refuse proposed method",
+				  eap_method ?  eap_method->name : "unknown");
 		goto nak;
 	}
 
 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
 		"vendor=%u method=%u", sm->reqVendor, method);
 
+	eap_notify_status(sm, "accept proposed method",
+			  eap_method ?  eap_method->name : "unknown");
 	/*
 	 * RFC 4137 does not define specific operation for fast
 	 * re-authentication (session resumption). The design here is to allow
@@ -256,7 +273,7 @@
 
 	sm->selectedMethod = sm->reqMethod;
 	if (sm->m == NULL)
-		sm->m = eap_peer_get_eap_method(sm->reqVendor, method);
+		sm->m = eap_method;
 	if (!sm->m) {
 		wpa_printf(MSG_DEBUG, "EAP: Could not find selected method: "
 			   "vendor %d method %d",
@@ -938,7 +955,7 @@
 static int eap_sm_imsi_identity(struct eap_sm *sm,
 				struct eap_peer_config *conf)
 {
-	int aka = 0;
+	enum { EAP_SM_SIM, EAP_SM_AKA, EAP_SM_AKA_PRIME } method = EAP_SM_SIM;
 	char imsi[100];
 	size_t imsi_len;
 	struct eap_method_type *m = conf->eap_methods;
@@ -966,8 +983,14 @@
 	for (i = 0; m && (m[i].vendor != EAP_VENDOR_IETF ||
 			  m[i].method != EAP_TYPE_NONE); i++) {
 		if (m[i].vendor == EAP_VENDOR_IETF &&
+		    m[i].method == EAP_TYPE_AKA_PRIME) {
+			method = EAP_SM_AKA_PRIME;
+			break;
+		}
+
+		if (m[i].vendor == EAP_VENDOR_IETF &&
 		    m[i].method == EAP_TYPE_AKA) {
-			aka = 1;
+			method = EAP_SM_AKA;
 			break;
 		}
 	}
@@ -980,7 +1003,17 @@
 		return -1;
 	}
 
-	conf->identity[0] = aka ? '0' : '1';
+	switch (method) {
+	case EAP_SM_SIM:
+		conf->identity[0] = '1';
+		break;
+	case EAP_SM_AKA:
+		conf->identity[0] = '0';
+		break;
+	case EAP_SM_AKA_PRIME:
+		conf->identity[0] = '6';
+		break;
+	}
 	os_memcpy(conf->identity + 1, imsi, imsi_len);
 	conf->identity_len = 1 + imsi_len;
 
@@ -1219,10 +1252,12 @@
 		break;
 	case EAP_CODE_SUCCESS:
 		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Success");
+		eap_notify_status(sm, "completion", "success");
 		sm->rxSuccess = TRUE;
 		break;
 	case EAP_CODE_FAILURE:
 		wpa_printf(MSG_DEBUG, "EAP: Received EAP-Failure");
+		eap_notify_status(sm, "completion", "failure");
 		sm->rxFailure = TRUE;
 		break;
 	default:
@@ -1240,6 +1275,10 @@
 	char *hash_hex = NULL;
 
 	switch (ev) {
+	case TLS_CERT_CHAIN_SUCCESS:
+		eap_notify_status(sm, "remote certificate verification",
+				  "success");
+		break;
 	case TLS_CERT_CHAIN_FAILURE:
 		wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR
 			"reason=%d depth=%d subject='%s' err='%s'",
@@ -1247,6 +1286,8 @@
 			data->cert_fail.depth,
 			data->cert_fail.subject,
 			data->cert_fail.reason_txt);
+		eap_notify_status(sm, "remote certificate verification",
+				  data->cert_fail.reason_txt);
 		break;
 	case TLS_PEER_CERTIFICATE:
 		if (!sm->eapol_cb->notify_cert)
@@ -1267,6 +1308,14 @@
 					  data->peer_cert.subject,
 					  hash_hex, data->peer_cert.cert);
 		break;
+	case TLS_ALERT:
+		if (data->alert.is_local)
+			eap_notify_status(sm, "local TLS alert",
+					  data->alert.description);
+		else
+			eap_notify_status(sm, "remote TLS alert",
+					  data->alert.description);
+		break;
 	}
 
 	os_free(hash_hex);
@@ -1321,6 +1370,13 @@
 		return NULL;
 	}
 
+	sm->ssl_ctx2 = tls_init(&tlsconf);
+	if (sm->ssl_ctx2 == NULL) {
+		wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS "
+			   "context (2).");
+		/* Run without separate TLS context within TLS tunnel */
+	}
+
 	return sm;
 }
 
@@ -1338,6 +1394,8 @@
 		return;
 	eap_deinit_prev_method(sm, "EAP deinit");
 	eap_sm_abort(sm);
+	if (sm->ssl_ctx2)
+		tls_deinit(sm->ssl_ctx2);
 	tls_deinit(sm->ssl_ctx);
 	os_free(sm);
 }