Cumulative patch from commit 20ff2642e192437245422c9654463bcebf65b277

20ff264 WPS: Clear WPS data on init failure
f19e370 WPS: Do not advertise WPA/WPA2-Enterprise Auth Type Flags
1b5df9e nl80211: Do not indicate scan started event on scan_for_auth
bb23826 HS 2.0R2: Clean up debug log during exit path
48408fc HS 2.0R2: Do not mandate OCSP response for EST operations
8f60293 HS 2.0R2: Do not use OSU cert validation for EST
40bdcea HS 2.0R2: Configure OSU client trust root more consistently
4d65ded HS 2.0R2: Clean up debug from libcurl

Change-Id: I44aa20ac92abf03ea7b47f1ecad72dc07a0870d9
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/hs20/client/est.c b/hs20/client/est.c
index c1d514a..ec05bc4 100644
--- a/hs20/client/est.c
+++ b/hs20/client/est.c
@@ -1,6 +1,6 @@
 /*
  * Hotspot 2.0 OSU client - EST client
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -108,8 +108,13 @@
 	os_snprintf(buf, buflen, "%s/cacerts", url);
 	wpa_printf(MSG_INFO, "Download EST cacerts from %s", buf);
 	write_summary(ctx, "Download EST cacerts from %s", buf);
+	ctx->no_osu_cert_validation = 1;
+	http_ocsp_set(ctx->http, 1);
 	res = http_download_file(ctx->http, buf, "Cert/est-cacerts.txt",
 				 ctx->ca_fname);
+	http_ocsp_set(ctx->http,
+		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
+	ctx->no_osu_cert_validation = 0;
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "Failed to download EST cacerts from %s",
 			   buf);
@@ -550,8 +555,13 @@
 	os_snprintf(buf, buflen, "%s/csrattrs", url);
 	wpa_printf(MSG_INFO, "Download csrattrs from %s", buf);
 	write_summary(ctx, "Download EST csrattrs from %s", buf);
+	ctx->no_osu_cert_validation = 1;
+	http_ocsp_set(ctx->http, 1);
 	res = http_download_file(ctx->http, buf, "Cert/est-csrattrs.txt",
 				 ctx->ca_fname);
+	http_ocsp_set(ctx->http,
+		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
+	ctx->no_osu_cert_validation = 0;
 	os_free(buf);
 	if (res < 0) {
 		wpa_printf(MSG_INFO, "Failed to download EST csrattrs - assume no extra attributes are needed");
@@ -647,10 +657,15 @@
 		os_snprintf(buf, buflen, "%s/simpleenroll", url);
 	wpa_printf(MSG_INFO, "EST simpleenroll URL: %s", buf);
 	write_summary(ctx, "EST simpleenroll URL: %s", buf);
+	ctx->no_osu_cert_validation = 1;
+	http_ocsp_set(ctx->http, 1);
 	resp = http_post(ctx->http, buf, req, "application/pkcs10",
 			 "Content-Transfer-Encoding: base64",
 			 ctx->ca_fname, user, pw, client_cert, client_key,
 			 &resp_len);
+	http_ocsp_set(ctx->http,
+		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
+	ctx->no_osu_cert_validation = 0;
 	os_free(buf);
 	if (resp == NULL) {
 		wpa_printf(MSG_INFO, "EST certificate enrollment failed");
diff --git a/hs20/client/oma_dm_client.c b/hs20/client/oma_dm_client.c
index 8fc350b..82e9106 100644
--- a/hs20/client/oma_dm_client.c
+++ b/hs20/client/oma_dm_client.c
@@ -1,6 +1,6 @@
 /*
  * Hotspot 2.0 - OMA DM client
- * Copyright (c) 2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -909,7 +909,7 @@
 
 static xml_node_t * oma_dm_send_recv(struct hs20_osu_client *ctx,
 				     const char *url, xml_node_t *syncml,
-				     const char *ext_hdr, const char *ca_fname,
+				     const char *ext_hdr,
 				     const char *username, const char *password,
 				     const char *client_cert,
 				     const char *client_key)
@@ -928,7 +928,7 @@
 	os_free(ctx->server_url);
 	ctx->server_url = os_strdup(url);
 	res = http_post(ctx->http, url, str, "application/vnd.syncml.dm+xml",
-			ext_hdr, ca_fname, username, password,
+			ext_hdr, ctx->ca_fname, username, password,
 			client_cert, client_key, NULL);
 	os_free(str);
 	os_free(resp_uri);
@@ -1123,8 +1123,7 @@
 }
 
 
-int cmd_oma_dm_prov(struct hs20_osu_client *ctx, const char *url,
-		    const char *ca_fname)
+int cmd_oma_dm_prov(struct hs20_osu_client *ctx, const char *url)
 {
 	xml_node_t *syncml, *resp;
 	char *resp_uri = NULL;
@@ -1145,8 +1144,7 @@
 
 	while (syncml) {
 		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : url,
-					syncml, NULL, ca_fname, NULL, NULL,
-					NULL, NULL);
+					syncml, NULL, NULL, NULL, NULL, NULL);
 		if (resp == NULL)
 			return -1;
 
@@ -1162,8 +1160,7 @@
 }
 
 
-int cmd_oma_dm_sim_prov(struct hs20_osu_client *ctx, const char *url,
-			const char *ca_fname)
+int cmd_oma_dm_sim_prov(struct hs20_osu_client *ctx, const char *url)
 {
 	xml_node_t *syncml, *resp;
 	char *resp_uri = NULL;
@@ -1192,8 +1189,7 @@
 
 	while (syncml) {
 		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : url,
-					syncml, NULL, ca_fname, NULL, NULL,
-					NULL, NULL);
+					syncml, NULL, NULL, NULL, NULL, NULL);
 		if (resp == NULL)
 			return -1;
 
@@ -1223,7 +1219,7 @@
 
 
 void oma_dm_pol_upd(struct hs20_osu_client *ctx, const char *address,
-		    const char *pps_fname, const char *ca_fname,
+		    const char *pps_fname,
 		    const char *client_cert, const char *client_key,
 		    const char *cred_username, const char *cred_password,
 		    xml_node_t *pps)
@@ -1242,7 +1238,7 @@
 
 	while (syncml) {
 		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : address,
-					syncml, NULL, ca_fname, cred_username,
+					syncml, NULL, cred_username,
 					cred_password, client_cert, client_key);
 		if (resp == NULL)
 			return;
@@ -1270,7 +1266,7 @@
 
 
 void oma_dm_sub_rem(struct hs20_osu_client *ctx, const char *address,
-		    const char *pps_fname, const char *ca_fname,
+		    const char *pps_fname,
 		    const char *client_cert, const char *client_key,
 		    const char *cred_username, const char *cred_password,
 		    xml_node_t *pps)
@@ -1289,7 +1285,7 @@
 
 	while (syncml) {
 		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : address,
-					syncml, NULL, ca_fname, cred_username,
+					syncml, NULL, cred_username,
 					cred_password, client_cert, client_key);
 		if (resp == NULL)
 			return;
diff --git a/hs20/client/osu_client.c b/hs20/client/osu_client.c
index 2175fc3..ea269ab 100644
--- a/hs20/client/osu_client.c
+++ b/hs20/client/osu_client.c
@@ -1,6 +1,6 @@
 /*
  * Hotspot 2.0 OSU client
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -302,7 +302,12 @@
 	xml_node_get_text_free(ctx->xml, hash);
 
 	write_summary(ctx, "Download certificate from %s", url);
+	ctx->no_osu_cert_validation = 1;
+	http_ocsp_set(ctx->http, 1);
 	res = http_download_file(ctx->http, url, TMP_CERT_DL_FILE, NULL);
+	http_ocsp_set(ctx->http,
+		      (ctx->workarounds & WORKAROUND_OCSP_OPTIONAL) ? 1 : 2);
+	ctx->no_osu_cert_validation = 0;
 	xml_node_get_text_free(ctx->xml, url);
 	if (res < 0)
 		return -1;
@@ -1993,7 +1998,7 @@
 
 
 static int osu_connect(struct hs20_osu_client *ctx, const char *bssid,
-		       const char *ssid, const char *url, const char *ca_fname,
+		       const char *ssid, const char *url,
 		       unsigned int methods, int no_prod_assoc,
 		       const char *osu_nai)
 {
@@ -2068,9 +2073,9 @@
 
 	ctx->no_reconnect = 1;
 	if (methods & 0x02)
-		res = cmd_prov(ctx, url, ca_fname);
+		res = cmd_prov(ctx, url);
 	else if (methods & 0x01)
-		res = cmd_oma_dm_prov(ctx, url, ca_fname);
+		res = cmd_oma_dm_prov(ctx, url);
 
 	wpa_printf(MSG_INFO, "Remove OSU network connection");
 	write_summary(ctx, "Remove OSU network connection");
@@ -2093,7 +2098,7 @@
 
 
 static int cmd_osu_select(struct hs20_osu_client *ctx, const char *dir,
-			  int connect, const char *ca_fname, int no_prod_assoc,
+			  int connect, int no_prod_assoc,
 			  const char *friendly_name)
 {
 	char fname[255];
@@ -2264,14 +2269,14 @@
 
 		if (connect == 2) {
 			if (last->methods & 0x02)
-				ret = cmd_prov(ctx, last->url, ca_fname);
+				ret = cmd_prov(ctx, last->url);
 			else if (last->methods & 0x01)
-				ret = cmd_oma_dm_prov(ctx, last->url, ca_fname);
+				ret = cmd_oma_dm_prov(ctx, last->url);
 			else
 				ret = -1;
 		} else if (connect)
 			ret = osu_connect(ctx, last->bssid, last->osu_ssid,
-					  last->url, ca_fname, last->methods,
+					  last->url, last->methods,
 					  no_prod_assoc, last->osu_nai);
 	} else
 		ret = -1;
@@ -2282,8 +2287,8 @@
 }
 
 
-static int cmd_signup(struct hs20_osu_client *ctx, const char *ca_fname,
-		      int no_prod_assoc, const char *friendly_name)
+static int cmd_signup(struct hs20_osu_client *ctx, int no_prod_assoc,
+		      const char *friendly_name)
 {
 	char dir[255];
 	char fname[300], buf[400];
@@ -2334,8 +2339,7 @@
 	}
 	wpa_printf(MSG_INFO, "OSU provider fetch completed");
 
-	return cmd_osu_select(ctx, fname, 1, ca_fname, no_prod_assoc,
-			      friendly_name);
+	return cmd_osu_select(ctx, fname, 1, no_prod_assoc, friendly_name);
 }
 
 
@@ -2354,8 +2358,6 @@
 	char *client_key = NULL;
 	int spp;
 
-	ctx->ca_fname = ca_fname;
-
 	wpa_printf(MSG_INFO, "Subscription remediation requested with Server URL: %s",
 		   address);
 
@@ -2399,6 +2401,7 @@
 		return;
 	}
 	wpa_printf(MSG_INFO, "Using server trust root: %s", ca_fname);
+	ctx->ca_fname = ca_fname;
 
 	pps = node_from_file(ctx->xml, pps_fname);
 	if (pps == NULL) {
@@ -2482,11 +2485,11 @@
 	}
 
 	if (spp)
-		spp_sub_rem(ctx, address, pps_fname, ca_fname,
+		spp_sub_rem(ctx, address, pps_fname,
 			    client_cert, client_key,
 			    cred_username, cred_password, pps);
 	else
-		oma_dm_sub_rem(ctx, address, pps_fname, ca_fname,
+		oma_dm_sub_rem(ctx, address, pps_fname,
 			       client_cert, client_key,
 			       cred_username, cred_password, pps);
 
@@ -2555,6 +2558,7 @@
 		return -1;
 	}
 	wpa_printf(MSG_INFO, "Using server trust root: %s", ca_fname);
+	ctx->ca_fname = ca_fname;
 
 	pps = node_from_file(ctx->xml, pps_fname);
 	if (pps == NULL) {
@@ -2628,11 +2632,11 @@
 	}
 
 	if (spp)
-		spp_pol_upd(ctx, address, pps_fname, ca_fname,
+		spp_pol_upd(ctx, address, pps_fname,
 			    client_cert, client_key,
 			    cred_username, cred_password, pps);
 	else
-		oma_dm_pol_upd(ctx, address, pps_fname, ca_fname,
+		oma_dm_pol_upd(ctx, address, pps_fname,
 			       client_cert, client_key,
 			       cred_username, cred_password, pps);
 
@@ -2693,7 +2697,8 @@
 	int found;
 	char *host = NULL;
 
-	wpa_printf(MSG_INFO, "osu_cert_cb");
+	wpa_printf(MSG_INFO, "osu_cert_cb(osu_cert_validation=%d)",
+		   !ctx->no_osu_cert_validation);
 
 	host = get_hostname(ctx->server_url);
 
@@ -2737,7 +2742,8 @@
 		}
 	}
 
-	for (j = 0; j < ctx->friendly_name_count; j++) {
+	for (j = 0; !ctx->no_osu_cert_validation &&
+		     j < ctx->friendly_name_count; j++) {
 		int found = 0;
 		for (i = 0; i < cert->num_othername; i++) {
 			if (os_strcmp(cert->othername[i].oid,
@@ -2776,7 +2782,7 @@
 				  logo->hash, logo->hash_len);
 	}
 
-	for (j = 0; j < ctx->icon_count; j++) {
+	for (j = 0; !ctx->no_osu_cert_validation && j < ctx->icon_count; j++) {
 		int found = 0;
 		char *name = ctx->icon_filename[j];
 		size_t name_len = os_strlen(name);
@@ -2812,7 +2818,7 @@
 		}
 	}
 
-	for (j = 0; j < ctx->icon_count; j++) {
+	for (j = 0; !ctx->no_osu_cert_validation && j < ctx->icon_count; j++) {
 		int found = 0;
 
 		for (i = 0; i < cert->num_logo; i++) {
@@ -3077,13 +3083,15 @@
 			usage();
 			exit(0);
 		}
-		cmd_prov(&ctx, argv[optind + 1], argv[optind + 2]);
+		ctx.ca_fname = argv[optind + 2];
+		cmd_prov(&ctx, argv[optind + 1]);
 	} else if (strcmp(argv[optind], "sim_prov") == 0) {
 		if (argc - optind < 2) {
 			usage();
 			exit(0);
 		}
-		cmd_sim_prov(&ctx, argv[optind + 1], argv[optind + 2]);
+		ctx.ca_fname = argv[optind + 2];
+		cmd_sim_prov(&ctx, argv[optind + 1]);
 	} else if (strcmp(argv[optind], "dl_osu_ca") == 0) {
 		if (argc - optind < 2) {
 			usage();
@@ -3107,13 +3115,11 @@
 			usage();
 			exit(0);
 		}
-		cmd_osu_select(&ctx, argv[optind + 1], 2,
-			       argc > optind + 2 ? argv[optind + 2] : NULL,
-			       1, NULL);
+		ctx.ca_fname = argc > optind + 2 ? argv[optind + 2] : NULL;
+		cmd_osu_select(&ctx, argv[optind + 1], 2, 1, NULL);
 	} else if (strcmp(argv[optind], "signup") == 0) {
-		ret = cmd_signup(&ctx,
-				 argc > optind + 1 ? argv[optind + 1] : NULL,
-				 no_prod_assoc, friendly_name);
+		ctx.ca_fname = argc > optind + 1 ? argv[optind + 1] : NULL;
+		ret = cmd_signup(&ctx, no_prod_assoc, friendly_name);
 	} else if (strcmp(argv[optind], "set_pps") == 0) {
 		if (argc - optind < 2) {
 			usage();
@@ -3131,14 +3137,15 @@
 			usage();
 			exit(0);
 		}
-		cmd_oma_dm_prov(&ctx, argv[optind + 1], argv[optind + 2]);
+		ctx.ca_fname = argv[optind + 2];
+		cmd_oma_dm_prov(&ctx, argv[optind + 1]);
 	} else if (strcmp(argv[optind], "oma_dm_sim_prov") == 0) {
 		if (argc - optind < 2) {
 			usage();
 			exit(0);
 		}
-		if (cmd_oma_dm_sim_prov(&ctx, argv[optind + 1],
-					argv[optind + 2]) < 0) {
+		ctx.ca_fname = argv[optind + 2];
+		if (cmd_oma_dm_sim_prov(&ctx, argv[optind + 1]) < 0) {
 			write_summary(&ctx, "Failed to complete OMA DM SIM provisioning");
 			return -1;
 		}
@@ -3186,11 +3193,11 @@
 		wpa_printf(MSG_INFO, "Unknown command '%s'", argv[optind]);
 	}
 
+	deinit_ctx(&ctx);
 	wpa_printf(MSG_DEBUG,
 		   "===[hs20-osu-client END ]======================");
 
 	wpa_debug_close_file();
-	deinit_ctx(&ctx);
 
 	return ret;
 }
diff --git a/hs20/client/osu_client.h b/hs20/client/osu_client.h
index ef568b4..9a7059e 100644
--- a/hs20/client/osu_client.h
+++ b/hs20/client/osu_client.h
@@ -1,6 +1,6 @@
 /*
  * Hotspot 2.0 - OSU client
- * Copyright (c) 2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -34,6 +34,7 @@
 	const char *summary_file;
 	const char *ifname;
 	const char *ca_fname;
+	int no_osu_cert_validation; /* for EST operations */
 	char *fqdn;
 	char *server_url;
 	struct osu_lang_text friendly_name[MAX_OSU_VALS];
