Parcourir la source

HS 2.0: Add Home SP FQDN and roaming/home to status command

This allows the ctrl_iface STATUS information to be used to determine
which Home SP credential (domain in the cred block) was used and whether
the network is operated by the home SP.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Jouni Malinen il y a 12 ans
Parent
commit
e99b4f3a14
3 fichiers modifiés avec 87 ajouts et 35 suppressions
  1. 39 0
      wpa_supplicant/ctrl_iface.c
  2. 45 35
      wpa_supplicant/interworking.c
  3. 3 0
      wpa_supplicant/interworking.h

+ 39 - 0
wpa_supplicant/ctrl_iface.c

@@ -1400,6 +1400,45 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
 			return pos - buf;
 		pos += ret;
 	}
+
+	if (wpa_s->current_ssid) {
+		struct wpa_cred *cred;
+		char *type;
+
+		for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+			if (wpa_s->current_ssid->parent_cred != cred)
+				continue;
+			if (!cred->domain)
+				continue;
+
+			ret = os_snprintf(pos, end - pos, "home_sp=%s\n",
+					  cred->domain);
+			if (ret < 0 || ret >= end - pos)
+				return pos - buf;
+			pos += ret;
+
+			if (wpa_s->current_bss == NULL ||
+			    wpa_s->current_bss->anqp == NULL)
+				res = -1;
+			else
+				res = interworking_home_sp_cred(
+					wpa_s, cred,
+					wpa_s->current_bss->anqp->domain_name);
+			if (res > 0)
+				type = "home";
+			else if (res == 0)
+				type = "roaming";
+			else
+				type = "unknown";
+
+			ret = os_snprintf(pos, end - pos, "sp_type=%s\n", type);
+			if (ret < 0 || ret >= end - pos)
+				return pos - buf;
+			pos += ret;
+
+			break;
+		}
+	}
 #endif /* CONFIG_HS20 */
 
 	if (wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) ||

+ 45 - 35
wpa_supplicant/interworking.c

@@ -1438,50 +1438,60 @@ static int domain_name_list_contains(struct wpabuf *domain_names,
 }
 
 
-static int interworking_home_sp(struct wpa_supplicant *wpa_s,
-				struct wpabuf *domain_names)
+int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
+			      struct wpa_cred *cred,
+			      struct wpabuf *domain_names)
 {
-	struct wpa_cred *cred;
 #ifdef INTERWORKING_3GPP
 	char nai[100], *realm;
-#endif /* INTERWORKING_3GPP */
 
-	if (domain_names == NULL || wpa_s->conf->cred == NULL)
-		return -1;
-
-	for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
-#ifdef INTERWORKING_3GPP
-		char *imsi = NULL;
-		int mnc_len = 0;
-		if (cred->imsi)
-			imsi = cred->imsi;
+	char *imsi = NULL;
+	int mnc_len = 0;
+	if (cred->imsi)
+		imsi = cred->imsi;
 #ifdef CONFIG_PCSC
-		else if (cred->pcsc && wpa_s->conf->pcsc_reader &&
-			 wpa_s->scard && wpa_s->imsi[0]) {
-			imsi = wpa_s->imsi;
-			mnc_len = wpa_s->mnc_len;
-		}
+	else if (cred->pcsc && wpa_s->conf->pcsc_reader &&
+		 wpa_s->scard && wpa_s->imsi[0]) {
+		imsi = wpa_s->imsi;
+		mnc_len = wpa_s->mnc_len;
+	}
 #endif /* CONFIG_PCSC */
-		if (imsi && build_root_nai(nai, sizeof(nai), imsi, mnc_len, 0)
-		    == 0) {
-			realm = os_strchr(nai, '@');
-			if (realm)
-				realm++;
-			wpa_printf(MSG_DEBUG, "Interworking: Search for match "
-				   "with SIM/USIM domain %s", realm);
-			if (realm &&
-			    domain_name_list_contains(domain_names, realm))
-				return 1;
-		}
+	if (imsi && build_root_nai(nai, sizeof(nai), imsi, mnc_len, 0) == 0) {
+		realm = os_strchr(nai, '@');
+		if (realm)
+			realm++;
+		wpa_printf(MSG_DEBUG, "Interworking: Search for match "
+			   "with SIM/USIM domain %s", realm);
+		if (realm &&
+		    domain_name_list_contains(domain_names, realm))
+			return 1;
+	}
 #endif /* INTERWORKING_3GPP */
 
-		if (cred->domain == NULL)
-			continue;
+	if (cred->domain == NULL)
+		return 0;
 
-		wpa_printf(MSG_DEBUG, "Interworking: Search for match with "
-			   "home SP FQDN %s", cred->domain);
-		if (domain_name_list_contains(domain_names, cred->domain))
-			return 1;
+	wpa_printf(MSG_DEBUG, "Interworking: Search for match with "
+		   "home SP FQDN %s", cred->domain);
+	if (domain_name_list_contains(domain_names, cred->domain))
+		return 1;
+
+	return 0;
+}
+
+
+static int interworking_home_sp(struct wpa_supplicant *wpa_s,
+				struct wpabuf *domain_names)
+{
+	struct wpa_cred *cred;
+
+	if (domain_names == NULL || wpa_s->conf->cred == NULL)
+		return -1;
+
+	for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+		int res = interworking_home_sp_cred(wpa_s, cred, domain_names);
+		if (res)
+			return res;
 	}
 
 	return 0;

+ 3 - 0
wpa_supplicant/interworking.h

@@ -25,5 +25,8 @@ void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s);
 int interworking_select(struct wpa_supplicant *wpa_s, int auto_select);
 int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss);
 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);
 
 #endif /* INTERWORKING_H */