Interworking: Add support for multiple credentials
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 16 Feb 2012 14:34:22 +0000 (16:34 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 16 Feb 2012 14:34:22 +0000 (16:34 +0200)
This replaces the global home_* parameters with a list of credentials
that can be configured similarly to network blocks. For example:

cred={
realm="example.com"
username="user@example.com"
password="password"
ca_cert="/etc/wpa_supplicant/ca.pem"
domain="example.com"
}

cred={
imsi="310026-000000000"
milenage="90dca4eda45b53cf0f12d7c9c3bc6a89:cb9cccc4b9258e6dca4760379fb82581:000000000123"
}

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

wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/interworking.c

index 5910b5d..3d3552f 100644 (file)
@@ -1774,6 +1774,19 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
 }
 
 
+void wpa_config_free_cred(struct wpa_cred *cred)
+{
+       os_free(cred->realm);
+       os_free(cred->username);
+       os_free(cred->password);
+       os_free(cred->ca_cert);
+       os_free(cred->imsi);
+       os_free(cred->milenage);
+       os_free(cred->domain);
+       os_free(cred);
+}
+
+
 /**
  * wpa_config_free - Free configuration data
  * @config: Configuration data from wpa_config_read()
@@ -1787,6 +1800,7 @@ void wpa_config_free(struct wpa_config *config)
        struct wpa_config_blob *blob, *prevblob;
 #endif /* CONFIG_NO_CONFIG_BLOBS */
        struct wpa_ssid *ssid, *prev = NULL;
+       struct wpa_cred *cred, *cprev;
 
        ssid = config->ssid;
        while (ssid) {
@@ -1795,6 +1809,13 @@ void wpa_config_free(struct wpa_config *config)
                wpa_config_free_ssid(prev);
        }
 
+       cred = config->cred;
+       while (cred) {
+               cprev = cred;
+               cred = cred->next;
+               wpa_config_free_cred(cprev);
+       }
+
 #ifndef CONFIG_NO_CONFIG_BLOBS
        blob = config->blobs;
        prevblob = NULL;
@@ -1819,13 +1840,6 @@ void wpa_config_free(struct wpa_config *config)
        os_free(config->config_methods);
        os_free(config->p2p_ssid_postfix);
        os_free(config->pssid);
-       os_free(config->home_realm);
-       os_free(config->home_username);
-       os_free(config->home_password);
-       os_free(config->home_ca_cert);
-       os_free(config->home_imsi);
-       os_free(config->home_milenage);
-       os_free(config->home_domain);
        os_free(config);
 }
 
@@ -2197,6 +2211,67 @@ void wpa_config_update_psk(struct wpa_ssid *ssid)
 }
 
 
+int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
+                       const char *value, int line)
+{
+       char *val;
+       size_t len;
+
+       val = wpa_config_parse_string(value, &len);
+       if (val == NULL)
+               return -1;
+
+       if (os_strcmp(var, "realm") == 0) {
+               os_free(cred->realm);
+               cred->realm = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "username") == 0) {
+               os_free(cred->username);
+               cred->username = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "password") == 0) {
+               os_free(cred->password);
+               cred->password = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "ca_cert") == 0) {
+               os_free(cred->ca_cert);
+               cred->ca_cert = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "imsi") == 0) {
+               os_free(cred->imsi);
+               cred->imsi = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "milenage") == 0) {
+               os_free(cred->milenage);
+               cred->milenage = val;
+               return 0;
+       }
+
+       if (os_strcmp(var, "domain") == 0) {
+               os_free(cred->domain);
+               cred->domain = val;
+               return 0;
+       }
+
+       if (line) {
+               wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
+                          line, var);
+       }
+
+       return -1;
+}
+
+
 #ifndef CONFIG_NO_CONFIG_BLOBS
 /**
  * wpa_config_get_blob - Get a named configuration blob
@@ -2589,13 +2664,6 @@ static const struct global_parse_data global_fields[] = {
        { INT_RANGE(filter_ssids, 0, 1), 0 },
        { INT(max_num_sta), 0 },
        { INT_RANGE(disassoc_low_ack, 0, 1), 0 },
-       { STR(home_realm), 0 },
-       { STR(home_username), 0 },
-       { STR(home_password), 0 },
-       { STR(home_ca_cert), 0 },
-       { STR(home_imsi), 0 },
-       { STR(home_milenage), 0 },
-       { STR(home_domain), 0 },
        { INT_RANGE(interworking, 0, 1), 0 },
        { FUNC(hessid), 0 },
        { INT_RANGE(access_network_type, 0, 15), 0 }
index 380bfbb..e45b608 100644 (file)
 #include "wps/wps.h"
 
 
+struct wpa_cred {
+       /**
+        * next - Next credential in the list
+        *
+        * This pointer can be used to iterate over all credentials. The head
+        * of this list is stored in the cred field of struct wpa_config.
+        */
+       struct wpa_cred *next;
+
+       /**
+        * id - Unique id for the credential
+        *
+        * This identifier is used as a unique identifier for each credential
+        * block when using the control interface. Each credential is allocated
+        * an id when it is being created, either when reading the
+        * configuration file or when a new credential is added through the
+        * control interface.
+        */
+       int id;
+
+       /**
+        * realm - Home Realm for Interworking
+        */
+       char *realm;
+
+       /**
+        * username - Username for Interworking network selection
+        */
+       char *username;
+
+       /**
+        * password - Password for Interworking network selection
+        */
+       char *password;
+
+       /**
+        * ca_cert - CA certificate for Interworking network selection
+        */
+       char *ca_cert;
+
+       /**
+        * imsi - IMSI in <MCC> | <MNC> | '-' | <MSIN> format
+        */
+       char *imsi;
+
+       /**
+        * milenage - Milenage parameters for SIM/USIM simulator in
+        *      <Ki>:<OPc>:<SQN> format
+        */
+       char *milenage;
+
+       /**
+        * domain - Home service provider FQDN
+        *
+        * This is used to compare against the Domain Name List to figure out
+        * whether the AP is operated by the Home SP.
+        */
+       char *domain;
+};
+
+
 #define CFG_CHANGED_DEVICE_NAME BIT(0)
 #define CFG_CHANGED_CONFIG_METHODS BIT(1)
 #define CFG_CHANGED_DEVICE_TYPE BIT(2)
