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>
This commit is contained in:
Jouni Malinen 2012-12-16 12:01:50 +02:00 committed by Jouni Malinen
parent 9aae09f196
commit dbea8ac7ab
6 changed files with 80 additions and 0 deletions

View file

@ -190,6 +190,11 @@ Credentials can be pre-configured for automatic network selection:
# phase2: Pre-configure Phase 2 (inner authentication) parameters # phase2: Pre-configure Phase 2 (inner authentication) parameters
# This optional field is used with like the 'eap' parameter. # 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: # for example:
# #
#cred={ #cred={

View file

@ -1835,6 +1835,7 @@ void wpa_config_free_cred(struct wpa_cred *cred)
os_free(cred->eap_method); os_free(cred->eap_method);
os_free(cred->phase1); os_free(cred->phase1);
os_free(cred->phase2); os_free(cred->phase2);
os_free(cred->excluded_ssid);
os_free(cred); os_free(cred);
} }
@ -2411,6 +2412,34 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
return 0; 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) { if (line) {
wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.", wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
line, var); line, var);

View file

@ -196,6 +196,12 @@ struct wpa_cred {
* Pre-configured EAP parameters or %NULL. * Pre-configured EAP parameters or %NULL.
*/ */
char *phase2; char *phase2;
struct excluded_ssid {
u8 ssid[MAX_SSID_LEN];
size_t ssid_len;
} *excluded_ssid;
size_t num_excluded_ssid;
}; };

View file

@ -742,6 +742,16 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
fprintf(f, "\tphase1=\"%s\"\n", cred->phase1); fprintf(f, "\tphase1=\"%s\"\n", cred->phase1);
if (cred->phase2) if (cred->phase2)
fprintf(f, "\tphase2=\"%s\"\n", 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");
}
}
} }

View 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( static struct wpa_cred * interworking_credentials_available_roaming_consortium(
struct wpa_supplicant *wpa_s, struct wpa_bss *bss) 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)) cred->roaming_consortium_len))
continue; continue;
if (cred_excluded_ssid(cred, bss))
continue;
if (selected == NULL || if (selected == NULL ||
selected->priority < cred->priority) selected->priority < cred->priority)
selected = cred; 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); ret = plmn_id_match(bss->anqp->anqp_3gpp, imsi, mnc_len);
wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not "); wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
if (ret) { if (ret) {
if (cred_excluded_ssid(cred, bss))
continue;
if (selected == NULL || if (selected == NULL ||
selected->priority < cred->priority) selected->priority < cred->priority)
selected = cred; selected = cred;
@ -1383,6 +1406,8 @@ static struct wpa_cred * interworking_credentials_available_realm(
if (!nai_realm_match(&realm[i], cred->realm)) if (!nai_realm_match(&realm[i], cred->realm))
continue; continue;
if (nai_realm_find_eap(cred, &realm[i])) { if (nai_realm_find_eap(cred, &realm[i])) {
if (cred_excluded_ssid(cred, bss))
continue;
if (selected == NULL || if (selected == NULL ||
selected->priority < cred->priority) selected->priority < cred->priority)
selected = cred; selected = cred;

View file

@ -389,6 +389,11 @@ fast_reauth=1
# phase2: Pre-configure Phase 2 (inner authentication) parameters # phase2: Pre-configure Phase 2 (inner authentication) parameters
# This optional field is used with like the 'eap' parameter. # 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: # for example:
# #
#cred={ #cred={