]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Interworking: Allow SSID-based network exclusion for credentials
authorJouni Malinen <jouni@qca.qualcomm.com>
Sun, 16 Dec 2012 10:01:50 +0000 (12:01 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 16 Dec 2012 10:01:50 +0000 (12:01 +0200)
The new excluded_ssid parameter within a cred block can be used to
excluded networks from matching with credentials.

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/interworking.c
wpa_supplicant/wpa_supplicant.conf

index feb9049005133b7fe1bfb829219f03b31a7749f5..5669c55c32d5edc521fc32087be9368dd8d5bb9d 100644 (file)
@@ -190,6 +190,11 @@ Credentials can be pre-configured for automatic network selection:
 # phase2: Pre-configure Phase 2 (inner authentication) parameters
 #      This optional field is used with like the 'eap' parameter.
 #
+# excluded_ssid: Excluded SSID
+#      This optional field can be used to excluded specific SSID(s) from
+#      matching with the network. Multiple entries can be used to specify more
+#      than one SSID.
+#
 # for example:
 #
 #cred={
index e157845f73917de05dfc51bb2534e107118cc096..58e56ce9de5ff0416a770b8d4e68bcd989a7a90c 100644 (file)
@@ -1835,6 +1835,7 @@ void wpa_config_free_cred(struct wpa_cred *cred)
        os_free(cred->eap_method);
        os_free(cred->phase1);
        os_free(cred->phase2);
+       os_free(cred->excluded_ssid);
        os_free(cred);
 }
 
@@ -2411,6 +2412,34 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
                return 0;
        }
 
+       if (os_strcmp(var, "excluded_ssid") == 0) {
+               struct excluded_ssid *e;
+
+               if (len > MAX_SSID_LEN) {
+                       wpa_printf(MSG_ERROR, "Line %d: invalid "
+                                  "excluded_ssid length %d", line, (int) len);
+                       os_free(val);
+                       return -1;
+               }
+
+               e = os_realloc_array(cred->excluded_ssid,
+                                    cred->num_excluded_ssid + 1,
+                                    sizeof(struct excluded_ssid));
+               if (e == NULL) {
+                       os_free(val);
+                       return -1;
+               }
+               cred->excluded_ssid = e;
+
+               e = &cred->excluded_ssid[cred->num_excluded_ssid++];
+               os_memcpy(e->ssid, val, len);
+               e->ssid_len = len;
+
+               os_free(val);
+
+               return 0;
+       }
+
        if (line) {
                wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
                           line, var);
index c0aea0b338bf6724387e1e916eaacf6057f0c84f..1bca44420be2ca27d4c55a9e8795be1e8465f382 100644 (file)
@@ -196,6 +196,12 @@ struct wpa_cred {
         * Pre-configured EAP parameters or %NULL.
         */
        char *phase2;
+
+       struct excluded_ssid {
+               u8 ssid[MAX_SSID_LEN];
+               size_t ssid_len;
+       } *excluded_ssid;
+       size_t num_excluded_ssid;
 };
 
 
index 3ba0abe2c04c163ee63829bb0bda755f260423c2..b6fb3e607bcf77b983629b16e2b59eed564e2b0b 100644 (file)
@@ -742,6 +742,16 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
                fprintf(f, "\tphase1=\"%s\"\n", cred->phase1);
        if (cred->phase2)
                fprintf(f, "\tphase2=\"%s\"\n", cred->phase2);
+       if (cred->excluded_ssid) {
+               size_t i, j;
+               for (i = 0; i < cred->num_excluded_ssid; i++) {
+                       struct excluded_ssid *e = &cred->excluded_ssid[i];
+                       fprintf(f, "\texcluded_ssid=");
+                       for (j = 0; j < e->ssid_len; j++)
+                               fprintf(f, "%02x", e->ssid[j]);
+                       fprintf(f, "\n");
+               }
+       }
 }
 
 
index 875abce20675fcda732c7b560e6d71f408c48d05..0572556943be283627a0b3ac95e7003db46bf31a 100644 (file)
@@ -948,6 +948,24 @@ static int roaming_consortium_match(const u8 *ie, const struct wpabuf *anqp,
 }
 
 
+static int cred_excluded_ssid(struct wpa_cred *cred, struct wpa_bss *bss)
+{
+       size_t i;
+
+       if (!cred->excluded_ssid)
+               return 0;
+
+       for (i = 0; i < cred->num_excluded_ssid; i++) {
+               struct excluded_ssid *e = &cred->excluded_ssid[i];
+               if (bss->ssid_len == e->ssid_len &&
+                   os_memcmp(bss->ssid, e->ssid, e->ssid_len) == 0)
+                       return 1;
+       }
+
+       return 0;
+}
+
+
 static struct wpa_cred * interworking_credentials_available_roaming_consortium(
        struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
 {
@@ -975,6 +993,9 @@ static struct wpa_cred * interworking_credentials_available_roaming_consortium(
                                              cred->roaming_consortium_len))
                        continue;
 
+               if (cred_excluded_ssid(cred, bss))
+                       continue;
+
                if (selected == NULL ||
                    selected->priority < cred->priority)
                        selected = cred;
@@ -1343,6 +1364,8 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
                ret = plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len);
                wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
                if (ret) {
+                       if (cred_excluded_ssid(cred, bss))
+                               continue;
                        if (selected == NULL ||
                            selected->priority < cred->priority)
                                selected = cred;
@@ -1383,6 +1406,8 @@ static struct wpa_cred * interworking_credentials_available_realm(
                        if (!nai_realm_match(&realm[i], cred->realm))
                                continue;
                        if (nai_realm_find_eap(cred, &realm[i])) {
+                               if (cred_excluded_ssid(cred, bss))
+                                       continue;
                                if (selected == NULL ||
                                    selected->priority < cred->priority)
                                        selected = cred;
index 5f0dec66e0c816f9b7e4f5e512ba410789cc34ba..ebefe607179b3d972115afc7ecc34059a588c9c1 100644 (file)
@@ -389,6 +389,11 @@ fast_reauth=1
 # phase2: Pre-configure Phase 2 (inner authentication) parameters
 #      This optional field is used with like the 'eap' parameter.
 #
+# excluded_ssid: Excluded SSID
+#      This optional field can be used to excluded specific SSID(s) from
+#      matching with the network. Multiple entries can be used to specify more
+#      than one SSID.
+#
 # for example:
 #
 #cred={