]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Interworking: Add support for multiple home FQDNs
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 2 Aug 2013 15:42:54 +0000 (18:42 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 18 Oct 2013 11:13:45 +0000 (14:13 +0300)
Credentials can now be configured with more than one FQDN ('domain'
field in the cred block) to perform Domain Name List matching against
multiple home domains.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

wpa_supplicant/README-HS20
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/interworking.c
wpa_supplicant/wpa_supplicant.conf

index 5669c55c32d5edc521fc32087be9368dd8d5bb9d..7a570bdd7d273fcc3688c3221d75b318d39e08d0 100644 (file)
@@ -166,9 +166,11 @@ Credentials can be pre-configured for automatic network selection:
 # milenage: Milenage parameters for SIM/USIM simulator in <Ki>:<OPc>:<SQN>
 #      format
 #
-# domain: Home service provider FQDN
+# domain: Home service provider FQDN(s)
 #      This is used to compare against the Domain Name List to figure out
-#      whether the AP is operated by the Home SP.
+#      whether the AP is operated by the Home SP. Multiple domain entries can
+#      be used to configure alternative FQDNs that will be considered home
+#      networks.
 #
 # roaming_consortium: Roaming Consortium OI
 #      If roaming_consortium_len is non-zero, this field contains the
index c4fc7b67026a05c148aa61812443309ba7421ad3..2b47e8e69f79718605b28ff193dd4b1253f8296f 100644 (file)
@@ -1855,6 +1855,8 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
 
 void wpa_config_free_cred(struct wpa_cred *cred)
 {
+       size_t i;
+
        os_free(cred->realm);
        os_free(cred->username);
        os_free(cred->password);
@@ -1864,6 +1866,8 @@ void wpa_config_free_cred(struct wpa_cred *cred)
        os_free(cred->private_key_passwd);
        os_free(cred->imsi);
        os_free(cred->milenage);
+       for (i = 0; i < cred->num_domain; i++)
+               os_free(cred->domain[i]);
        os_free(cred->domain);
        os_free(cred->eap_method);
        os_free(cred->phase1);
@@ -2437,8 +2441,16 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
        }
 
        if (os_strcmp(var, "domain") == 0) {
-               os_free(cred->domain);
-               cred->domain = val;
+               char **new_domain;
+               new_domain = os_realloc_array(cred->domain,
+                                             cred->num_domain + 1,
+                                             sizeof(char *));
+               if (new_domain == NULL) {
+                       os_free(val);
+                       return -1;
+               }
+               new_domain[cred->num_domain++] = val;
+               cred->domain = new_domain;
                return 0;
        }
 
index 1748cf3b8606d870fc0cb956d62b03c614fa4e1b..27301b803f213c88973914b39ce587e96995480e 100644 (file)
@@ -150,12 +150,19 @@ struct wpa_cred {
        char *milenage;
 
        /**
-        * domain - Home service provider FQDN
+        * domain - Home service provider FQDN(s)
         *
         * This is used to compare against the Domain Name List to figure out
-        * whether the AP is operated by the Home SP.
+        * whether the AP is operated by the Home SP. Multiple domain entries
+        * can be used to configure alternative FQDNs that will be considered
+        * home networks.
         */
-       char *domain;
+       char **domain;
+
+       /**
+        * num_domain - Number of FQDNs in the domain array
+        */
+       size_t num_domain;
 
        /**
         * roaming_consortium - Roaming Consortium OI
index 6512a8270d3e4509fcc65ee5b5e6b581e9c9a0ac..2c14a2c91532f94fc0835190d5275344f4bcbcfc 100644 (file)
@@ -728,6 +728,8 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 
 static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
 {
+       size_t i;
+
        if (cred->priority)
                fprintf(f, "\tpriority=%d\n", cred->priority);
        if (cred->pcsc)
@@ -753,10 +755,9 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
                fprintf(f, "\timsi=\"%s\"\n", cred->imsi);
        if (cred->milenage)
                fprintf(f, "\tmilenage=\"%s\"\n", cred->milenage);
-       if (cred->domain)
-               fprintf(f, "\tdomain=\"%s\"\n", cred->domain);
+       for (i = 0; i < cred->num_domain; i++)
+               fprintf(f, "\tdomain=\"%s\"\n", cred->domain[i]);
        if (cred->roaming_consortium_len) {
-               size_t i;
                fprintf(f, "\troaming_consortium=");
                for (i = 0; i < cred->roaming_consortium_len; i++)
                        fprintf(f, "%02x", cred->roaming_consortium[i]);
@@ -773,7 +774,7 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
        if (cred->phase2)
                fprintf(f, "\tphase2=\"%s\"\n", cred->phase2);
        if (cred->excluded_ssid) {
-               size_t i, j;
+               size_t j;
                for (i = 0; i < cred->num_excluded_ssid; i++) {
                        struct excluded_ssid *e = &cred->excluded_ssid[i];
                        fprintf(f, "\texcluded_ssid=");
index 0f893f7e6f131a60cc29c7d6c4f622f4a2c04a8c..7b3af28d0ce2f1312e7ebafbb63a3c9a7e8f58be 100644 (file)
@@ -1565,16 +1565,21 @@ static int wpa_supplicant_ctrl_iface_status(struct wpa_supplicant *wpa_s,
                char *type;
 
                for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+                       size_t i;
+
                        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;
+                       for (i = 0; i < cred->num_domain; i++) {
+                               ret = os_snprintf(pos, end - pos,
+                                                 "home_sp=%s\n",
+                                                 cred->domain[i]);
+                               if (ret < 0 || ret >= end - pos)
+                                       return pos - buf;
+                               pos += ret;
+                       }
 
                        if (wpa_s->current_bss == NULL ||
                            wpa_s->current_bss->anqp == NULL)
@@ -2448,7 +2453,7 @@ static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
                ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n",
                                  cred->id, cred->realm ? cred->realm : "",
                                  cred->username ? cred->username : "",
-                                 cred->domain ? cred->domain : "",
+                                 cred->domain ? cred->domain[0] : "",
                                  cred->imsi ? cred->imsi : "");
                if (ret < 0 || ret >= end - pos)
                        return pos - buf;
@@ -2533,9 +2538,16 @@ static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
                while (cred) {
                        prev = cred;
                        cred = cred->next;
-                       if (prev->domain &&
-                           os_strcmp(prev->domain, cmd + 8) == 0)
-                               wpas_ctrl_remove_cred(wpa_s, prev);
+                       if (prev->domain) {
+                               size_t i;
+                               for (i = 0; i < prev->num_domain; i++) {
+                                       if (os_strcmp(prev->domain[i], cmd + 8)
+                                           != 0)
+                                               continue;
+                                       wpas_ctrl_remove_cred(wpa_s, prev);
+                                       break;
+                               }
+                       }
                }
                return 0;
        }
index 36f75a16626e512499af5f9b88918ffc0e1e9ecc..01acae1c66a401ae63682263387f9bb59548d07f 100644 (file)
@@ -1514,6 +1514,7 @@ int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
                              struct wpa_cred *cred,
                              struct wpabuf *domain_names)
 {
+       size_t i;
 #ifdef INTERWORKING_3GPP
        char nai[100], *realm;
 
@@ -1544,10 +1545,12 @@ int interworking_home_sp_cred(struct wpa_supplicant *wpa_s,
        if (domain_names == NULL || 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;
+       for (i = 0; i < cred->num_domain; i++) {
+               wpa_printf(MSG_DEBUG, "Interworking: Search for match with "
+                          "home SP FQDN %s", cred->domain[i]);
+               if (domain_name_list_contains(domain_names, cred->domain[i]))
+                       return 1;
+       }
 
        return 0;
 }
index d73d3715af9c22654c179065185a5f81d46c2c38..6414f447dbc52dada3c3ee7b87f41016251d4743 100644 (file)
@@ -399,9 +399,11 @@ fast_reauth=1
 # milenage: Milenage parameters for SIM/USIM simulator in <Ki>:<OPc>:<SQN>
 #      format
 #
-# domain: Home service provider FQDN
+# domain: Home service provider FQDN(s)
 #      This is used to compare against the Domain Name List to figure out
-#      whether the AP is operated by the Home SP.
+#      whether the AP is operated by the Home SP. Multiple domain entries can
+#      be used to configure alternative FQDNs that will be considered home
+#      networks.
 #
 # roaming_consortium: Roaming Consortium OI
 #      If roaming_consortium_len is non-zero, this field contains the