@@ -73,39 +74,35 @@
 /* spp_client.c */
 
 void spp_sub_rem(struct hs20_osu_client *ctx, const char *address,
-		 const char *pps_fname, const char *ca_fname,
+		 const char *pps_fname,
 		 const char *client_cert, const char *client_key,
 		 const char *cred_username, const char *cred_password,
 		 xml_node_t *pps);
 void spp_pol_upd(struct hs20_osu_client *ctx, const char *address,
-		 const char *pps_fname, const char *ca_fname,
+		 const char *pps_fname,
 		 const char *client_cert, const char *client_key,
 		 const char *cred_username, const char *cred_password,
 		 xml_node_t *pps);
-int cmd_prov(struct hs20_osu_client *ctx, const char *url,
-	     const char *ca_fname);
-int cmd_sim_prov(struct hs20_osu_client *ctx, const char *url,
-		 const char *ca_fname);
+int cmd_prov(struct hs20_osu_client *ctx, const char *url);
+int cmd_sim_prov(struct hs20_osu_client *ctx, const char *url);
 
 
 /* oma_dm_client.c */
 
-int cmd_oma_dm_prov(struct hs20_osu_client *ctx, const char *url,
-		    const char *ca_fname);
-int cmd_oma_dm_sim_prov(struct hs20_osu_client *ctx, const char *url,
-			const char *ca_fname);
+int cmd_oma_dm_prov(struct hs20_osu_client *ctx, const char *url);
+int cmd_oma_dm_sim_prov(struct hs20_osu_client *ctx, const char *url);
 void oma_dm_sub_rem(struct hs20_osu_client *ctx, const char *address,
-		    const char *pps_fname, const char *ca_fname,
+		    const char *pps_fname,
 		    const char *client_cert, const char *client_key,
 		    const char *cred_username, const char *cred_password,
 		    xml_node_t *pps);
 void oma_dm_pol_upd(struct hs20_osu_client *ctx, const char *address,
-		    const char *pps_fname, const char *ca_fname,
+		    const char *pps_fname,
 		    const char *client_cert, const char *client_key,
 		    const char *cred_username, const char *cred_password,
 		    xml_node_t *pps);
 void cmd_oma_dm_sub_rem(struct hs20_osu_client *ctx, const char *address,
-			const char *pps_fname, const char *ca_fname);
+			const char *pps_fname);
 void cmd_oma_dm_add(struct hs20_osu_client *ctx, const char *pps_fname,
 		    const char *add_fname);
 void cmd_oma_dm_replace(struct hs20_osu_client *ctx, const char *pps_fname,
diff --git a/hs20/client/spp_client.c b/hs20/client/spp_client.c
index 8022ccb..302a050 100644
--- a/hs20/client/spp_client.c
+++ b/hs20/client/spp_client.c
@@ -1,6 +1,6 @@
 /*
  * Hotspot 2.0 SPP client
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -776,7 +776,7 @@
 
 
 void spp_sub_rem(struct hs20_osu_client *ctx, const char *address,
-		 const char *pps_fname, const char *ca_fname,
+		 const char *pps_fname,
 		 const char *client_cert, const char *client_key,
 		 const char *cred_username, const char *cred_password,
 		 xml_node_t *pps)
@@ -787,7 +787,7 @@
 	os_free(ctx->server_url);
 	ctx->server_url = os_strdup(address);
 
-	if (soap_init_client(ctx->http, address, ca_fname,
+	if (soap_init_client(ctx->http, address, ctx->ca_fname,
 			     cred_username, cred_password, client_cert,
 			     client_key) == 0) {
 		spp_post_dev_data(ctx, SPP_SUBSCRIPTION_REMEDIATION,
@@ -923,7 +923,7 @@
 
 
 void spp_pol_upd(struct hs20_osu_client *ctx, const char *address,
-		 const char *pps_fname, const char *ca_fname,
+		 const char *pps_fname,
 		 const char *client_cert, const char *client_key,
 		 const char *cred_username, const char *cred_password,
 		 xml_node_t *pps)
@@ -934,7 +934,7 @@
 	os_free(ctx->server_url);
 	ctx->server_url = os_strdup(address);
 
-	if (soap_init_client(ctx->http, address, ca_fname, cred_username,
+	if (soap_init_client(ctx->http, address, ctx->ca_fname, cred_username,
 			     cred_password, client_cert, client_key) == 0) {
 		spp_post_dev_data(ctx, SPP_POLICY_UPDATE, "Policy update",
 				  pps_fname, pps);
@@ -942,14 +942,11 @@
 }
 
 
-int cmd_prov(struct hs20_osu_client *ctx, const char *url,
-	     const char *ca_fname)
+int cmd_prov(struct hs20_osu_client *ctx, const char *url)
 {
 	unlink("Cert/est_cert.der");
 	unlink("Cert/est_cert.pem");
 
-	ctx->ca_fname = ca_fname;
-
 	if (url == NULL) {
 		wpa_printf(MSG_INFO, "Invalid prov command (missing URL)");
 		return -1;
@@ -960,8 +957,8 @@
 	os_free(ctx->server_url);
 	ctx->server_url = os_strdup(url);
 
-	if (soap_init_client(ctx->http, url, ca_fname, NULL, NULL, NULL, NULL) <
-	    0)
+	if (soap_init_client(ctx->http, url, ctx->ca_fname, NULL, NULL, NULL,
+			     NULL) < 0)
 		return -1;
 	spp_post_dev_data(ctx, SPP_SUBSCRIPTION_REGISTRATION,
 			  "Subscription registration", NULL, NULL);
@@ -970,11 +967,8 @@
 }
 
 
-int cmd_sim_prov(struct hs20_osu_client *ctx, const char *url,
-	     const char *ca_fname)
+int cmd_sim_prov(struct hs20_osu_client *ctx, const char *url)
 {
-	ctx->ca_fname = ca_fname;
-
 	if (url == NULL) {
 		wpa_printf(MSG_INFO, "Invalid prov command (missing URL)");
 		return -1;
@@ -991,8 +985,8 @@
 		wpa_printf(MSG_INFO, "Could not get IP address for WLAN - try connection anyway");
 	}
 
-	if (soap_init_client(ctx->http, url, ca_fname, NULL, NULL, NULL, NULL) <
-	    0)
+	if (soap_init_client(ctx->http, url, ctx->ca_fname, NULL, NULL, NULL,
+			     NULL) < 0)
 		return -1;
 	spp_post_dev_data(ctx, SPP_SUBSCRIPTION_REGISTRATION,
 			  "Subscription provisioning", NULL, NULL);
diff --git a/src/ap/wps_hostapd.c b/src/ap/wps_hostapd.c
index 3a40125..62cd03c 100644
--- a/src/ap/wps_hostapd.c
+++ b/src/ap/wps_hostapd.c
@@ -40,6 +40,7 @@
 				    const u8 *ie, size_t ie_len,
 				    int ssi_signal);
 static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
+static void hostapd_wps_nfc_clear(struct wps_context *wps);
 
 
 struct wps_for_each_data {
@@ -897,7 +898,7 @@
 }
 
 
-static void hostapd_wps_clear_ies(struct hostapd_data *hapd)
+static void hostapd_wps_clear_ies(struct hostapd_data *hapd, int deinit_only)
 {
 	wpabuf_free(hapd->wps_beacon_ie);
 	hapd->wps_beacon_ie = NULL;
@@ -905,6 +906,9 @@
 	wpabuf_free(hapd->wps_probe_resp_ie);
 	hapd->wps_probe_resp_ie = NULL;
 
+	if (deinit_only)
+		return;
+
 	hostapd_set_ap_wps_ie(hapd);
 }
 
@@ -987,6 +991,21 @@
 }
 
 
+static void hostapd_free_wps(struct wps_context *wps)
+{
+	int i;
+
+	for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
+		wpabuf_free(wps->dev.vendor_ext[i]);
+	wps_device_data_free(&wps->dev);
+	os_free(wps->network_key);
+	hostapd_wps_nfc_clear(wps);
+	wpabuf_free(wps->dh_pubkey);
+	wpabuf_free(wps->dh_privkey);
+	os_free(wps);
+}
+
+
 int hostapd_init_wps(struct hostapd_data *hapd,
 		     struct hostapd_bss_config *conf)
 {
@@ -994,7 +1013,7 @@
 	struct wps_registrar_config cfg;
 
 	if (conf->wps_state == 0) {
-		hostapd_wps_clear_ies(hapd);
+		hostapd_wps_clear_ies(hapd, 0);
 		return 0;
 	}
 
@@ -1062,10 +1081,8 @@
 	os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
 		  WPS_DEV_TYPE_LEN);
 
-	if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) {
-		os_free(wps);
-		return -1;
-	}
+	if (hostapd_wps_set_vendor_ext(hapd, wps) < 0)
+		goto fail;
 
 	wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
 
@@ -1125,19 +1142,15 @@
 		wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
 	} else if (conf->ssid.wpa_psk) {
 		wps->network_key = os_malloc(2 * PMK_LEN + 1);
-		if (wps->network_key == NULL) {
-			os_free(wps);
-			return -1;
-		}
+		if (wps->network_key == NULL)
+			goto fail;
 		wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
 				 conf->ssid.wpa_psk->psk, PMK_LEN);
 		wps->network_key_len = 2 * PMK_LEN;
 	} else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
 		wps->network_key = os_malloc(conf->ssid.wep.len[0]);
-		if (wps->network_key == NULL) {
-			os_free(wps);
-			return -1;
-		}
+		if (wps->network_key == NULL)
+			goto fail;
 		os_memcpy(wps->network_key, conf->ssid.wep.key[0],
 			  conf->ssid.wep.len[0]);
 		wps->network_key_len = conf->ssid.wep.len[0];
@@ -1183,9 +1196,7 @@
 	wps->registrar = wps_registrar_init(wps, &cfg);
 	if (wps->registrar == NULL) {
 		wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar");
-		os_free(wps->network_key);
-		os_free(wps);
-		return -1;
+		goto fail;
 	}
 
 #ifdef CONFIG_WPS_UPNP
@@ -1201,6 +1212,10 @@
 	hapd->wps = wps;
 
 	return 0;
+
+fail:
+	hostapd_free_wps(wps);
+	return -1;
 }
 
 
@@ -1215,8 +1230,7 @@
 	if (hostapd_wps_upnp_init(hapd, wps) < 0) {
 		wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP");
 		wps_registrar_deinit(wps->registrar);
-		os_free(wps->network_key);
-		os_free(wps);
+		hostapd_free_wps(wps);
 		hapd->wps = NULL;
 		return -1;
 	}
@@ -1246,21 +1260,18 @@
 	eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
 	eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
 	eloop_cancel_timeout(wps_reload_config, hapd->iface, NULL);
-	if (hapd->wps == NULL)
+	if (hapd->wps == NULL) {
+		hostapd_wps_clear_ies(hapd, 1);
 		return;
+	}
 #ifdef CONFIG_WPS_UPNP
 	hostapd_wps_upnp_deinit(hapd);
 #endif /* CONFIG_WPS_UPNP */
 	wps_registrar_deinit(hapd->wps->registrar);
-	os_free(hapd->wps->network_key);
-	wps_device_data_free(&hapd->wps->dev);
-	wpabuf_free(hapd->wps->dh_pubkey);
-	wpabuf_free(hapd->wps->dh_privkey);
 	wps_free_pending_msgs(hapd->wps->upnp_msgs);
-	hostapd_wps_nfc_clear(hapd->wps);
-	os_free(hapd->wps);
+	hostapd_free_wps(hapd->wps);
 	hapd->wps = NULL;
-	hostapd_wps_clear_ies(hapd);
+	hostapd_wps_clear_ies(hapd, 1);
 }
 
 
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index d60f95b..dcd002e 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2900,6 +2900,16 @@
 	case NL80211_CMD_TRIGGER_SCAN:
 		wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");
 		drv->scan_state = SCAN_STARTED;