@@ -72,6 +133,13 @@ struct wpa_config {
        int num_prio;
 
        /**
+        * cred - Head of the credential list
+        *
+        * This is the head for the list of all the configured credentials.
+        */
+       struct wpa_cred *cred;
+
+       /**
         * eapol_version - IEEE 802.1X/EAPOL version number
         *
         * wpa_supplicant is implemented based on IEEE Std 802.1X-2004 which
@@ -447,45 +515,6 @@ struct wpa_config {
         * Homogeneous ESS. This is used only if interworking is enabled.
         */
        u8 hessid[ETH_ALEN];
-
-       /**
-        * home_realm - Home Realm for Interworking
-        */
-       char *home_realm;
-
-       /**
-        * home_username - Username for Interworking network selection
-        */
-       char *home_username;
-
-       /**
-        * home_password - Password for Interworking network selection
-        */
-       char *home_password;
-
-       /**
-        * home_ca_cert - CA certificate for Interworking network selection
-        */
-       char *home_ca_cert;
-
-       /**
-        * home_imsi - IMSI in <MCC> | <MNC> | '-' | <MSIN> format
-        */
-       char *home_imsi;
-
-       /**
-        * home_milenage - Milenage parameters for SIM/USIM simulator in
-        *      <Ki>:<OPc>:<SQN> format
-        */
-       char *home_milenage;
-
-       /**
-        * home_domain - Home service provider FQDN
-        *
-        * This is used to compare against the Domain Name List to figure out
-        * whether the AP is operated by the Home SP.
-        */
-       char *home_domain;
 };
 
 
@@ -518,6 +547,10 @@ void wpa_config_set_blob(struct wpa_config *config,
 void wpa_config_free_blob(struct wpa_config_blob *blob);
 int wpa_config_remove_blob(struct wpa_config *config, const char *name);
 
+void wpa_config_free_cred(struct wpa_cred *cred);
+int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
+                       const char *value, int line);
+
 struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
                                           const char *driver_param);
 #ifndef CONFIG_NO_STDOUT_DEBUG
index a1955d4..01e2a3d 100644 (file)
@@ -178,6 +178,61 @@ static struct wpa_ssid * wpa_config_read_network(FILE *f, int *line, int id)
 }
 
 
