aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-03-04 14:02:56 (GMT)
committerJouni Malinen <j@w1.fi>2012-03-04 14:02:56 (GMT)
commitd7b01abd5ec3d0d638ebfe7093910991f42e18a7 (patch)
treedd85eeb167cea34141804f6e293091d3147ac11d
parentc21246f5293ceb4ca948e9985af0298398dd5dd5 (diff)
downloadhostap-d7b01abd5ec3d0d638ebfe7093910991f42e18a7.zip
hostap-d7b01abd5ec3d0d638ebfe7093910991f42e18a7.tar.gz
hostap-d7b01abd5ec3d0d638ebfe7093910991f42e18a7.tar.bz2
Interworking: Support real SIM/USIM card for network selection
Signed-hostap: Jouni Malinen <j@w1.fi>
-rw-r--r--wpa_supplicant/config.c5
-rw-r--r--wpa_supplicant/config.h5
-rw-r--r--wpa_supplicant/config_file.c2
-rw-r--r--wpa_supplicant/interworking.c47
-rw-r--r--wpa_supplicant/wpa_supplicant.conf2
5 files changed, 54 insertions, 7 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index fc3205e..0350b8e 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2229,6 +2229,11 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
return 0;
}
+ if (os_strcmp(var, "pcsc") == 0) {
+ cred->pcsc = atoi(value);
+ return 0;
+ }
+
val = wpa_config_parse_string(value, &len);
if (val == NULL) {
wpa_printf(MSG_ERROR, "Line %d: invalid field '%s' string "
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 0dcb4c8..5b002a2 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -61,6 +61,11 @@ struct wpa_cred {
int priority;
/**
+ * pcsc - Use PC/SC and SIM/USIM card
+ */
+ int pcsc;
+
+ /**
* realm - Home Realm for Interworking
*/
char *realm;
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 12e909a..b3dd40e 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -659,6 +659,8 @@ static void wpa_config_write_cred(FILE *f, struct wpa_cred *cred)
{
if (cred->priority)
fprintf(f, "\tpriority=%d\n", cred->priority);
+ if (cred->pcsc)
+ fprintf(f, "\tpcsc=%d\n", cred->pcsc);
if (cred->realm)
fprintf(f, "\trealm=\"%s\"\n", cred->realm);
if (cred->username)
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 74d9a1a..a721e5d 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -599,6 +599,17 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
char *sep;
+ const char *imsi;
+ int mnc_len;
+
+#ifdef PCSC_FUNCS
+ if (cred->pcsc && wpa_s->conf->pcsc_reader && wpa_s->scard &&
+ wpa_s->imsi[0]) {
+ imsi = wpa_s->imsi;
+ mnc_len = wpa_s->mnc_len;
+ goto compare;
+ }
+#endif /* PCSC_FUNCS */
if (cred->imsi == NULL || !cred->imsi[0] ||
cred->milenage == NULL || !cred->milenage[0])
@@ -608,9 +619,13 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
if (sep == NULL ||
(sep - cred->imsi != 5 && sep - cred->imsi != 6))
continue;
+ mnc_len = sep - cred->imsi - 3;
+ imsi = cred->imsi;
- if (plmn_id_match(bss->anqp_3gpp, cred->imsi,
- sep - cred->imsi - 3))
+#ifdef PCSC_FUNCS
+ compare:
+#endif /* PCSC_FUNCS */
+ if (plmn_id_match(bss->anqp_3gpp, imsi, mnc_len))
break;
}
if (cred == NULL)
@@ -641,7 +656,7 @@ 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, cred->imsi, '1') < 0) {
+ if (!cred->pcsc && set_root_nai(ssid, cred->imsi, '1') < 0) {
wpa_printf(MSG_DEBUG, "Failed to set Root NAI");
goto fail;
}
@@ -650,10 +665,13 @@ static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
if (wpa_config_set_quoted(ssid, "password",
cred->milenage) < 0)
goto fail;
- } else {
- /* TODO: PIN */
+ } else if (cred->pcsc) {
if (wpa_config_set_quoted(ssid, "pcsc", "") < 0)
goto fail;
+ if (wpa_s->conf->pcsc_pin &&
+ wpa_config_set_quoted(ssid, "pin", wpa_s->conf->pcsc_pin)
+ < 0)
+ goto fail;
}
if (cred->password && cred->password[0] &&
@@ -871,6 +889,17 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
for (cred = wpa_s->conf->cred; cred; cred = cred->next) {
char *sep;
+ const char *imsi;
+ int mnc_len;
+
+#ifdef PCSC_FUNCS
+ if (cred->pcsc && wpa_s->conf->pcsc_reader && wpa_s->scard &&
+ wpa_s->imsi[0]) {
+ imsi = wpa_s->imsi;
+ mnc_len = wpa_s->mnc_len;
+ goto compare;
+ }
+#endif /* PCSC_FUNCS */
if (cred->imsi == NULL || !cred->imsi[0] ||
cred->milenage == NULL || !cred->milenage[0])
@@ -880,11 +909,15 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
if (sep == NULL ||
(sep - cred->imsi != 5 && sep - cred->imsi != 6))
continue;
+ mnc_len = sep - cred->imsi - 3;
+ imsi = cred->imsi;
+#ifdef PCSC_FUNCS
+ compare:
+#endif /* PCSC_FUNCS */
wpa_printf(MSG_DEBUG, "Interworking: Parsing 3GPP info from "
MACSTR, MAC2STR(bss->bssid));
- ret = plmn_id_match(bss->anqp_3gpp, cred->imsi,
- sep - cred->imsi - 3);
+ ret = plmn_id_match(bss->anqp_3gpp, imsi, mnc_len);
wpa_printf(MSG_DEBUG, "PLMN match %sfound", ret ? "" : "not ");
if (ret) {
if (selected == NULL ||
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 279991a..70d3030 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -255,6 +255,8 @@ fast_reauth=1
# network (based on either an enabled network block or a credential)
# with the highest priority value will be selected.
#
+# pcsc: Use PC/SC and SIM/USIM card
+#
# realm: Home Realm for Interworking
#
# username: Username for Interworking network selection