+		if (drv->scan_for_auth) {
+			/*
+			 * Cannot indicate EVENT_SCAN_STARTED here since we skip
+			 * EVENT_SCAN_RESULTS in scan_for_auth case and the
+			 * upper layer implementation could get confused about
+			 * scanning state.
+			 */
+			wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");
+			break;
+		}
 		wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);
 		break;
 	case NL80211_CMD_START_SCHED_SCAN:
diff --git a/src/utils/http_curl.c b/src/utils/http_curl.c
index 668c1a6..07d9af0 100644
--- a/src/utils/http_curl.c
+++ b/src/utils/http_curl.c
@@ -1,6 +1,6 @@
 /*
  * HTTP wrapper for libcurl
- * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2014, Qualcomm Atheros, Inc.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -82,15 +82,28 @@
 static void debug_dump(struct http_ctx *ctx, const char *title,
 		       const char *buf, size_t len)
 {
-	char *txt = os_malloc(len + 1);
+	char *txt;
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (buf[i] < 32 && buf[i] != '\t' && buf[i] != '\n' &&
+		    buf[i] != '\r') {
+			wpa_hexdump_ascii(MSG_MSGDUMP, title, buf, len);
+			return;
+		}
+	}
+
+	txt = os_malloc(len + 1);
 	if (txt == NULL)
 		return;
 	os_memcpy(txt, buf, len);
 	txt[len] = '\0';
 	while (len > 0) {
 		len--;
-		if (txt[len] == '\r' || txt[len] == '\n')
-		    txt[len] = '\0';
+		if (txt[len] == '\n' || txt[len] == '\r')
+			txt[len] = '\0';
+		else
+			break;
 	}
 	wpa_printf(MSG_MSGDUMP, "%s[%s]", title, txt);
 	os_free(txt);
@@ -134,21 +147,11 @@
 }
 
 
-static size_t curl_cb_header(void *ptr, size_t size, size_t nmemb,
-			     void *userdata)
-{
-	struct http_ctx *ctx = userdata;
-	debug_dump(ctx, "curl header", ptr, size * nmemb);
-	return size * nmemb;
-}
-
-
 static size_t curl_cb_write(void *ptr, size_t size, size_t nmemb,
 			    void *userdata)
 {
 	struct http_ctx *ctx = userdata;
 	char *n;
-	debug_dump(ctx, "curl write", ptr, size * nmemb);
 	n = os_realloc(ctx->curl_buf, ctx->curl_buf_len + size * nmemb + 1);
 	if (n == NULL)
 		return 0;
@@ -1275,8 +1278,6 @@
 	curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
 	curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug);
 	curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx);
-	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_cb_header);
-	curl_easy_setopt(curl, CURLOPT_HEADERDATA, ctx);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_cb_write);
 	curl_easy_setopt(curl, CURLOPT_WRITEDATA, ctx);
 	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
@@ -1527,8 +1528,6 @@
 	}
 	curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, curl_cb_debug);
 	curl_easy_setopt(curl, CURLOPT_DEBUGDATA, ctx);
-	curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, curl_cb_header);
-	curl_easy_setopt(curl, CURLOPT_HEADERDATA, ctx);
 	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite);
 	curl_easy_setopt(curl, CURLOPT_WRITEDATA, f);
 	curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
diff --git a/src/wps/wps_attr_build.c b/src/wps/wps_attr_build.c
index 62d0feb..c7e1cbb 100644
--- a/src/wps/wps_attr_build.c
+++ b/src/wps/wps_attr_build.c
@@ -296,6 +296,9 @@
 int wps_build_auth_type_flags(struct wps_data *wps, struct wpabuf *msg)
 {
 	u16 auth_types = WPS_AUTH_TYPES;
+	/* WPA/WPA2-Enterprise enrollment not supported through WPS */
+	auth_types &= ~WPS_AUTH_WPA;
+	auth_types &= ~WPS_AUTH_WPA2;
 #ifdef CONFIG_WPS2
 	auth_types &= ~WPS_AUTH_SHARED;
 #endif /* CONFIG_WPS2 */