Cumulative patch from commit 390b92913a9a1b3a6aaf70e8b5971a7b7c76cabc

390b929 TLS testing: Allow hostapd to be used as a TLS testing tool
994afe3 RADIUS server: Allow TLS implementation add log entries
01f7fe1 RADIUS server: Allow EAP methods to log into SQLite DB
8a57da7 RADIUS server: Add option for storing log information to SQLite DB
f3ef7a2 TLS client: Send decrypt_error on verify_data validation error
129b9b9 TLS: Share a helper function for verifying Signature
6531963 TLS: Use a helper function for calculating ServerKeyExchange hash
65074a2 TLS: Add support for DHE-RSA cipher suites
41ebfe9 TLS server: Enable SHA256-based cipher suites
60b893d wpa_supplicant: Allow external management frame processing for testing
ec33bc6 Enable RADIUS message dumps with excessive debug verbosity
226e357 Revert "bridge: Track inter-BSS usage"
d0ee16e Allow arbitrary RADIUS attributes to be added into Access-Accept
0ac3876 Fix PMF protect disconnection on session timeout
49021c1 Fix hostapd error path regression

Change-Id: Ie0710c036cca2fb370d28684cc5a5d28a075dfc1
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h
index 197b232..698a5ac 100644
--- a/src/eap_server/eap.h
+++ b/src/eap_server/eap.h
@@ -35,6 +35,7 @@
 	unsigned int remediation:1;
 	int ttls_auth; /* bitfield of
 			* EAP_TTLS_AUTH_{PAP,CHAP,MSCHAP,MSCHAPV2} */
+	struct hostapd_radius_attr *accept_attr;
 };
 
 struct eap_eapol_interface {
@@ -80,6 +81,7 @@
 	int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
 			    int phase2, struct eap_user *user);
 	const char * (*get_eap_req_id_text)(void *ctx, size_t *len);
+	void (*log_msg)(void *ctx, const char *msg);
 };
 
 struct eap_config {
@@ -108,6 +110,10 @@
 
 	const u8 *server_id;
 	size_t server_id_len;
+
+#ifdef CONFIG_TESTING_OPTIONS
+	u32 tls_test_flags;
+#endif /* CONFIG_TESTING_OPTIONS */
 };
 
 
diff --git a/src/eap_server/eap_i.h b/src/eap_server/eap_i.h
index 003e202..3a6802b 100644
--- a/src/eap_server/eap_i.h
+++ b/src/eap_server/eap_i.h
@@ -191,10 +191,16 @@
 
 	const u8 *server_id;
 	size_t server_id_len;
+
+#ifdef CONFIG_TESTING_OPTIONS
+	u32 tls_test_flags;
+#endif /* CONFIG_TESTING_OPTIONS */
 };
 
 int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
 		 int phase2);
+void eap_log_msg(struct eap_sm *sm, const char *fmt, ...)
+PRINTF_FORMAT(2, 3);
 void eap_sm_process_nak(struct eap_sm *sm, const u8 *nak_list, size_t len);
 
 #endif /* EAP_I_H */
diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c
index 233e272..65d00dd 100644
--- a/src/eap_server/eap_server.c
+++ b/src/eap_server/eap_server.c
@@ -119,6 +119,32 @@
 }
 
 
+void eap_log_msg(struct eap_sm *sm, const char *fmt, ...)
+{
+	va_list ap;
+	char *buf;
+	int buflen;
+
+	if (sm == NULL || sm->eapol_cb == NULL || sm->eapol_cb->log_msg == NULL)
+		return;
+
+	va_start(ap, fmt);
+	buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
+	va_end(ap);
+
+	buf = os_malloc(buflen);
+	if (buf == NULL)
+		return;
+	va_start(ap, fmt);
+	vsnprintf(buf, buflen, fmt, ap);
+	va_end(ap);
+
+	sm->eapol_cb->log_msg(sm->eapol_ctx, buf);
+
+	os_free(buf);
+}
+
+
 SM_STATE(EAP, DISABLED)
 {
 	SM_ENTRY(EAP, DISABLED);
@@ -366,6 +392,7 @@
 	}
 	if (sm->m == NULL) {
 		wpa_printf(MSG_DEBUG, "EAP: Could not find suitable EAP method");
+		eap_log_msg(sm, "Could not find suitable EAP method");
 		sm->decision = DECISION_FAILURE;
 		return;
 	}
@@ -377,6 +404,8 @@
 
 	wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_PROPOSED_METHOD
 		"vendor=%u method=%u", vendor, sm->currentMethod);
+	eap_log_msg(sm, "Propose EAP method vendor=%u method=%u",
+		    vendor, sm->currentMethod);
 }
 
 