+static struct wpa_cred * wpa_config_read_cred(FILE *f, int *line, int id)
+{
+       struct wpa_cred *cred;
+       int errors = 0, end = 0;
+       char buf[256], *pos, *pos2;
+
+       wpa_printf(MSG_MSGDUMP, "Line: %d - start of a new cred block", *line);
+       cred = os_zalloc(sizeof(*cred));
+       if (cred == NULL)
+               return NULL;
+       cred->id = id;
+
+       while (wpa_config_get_line(buf, sizeof(buf), f, line, &pos)) {
+               if (os_strcmp(pos, "}") == 0) {
+                       end = 1;
+                       break;
+               }
+
+               pos2 = os_strchr(pos, '=');
+               if (pos2 == NULL) {
+                       wpa_printf(MSG_ERROR, "Line %d: Invalid cred line "
+                                  "'%s'.", *line, pos);
+                       errors++;
+                       continue;
+               }
+
+               *pos2++ = '\0';
+               if (*pos2 == '"') {
+                       if (os_strchr(pos2 + 1, '"') == NULL) {
+                               wpa_printf(MSG_ERROR, "Line %d: invalid "
+                                          "quotation '%s'.", *line, pos2);
+                               errors++;
+                               continue;
+                       }
+               }
+
+               if (wpa_config_set_cred(cred, pos, pos2, *line) < 0)
+                       errors++;
+       }
+
+       if (!end) {
+               wpa_printf(MSG_ERROR, "Line %d: cred block was not "
+                          "terminated properly.", *line);
+               errors++;
+       }
+
+       if (errors) {
+               wpa_config_free_cred(cred);
+               cred = NULL;
+       }
+
+       return cred;
+}
+
+
 #ifndef CONFIG_NO_CONFIG_BLOBS
 static struct wpa_config_blob * wpa_config_read_blob(FILE *f, int *line,
                                                     const char *name)
@@ -267,8 +322,10 @@ struct wpa_config * wpa_config_read(const char *name)
        char buf[256], *pos;
        int errors = 0, line = 0;
        struct wpa_ssid *ssid, *tail = NULL, *head = NULL;
+       struct wpa_cred *cred, *cred_tail = NULL, *cred_head = NULL;
        struct wpa_config *config;
        int id = 0;
+       int cred_id = 0;
 
        config = wpa_config_alloc_empty(NULL, NULL);
        if (config == NULL)
@@ -302,6 +359,20 @@ struct wpa_config * wpa_config_read(const char *name)
                                errors++;
                                continue;
                        }
