EAP peer: Add framework for external SIM/USIM processing
The new configuration parameter external_sim=<0/1> can now be used to configure wpa_supplicant to use external SIM/USIM processing (e.g., GSM authentication for EAP-SIM or UMTS authentication for EAP-AKA). The requests and responses for such operations are sent over the ctrl_iface CTRL-REQ-SIM and CTRL-RSP-SIM commands similarly to the existing password query mechanism. Changes to the EAP methods to use this new mechanism will be added in separate commits. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
7e8bc7d6fb
commit
a5d44ac083
18 changed files with 122 additions and 4 deletions
|
@ -312,6 +312,7 @@ enum wpa_ctrl_req_type {
|
|||
WPA_CTRL_REQ_EAP_PIN,
|
||||
WPA_CTRL_REQ_EAP_OTP,
|
||||
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
||||
WPA_CTRL_REQ_SIM,
|
||||
NUM_WPA_CTRL_REQS
|
||||
};
|
||||
|
||||
|
|
|
@ -1638,7 +1638,8 @@ static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
|
|||
const char *msg, size_t msglen)
|
||||
{
|
||||
struct eap_peer_config *config;
|
||||
char *txt = NULL, *tmp;
|
||||
const char *txt = NULL;
|
||||
char *tmp;
|
||||
|
||||
if (sm == NULL)
|
||||
return;
|
||||
|
@ -1681,6 +1682,9 @@ static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field,
|
|||
case WPA_CTRL_REQ_EAP_PASSPHRASE:
|
||||
config->pending_req_passphrase++;
|
||||
break;
|
||||
case WPA_CTRL_REQ_SIM:
|
||||
txt = msg;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
@ -1791,6 +1795,17 @@ void eap_sm_request_passphrase(struct eap_sm *sm)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_sm_request_sim - Request external SIM processing
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @req: EAP method specific request
|
||||
*/
|
||||
void eap_sm_request_sim(struct eap_sm *sm, const char *req)
|
||||
{
|
||||
eap_sm_request(sm, WPA_CTRL_REQ_SIM, req, os_strlen(req));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_sm_notify_ctrl_attached - Notification of attached monitor
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
|
@ -2304,6 +2319,17 @@ void eap_set_force_disabled(struct eap_sm *sm, int disabled)
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_set_external_sim - Set external_sim flag
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
* @external_sim: Whether external SIM/USIM processing is used
|
||||
*/
|
||||
void eap_set_external_sim(struct eap_sm *sm, int external_sim)
|
||||
{
|
||||
sm->external_sim = external_sim;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_notify_pending - Notify that EAP method is ready to re-process a request
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
|
|
|
@ -296,6 +296,7 @@ void eap_sm_request_new_password(struct eap_sm *sm);
|
|||
void eap_sm_request_pin(struct eap_sm *sm);
|
||||
void eap_sm_request_otp(struct eap_sm *sm, const char *msg, size_t msg_len);
|
||||
void eap_sm_request_passphrase(struct eap_sm *sm);
|
||||
void eap_sm_request_sim(struct eap_sm *sm, const char *req);
|
||||
void eap_sm_notify_ctrl_attached(struct eap_sm *sm);
|
||||
u32 eap_get_phase2_type(const char *name, int *vendor);
|
||||
struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
|
||||
|
@ -303,6 +304,7 @@ struct eap_method_type * eap_get_phase2_types(struct eap_peer_config *config,
|
|||
void eap_set_fast_reauth(struct eap_sm *sm, int enabled);
|
||||
void eap_set_workaround(struct eap_sm *sm, unsigned int workaround);
|
||||
void eap_set_force_disabled(struct eap_sm *sm, int disabled);
|
||||
void eap_set_external_sim(struct eap_sm *sm, int external_sim);
|
||||
int eap_key_available(struct eap_sm *sm);
|
||||
void eap_notify_success(struct eap_sm *sm);
|
||||
void eap_notify_lower_layer_success(struct eap_sm *sm);
|
||||
|
|
|
@ -669,6 +669,15 @@ struct eap_peer_config {
|
|||
* 2 = require valid OCSP stapling response
|
||||
*/
|
||||
int ocsp;
|
||||
|
||||
/**
|
||||
* external_sim_resp - Response from external SIM processing
|
||||
*
|
||||
* This field should not be set in configuration step. It is only used
|
||||
* internally when control interface is used to request external
|
||||
* SIM/USIM processing.
|
||||
*/
|
||||
char *external_sim_resp;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -348,6 +348,8 @@ struct eap_sm {
|
|||
|
||||
struct ext_password_data *ext_pw;
|
||||
struct wpabuf *ext_pw_buf;
|
||||
|
||||
int external_sim;
|
||||
};
|
||||
|
||||
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
|
||||
|
|
|
@ -1479,6 +1479,7 @@ void eapol_sm_notify_config(struct eapol_sm *sm,
|
|||
eap_set_fast_reauth(sm->eap, conf->fast_reauth);
|
||||
eap_set_workaround(sm->eap, conf->workaround);
|
||||
eap_set_force_disabled(sm->eap, conf->eap_disabled);
|
||||
eap_set_external_sim(sm->eap, conf->external_sim);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,11 @@ struct eapol_config {
|
|||
* eap_disabled - Whether EAP is disabled
|
||||
*/
|
||||
int eap_disabled;
|
||||
|
||||
/**
|
||||
* external_sim - Use external processing for SIM/USIM operations
|
||||
*/
|
||||
int external_sim;
|
||||
};
|
||||
|
||||
struct eapol_sm;
|
||||
|
|
|
@ -284,6 +284,17 @@ OK
|
|||
Note: the return value of add_cred is used as the first argument to
|
||||
the following set_cred commands.
|
||||
|
||||
Add a SIM credential using a external SIM/USIM processing:
|
||||
|
||||
> set external_sim 1
|
||||
OK
|
||||
> add_cred
|
||||
1
|
||||
> set_cred 1 imsi "23456-0000000000"
|
||||
OK
|
||||
> set_cred 1 eap SIM
|
||||
OK
|
||||
|
||||
|
||||
Add a WPA2-Enterprise network:
|
||||
|
||||
|
|
|
@ -1815,6 +1815,7 @@ static void eap_peer_config_free(struct eap_peer_config *eap)
|
|||
os_free(eap->pending_req_otp);
|
||||
os_free(eap->pac_file);
|
||||
os_free(eap->new_password);
|
||||
os_free(eap->external_sim_resp);
|
||||
}
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
||||
|
@ -3194,6 +3195,7 @@ static const struct global_parse_data global_fields[] = {
|
|||
{ STR(pkcs11_module_path), 0 },
|
||||
{ STR(pcsc_reader), 0 },
|
||||
{ STR(pcsc_pin), 0 },
|
||||
{ INT(external_sim), 0 },
|
||||
{ STR(driver_param), 0 },
|
||||
{ INT(dot11RSNAConfigPMKLifetime), 0 },
|
||||
{ INT(dot11RSNAConfigPMKReauthThreshold), 0 },
|
||||
|
|
|
@ -452,6 +452,11 @@ struct wpa_config {
|
|||
*/
|
||||
char *pcsc_pin;
|
||||
|
||||
/**
|
||||
* external_sim - Use external processing for SIM/USIM operations
|
||||
*/
|
||||
int external_sim;
|
||||
|
||||
/**
|
||||
* driver_param - Driver interface parameters
|
||||
*
|
||||
|
|
|
@ -1055,6 +1055,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
|
|||
if (config->sched_scan_interval)
|
||||
fprintf(f, "sched_scan_interval=%u\n",
|
||||
config->sched_scan_interval);
|
||||
|
||||
if (config->external_sim)
|
||||
fprintf(f, "external_sim=%d\n", config->external_sim);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NO_CONFIG_WRITE */
|
||||
|
|
|
@ -623,6 +623,9 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
|
|||
wpa_config_write_reg_dword(hk, TEXT("okc"), config->okc, 0);
|
||||
wpa_config_write_reg_dword(hk, TEXT("pmf"), config->pmf, 0);
|
||||
|
||||
wpa_config_write_reg_dword(hk, TEXT("external_sim"),
|
||||
config->external_sim, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -551,6 +551,7 @@ static int test_eapol(struct eapol_test_data *e, struct wpa_supplicant *wpa_s,
|
|||
eapol_conf.required_keys = 0;
|
||||
eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
|
||||
eapol_conf.workaround = ssid->eap_workaround;
|
||||
eapol_conf.external_sim = wpa_s->conf->external_sim;
|
||||
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
|
||||
eapol_sm_register_scard_ctx(wpa_s->eapol, wpa_s->scard);
|
||||
|
||||
|
|
|
@ -275,7 +275,8 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
|
|||
#ifdef PCSC_FUNCS
|
||||
int aka = 0, sim = 0;
|
||||
|
||||
if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL)
|
||||
if (ssid->eap.pcsc == NULL || wpa_s->scard != NULL ||
|
||||
wpa_s->conf->external_sim)
|
||||
return 0;
|
||||
|
||||
if (ssid->eap.eap_methods == NULL) {
|
||||
|
|
|
@ -1407,7 +1407,8 @@ static struct wpa_cred * interworking_credentials_available_3gpp(
|
|||
#endif /* CONFIG_EAP_PROXY */
|
||||
|
||||
if (cred->imsi == NULL || !cred->imsi[0] ||
|
||||
cred->milenage == NULL || !cred->milenage[0])
|
||||
(!wpa_s->conf->external_sim &&
|
||||
(cred->milenage == NULL || !cred->milenage[0])))
|
||||
continue;
|
||||
|
||||
sep = os_strchr(cred->imsi, '-');
|
||||
|
|
|
@ -625,7 +625,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
|
|||
"wps_nfc_dev_pw", "ext_password_backend",
|
||||
"p2p_go_max_inactivity", "auto_interworking", "okc", "pmf",
|
||||
"sae_groups", "dtim_period", "beacon_int", "ap_vendor_elements",
|
||||
"ignore_old_scan_res", "freq_list"
|
||||
"ignore_old_scan_res", "freq_list", "external_sim"
|
||||
};
|
||||
int i, num_fields = sizeof(fields) / sizeof(fields[0]);
|
||||
|
||||
|
@ -1270,6 +1270,38 @@ static int wpa_cli_cmd_otp(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
|||
}
|
||||
|
||||
|
||||
static int wpa_cli_cmd_sim(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||
{
|
||||
char cmd[256], *pos, *end;
|
||||
int i, ret;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("Invalid SIM command: needs two arguments "
|
||||
"(network id and SIM operation response)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
end = cmd + sizeof(cmd);
|
||||
pos = cmd;
|
||||
ret = os_snprintf(pos, end - pos, WPA_CTRL_RSP "SIM-%s:%s",
|
||||
argv[0], argv[1]);
|
||||
if (ret < 0 || ret >= end - pos) {
|
||||
printf("Too long SIM command.\n");
|
||||
return -1;
|
||||
}
|
||||
pos += ret;
|
||||
for (i = 2; i < argc; i++) {
|
||||
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
|
||||
if (ret < 0 || ret >= end - pos) {
|
||||
printf("Too long SIM command.\n");
|
||||
return -1;
|
||||
}
|
||||
pos += ret;
|
||||
}
|
||||
return wpa_ctrl_command(ctrl, cmd);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_cli_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
|
@ -2466,6 +2498,9 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
|||
cli_cmd_flag_sensitive,
|
||||
"<network id> <passphrase> = configure private key passphrase\n"
|
||||
" for an SSID" },
|
||||
{ "sim", wpa_cli_cmd_sim, NULL,
|
||||
cli_cmd_flag_sensitive,
|
||||
"<network id> <pin> = report SIM operation result" },
|
||||
{ "bssid", wpa_cli_cmd_bssid, NULL,
|
||||
cli_cmd_flag_none,
|
||||
"<network id> <BSSID> = set preferred BSSID for an SSID" },
|
||||
|
|
|
@ -303,6 +303,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s)
|
|||
!wpa_key_mgmt_wpa_ieee8021x(wpa_s->key_mgmt) &&
|
||||
wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X_NO_WPA &&
|
||||
wpa_s->key_mgmt != WPA_KEY_MGMT_WPS;
|
||||
eapol_conf.external_sim = wpa_s->conf->external_sim;
|
||||
eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
}
|
||||
|
@ -3750,6 +3751,10 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
|
|||
if (ssid == wpa_s->current_ssid)
|
||||
wpa_s->reassociate = 1;
|
||||
break;
|
||||
case WPA_CTRL_REQ_SIM:
|
||||
os_free(eap->external_sim_resp);
|
||||
eap->external_sim_resp = os_strdup(value);
|
||||
break;
|
||||
default:
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
|
||||
return -1;
|
||||
|
|
|
@ -611,6 +611,8 @@ enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field)
|
|||
return WPA_CTRL_REQ_EAP_OTP;
|
||||
else if (os_strcmp(field, "PASSPHRASE") == 0)
|
||||
return WPA_CTRL_REQ_EAP_PASSPHRASE;
|
||||
else if (os_strcmp(field, "SIM") == 0)
|
||||
return WPA_CTRL_REQ_SIM;
|
||||
return WPA_CTRL_REQ_UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -647,6 +649,9 @@ const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
|
|||
*txt = "Private key passphrase";
|
||||
ret = "PASSPHRASE";
|
||||
break;
|
||||
case WPA_CTRL_REQ_SIM:
|
||||
ret = "SIM";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue