static void * eap_ikev2_init(struct eap_sm *sm) { struct eap_ikev2_data *data; const u8 *identity, *password; size_t identity_len, password_len; int fragment_size; identity = eap_get_config_identity(sm, &identity_len); if (identity == NULL) { wpa_printf(MSG_INFO, "EAP-IKEV2: No identity available"); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = WAIT_START; fragment_size = eap_get_config_fragment_size(sm); if (fragment_size <= 0) data->fragment_size = IKEV2_FRAGMENT_SIZE; else data->fragment_size = fragment_size; data->ikev2.state = SA_INIT; data->ikev2.peer_auth = PEER_AUTH_SECRET; data->ikev2.key_pad = (u8 *) os_strdup("Key Pad for EAP-IKEv2"); if (data->ikev2.key_pad == NULL) goto failed; data->ikev2.key_pad_len = 21; data->ikev2.IDr = os_malloc(identity_len); if (data->ikev2.IDr == NULL) goto failed; os_memcpy(data->ikev2.IDr, identity, identity_len); data->ikev2.IDr_len = identity_len; password = eap_get_config_password(sm, &password_len); if (password) { data->ikev2.shared_secret = os_malloc(password_len); if (data->ikev2.shared_secret == NULL) goto failed; os_memcpy(data->ikev2.shared_secret, password, password_len); data->ikev2.shared_secret_len = password_len; } return data; failed: ikev2_responder_deinit(&data->ikev2); os_free(data); return NULL; }
static void * eap_pwd_init(struct eap_sm *sm) { struct eap_pwd_data *data; const u8 *identity, *password; size_t identity_len, password_len; int fragment_size; password = eap_get_config_password(sm, &password_len); if (password == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: No password configured!"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: No identity configured!"); return NULL; } if ((data = os_zalloc(sizeof(*data))) == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: memory allocation data fail"); return NULL; } if ((data->bnctx = BN_CTX_new()) == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: bn context allocation fail"); os_free(data); return NULL; } if ((data->id_peer = os_malloc(identity_len)) == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: memory allocation id fail"); BN_CTX_free(data->bnctx); os_free(data); return NULL; } os_memcpy(data->id_peer, identity, identity_len); data->id_peer_len = identity_len; if ((data->password = os_malloc(password_len)) == NULL) { wpa_printf(MSG_INFO, "EAP-PWD: memory allocation psk fail"); BN_CTX_free(data->bnctx); bin_clear_free(data->id_peer, data->id_peer_len); os_free(data); return NULL; } os_memcpy(data->password, password, password_len); data->password_len = password_len; data->out_frag_pos = data->in_frag_pos = 0; data->inbuf = data->outbuf = NULL; fragment_size = eap_get_config_fragment_size(sm); if (fragment_size <= 0) data->mtu = 1020; /* default from RFC 5931 */ else data->mtu = fragment_size; data->state = PWD_ID_Req; return data; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos, *end; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; int nfc = 0; u8 pkhash[WPS_OOB_PUBKEY_HASH_LEN]; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; if (cfg.pin_len == 6 && os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) { cfg.pin = NULL; cfg.pin_len = 0; nfc = 1; } } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } pos = os_strstr(phase1, "dev_pw_id="); if (pos) { u16 id = atoi(pos + 10); if (id == DEV_PW_NFC_CONNECTION_HANDOVER) nfc = 1; if (cfg.pin || id == DEV_PW_NFC_CONNECTION_HANDOVER) cfg.dev_pw_id = id; } if (cfg.pin == NULL && !cfg.pbc && !nfc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, " pkhash="); if (pos) { size_t len; pos += 8; end = os_strchr(pos, ' '); if (end) len = end - pos; else len = os_strlen(pos); if (len != 2 * WPS_OOB_PUBKEY_HASH_LEN || hexstr2bin(pos, pkhash, WPS_OOB_PUBKEY_HASH_LEN)) { wpa_printf(MSG_INFO, "EAP-WSC: Invalid pkhash"); os_free(data); return NULL; } cfg.peer_pubkey_hash = pkhash; } res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to parse new AP " "settings"); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); wpa_printf(MSG_DEBUG, "EAP-WSC: wps_init failed"); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, NULL, cfg.pin, cfg.pin_len, 0); } /* Use reduced client timeout for WPS to avoid long wait */ if (sm->ClientTimeout > 30) sm->ClientTimeout = 30; return data; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN]; int nfc = 0; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; if (cfg.pin_len >= WPS_OOB_DEVICE_PASSWORD_MIN_LEN * 2 && cfg.pin_len <= WPS_OOB_DEVICE_PASSWORD_LEN * 2 && hexstr2bin((const char *) cfg.pin, dev_pw, cfg.pin_len / 2) == 0) { /* Convert OOB Device Password to binary */ cfg.pin = dev_pw; cfg.pin_len /= 2; } if (cfg.pin_len == 6 && os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) { cfg.pin = NULL; cfg.pin_len = 0; nfc = 1; } } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } if (cfg.pin == NULL && !cfg.pbc && !nfc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, "dev_pw_id="); if (pos && cfg.pin) cfg.dev_pw_id = atoi(pos + 10); res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, NULL, cfg.pin, cfg.pin_len, 0); } /* Use reduced client timeout for WPS to avoid long wait */ if (sm->ClientTimeout > 30) sm->ClientTimeout = 30; return data; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } if (cfg.pin == NULL && !cfg.pbc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, "dev_pw_id="); if (pos && cfg.pin) cfg.dev_pw_id = atoi(pos + 10); res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, cfg.pin, cfg.pin_len, 0); } return data; }