+               } else if (os_strcmp(pos, "cred={") == 0) {
+                       cred = wpa_config_read_cred(f, &line, cred_id++);
+                       if (cred == NULL) {
+                               wpa_printf(MSG_ERROR, "Line %d: failed to "
+                                          "parse cred block.", line);
+                               errors++;
+                               continue;
+                       }
+                       if (cred_head == NULL) {
+                               cred_head = cred_tail = cred;
+                       } else {
+                               cred_tail->next = cred;
+                               cred_tail = cred;
+                       }
 #ifndef CONFIG_NO_CONFIG_BLOBS
                } else if (os_strncmp(pos, "blob-base64-", 12) == 0) {
                        if (wpa_config_process_blob(config, f, &line, pos + 12)
@@ -322,6 +393,7 @@ struct wpa_config * wpa_config_read(const char *name)
 
        config->ssid = head;
        wpa_config_debug_dump_networks(config);
+       config->cred = cred_head;
 
 #ifndef WPA_IGNORE_CONFIG_ERRORS
        if (errors) {
@@ -712,18 +784,6 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
        if (config->disassoc_low_ack)
                fprintf(f, "disassoc_low_ack=%u\n", config->disassoc_low_ack);
 #ifdef CONFIG_INTERWORKING
-       if (config->home_realm)
-               fprintf(f, "home_realm=%s\n", config->home_realm);
-       if (config->home_username)
-               fprintf(f, "home_username=%s\n", config->home_username);
-       if (config->home_password)
-               fprintf(f, "home_password=%s\n", config->home_password);
-       if (config->home_ca_cert)
-               fprintf(f, "home_ca_cert=%s\n", config->home_ca_cert);
-       if (config->home_imsi)
-               fprintf(f, "home_imsi=%s\n", config->home_imsi);
-       if (config->home_milenage)
-               fprintf(f, "home_milenage=%s\n", config->home_milenage);
        if (config->interworking)
                fprintf(f, "interworking=%u\n", config->interworking);
        if (!is_zero_ether_addr(config->hessid))
index 08b24f4..37bca7f 100644 (file)
@@ -416,15 +416,16 @@ static int nai_realm_cred_username(struct nai_realm_eap *eap)
 }
 
 
-static struct nai_realm_eap * nai_realm_find_eap(struct wpa_supplicant *wpa_s,
+static struct nai_realm_eap * nai_realm_find_eap(struct wpa_cred *cred,
                                                 struct nai_realm *realm)
 {
        u8 e;
 
-       if (wpa_s->conf->home_username == NULL ||
-           wpa_s->conf->home_username[0] == '\0' ||
-           wpa_s->conf->home_password == NULL ||
-           wpa_s->conf->home_password[0] == '\0')
+       if (cred == NULL ||
+           cred->username == NULL ||
+           cred->username[0] == '\0' ||
+           cred->password == NULL ||
+           cred->password[0] == '\0')
                return NULL;
 
        for (e = 0; e < realm->eap_count; e++) {
@@ -571,9 +572,23 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
                                     struct wpa_bss *bss)
 {
 #ifdef INTERWORKING_3GPP
+       struct wpa_cred *cred;
        struct wpa_ssid *ssid;
        const u8 *ie;
 
+       if (bss->anqp_3gpp == NULL)
+               return -1;
+
+       for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+               if (cred->imsi == NULL || !cred->imsi[0] ||
+                   cred->milenage == NULL || !cred->milenage[0])
+                       continue;
+               if (plmn_id_match(bss->anqp_3gpp, cred->imsi))
+                       break;
+       }
+       if (cred == NULL)
+               return -1;
+
        ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
        if (ie == NULL)
                return -1;
@@ -598,14 +613,14 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
                wpa_printf(MSG_DEBUG, "EAP-SIM not supported");
                goto fail;
        }
-       if (set_root_nai(ssid, wpa_s->conf->home_imsi, '1') < 0) {
+       if (set_root_nai(ssid, cred->imsi, '1') < 0) {
                wpa_printf(MSG_DEBUG, "Failed to set Root NAI");
                goto fail;
        }
 
-       if (wpa_s->conf->home_milenage && wpa_s->conf->home_milenage[0]) {
+       if (cred->milenage && cred->milenage[0]) {
                if (wpa_config_set_quoted(ssid, "password",
-                                         wpa_s->conf->home_milenage) < 0)
+                                         cred->milenage) < 0)
                        goto fail;
        } else {
                /* TODO: PIN */
@@ -613,9 +628,8 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
                        goto fail;
        }
 
-       if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
-           wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
-           < 0)
+       if (cred->password && cred->password[0] &&
+           wpa_config_set_quoted(ssid, "password", cred->password) < 0)
                goto fail;
 
        wpa_s->disconnected = 0;
@@ -634,6 +648,7 @@ fail:
 
 int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
+       struct wpa_cred *cred;
        struct wpa_ssid *ssid;
        struct nai_realm *realm;
        struct nai_realm_eap *eap = NULL;
@@ -641,7 +656,7 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
        char buf[100];
        const u8 *ie;
 
-       if (bss == NULL)
+       if (wpa_s->conf->cred == NULL || bss == NULL)
                return -1;
        ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
        if (ie == NULL || ie[1] == 0) {
@@ -657,10 +672,14 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
                count = 0;
        }
 
-       for (i = 0; i < count; i++) {
-               if (!nai_realm_match(&realm[i], wpa_s->conf->home_realm))
-                       continue;
-               eap = nai_realm_find_eap(wpa_s, &realm[i]);
+       for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+               for (i = 0; i < count; i++) {
+                       if (!nai_realm_match(&realm[i], cred->realm))
+                               continue;
+                       eap = nai_realm_find_eap(cred, &realm[i]);
+                       if (eap)
+                               break;
+               }
                if (eap)
                        break;
        }
@@ -701,11 +720,11 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
                goto fail;
 
        if (eap->method == EAP_TYPE_TTLS &&
-           wpa_s->conf->home_username && wpa_s->conf->home_username[0]) {
+           cred->username && cred->username[0]) {
                const char *pos;
                char *anon;
                /* Use anonymous NAI in Phase 1 */
-               pos = os_strchr(wpa_s->conf->home_username, '@');
+               pos = os_strchr(cred->username, '@');
                if (pos) {
                        size_t buflen = 9 + os_strlen(pos) + 1;
                        anon = os_malloc(buflen);
@@ -725,14 +744,12 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
                os_free(anon);
        }
 
-       if (wpa_s->conf->home_username && wpa_s->conf->home_username[0] &&
-           wpa_config_set_quoted(ssid, "identity",
-                                 wpa_s->conf->home_username) < 0)
+       if (cred->username && cred->username[0] &&
+           wpa_config_set_quoted(ssid, "identity", cred->username) < 0)
                goto fail;
 
-       if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
-           wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
-           < 0)
+       if (cred->password && cred->password[0] &&
+           wpa_config_set_quoted(ssid, "password", cred->password) < 0)
                goto fail;
 
        switch (eap->method) {
@@ -776,9 +793,8 @@ int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
                break;
        }
 
-       if (wpa_s->conf->home_ca_cert && wpa_s->conf->home_ca_cert[0] &&
-           wpa_config_set_quoted(ssid, "ca_cert", wpa_s->conf->home_ca_cert) <
-           0)
+       if (cred->ca_cert && cred->ca_cert[0] &&
+           wpa_config_set_quoted(ssid, "ca_cert", cred->ca_cert) < 0)
                goto fail;
 
        nai_realm_free(realm, count);
@@ -800,29 +816,34 @@ fail:
 static int interworking_credentials_available_3gpp(
        struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
-       int ret = 0;
+       struct wpa_cred *cred;
+       int ret;
 
 #ifdef INTERWORKING_3GPP
        if (bss->anqp_3gpp == NULL)
-               return ret;
+               return 0;
 
-       if (wpa_s->conf->home_imsi == NULL || !wpa_s->conf->home_imsi[0] ||
-           wpa_s->conf->home_milenage == NULL ||
-           !wpa_s->conf->home_milenage[0])
-               return ret;
+       for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+               if (cred->imsi == NULL || !cred->imsi[0] ||
+                   cred->milenage == NULL || !cred->milenage[0])
+                       continue;
 
-       wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from " MACSTR,
-                  MAC2STR(bss->bssid));
-       ret = plmn_id_match(bss->anqp_3gpp, wpa_s->conf->home_imsi);
-       wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
+               wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from "
+                          MACSTR, MAC2STR(bss->bssid));
+               ret = plmn_id_match(bss->anqp_3gpp, cred->imsi);
+               wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
+               if (ret)
+                       return 1;
+       }
 #endif /* INTERWORKING_3GPP */
