aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-12-16 10:01:50 (GMT)
committerJouni Malinen <j@w1.fi>2012-12-16 10:01:50 (GMT)
commitdbea8ac7ab771758d51b6b39892ad14fcdfe0aaa (patch)
tree2f4d572ea209df3b0d361a9d1b04506212187916 /wpa_supplicant
parent9aae09f196f088f9561c096a5a0e6c1aa27330e6 (diff)
downloadhostap-dbea8ac7ab771758d51b6b39892ad14fcdfe0aaa.zip
hostap-dbea8ac7ab771758d51b6b39892ad14fcdfe0aaa.tar.gz
hostap-dbea8ac7ab771758d51b6b39892ad14fcdfe0aaa.tar.bz2
Interworking: Allow SSID-based network exclusion for credentials
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>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/README-HS205
-rw-r--r--wpa_supplicant/config.c29
-rw-r--r--wpa_supplicant/config.h6
-rw-r--r--wpa_supplicant/config_file.c10
-rw-r--r--wpa_supplicant/interworking.c25
-rw-r--r--wpa_supplicant/wpa_supplicant.conf5
6 files changed, 80 insertions, 0 deletions
diff --git a/wpa_supplicant/README-HS20 b/wpa_supplicant/README-HS20
index feb9049..5669c55 100644
--- a/wpa_supplicant/README-HS20
+++ b/wpa_supplicant/README-HS20
@@ -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={
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index e157845..58e56ce 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -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);
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index c0aea0b..1bca444 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -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;
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 3ba0abe..b6fb3e6 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -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");
+ }
+ }
}
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 875abce..0572556 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -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;
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 5f0dec6..ebefe60 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -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={