Browse Source

HS 2.0R2: Add tracking of provisioning SP

The new provisioning_sp cred field can now be used to track which SP
provisioned the credential. This makes it easier to find the matching
PPS MO from the management tree (./Wi-Fi/<provisioning_sp>).

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen 11 years ago
parent
commit
aa26ba68b4

+ 4 - 0
wpa_supplicant/README-HS20

@@ -223,6 +223,10 @@ Credentials can be pre-configured for automatic network selection:
 # update_identifier: PPS MO ID
 #	(Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
 #
+# provisioning_sp: FQDN of the SP that provisioned the credential
+#	This optional field can be used to keep track of the SP that provisioned
+#	the credential to find the PPS MO (./Wi-Fi/<provisioning_sp>).
+#
 # for example:
 #
 #cred={

+ 7 - 0
wpa_supplicant/config.c

@@ -1930,6 +1930,7 @@ void wpa_config_free_cred(struct wpa_cred *cred)
 	os_free(cred->phase2);
 	os_free(cred->excluded_ssid);
 	os_free(cred->roaming_partner);
+	os_free(cred->provisioning_sp);
 	os_free(cred);
 }
 
@@ -2660,6 +2661,12 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
 		return 0;
 	}
 
+	if (os_strcmp(var, "provisioning_sp") == 0) {
+		os_free(cred->provisioning_sp);
+		cred->provisioning_sp = val;
+		return 0;
+	}
+
 	if (line) {
 		wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
 			   line, var);

+ 5 - 0
wpa_supplicant/config.h

@@ -246,6 +246,11 @@ struct wpa_cred {
 	size_t num_roaming_partner;
 
 	int update_identifier;
+
+	/**
+	 * provisioning_sp - FQDN of the SP that provisioned the credential
+	 */
+	char *provisioning_sp;
 };
 
 

+ 3 - 0
wpa_supplicant/config_file.c

@@ -806,6 +806,9 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
 	}
 	if (cred->update_identifier)
 		fprintf(f, "\tupdate_identifier=%d\n", cred->update_identifier);
+
+	if (cred->provisioning_sp)
+		fprintf(f, "\tprovisioning_sp=%s\n", cred->provisioning_sp);
 }
 
 

+ 42 - 4
wpa_supplicant/ctrl_iface.c

@@ -1720,15 +1720,38 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
 			if (wpa_s->current_ssid->parent_cred != cred)
 				continue;
 
-			for (i = 0; cred->domain && i < cred->num_domain; i++) {
+			if (cred->provisioning_sp) {
 				ret = os_snprintf(pos, end - pos,
-						  "home_sp=%s\n",
-						  cred->domain[i]);
+						  "provisioning_sp=%s\n",
+						  cred->provisioning_sp);
 				if (ret < 0 || ret >= end - pos)
 					return pos - buf;
 				pos += ret;
 			}
 
+			if (!cred->domain)
+				goto no_domain;
+
+			i = 0;
+			if (wpa_s->current_bss && wpa_s->current_bss->anqp) {
+				struct wpabuf *names =
+					wpa_s->current_bss->anqp->domain_name;
+				for (i = 0; names && i < cred->num_domain; i++)
+				{
+					if (domain_name_list_contains(
+						    names, cred->domain[i], 1))
+						break;
+				}
+				if (i == cred->num_domain)
+					i = 0; /* show first entry by default */
+			}
+			ret = os_snprintf(pos, end - pos, "home_sp=%s\n",
+					  cred->domain[i]);
+			if (ret < 0 || ret >= end - pos)
+				return pos - buf;
+			pos += ret;
+
+		no_domain:
 			if (wpa_s->current_bss == NULL ||
 			    wpa_s->current_bss->anqp == NULL)
 				res = -1;
@@ -2695,7 +2718,8 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
 	int id;
 	struct wpa_cred *cred, *prev;
 
-	/* cmd: "<cred id>", "all", or "sp_fqdn=<FQDN>" */
+	/* cmd: "<cred id>", "all", "sp_fqdn=<FQDN>", or
+	 * "provisioning_sp=<FQDN> */
 	if (os_strcmp(cmd, "all") == 0) {
 		wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
 		cred = wpa_s->conf->cred;
@@ -2728,6 +2752,20 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
 		return 0;
 	}
 
+	if (os_strncmp(cmd, "provisioning_sp=", 16) == 0) {
+		wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED provisioning SP FQDN '%s'",
+			   cmd + 16);
+		cred = wpa_s->conf->cred;
+		while (cred) {
+			prev = cred;
+			cred = cred->next;
+			if (prev->provisioning_sp &&
+			    os_strcmp(prev->provisioning_sp, cmd + 16) == 0)
+				wpas_ctrl_remove_cred(wpa_s, prev);
+		}
+		return 0;
+	}
+
 	id = atoi(cmd);
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
 

+ 2 - 2
wpa_supplicant/interworking.c

@@ -1634,8 +1634,8 @@ static struct wpa_cred * interworking_credentials_available(
 }
 
 
-static int domain_name_list_contains(struct wpabuf *domain_names,
-				     const char *domain, int exact_match)
+int domain_name_list_contains(struct wpabuf *domain_names,
+			      const char *domain, int exact_match)
 {
 	const u8 *pos, *end;
 	size_t len;

+ 2 - 0
wpa_supplicant/interworking.h

@@ -29,5 +29,7 @@ void interworking_start_fetch_anqp(struct wpa_supplicant *wpa_s);
 int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
 			      struct wpa_cred *cred,
 			      struct wpabuf *domain_names);
+int domain_name_list_contains(struct wpabuf *domain_names,
+			      const char *domain, int exact_match);
 
 #endif /* INTERWORKING_H */

+ 4 - 0
wpa_supplicant/wpa_supplicant.conf

@@ -442,6 +442,10 @@ fast_reauth=1
 # update_identifier: PPS MO ID
 #	(Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
 #
+# provisioning_sp: FQDN of the SP that provisioned the credential
+#	This optional field can be used to keep track of the SP that provisioned
+#	the credential to find the PPS MO (./Wi-Fi/<provisioning_sp>).
+#
 # for example:
 #
 #cred={