@@ -693,6 +722,7 @@
 				   "respMethod=%d currentMethod=%d",
 				   sm->rxResp, sm->respId, sm->currentId,
 				   sm->respMethod, sm->currentMethod);
+			eap_log_msg(sm, "Discard received EAP message");
 			SM_ENTER(EAP, DISCARD);
 		}
 		break;
@@ -1297,6 +1327,10 @@
 	sm->server_id = conf->server_id;
 	sm->server_id_len = conf->server_id_len;
 
+#ifdef CONFIG_TESTING_OPTIONS
+	sm->tls_test_flags = conf->tls_test_flags;
+#endif /* CONFIG_TESTING_OPTIONS */
+
 	wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
 
 	return sm;
diff --git a/src/eap_server/eap_server_identity.c b/src/eap_server/eap_server_identity.c
index 51dc4e8..b3c2087 100644
--- a/src/eap_server/eap_server_identity.c
+++ b/src/eap_server/eap_server_identity.c
@@ -102,6 +102,7 @@
 	struct eap_identity_data *data = priv;
 	const u8 *pos;
 	size_t len;
+	char *buf;
 
 	if (data->pick_up) {
 		if (eap_identity_check(sm, data, respData)) {
@@ -119,6 +120,12 @@
 		return; /* Should not happen - frame already validated */
 
 	wpa_hexdump_ascii(MSG_DEBUG, "EAP-Identity: Peer identity", pos, len);
+	buf = os_malloc(len * 3 + 1);
+	if (buf) {
+		printf_encode(buf, len * 3 + 1, pos, len);
+		eap_log_msg(sm, "EAP-Response/Identity '%s'", buf);
+		os_free(buf);
+	}
 	if (sm->identity)
 		sm->update_user = TRUE;
 	os_free(sm->identity);
diff --git a/src/eap_server/eap_server_mschapv2.c b/src/eap_server/eap_server_mschapv2.c
index 3153d2e..790c719 100644
--- a/src/eap_server/eap_server_mschapv2.c
+++ b/src/eap_server/eap_server_mschapv2.c
@@ -290,6 +290,7 @@
 	const u8 *username, *user;
 	size_t username_len, user_len;
 	int res;
+	char *buf;
 
 	pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_MSCHAPV2, respData,
 			       &len);
@@ -329,6 +330,13 @@
 	wpa_printf(MSG_MSGDUMP, "EAP-MSCHAPV2: Flags 0x%x", flags);
 	wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-MSCHAPV2: Name", name, name_len);
 
+	buf = os_malloc(name_len * 3 + 1);
+	if (buf) {
+		printf_encode(buf, name_len * 3 + 1, name, name_len);
+		eap_log_msg(sm, "EAP-MSCHAPV2 Name '%s'", buf);
+		os_free(buf);
+	}
+
 	/* MSCHAPv2 does not include optional domain name in the
 	 * challenge-response calculation, so remove domain prefix
 	 * (if present). */
diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c
index de5ab0d..01853e6 100644
--- a/src/eap_server/eap_server_tls_common.c
+++ b/src/eap_server/eap_server_tls_common.c
@@ -34,6 +34,15 @@
 }
 
 
+#ifdef CONFIG_TLS_INTERNAL
+static void eap_server_tls_log_cb(void *ctx, const char *msg)
+{
+	struct eap_sm *sm = ctx;
+	eap_log_msg(sm, "TLS: %s", msg);
+}
+#endif /* CONFIG_TLS_INTERNAL */
+
+
 int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
 			    int verify_peer)
 {
@@ -52,6 +61,13 @@
 		return -1;
 	}
 
+#ifdef CONFIG_TLS_INTERNAL
+	tls_connection_set_log_cb(data->conn, eap_server_tls_log_cb, sm);
+#ifdef CONFIG_TESTING_OPTIONS
+	tls_connection_set_test_flags(data->conn, sm->tls_test_flags);
+#endif /* CONFIG_TESTING_OPTIONS */
+#endif /* CONFIG_TLS_INTERNAL */
+
 	if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) {
 		wpa_printf(MSG_INFO, "SSL: Failed to configure verification "
 			   "of TLS peer certificate");
diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c
index 647bd2f..24225a4 100644
--- a/src/eap_server/eap_server_ttls.c
+++ b/src/eap_server/eap_server_ttls.c
@@ -984,6 +984,16 @@
 	}
 
 	if (parse.user_name) {
+		char *nbuf;
+		nbuf = os_malloc(parse.user_name_len * 3 + 1);
+		if (nbuf) {
+			printf_encode(nbuf, parse.user_name_len * 3 + 1,
+				      parse.user_name,
+				      parse.user_name_len);
+			eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf);
+			os_free(nbuf);
+		}
+
 		os_free(sm->identity);
 		sm->identity = os_malloc(parse.user_name_len);
 		if (sm->identity == NULL) {