-       return ret;
+       return 0;
 }
 
 
 static int interworking_credentials_available_realm(
        struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
+       struct wpa_cred *cred;
        struct nai_realm *realm;
        u16 count, i;
        int found = 0;
@@ -830,7 +851,7 @@ static int interworking_credentials_available_realm(
        if (bss->anqp_nai_realm == NULL)
                return 0;
 
-       if (wpa_s->conf->home_realm == NULL)
+       if (wpa_s->conf->cred == NULL)
                return 0;
 
        wpa_printf(MSG_DEBUG, "Interworking: Parsing NAI Realm list from "
@@ -842,13 +863,20 @@ static int interworking_credentials_available_realm(
                return 0;
        }
 
-       for (i = 0; i < count; i++) {
-               if (!nai_realm_match(&realm[i], wpa_s->conf->home_realm))
+       for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
+               if (cred->realm == NULL)
                        continue;
-               if (nai_realm_find_eap(wpa_s, &realm[i])) {
-                       found++;
-                       break;
+
+               for (i = 0; i < count; i++) {
+                       if (!nai_realm_match(&realm[i], cred->realm))
+                               continue;
+                       if (nai_realm_find_eap(cred, &realm[i])) {
+                               found++;
+                               break;
+                       }
                }
+               if (found)
+                       break;
        }
 
        nai_realm_free(realm, count);
@@ -895,33 +923,39 @@ static int domain_name_list_contains(struct wpabuf *domain_names,
 static int interworking_home_sp(struct wpa_supplicant *wpa_s,
                                struct wpabuf *domain_names)
 {
+       struct wpa_cred *cred;
 #ifdef INTERWORKING_3GPP
        char nai[100], *realm;
 #endif /* INTERWORKING_3GPP */
 
-       if (domain_names == NULL)
+       if (domain_names == NULL || wpa_s->conf->cred == NULL)
                return -1;
 
+       for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
 #ifdef INTERWORKING_3GPP
-       if (wpa_s->conf->home_imsi &&
-           build_root_nai(nai, wpa_s->conf->home_imsi, 0) == 0) {
-               realm = os_strchr(nai, '@');
-               if (realm)
-                       realm++;
+               if (cred->imsi &&
+                   build_root_nai(nai, cred->imsi, 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;
+
                wpa_printf(MSG_DEBUG, "Interworking: Search for match with "
-                          "SIM/USIM domain %s", realm);
-               if (realm && domain_name_list_contains(domain_names, realm))
+                          "home SP FQDN %s", cred->domain);
+               if (domain_name_list_contains(domain_names, cred->domain))
                        return 1;
        }
-#endif /* INTERWORKING_3GPP */
-
-       if (wpa_s->conf->home_domain == NULL)
-               return -1;
 
-       wpa_printf(MSG_DEBUG, "Interworking: Search for match with "
-                  "home SP FQDN %s", wpa_s->conf->home_domain);
-       return domain_name_list_contains(domain_names,
-                                        wpa_s->conf->home_domain);
+       return 0;
 }