static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx) { struct wpa_priv_interface *iface = eloop_ctx; char buf[2000], *pos; void *cmd_buf; size_t cmd_len; int res, cmd; struct sockaddr_un from; socklen_t fromlen = sizeof(from); res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from, &fromlen); if (res < 0) { perror("recvfrom"); return; } if (res < (int) sizeof(int)) { wpa_printf(MSG_DEBUG, "Too short command (len=%d)", res); return; } os_memcpy(&cmd, buf, sizeof(int)); wpa_printf(MSG_DEBUG, "Command %d for interface %s", cmd, iface->ifname); cmd_buf = &buf[sizeof(int)]; cmd_len = res - sizeof(int); switch (cmd) { case PRIVSEP_CMD_REGISTER: wpa_priv_cmd_register(iface, &from); break; case PRIVSEP_CMD_UNREGISTER: wpa_priv_cmd_unregister(iface, &from); break; case PRIVSEP_CMD_SET_WPA: wpa_priv_cmd_set_wpa(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_SCAN: wpa_priv_cmd_scan(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_GET_SCAN_RESULTS: wpa_priv_cmd_get_scan_results(iface, &from); break; case PRIVSEP_CMD_ASSOCIATE: wpa_priv_cmd_associate(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_GET_BSSID: wpa_priv_cmd_get_bssid(iface, &from); break; case PRIVSEP_CMD_GET_SSID: wpa_priv_cmd_get_ssid(iface, &from); break; case PRIVSEP_CMD_SET_KEY: wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_GET_CAPA: wpa_priv_cmd_get_capa(iface, &from); break; case PRIVSEP_CMD_L2_REGISTER: wpa_priv_cmd_l2_register(iface, &from, cmd_buf, cmd_len); break; case PRIVSEP_CMD_L2_UNREGISTER: wpa_priv_cmd_l2_unregister(iface, &from); break; case PRIVSEP_CMD_L2_NOTIFY_AUTH_START: wpa_priv_cmd_l2_notify_auth_start(iface, &from); break; case PRIVSEP_CMD_L2_SEND: wpa_priv_cmd_l2_send(iface, &from, cmd_buf, cmd_len); break; case PRIVSEP_CMD_SET_MODE: wpa_priv_cmd_set_mode(iface, cmd_buf, cmd_len); break; case PRIVSEP_CMD_SET_COUNTRY: pos = cmd_buf; if (pos + cmd_len >= buf + sizeof(buf)) break; pos[cmd_len] = '\0'; wpa_priv_cmd_set_country(iface, pos); break; } }
static int wpa_driver_roboswitch_get_bssid(void *priv, u8 *bssid) { /* Report PAE group address as the "BSSID" for wired connection. */ os_memcpy(bssid, pae_group_addr, ETH_ALEN); return 0; }
int wps_derive_keys(struct wps_data *wps) { struct wpabuf *pubkey, *dh_shared; u8 dhkey[SHA256_MAC_LEN], kdk[SHA256_MAC_LEN]; const u8 *addr[3]; size_t len[3]; u8 keys[WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN + WPS_EMSK_LEN]; if (wps->dh_privkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Own DH private key not available"); return -1; } pubkey = wps->registrar ? wps->dh_pubkey_e : wps->dh_pubkey_r; if (pubkey == NULL) { wpa_printf(MSG_DEBUG, "WPS: Peer DH public key not available"); return -1; } wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH Private Key", wps->dh_privkey); wpa_hexdump_buf(MSG_DEBUG, "WPS: DH peer Public Key", pubkey); dh_shared = dh5_derive_shared(wps->dh_ctx, pubkey, wps->dh_privkey); dh5_free(wps->dh_ctx); wps->dh_ctx = NULL; dh_shared = wpabuf_zeropad(dh_shared, 192); if (dh_shared == NULL) { wpa_printf(MSG_DEBUG, "WPS: Failed to derive DH shared key"); return -1; } /* Own DH private key is not needed anymore */ wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; wpa_hexdump_buf_key(MSG_DEBUG, "WPS: DH shared key", dh_shared); /* DHKey = SHA-256(g^AB mod p) */ addr[0] = wpabuf_head(dh_shared); len[0] = wpabuf_len(dh_shared); sha256_vector(1, addr, len, dhkey); wpa_hexdump_key(MSG_DEBUG, "WPS: DHKey", dhkey, sizeof(dhkey)); wpabuf_free(dh_shared); /* KDK = HMAC-SHA-256_DHKey(N1 || EnrolleeMAC || N2) */ addr[0] = wps->nonce_e; len[0] = WPS_NONCE_LEN; addr[1] = wps->mac_addr_e; len[1] = ETH_ALEN; addr[2] = wps->nonce_r; len[2] = WPS_NONCE_LEN; hmac_sha256_vector(dhkey, sizeof(dhkey), 3, addr, len, kdk); wpa_hexdump_key(MSG_DEBUG, "WPS: KDK", kdk, sizeof(kdk)); wps_kdf(kdk, NULL, 0, "Wi-Fi Easy and Secure Key Derivation", keys, sizeof(keys)); os_memcpy(wps->authkey, keys, WPS_AUTHKEY_LEN); os_memcpy(wps->keywrapkey, keys + WPS_AUTHKEY_LEN, WPS_KEYWRAPKEY_LEN); os_memcpy(wps->emsk, keys + WPS_AUTHKEY_LEN + WPS_KEYWRAPKEY_LEN, WPS_EMSK_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: AuthKey", wps->authkey, WPS_AUTHKEY_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: KeyWrapKey", wps->keywrapkey, WPS_KEYWRAPKEY_LEN); wpa_hexdump_key(MSG_DEBUG, "WPS: EMSK", wps->emsk, WPS_EMSK_LEN); return 0; }
void ICACHE_FLASH_ATTR user_init() { uart_init(BIT_RATE_115200, BIT_RATE_115200); os_delay_us(100); #ifdef PLATFORM_DEBUG ets_uart_printf("ESP8266 platform starting...\r\n"); #endif struct softap_config apConfig; struct ip_info ipinfo; char ssid[33]; char password[33]; char macaddress[17]; char info[150]; if(wifi_get_opmode() != SOFTAP_MODE) { #ifdef PLATFORM_DEBUG ets_uart_printf("ESP8266 not in SOFTAP mode, restarting in SOFTAP mode...\r\n"); #endif wifi_set_opmode(SOFTAP_MODE); //after esp_iot_sdk_v0.9.2, need not to restart //system_restart(); } IP4_ADDR(&ipinfo.ip, 10, 10, 10, 1); IP4_ADDR(&ipinfo.gw, 10, 10, 10, 1); IP4_ADDR(&ipinfo.netmask, 255, 255, 255, 0); wifi_set_ip_info(SOFTAP_IF, &ipinfo); wifi_get_macaddr(SOFTAP_IF, macaddr); wifi_softap_get_config(&apConfig); os_memset(apConfig.ssid, 0, sizeof(apConfig.ssid)); os_sprintf(ssid, "%s", WIFI_APSSID); os_memcpy(apConfig.ssid, ssid, os_strlen(ssid)); if (wifi_get_opmode() == SOFTAP_MODE) { #ifdef WIFI_APWPA os_memset(apConfig.password, 0, sizeof(apConfig.password)); os_sprintf(password, "%s", WIFI_APPASSWORD); os_memcpy(apConfig.password, password, os_strlen(password)); apConfig.authmode = AUTH_WPA_WPA2_PSK; #else apConfig.authmode = AUTH_OPEN; #endif apConfig.channel = 7; apConfig.max_connection = 255; apConfig.ssid_hidden = 0; wifi_softap_set_config(&apConfig); } #ifdef PLATFORM_DEBUG if (wifi_get_opmode() == SOFTAP_MODE) { wifi_softap_get_config(&apConfig); os_sprintf(macaddress, MACSTR, MAC2STR(macaddr)); os_sprintf(info,"OPMODE: %u, SSID: %s, PASSWORD: %s, CHANNEL: %d, AUTHMODE: %d, MACADDRESS: %s\r\n", wifi_get_opmode(), apConfig.ssid, apConfig.password, apConfig.channel, apConfig.authmode, macaddress); ets_uart_printf(info); } #endif BtnInit(); #ifdef PLATFORM_DEBUG ets_uart_printf("ESP8266 platform started!\r\n"); #endif }
static void eap_psk_process_4(struct eap_sm *sm, struct eap_psk_data *data, struct wpabuf *respData) { const struct eap_psk_hdr_4 *resp; u8 *decrypted, nonce[16]; size_t left; const u8 *pos, *tag; if (data->state != PSK_3) return; wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-4"); pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &left); if (pos == NULL || left < sizeof(*resp)) { wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); return; } resp = (const struct eap_psk_hdr_4 *) pos; pos = (const u8 *) (resp + 1); left -= sizeof(*resp); wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Encrypted PCHANNEL", pos, left); if (left < 4 + 16 + 1) { wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in " "PSK-4 (len=%lu, expected 21)", (unsigned long) left); return; } if (pos[0] == 0 && pos[1] == 0 && pos[2] == 0 && pos[3] == 0) { wpa_printf(MSG_DEBUG, "EAP-PSK: Nonce did not increase"); return; } os_memset(nonce, 0, 12); os_memcpy(nonce + 12, pos, 4); pos += 4; left -= 4; tag = pos; pos += 16; left -= 16; decrypted = os_malloc(left); if (decrypted == NULL) return; os_memcpy(decrypted, pos, left); if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce), wpabuf_head(respData), 22, decrypted, left, tag)) { wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed"); os_free(decrypted); data->state = FAILURE; return; } wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message", decrypted, left); /* Verify R flag */ switch (decrypted[0] >> 6) { case EAP_PSK_R_FLAG_CONT: wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported"); data->state = FAILURE; break; case EAP_PSK_R_FLAG_DONE_SUCCESS: wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS"); data->state = SUCCESS; break; case EAP_PSK_R_FLAG_DONE_FAILURE: wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE"); data->state = FAILURE; break; } os_free(decrypted); }
int eap_sim_db_get_gsm_triplets(void *priv, const u8 *identity, size_t identity_len, int max_chal, u8 *_rand, u8 *kc, u8 *sres, void *cb_session_ctx) { struct eap_sim_db_data *data = priv; struct eap_sim_db_pending *entry; int len, ret; size_t i; char msg[40]; if (identity_len < 2 || identity[0] != EAP_SIM_PERMANENT_PREFIX) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity", identity, identity_len); return EAP_SIM_DB_FAILURE; } identity++; identity_len--; for (i = 0; i < identity_len; i++) { if (identity[i] == '@') { identity_len = i; break; } } if (identity_len + 1 > sizeof(entry->imsi)) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity", identity, identity_len); return EAP_SIM_DB_FAILURE; } wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Get GSM triplets for IMSI", identity, identity_len); entry = eap_sim_db_get_pending(data, identity, identity_len, 0); if (entry) { int num_chal; if (entry->state == FAILURE) { wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " "failure"); os_free(entry); return EAP_SIM_DB_FAILURE; } if (entry->state == PENDING) { wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " "still pending"); eap_sim_db_add_pending(data, entry); return EAP_SIM_DB_PENDING; } wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending entry -> " "%d challenges", entry->u.sim.num_chal); num_chal = entry->u.sim.num_chal; if (num_chal > max_chal) num_chal = max_chal; os_memcpy(_rand, entry->u.sim.rand, num_chal * GSM_RAND_LEN); os_memcpy(sres, entry->u.sim.sres, num_chal * EAP_SIM_SRES_LEN); os_memcpy(kc, entry->u.sim.kc, num_chal * EAP_SIM_KC_LEN); os_free(entry); return num_chal; } if (data->sock < 0) { if (eap_sim_db_open_socket(data) < 0) return EAP_SIM_DB_FAILURE; } len = os_snprintf(msg, sizeof(msg), "SIM-REQ-AUTH "); if (len < 0 || len + identity_len >= sizeof(msg)) return EAP_SIM_DB_FAILURE; os_memcpy(msg + len, identity, identity_len); len += identity_len; ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal); if (ret < 0 || (size_t) ret >= sizeof(msg) - len) return EAP_SIM_DB_FAILURE; len += ret; wpa_hexdump(MSG_DEBUG, "EAP-SIM DB: requesting SIM authentication " "data for IMSI", identity, identity_len); if (eap_sim_db_send(data, msg, len) < 0) return EAP_SIM_DB_FAILURE; entry = os_zalloc(sizeof(*entry)); if (entry == NULL) return EAP_SIM_DB_FAILURE; os_get_time(&entry->timestamp); os_memcpy(entry->imsi, identity, identity_len); entry->imsi_len = identity_len; entry->cb_session_ctx = cb_session_ctx; entry->state = PENDING; eap_sim_db_add_pending(data, entry); eap_sim_db_expire_pending(data); return EAP_SIM_DB_PENDING; }
static int hapd_wps_cred_cb(struct hostapd_data *hapd, void *ctx) { const struct wps_credential *cred = ctx; FILE *oconf, *nconf; size_t len, i; char *tmp_fname; char buf[1024]; int multi_bss; int wpa; if (hapd->wps == NULL) return 0; wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", cred->cred_attr, cred->cred_attr_len); wpa_printf(MSG_DEBUG, "WPS: Received new AP Settings"); wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", cred->ssid, cred->ssid_len); wpa_printf(MSG_DEBUG, "WPS: Authentication Type 0x%x", cred->auth_type); wpa_printf(MSG_DEBUG, "WPS: Encryption Type 0x%x", cred->encr_type); wpa_printf(MSG_DEBUG, "WPS: Network Key Index %d", cred->key_idx); wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", cred->key, cred->key_len); wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(cred->mac_addr)); if ((hapd->conf->wps_cred_processing == 1 || hapd->conf->wps_cred_processing == 2) && cred->cred_attr) { hapd_new_ap_event(hapd, cred->cred_attr, cred->cred_attr_len); } else if (hapd->conf->wps_cred_processing == 1 || hapd->conf->wps_cred_processing == 2) { struct wpabuf *attr; attr = wpabuf_alloc(200); if (attr && wps_build_credential_wrap(attr, cred) == 0) hapd_new_ap_event(hapd, wpabuf_head_u8(attr), wpabuf_len(attr)); wpabuf_free(attr); } else wpa_msg(hapd->msg_ctx, MSG_INFO, WPS_EVENT_NEW_AP_SETTINGS); if (hapd->conf->wps_cred_processing == 1) return 0; os_memcpy(hapd->wps->ssid, cred->ssid, cred->ssid_len); hapd->wps->ssid_len = cred->ssid_len; hapd->wps->encr_types = cred->encr_type; hapd->wps->auth_types = cred->auth_type; if (cred->key_len == 0) { os_free(hapd->wps->network_key); hapd->wps->network_key = NULL; hapd->wps->network_key_len = 0; } else { if (hapd->wps->network_key == NULL || hapd->wps->network_key_len < cred->key_len) { hapd->wps->network_key_len = 0; os_free(hapd->wps->network_key); hapd->wps->network_key = os_malloc(cred->key_len); if (hapd->wps->network_key == NULL) return -1; } hapd->wps->network_key_len = cred->key_len; os_memcpy(hapd->wps->network_key, cred->key, cred->key_len); } hapd->wps->wps_state = WPS_STATE_CONFIGURED; len = os_strlen(hapd->iface->config_fname) + 5; tmp_fname = os_malloc(len); if (tmp_fname == NULL) return -1; os_snprintf(tmp_fname, len, "%s-new", hapd->iface->config_fname); oconf = fopen(hapd->iface->config_fname, "r"); if (oconf == NULL) { wpa_printf(MSG_WARNING, "WPS: Could not open current " "configuration file"); os_free(tmp_fname); return -1; } nconf = fopen(tmp_fname, "w"); if (nconf == NULL) { wpa_printf(MSG_WARNING, "WPS: Could not write updated " "configuration file"); os_free(tmp_fname); fclose(oconf); return -1; } fprintf(nconf, "# WPS configuration - START\n"); fprintf(nconf, "wps_state=2\n"); fprintf(nconf, "ssid="); for (i = 0; i < cred->ssid_len; i++) fputc(cred->ssid[i], nconf); fprintf(nconf, "\n"); if ((cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) && (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK))) wpa = 3; else if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)) wpa = 2; else if (cred->auth_type & (WPS_AUTH_WPA | WPS_AUTH_WPAPSK)) wpa = 1; else wpa = 0; if (wpa) { char *prefix; fprintf(nconf, "wpa=%d\n", wpa); fprintf(nconf, "wpa_key_mgmt="); prefix = ""; if (cred->auth_type & (WPS_AUTH_WPA2 | WPS_AUTH_WPA)) { fprintf(nconf, "WPA-EAP"); prefix = " "; } if (cred->auth_type & (WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK)) fprintf(nconf, "%sWPA-PSK", prefix); fprintf(nconf, "\n"); fprintf(nconf, "wpa_pairwise="); prefix = ""; if (cred->encr_type & WPS_ENCR_AES) { fprintf(nconf, "CCMP"); prefix = " "; } if (cred->encr_type & WPS_ENCR_TKIP) { fprintf(nconf, "%sTKIP", prefix); } fprintf(nconf, "\n"); if (cred->key_len >= 8 && cred->key_len < 64) { fprintf(nconf, "wpa_passphrase="); for (i = 0; i < cred->key_len; i++) fputc(cred->key[i], nconf); fprintf(nconf, "\n"); } else if (cred->key_len == 64) { fprintf(nconf, "wpa_psk="); for (i = 0; i < cred->key_len; i++) fputc(cred->key[i], nconf); fprintf(nconf, "\n"); } else { wpa_printf(MSG_WARNING, "WPS: Invalid key length %lu " "for WPA/WPA2", (unsigned long) cred->key_len); } fprintf(nconf, "auth_algs=1\n"); } else { if ((cred->auth_type & WPS_AUTH_OPEN) && (cred->auth_type & WPS_AUTH_SHARED)) fprintf(nconf, "auth_algs=3\n"); else if (cred->auth_type & WPS_AUTH_SHARED) fprintf(nconf, "auth_algs=2\n"); else fprintf(nconf, "auth_algs=1\n"); if (cred->encr_type & WPS_ENCR_WEP && cred->key_idx <= 4) { int key_idx = cred->key_idx; if (key_idx) key_idx--; fprintf(nconf, "wep_default_key=%d\n", key_idx); fprintf(nconf, "wep_key%d=", key_idx); if (cred->key_len == 10 || cred->key_len == 26) { /* WEP key as a hex string */ for (i = 0; i < cred->key_len; i++) fputc(cred->key[i], nconf); } else { /* Raw WEP key; convert to hex */ for (i = 0; i < cred->key_len; i++) fprintf(nconf, "%02x", cred->key[i]); } fprintf(nconf, "\n"); } } fprintf(nconf, "# WPS configuration - END\n"); multi_bss = 0; while (fgets(buf, sizeof(buf), oconf)) { if (os_strncmp(buf, "bss=", 4) == 0) multi_bss = 1; if (!multi_bss && (str_starts(buf, "ssid=") || str_starts(buf, "auth_algs=") || str_starts(buf, "wep_default_key=") || str_starts(buf, "wep_key") || str_starts(buf, "wps_state=") || str_starts(buf, "wpa=") || str_starts(buf, "wpa_psk=") || str_starts(buf, "wpa_pairwise=") || str_starts(buf, "rsn_pairwise=") || str_starts(buf, "wpa_key_mgmt=") || str_starts(buf, "wpa_passphrase="))) { fprintf(nconf, "#WPS# %s", buf); } else fprintf(nconf, "%s", buf); } fclose(nconf); fclose(oconf); if (rename(tmp_fname, hapd->iface->config_fname) < 0) { wpa_printf(MSG_WARNING, "WPS: Failed to rename the updated " "configuration file: %s", strerror(errno)); os_free(tmp_fname); return -1; } os_free(tmp_fname); #ifdef CONFIG_ATHEROS_AP /* to support saving the config in flash for 2mb flash ap solutions */ os_snprintf(buf, sizeof(buf), "cfg wpssave %s", hapd->iface->config_fname); system(buf); /* mark the wps state to configured in flash parameters */ system("cfg -a WPS_ENABLE=2"); system("cfg -a WPS_ENABLE_2=2"); /* save the param in nvram*/ system("cfg -c"); #endif /* CONFIG_ATHEROS_AP */ /* Schedule configuration reload after short period of time to allow * EAP-WSC to be finished. */ eloop_register_timeout(0, 100000, wps_reload_config, hapd->iface, NULL); wpa_printf(MSG_DEBUG, "WPS: AP configuration updated"); return 0; }
static struct wpabuf * eap_sim_process_start(struct eap_sm *sm, struct eap_sim_data *data, u8 id, struct eap_sim_attrs *attr) { int selected_version = -1, id_error; size_t i; u8 *pos; wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Start"); if (attr->version_list == NULL) { wpa_printf(MSG_INFO, "EAP-SIM: No AT_VERSION_LIST in " "SIM/Start"); return eap_sim_client_error(data, id, EAP_SIM_UNSUPPORTED_VERSION); } os_free(data->ver_list); data->ver_list = os_malloc(attr->version_list_len); if (data->ver_list == NULL) { wpa_printf(MSG_DEBUG, "EAP-SIM: Failed to allocate " "memory for version list"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } os_memcpy(data->ver_list, attr->version_list, attr->version_list_len); data->ver_list_len = attr->version_list_len; pos = data->ver_list; for (i = 0; i < data->ver_list_len / 2; i++) { int ver = pos[0] * 256 + pos[1]; pos += 2; if (eap_sim_supported_ver(ver)) { selected_version = ver; break; } } if (selected_version < 0) { wpa_printf(MSG_INFO, "EAP-SIM: Could not find a supported " "version"); return eap_sim_client_error(data, id, EAP_SIM_UNSUPPORTED_VERSION); } wpa_printf(MSG_DEBUG, "EAP-SIM: Selected Version %d", selected_version); data->selected_version = selected_version; id_error = 0; switch (attr->id_req) { case NO_ID_REQ: break; case ANY_ID: if (data->num_id_req > 0) id_error++; data->num_id_req++; break; case FULLAUTH_ID: if (data->num_id_req > 1) id_error++; data->num_id_req++; break; case PERMANENT_ID: if (data->num_id_req > 2) id_error++; data->num_id_req++; break; } if (id_error) { wpa_printf(MSG_INFO, "EAP-SIM: Too many ID requests " "used within one authentication"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } return eap_sim_response_start(sm, data, id, attr->id_req); }
static struct wpabuf * eap_sim_process_challenge(struct eap_sm *sm, struct eap_sim_data *data, u8 id, const struct wpabuf *reqData, struct eap_sim_attrs *attr) { const u8 *identity; size_t identity_len; struct eap_sim_attrs eattr; wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Challenge"); data->reauth = 0; if (!attr->mac || !attr->rand) { wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " "did not include%s%s", !attr->mac ? " AT_MAC" : "", !attr->rand ? " AT_RAND" : ""); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } wpa_printf(MSG_DEBUG, "EAP-SIM: %lu challenges", (unsigned long) attr->num_chal); if (attr->num_chal < data->min_num_chal) { wpa_printf(MSG_INFO, "EAP-SIM: Insufficient number of " "challenges (%lu)", (unsigned long) attr->num_chal); return eap_sim_client_error(data, id, EAP_SIM_INSUFFICIENT_NUM_OF_CHAL); } if (attr->num_chal > 3) { wpa_printf(MSG_INFO, "EAP-SIM: Too many challenges " "(%lu)", (unsigned long) attr->num_chal); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } /* Verify that RANDs are different */ if (os_memcmp(attr->rand, attr->rand + GSM_RAND_LEN, GSM_RAND_LEN) == 0 || (attr->num_chal > 2 && (os_memcmp(attr->rand, attr->rand + 2 * GSM_RAND_LEN, GSM_RAND_LEN) == 0 || os_memcmp(attr->rand + GSM_RAND_LEN, attr->rand + 2 * GSM_RAND_LEN, GSM_RAND_LEN) == 0))) { wpa_printf(MSG_INFO, "EAP-SIM: Same RAND used multiple times"); return eap_sim_client_error(data, id, EAP_SIM_RAND_NOT_FRESH); } os_memcpy(data->rand, attr->rand, attr->num_chal * GSM_RAND_LEN); data->num_chal = attr->num_chal; if (eap_sim_gsm_auth(sm, data)) { wpa_printf(MSG_WARNING, "EAP-SIM: GSM authentication failed"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } if (data->last_eap_identity) { identity = data->last_eap_identity; identity_len = data->last_eap_identity_len; } else if (data->pseudonym) { identity = data->pseudonym; identity_len = data->pseudonym_len; } else identity = eap_get_config_identity(sm, &identity_len); wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM: Selected identity for MK " "derivation", identity, identity_len); eap_sim_derive_mk(identity, identity_len, data->nonce_mt, data->selected_version, data->ver_list, data->ver_list_len, data->num_chal, (const u8 *) data->kc, data->mk); eap_sim_derive_keys(data->mk, data->k_encr, data->k_aut, data->msk, data->emsk); if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, data->nonce_mt, EAP_SIM_NONCE_MT_LEN)) { wpa_printf(MSG_WARNING, "EAP-SIM: Challenge message " "used invalid AT_MAC"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } /* Old reauthentication and pseudonym identities must not be used * anymore. In other words, if no new identities are received, full * authentication will be used on next reauthentication. */ eap_sim_clear_identities(data, CLEAR_PSEUDONYM | CLEAR_REAUTH_ID | CLEAR_EAP_ID); if (attr->encr_data) { u8 *decrypted; decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, attr->encr_data_len, attr->iv, &eattr, 0); if (decrypted == NULL) { return eap_sim_client_error( data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } eap_sim_learn_ids(data, &eattr); os_free(decrypted); } if (data->result_ind && attr->result_ind) data->use_result_ind = 1; if (data->state != FAILURE && data->state != RESULT_FAILURE) { eap_sim_state(data, data->use_result_ind ? RESULT_SUCCESS : SUCCESS); } data->num_id_req = 0; data->num_notification = 0; /* RFC 4186 specifies that counter is initialized to one after * fullauth, but initializing it to zero makes it easier to implement * reauth verification. */ data->counter = 0; return eap_sim_response_challenge(data, id); }
int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, const u8 *bssid, const u8 *ssid, size_t ssid_len, unsigned int force_freq, const u8 *go_dev_addr, int persistent_group) { struct p2p_device *dev; wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Request to invite peer " MACSTR " role=%d persistent=%d " "force_freq=%u", MAC2STR(peer), role, persistent_group, force_freq); if (bssid) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation for BSSID " MACSTR, MAC2STR(bssid)); if (go_dev_addr) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation for GO Device Address " MACSTR, MAC2STR(go_dev_addr)); os_memcpy(p2p->invite_go_dev_addr_buf, go_dev_addr, ETH_ALEN); p2p->invite_go_dev_addr = p2p->invite_go_dev_addr_buf; } else p2p->invite_go_dev_addr = NULL; wpa_hexdump_ascii(MSG_DEBUG, "P2P: Invitation for SSID", ssid, ssid_len); dev = p2p_get_device(p2p, peer); if (dev == NULL || (dev->listen_freq <= 0 && dev->oper_freq <= 0)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cannot invite unknown P2P Device " MACSTR, MAC2STR(peer)); return -1; } if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { if (!(dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cannot invite a P2P Device " MACSTR " that is in a group and is not discoverable", MAC2STR(peer)); } /* TODO: use device discoverability request through GO */ } dev->invitation_reqs = 0; if (force_freq) { if (p2p_freq_to_channel(p2p->cfg->country, force_freq, &p2p->op_reg_class, &p2p->op_channel) < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported frequency %u MHz", force_freq); return -1; } #ifdef ANDROID_P2P wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Single channel list %d", p2p->op_channel); #endif p2p->channels.reg_classes = 1; p2p->channels.reg_class[0].channels = 1; p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; p2p->channels.reg_class[0].channel[0] = p2p->op_channel; } else { #ifdef ANDROID_P2P wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "Full channel list"); #endif p2p->op_reg_class = p2p->cfg->op_reg_class; p2p->op_channel = p2p->cfg->op_channel; os_memcpy(&p2p->channels, &p2p->cfg->channels, sizeof(struct p2p_channels)); } if (p2p->state != P2P_IDLE) p2p_stop_find(p2p); p2p->inv_role = role; p2p->inv_bssid_set = bssid != NULL; if (bssid) os_memcpy(p2p->inv_bssid, bssid, ETH_ALEN); os_memcpy(p2p->inv_ssid, ssid, ssid_len); p2p->inv_ssid_len = ssid_len; p2p->inv_persistent = persistent_group; return p2p_invite_send(p2p, dev, go_dev_addr); }
static int eap_sim_gsm_auth(struct eap_sm *sm, struct eap_sim_data *data) { struct eap_peer_config *conf; wpa_printf(MSG_DEBUG, "EAP-SIM: GSM authentication algorithm"); conf = eap_get_config(sm); if (conf == NULL) return -1; if (conf->pcsc) { if (scard_gsm_auth(sm->scard_ctx, data->rand[0], data->sres[0], data->kc[0]) || scard_gsm_auth(sm->scard_ctx, data->rand[1], data->sres[1], data->kc[1]) || (data->num_chal > 2 && scard_gsm_auth(sm->scard_ctx, data->rand[2], data->sres[2], data->kc[2]))) { wpa_printf(MSG_DEBUG, "EAP-SIM: GSM SIM " "authentication could not be completed"); return -1; } return 0; } #ifdef CONFIG_SIM_SIMULATOR if (conf->password) { u8 opc[16], k[16]; const char *pos; size_t i; wpa_printf(MSG_DEBUG, "EAP-SIM: Use internal GSM-Milenage " "implementation for authentication"); if (conf->password_len < 65) { wpa_printf(MSG_DEBUG, "EAP-SIM: invalid GSM-Milenage " "password"); return -1; } pos = (const char *) conf->password; if (hexstr2bin(pos, k, 16)) return -1; pos += 32; if (*pos != ':') return -1; pos++; if (hexstr2bin(pos, opc, 16)) return -1; for (i = 0; i < data->num_chal; i++) { if (gsm_milenage(opc, k, data->rand[i], data->sres[i], data->kc[i])) { wpa_printf(MSG_DEBUG, "EAP-SIM: " "GSM-Milenage authentication " "could not be completed"); return -1; } wpa_hexdump(MSG_DEBUG, "EAP-SIM: RAND", data->rand[i], GSM_RAND_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: SRES", data->sres[i], EAP_SIM_SRES_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-SIM: Kc", data->kc[i], EAP_SIM_KC_LEN); } return 0; } #endif /* CONFIG_SIM_SIMULATOR */ #ifdef CONFIG_SIM_HARDCODED /* These hardcoded Kc and SRES values are used for testing. RAND to * KC/SREC mapping is very bogus as far as real authentication is * concerned, but it is quite useful for cases where the AS is rotating * the order of pre-configured values. */ { size_t i; wpa_printf(MSG_DEBUG, "EAP-SIM: Use hardcoded Kc and SRES " "values for testing"); for (i = 0; i < data->num_chal; i++) { if (data->rand[i][0] == 0xaa) { os_memcpy(data->kc[i], "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7", EAP_SIM_KC_LEN); os_memcpy(data->sres[i], "\xd1\xd2\xd3\xd4", EAP_SIM_SRES_LEN); } else if (data->rand[i][0] == 0xbb) { os_memcpy(data->kc[i], "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7", EAP_SIM_KC_LEN); os_memcpy(data->sres[i], "\xe1\xe2\xe3\xe4", EAP_SIM_SRES_LEN); } else { os_memcpy(data->kc[i], "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7", EAP_SIM_KC_LEN); os_memcpy(data->sres[i], "\xf1\xf2\xf3\xf4", EAP_SIM_SRES_LEN); } } } return 0; #else /* CONFIG_SIM_HARDCODED */ wpa_printf(MSG_DEBUG, "EAP-SIM: No GSM authentication algorithm " "enabled"); return -1; #endif /* CONFIG_SIM_HARDCODED */ }
void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, const u8 *data, size_t len, int rx_freq) { struct p2p_device *dev; struct p2p_message msg; struct wpabuf *resp = NULL; u8 status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; int freq; int go = 0; u8 group_bssid[ETH_ALEN], *bssid; int op_freq = 0; u8 reg_class = 0, channel = 0; struct p2p_channels intersection, *channels = NULL; int persistent; os_memset(group_bssid, 0, sizeof(group_bssid)); wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Received Invitation Request from " MACSTR " (freq=%d)", MAC2STR(sa), rx_freq); if (p2p_parse(data, len, &msg)) return; #ifdef CONFIG_MTK_WFD if(wfd_process_request_by_policy(p2p, &msg, &status,0) != 0) { goto fail; } #endif dev = p2p_get_device(p2p, sa); #ifdef CONFIG_MTK_WFD if(dev) { p2p_copy_wfd_info(dev, 0, &msg, 0); } #endif if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation Request from unknown peer " MACSTR, MAC2STR(sa)); if (p2p_add_device(p2p, sa, rx_freq, 0, data + 1, len - 1, 0)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation Request add device failed " MACSTR, MAC2STR(sa)); status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; goto fail; } dev = p2p_get_device(p2p, sa); if (dev == NULL) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Reject Invitation Request from unknown " "peer " MACSTR, MAC2STR(sa)); status = P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE; goto fail; } } if (!msg.group_id || !msg.channel_list) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Mandatory attribute missing in Invitation " "Request from " MACSTR, MAC2STR(sa)); status = P2P_SC_FAIL_INVALID_PARAMS; goto fail; } if (msg.invitation_flags) persistent = *msg.invitation_flags & P2P_INVITATION_FLAGS_TYPE; else { /* Invitation Flags is a mandatory attribute starting from P2P * spec 1.06. As a backwards compatibility mechanism, assume * the request was for a persistent group if the attribute is * missing. */ wpa_printf(MSG_DEBUG, "P2P: Mandatory Invitation Flags " "attribute missing from Invitation Request"); persistent = 1; } if (p2p_peer_channels_check(p2p, &p2p->cfg->channels, dev, msg.channel_list, msg.channel_list_len) < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No common channels found"); status = P2P_SC_FAIL_NO_COMMON_CHANNELS; goto fail; } if (p2p->cfg->invitation_process) { status = p2p->cfg->invitation_process( p2p->cfg->cb_ctx, sa, msg.group_bssid, msg.group_id, msg.group_id + ETH_ALEN, msg.group_id_len - ETH_ALEN, &go, group_bssid, &op_freq, persistent); } if (op_freq) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Invitation " "processing forced frequency %d MHz", op_freq); if (p2p_freq_to_channel(p2p->cfg->country, op_freq, ®_class, &channel) < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unknown forced freq %d MHz from " "invitation_process()", op_freq); status = P2P_SC_FAIL_NO_COMMON_CHANNELS; goto fail; } p2p_channels_intersect(&p2p->cfg->channels, &dev->channels, &intersection); if (!p2p_channels_includes(&intersection, reg_class, channel)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: forced freq %d MHz not in the supported " "channels interaction", op_freq); status = P2P_SC_FAIL_NO_COMMON_CHANNELS; goto fail; } if (status == P2P_SC_SUCCESS) channels = &intersection; } else { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: No forced channel from invitation processing - " "figure out best one to use"); p2p_channels_intersect(&p2p->cfg->channels, &dev->channels, &intersection); /* Default to own configuration as a starting point */ p2p->op_reg_class = p2p->cfg->op_reg_class; p2p->op_channel = p2p->cfg->op_channel; wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own default " "op_class %d channel %d", p2p->op_reg_class, p2p->op_channel); /* Use peer preference if specified and compatible */ if (msg.operating_channel) { int req_freq; req_freq = p2p_channel_to_freq( (const char *) msg.operating_channel, msg.operating_channel[3], msg.operating_channel[4]); wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer " "operating channel preference: %d MHz", req_freq); if (req_freq > 0 && p2p_channels_includes(&intersection, msg.operating_channel[3], msg.operating_channel[4])) { p2p->op_reg_class = msg.operating_channel[3]; p2p->op_channel = msg.operating_channel[4]; wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Use peer preference op_class %d " "channel %d", p2p->op_reg_class, p2p->op_channel); } else { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Cannot use peer channel " "preference"); } } if (!p2p_channels_includes(&intersection, p2p->op_reg_class, p2p->op_channel)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Initially selected channel (op_class %d " "channel %d) not in channel intersection - try " "to reselect", p2p->op_reg_class, p2p->op_channel); p2p_reselect_channel(p2p, &intersection); wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Re-selection result: op_class %d " "channel %d", p2p->op_reg_class, p2p->op_channel); if (!p2p_channels_includes(&intersection, p2p->op_reg_class, p2p->op_channel)) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer does not support selected " "operating channel (reg_class=%u " "channel=%u)", p2p->op_reg_class, p2p->op_channel); status = P2P_SC_FAIL_NO_COMMON_CHANNELS; goto fail; } } op_freq = p2p_channel_to_freq(p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); if (op_freq < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unknown operational channel " "(country=%c%c reg_class=%u channel=%u)", p2p->cfg->country[0], p2p->cfg->country[1], p2p->op_reg_class, p2p->op_channel); status = P2P_SC_FAIL_NO_COMMON_CHANNELS; goto fail; } wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating " "channel - %d MHz", op_freq); if (status == P2P_SC_SUCCESS) { reg_class = p2p->op_reg_class; channel = p2p->op_channel; channels = &intersection; } } fail: if (go && status == P2P_SC_SUCCESS && !is_zero_ether_addr(group_bssid)) bssid = group_bssid; else bssid = NULL; resp = p2p_build_invitation_resp(p2p, dev, msg.dialog_token, status, bssid, reg_class, channel, channels); if (resp == NULL) goto out; if (rx_freq > 0) freq = rx_freq; else freq = p2p_channel_to_freq(p2p->cfg->country, p2p->cfg->reg_class, p2p->cfg->channel); if (freq < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unknown regulatory class/channel"); goto out; } /* * Store copy of invitation data to be used when processing TX status * callback for the Acton frame. */ os_memcpy(p2p->inv_sa, sa, ETH_ALEN); if (msg.group_bssid) { os_memcpy(p2p->inv_group_bssid, msg.group_bssid, ETH_ALEN); p2p->inv_group_bssid_ptr = p2p->inv_group_bssid; } else p2p->inv_group_bssid_ptr = NULL; if (msg.group_id_len - ETH_ALEN <= 32) { os_memcpy(p2p->inv_ssid, msg.group_id + ETH_ALEN, msg.group_id_len - ETH_ALEN); p2p->inv_ssid_len = msg.group_id_len - ETH_ALEN; } os_memcpy(p2p->inv_go_dev_addr, msg.group_id, ETH_ALEN); p2p->inv_status = status; p2p->inv_op_freq = op_freq; p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE; #ifdef CONFIG_MTK_WFD wfd_process_request_and_switch_role(p2p, &msg, 0); #endif if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, p2p->cfg->dev_addr, wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Failed to send Action frame"); } out: wpabuf_free(resp); p2p_parse_free(&msg); }
/** * wps_init - Initialize WPS Registration protocol data * @cfg: WPS configuration * Returns: Pointer to allocated data or %NULL on failure * * This function is used to initialize WPS data for a registration protocol * instance (i.e., each run of registration protocol as a Registrar of * Enrollee. The caller is responsible for freeing this data after the * registration run has been completed by calling wps_deinit(). */ struct wps_data * wps_init(const struct wps_config *cfg) { struct wps_data *data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->wps = cfg->wps; data->registrar = cfg->registrar; if (cfg->registrar) { os_memcpy(data->uuid_r, cfg->wps->uuid, WPS_UUID_LEN); } else { os_memcpy(data->mac_addr_e, cfg->wps->dev.mac_addr, ETH_ALEN); os_memcpy(data->uuid_e, cfg->wps->uuid, WPS_UUID_LEN); } if (cfg->pin) { data->dev_pw_id = data->wps->oob_dev_pw_id == 0 ? cfg->dev_pw_id : data->wps->oob_dev_pw_id; data->dev_password = os_malloc(cfg->pin_len); if (data->dev_password == NULL) { os_free(data); return NULL; } os_memcpy(data->dev_password, cfg->pin, cfg->pin_len); data->dev_password_len = cfg->pin_len; } data->pbc = cfg->pbc; if (cfg->pbc) { /* Use special PIN '00000000' for PBC */ data->dev_pw_id = DEV_PW_PUSHBUTTON; os_free(data->dev_password); data->dev_password = os_malloc(8); if (data->dev_password == NULL) { os_free(data); return NULL; } os_memset(data->dev_password, '0', 8); data->dev_password_len = 8; } data->state = data->registrar ? RECV_M1 : SEND_M1; if (cfg->assoc_wps_ie) { struct wps_parse_attr attr; wpa_hexdump_buf(MSG_DEBUG, "WPS: WPS IE from (Re)AssocReq", cfg->assoc_wps_ie); if (wps_parse_msg(cfg->assoc_wps_ie, &attr) < 0) { wpa_printf(MSG_DEBUG, "WPS: Failed to parse WPS IE " "from (Re)AssocReq"); } else if (attr.request_type == NULL) { wpa_printf(MSG_DEBUG, "WPS: No Request Type attribute " "in (Re)AssocReq WPS IE"); } else { wpa_printf(MSG_DEBUG, "WPS: Request Type (from WPS IE " "in (Re)AssocReq WPS IE): %d", *attr.request_type); data->request_type = *attr.request_type; } } if (cfg->new_ap_settings) { data->new_ap_settings = os_malloc(sizeof(*data->new_ap_settings)); if (data->new_ap_settings == NULL) { os_free(data); return NULL; } os_memcpy(data->new_ap_settings, cfg->new_ap_settings, sizeof(*data->new_ap_settings)); } if (cfg->peer_addr) os_memcpy(data->peer_dev.mac_addr, cfg->peer_addr, ETH_ALEN); if (cfg->p2p_dev_addr) os_memcpy(data->p2p_dev_addr, cfg->p2p_dev_addr, ETH_ALEN); data->use_psk_key = cfg->use_psk_key; data->pbc_in_m1 = cfg->pbc_in_m1; return data; }
static struct wpa_priv_interface * wpa_priv_interface_init(const char *dir, const char *params) { struct wpa_priv_interface *iface; char *pos; size_t len; struct sockaddr_un addr; int i; pos = os_strchr(params, ':'); if (pos == NULL) return NULL; iface = os_zalloc(sizeof(*iface)); if (iface == NULL) return NULL; iface->fd = -1; len = pos - params; iface->driver_name = os_malloc(len + 1); if (iface->driver_name == NULL) { wpa_priv_interface_deinit(iface); return NULL; } os_memcpy(iface->driver_name, params, len); iface->driver_name[len] = '\0'; for (i = 0; wpa_supplicant_drivers[i]; i++) { if (os_strcmp(iface->driver_name, wpa_supplicant_drivers[i]->name) == 0) { iface->driver = wpa_supplicant_drivers[i]; break; } } if (iface->driver == NULL) { wpa_printf(MSG_ERROR, "Unsupported driver '%s'", iface->driver_name); wpa_priv_interface_deinit(iface); return NULL; } pos++; iface->ifname = os_strdup(pos); if (iface->ifname == NULL) { wpa_priv_interface_deinit(iface); return NULL; } len = os_strlen(dir) + 1 + os_strlen(iface->ifname); iface->sock_name = os_malloc(len + 1); if (iface->sock_name == NULL) { wpa_priv_interface_deinit(iface); return NULL; } os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname); if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) { wpa_priv_interface_deinit(iface); return NULL; } iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0); if (iface->fd < 0) { perror("socket(PF_UNIX)"); wpa_priv_interface_deinit(iface); return NULL; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path)); if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s", strerror(errno)); if (connect(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "Socket exists, but does not " "allow connections - assuming it was " "leftover from forced program termination"); if (unlink(iface->sock_name) < 0) { perror("unlink[ctrl_iface]"); wpa_printf(MSG_ERROR, "Could not unlink " "existing ctrl_iface socket '%s'", iface->sock_name); goto fail; } if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); goto fail; } wpa_printf(MSG_DEBUG, "Successfully replaced leftover " "socket '%s'", iface->sock_name); } else { wpa_printf(MSG_INFO, "Socket exists and seems to be " "in use - cannot override it"); wpa_printf(MSG_INFO, "Delete '%s' manually if it is " "not used anymore", iface->sock_name); goto fail; } } if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { perror("chmod"); goto fail; } eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL); return iface; fail: wpa_priv_interface_deinit(iface); return NULL; }
int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { struct wpa_driver_associate_params params; struct hostapd_iface *hapd_iface; struct hostapd_config *conf; size_t i; if (ssid->ssid == NULL || ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } wpa_supplicant_ap_deinit(wpa_s); wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')", wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); os_memset(¶ms, 0, sizeof(params)); params.ssid = ssid->ssid; params.ssid_len = ssid->ssid_len; switch (ssid->mode) { case WPAS_MODE_INFRA: params.mode = IEEE80211_MODE_INFRA; break; case WPAS_MODE_IBSS: params.mode = IEEE80211_MODE_IBSS; break; case WPAS_MODE_AP: case WPAS_MODE_P2P_GO: case WPAS_MODE_P2P_GROUP_FORMATION: params.mode = IEEE80211_MODE_AP; break; } params.freq = ssid->frequency; params.wpa_proto = ssid->proto; if (ssid->key_mgmt & WPA_KEY_MGMT_PSK) wpa_s->key_mgmt = WPA_KEY_MGMT_PSK; else wpa_s->key_mgmt = WPA_KEY_MGMT_NONE; params.key_mgmt_suite = key_mgmt2driver(wpa_s->key_mgmt); if (ssid->pairwise_cipher & WPA_CIPHER_CCMP) wpa_s->pairwise_cipher = WPA_CIPHER_CCMP; else if (ssid->pairwise_cipher & WPA_CIPHER_TKIP) wpa_s->pairwise_cipher = WPA_CIPHER_TKIP; else if (ssid->pairwise_cipher & WPA_CIPHER_NONE) wpa_s->pairwise_cipher = WPA_CIPHER_NONE; else { wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise " "cipher."); return -1; } params.pairwise_suite = cipher_suite2driver(wpa_s->pairwise_cipher); params.group_suite = params.pairwise_suite; #ifdef CONFIG_P2P if (ssid->mode == WPAS_MODE_P2P_GO || ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) params.p2p = 1; #endif /* CONFIG_P2P */ if (wpa_s->parent->set_ap_uapsd) params.uapsd = wpa_s->parent->ap_uapsd; else params.uapsd = -1; if (wpa_drv_associate(wpa_s, ¶ms) < 0) { wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality"); return -1; } wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface)); if (hapd_iface == NULL) return -1; hapd_iface->owner = wpa_s; hapd_iface->drv_flags = wpa_s->drv_flags; wpa_s->ap_iface->conf = conf = hostapd_config_defaults(); if (conf == NULL) { wpa_supplicant_ap_deinit(wpa_s); return -1; } if (params.uapsd > 0) { conf->bss->wmm_enabled = 1; conf->bss->wmm_uapsd = 1; } if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) { wpa_printf(MSG_ERROR, "Failed to create AP configuration"); wpa_supplicant_ap_deinit(wpa_s); return -1; } #ifdef CONFIG_P2P if (ssid->mode == WPAS_MODE_P2P_GO) conf->bss[0].p2p = P2P_ENABLED | P2P_GROUP_OWNER; else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) conf->bss[0].p2p = P2P_ENABLED | P2P_GROUP_OWNER | P2P_GROUP_FORMATION; #endif /* CONFIG_P2P */ hapd_iface->num_bss = conf->num_bss; hapd_iface->bss = os_zalloc(conf->num_bss * sizeof(struct hostapd_data *)); if (hapd_iface->bss == NULL) { wpa_supplicant_ap_deinit(wpa_s); return -1; } for (i = 0; i < conf->num_bss; i++) { hapd_iface->bss[i] = hostapd_alloc_bss_data(hapd_iface, conf, &conf->bss[i]); if (hapd_iface->bss[i] == NULL) { wpa_supplicant_ap_deinit(wpa_s); return -1; } hapd_iface->bss[i]->msg_ctx = wpa_s; hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent; hapd_iface->bss[i]->public_action_cb = ap_public_action_rx; hapd_iface->bss[i]->public_action_cb_ctx = wpa_s; hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx; hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s; hostapd_register_probereq_cb(hapd_iface->bss[i], ap_probe_req_rx, wpa_s); hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb; hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s; hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb; hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s; hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb; hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s; #ifdef CONFIG_P2P hapd_iface->bss[i]->p2p = wpa_s->global->p2p; hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init( wpa_s, ssid->p2p_persistent_group, ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION, ssid); #endif /* CONFIG_P2P */ hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb; hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s; } os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN); hapd_iface->bss[0]->driver = wpa_s->driver; hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv; wpa_s->current_ssid = ssid; os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN); wpa_s->assoc_freq = ssid->frequency; if (hostapd_setup_interface(wpa_s->ap_iface)) { wpa_printf(MSG_ERROR, "Failed to initialize AP interface"); wpa_supplicant_ap_deinit(wpa_s); return -1; } return 0; }
static struct wpabuf * eap_sim_process_reauthentication( struct eap_sm *sm, struct eap_sim_data *data, u8 id, const struct wpabuf *reqData, struct eap_sim_attrs *attr) { struct eap_sim_attrs eattr; u8 *decrypted; wpa_printf(MSG_DEBUG, "EAP-SIM: subtype Reauthentication"); if (data->reauth_id == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Server is trying " "reauthentication, but no reauth_id available"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } data->reauth = 1; if (eap_sim_verify_mac(data->k_aut, reqData, attr->mac, (u8 *) "", 0)) { wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " "did not have valid AT_MAC"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } if (attr->encr_data == NULL || attr->iv == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Reauthentication " "message did not include encrypted data"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } decrypted = eap_sim_parse_encr(data->k_encr, attr->encr_data, attr->encr_data_len, attr->iv, &eattr, 0); if (decrypted == NULL) { wpa_printf(MSG_WARNING, "EAP-SIM: Failed to parse encrypted " "data from reauthentication message"); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } if (eattr.nonce_s == NULL || eattr.counter < 0) { wpa_printf(MSG_INFO, "EAP-SIM: (encr) No%s%s in reauth packet", !eattr.nonce_s ? " AT_NONCE_S" : "", eattr.counter < 0 ? " AT_COUNTER" : ""); os_free(decrypted); return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET); } if (eattr.counter < 0 || (size_t) eattr.counter <= data->counter) { wpa_printf(MSG_INFO, "EAP-SIM: (encr) Invalid counter " "(%d <= %d)", eattr.counter, data->counter); data->counter_too_small = eattr.counter; /* Reply using Re-auth w/ AT_COUNTER_TOO_SMALL. The current * reauth_id must not be used to start a new reauthentication. * However, since it was used in the last EAP-Response-Identity * packet, it has to saved for the following fullauth to be * used in MK derivation. */ os_free(data->last_eap_identity); data->last_eap_identity = data->reauth_id; data->last_eap_identity_len = data->reauth_id_len; data->reauth_id = NULL; data->reauth_id_len = 0; os_free(decrypted); return eap_sim_response_reauth(data, id, 1); } data->counter = eattr.counter; os_memcpy(data->nonce_s, eattr.nonce_s, EAP_SIM_NONCE_S_LEN); wpa_hexdump(MSG_DEBUG, "EAP-SIM: (encr) AT_NONCE_S", data->nonce_s, EAP_SIM_NONCE_S_LEN); eap_sim_derive_keys_reauth(data->counter, data->reauth_id, data->reauth_id_len, data->nonce_s, data->mk, data->msk, data->emsk); eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); eap_sim_learn_ids(data, &eattr); if (data->result_ind && attr->result_ind) data->use_result_ind = 1; if (data->state != FAILURE && data->state != RESULT_FAILURE) { eap_sim_state(data, data->use_result_ind ? RESULT_SUCCESS : SUCCESS); } data->num_id_req = 0; data->num_notification = 0; if (data->counter > EAP_SIM_MAX_FAST_REAUTHS) { wpa_printf(MSG_DEBUG, "EAP-SIM: Maximum number of " "fast reauths performed - force fullauth"); eap_sim_clear_identities(data, CLEAR_REAUTH_ID | CLEAR_EAP_ID); } os_free(decrypted); return eap_sim_response_reauth(data, id, 0); }
static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_config *conf) { struct hostapd_bss_config *bss = &conf->bss[0]; int pairwise; conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); if (ssid->frequency == 0) { /* default channel 11 */ conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = 11; } else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) { conf->hw_mode = HOSTAPD_MODE_IEEE80211G; conf->channel = (ssid->frequency - 2407) / 5; } else if ((ssid->frequency >= 5180 && ssid->frequency <= 5240) || (ssid->frequency >= 5745 && ssid->frequency <= 5825)) { conf->hw_mode = HOSTAPD_MODE_IEEE80211A; conf->channel = (ssid->frequency - 5000) / 5; } else { wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", ssid->frequency); return -1; } /* TODO: enable HT40 if driver supports it; * drop to 11b if driver does not support 11g */ #ifdef CONFIG_IEEE80211N /* * Enable HT20 if the driver supports it, by setting conf->ieee80211n * and a mask of allowed capabilities within conf->ht_capab. * Using default config settings for: conf->ht_op_mode_fixed, * conf->secondary_channel, conf->require_ht */ if (wpa_s->hw.modes) { struct hostapd_hw_modes *mode = NULL; int i; for (i = 0; i < wpa_s->hw.num_modes; i++) { if (wpa_s->hw.modes[i].mode == conf->hw_mode) { mode = &wpa_s->hw.modes[i]; break; } } if (mode && mode->ht_capab) { conf->ieee80211n = 1; /* * white-list capabilities that won't cause issues * to connecting stations, while leaving the current * capabilities intact (currently disabled SMPS). */ conf->ht_capab |= mode->ht_capab & (HT_CAP_INFO_GREEN_FIELD | HT_CAP_INFO_SHORT_GI20MHZ | HT_CAP_INFO_SHORT_GI40MHZ | HT_CAP_INFO_RX_STBC_MASK | HT_CAP_INFO_MAX_AMSDU_SIZE); } } #endif /* CONFIG_IEEE80211N */ #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) { /* Remove 802.11b rates from supported and basic rate sets */ int *list = os_malloc(4 * sizeof(int)); if (list) { list[0] = 60; list[1] = 120; list[2] = 240; list[3] = -1; } conf->basic_rates = list; list = os_malloc(9 * sizeof(int)); if (list) { list[0] = 60; list[1] = 90; list[2] = 120; list[3] = 180; list[4] = 240; list[5] = 360; list[6] = 480; list[7] = 540; list[8] = -1; } conf->supported_rates = list; } bss->isolate = !wpa_s->conf->p2p_intra_bss; #endif /* CONFIG_P2P */ if (ssid->ssid_len == 0) { wpa_printf(MSG_ERROR, "No SSID configured for AP mode"); return -1; } os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len); bss->ssid.ssid[ssid->ssid_len] = '\0'; bss->ssid.ssid_len = ssid->ssid_len; bss->ssid.ssid_set = 1; if (ssid->auth_alg) bss->auth_algs = ssid->auth_alg; if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt)) bss->wpa = ssid->proto; bss->wpa_key_mgmt = ssid->key_mgmt; bss->wpa_pairwise = ssid->pairwise_cipher; if (ssid->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } else if (ssid->psk_set) { os_free(bss->ssid.wpa_psk); bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk)); if (bss->ssid.wpa_psk == NULL) return -1; os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN); bss->ssid.wpa_psk->group = 1; } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] || ssid->wep_key_len[2] || ssid->wep_key_len[3]) { struct hostapd_wep_keys *wep = &bss->ssid.wep; int i; for (i = 0; i < NUM_WEP_KEYS; i++) { if (ssid->wep_key_len[i] == 0) continue; wep->key[i] = os_malloc(ssid->wep_key_len[i]); if (wep->key[i] == NULL) return -1; os_memcpy(wep->key[i], ssid->wep_key[i], ssid->wep_key_len[i]); wep->len[i] = ssid->wep_key_len[i]; } wep->idx = ssid->wep_tx_keyidx; wep->keys_set = 1; } /* Select group cipher based on the enabled pairwise cipher suites */ pairwise = 0; if (bss->wpa & 1) pairwise |= bss->wpa_pairwise; if (bss->wpa & 2) { if (bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; pairwise |= bss->rsn_pairwise; } if (pairwise & WPA_CIPHER_TKIP) bss->wpa_group = WPA_CIPHER_TKIP; else bss->wpa_group = WPA_CIPHER_CCMP; if (bss->wpa && bss->ieee802_1x) bss->ssid.security_policy = SECURITY_WPA; else if (bss->wpa) bss->ssid.security_policy = SECURITY_WPA_PSK; else if (bss->ieee802_1x) { int cipher = WPA_CIPHER_NONE; bss->ssid.security_policy = SECURITY_IEEE_802_1X; bss->ssid.wep.default_len = bss->default_wep_key_len; if (bss->default_wep_key_len) cipher = bss->default_wep_key_len >= 13 ? WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else if (bss->ssid.wep.keys_set) { int cipher = WPA_CIPHER_WEP40; if (bss->ssid.wep.len[0] >= 13) cipher = WPA_CIPHER_WEP104; bss->ssid.security_policy = SECURITY_STATIC_WEP; bss->wpa_group = cipher; bss->wpa_pairwise = cipher; bss->rsn_pairwise = cipher; } else { bss->ssid.security_policy = SECURITY_PLAINTEXT; bss->wpa_group = WPA_CIPHER_NONE; bss->wpa_pairwise = WPA_CIPHER_NONE; bss->rsn_pairwise = WPA_CIPHER_NONE; } #ifdef CONFIG_WPS /* * Enable WPS by default for open and WPA/WPA2-Personal network, but * require user interaction to actually use it. Only the internal * Registrar is supported. */ if (bss->ssid.security_policy != SECURITY_WPA_PSK && bss->ssid.security_policy != SECURITY_PLAINTEXT) goto no_wps; bss->eap_server = 1; bss->wps_state = 2; bss->ap_setup_locked = 2; if (wpa_s->conf->config_methods) bss->config_methods = os_strdup(wpa_s->conf->config_methods); os_memcpy(bss->device_type, wpa_s->conf->device_type, WPS_DEV_TYPE_LEN); if (wpa_s->conf->device_name) { bss->device_name = os_strdup(wpa_s->conf->device_name); bss->friendly_name = os_strdup(wpa_s->conf->device_name); } if (wpa_s->conf->manufacturer) bss->manufacturer = os_strdup(wpa_s->conf->manufacturer); if (wpa_s->conf->model_name) bss->model_name = os_strdup(wpa_s->conf->model_name); if (wpa_s->conf->model_number) bss->model_number = os_strdup(wpa_s->conf->model_number); if (wpa_s->conf->serial_number) bss->serial_number = os_strdup(wpa_s->conf->serial_number); if (is_nil_uuid(wpa_s->conf->uuid)) os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN); else os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN); os_memcpy(bss->os_version, wpa_s->conf->os_version, 4); no_wps: #endif /* CONFIG_WPS */ if (wpa_s->max_stations && wpa_s->max_stations < wpa_s->conf->max_num_sta) bss->max_num_sta = wpa_s->max_stations; else bss->max_num_sta = wpa_s->conf->max_num_sta; bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack; return 0; }
int wpa_write_rsn_ie(struct wpa_auth_config *conf, u8 *buf, size_t len, const u8 *pmkid) { struct rsn_ie_hdr *hdr; int num_suites; u8 *pos, *count; u16 capab; hdr = (struct rsn_ie_hdr *) buf; hdr->elem_id = WLAN_EID_RSN; WPA_PUT_LE16(hdr->version, RSN_VERSION); pos = (u8 *) (hdr + 1); if (conf->wpa_group == WPA_CIPHER_CCMP) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); } else if (conf->wpa_group == WPA_CIPHER_TKIP) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); } else if (conf->wpa_group == WPA_CIPHER_WEP104) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP104); } else if (conf->wpa_group == WPA_CIPHER_WEP40) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_WEP40); } else { wpa_printf(MSG_DEBUG, "Invalid group cipher (%d).", conf->wpa_group); return -1; } pos += RSN_SELECTOR_LEN; num_suites = 0; count = pos; pos += 2; #ifdef CONFIG_RSN_TESTING if (rsn_testing) { RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1)); pos += RSN_SELECTOR_LEN; num_suites++; } #endif /* CONFIG_RSN_TESTING */ if (conf->rsn_pairwise & WPA_CIPHER_CCMP) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_CCMP); pos += RSN_SELECTOR_LEN; num_suites++; } if (conf->rsn_pairwise & WPA_CIPHER_TKIP) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_TKIP); pos += RSN_SELECTOR_LEN; num_suites++; } if (conf->rsn_pairwise & WPA_CIPHER_NONE) { RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_NONE); pos += RSN_SELECTOR_LEN; num_suites++; } #ifdef CONFIG_RSN_TESTING if (rsn_testing) { RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2)); pos += RSN_SELECTOR_LEN; num_suites++; } #endif /* CONFIG_RSN_TESTING */ if (num_suites == 0) { wpa_printf(MSG_DEBUG, "Invalid pairwise cipher (%d).", conf->rsn_pairwise); return -1; } WPA_PUT_LE16(count, num_suites); num_suites = 0; count = pos; pos += 2; #ifdef CONFIG_RSN_TESTING if (rsn_testing) { RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 1)); pos += RSN_SELECTOR_LEN; num_suites++; } #endif /* CONFIG_RSN_TESTING */ if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_UNSPEC_802_1X); pos += RSN_SELECTOR_LEN; num_suites++; } if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X); pos += RSN_SELECTOR_LEN; num_suites++; } #ifdef CONFIG_IEEE80211R if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_802_1X); pos += RSN_SELECTOR_LEN; num_suites++; } if (conf->wpa_key_mgmt & WPA_KEY_MGMT_FT_PSK) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_FT_PSK); pos += RSN_SELECTOR_LEN; num_suites++; } #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_IEEE80211W if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_802_1X_SHA256); pos += RSN_SELECTOR_LEN; num_suites++; } if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK_SHA256) { RSN_SELECTOR_PUT(pos, RSN_AUTH_KEY_MGMT_PSK_SHA256); pos += RSN_SELECTOR_LEN; num_suites++; } #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_RSN_TESTING if (rsn_testing) { RSN_SELECTOR_PUT(pos, RSN_SELECTOR(0x12, 0x34, 0x56, 2)); pos += RSN_SELECTOR_LEN; num_suites++; } #endif /* CONFIG_RSN_TESTING */ if (num_suites == 0) { wpa_printf(MSG_DEBUG, "Invalid key management type (%d).", conf->wpa_key_mgmt); return -1; } WPA_PUT_LE16(count, num_suites); /* RSN Capabilities */ capab = 0; if (conf->rsn_preauth) capab |= WPA_CAPABILITY_PREAUTH; if (conf->peerkey) capab |= WPA_CAPABILITY_PEERKEY_ENABLED; #if 0 /* In IOT test, if the capab is not zero, the sta will fail at EAPOL-key four way handshake. */ if (conf->wmm_enabled) { /* 4 PTKSA replay counters when using WMM */ capab |= (RSN_NUM_REPLAY_COUNTERS_16 << 2); } #endif #ifdef CONFIG_IEEE80211W if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { capab |= WPA_CAPABILITY_MFPC; if (conf->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) capab |= WPA_CAPABILITY_MFPR; } #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_RSN_TESTING if (rsn_testing) capab |= BIT(8) | BIT(14) | BIT(15); #endif /* CONFIG_RSN_TESTING */ WPA_PUT_LE16(pos, capab); pos += 2; if (pmkid) { if (pos + 2 + PMKID_LEN > buf + len) return -1; /* PMKID Count */ WPA_PUT_LE16(pos, 1); pos += 2; os_memcpy(pos, pmkid, PMKID_LEN); pos += PMKID_LEN; } #ifdef CONFIG_IEEE80211W if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) { if (pos + 2 + 4 > buf + len) return -1; if (pmkid == NULL) { /* PMKID Count */ WPA_PUT_LE16(pos, 0); pos += 2; } /* Management Group Cipher Suite */ RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); pos += RSN_SELECTOR_LEN; } #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_RSN_TESTING if (rsn_testing) { /* * Fill in any defined fields and add extra data to the end of * the element. */ int pmkid_count_set = pmkid != NULL; if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) pmkid_count_set = 1; /* PMKID Count */ WPA_PUT_LE16(pos, 0); pos += 2; if (conf->ieee80211w == NO_MGMT_FRAME_PROTECTION) { /* Management Group Cipher Suite */ RSN_SELECTOR_PUT(pos, RSN_CIPHER_SUITE_AES_128_CMAC); pos += RSN_SELECTOR_LEN; } os_memset(pos, 0x12, 17); pos += 17; } #endif /* CONFIG_RSN_TESTING */ hdr->len = (pos - buf) - 2; return pos - buf; }
int eap_sim_db_get_aka_auth(void *priv, const u8 *identity, size_t identity_len, u8 *_rand, u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len, void *cb_session_ctx) { struct eap_sim_db_data *data = priv; struct eap_sim_db_pending *entry; int len; size_t i; char msg[40]; if (identity_len < 2 || identity == NULL || identity[0] != EAP_AKA_PERMANENT_PREFIX) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity", identity, identity_len); return EAP_SIM_DB_FAILURE; } identity++; identity_len--; for (i = 0; i < identity_len; i++) { if (identity[i] == '@') { identity_len = i; break; } } if (identity_len + 1 > sizeof(entry->imsi)) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity", identity, identity_len); return EAP_SIM_DB_FAILURE; } wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: Get AKA auth for IMSI", identity, identity_len); entry = eap_sim_db_get_pending(data, identity, identity_len, 1); if (entry) { if (entry->state == FAILURE) { os_free(entry); wpa_printf(MSG_DEBUG, "EAP-SIM DB: Failure"); return EAP_SIM_DB_FAILURE; } if (entry->state == PENDING) { eap_sim_db_add_pending(data, entry); wpa_printf(MSG_DEBUG, "EAP-SIM DB: Pending"); return EAP_SIM_DB_PENDING; } wpa_printf(MSG_DEBUG, "EAP-SIM DB: Returning successfully " "received authentication data"); os_memcpy(_rand, entry->u.aka.rand, EAP_AKA_RAND_LEN); os_memcpy(autn, entry->u.aka.autn, EAP_AKA_AUTN_LEN); os_memcpy(ik, entry->u.aka.ik, EAP_AKA_IK_LEN); os_memcpy(ck, entry->u.aka.ck, EAP_AKA_CK_LEN); os_memcpy(res, entry->u.aka.res, EAP_AKA_RES_MAX_LEN); *res_len = entry->u.aka.res_len; os_free(entry); return 0; } if (data->sock < 0) { if (eap_sim_db_open_socket(data) < 0) return EAP_SIM_DB_FAILURE; } len = os_snprintf(msg, sizeof(msg), "AKA-REQ-AUTH "); if (len < 0 || len + identity_len >= sizeof(msg)) return EAP_SIM_DB_FAILURE; os_memcpy(msg + len, identity, identity_len); len += identity_len; wpa_hexdump(MSG_DEBUG, "EAP-SIM DB: requesting AKA authentication " "data for IMSI", identity, identity_len); if (eap_sim_db_send(data, msg, len) < 0) return EAP_SIM_DB_FAILURE; entry = os_zalloc(sizeof(*entry)); if (entry == NULL) return EAP_SIM_DB_FAILURE; os_get_time(&entry->timestamp); entry->aka = 1; os_memcpy(entry->imsi, identity, identity_len); entry->imsi_len = identity_len; entry->cb_session_ctx = cb_session_ctx; entry->state = PENDING; eap_sim_db_add_pending(data, entry); eap_sim_db_expire_pending(data); return EAP_SIM_DB_PENDING; }
int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, struct wpa_state_machine *sm, const u8 *wpa_ie, size_t wpa_ie_len, const u8 *mdie, size_t mdie_len) { struct wpa_ie_data data; int ciphers, key_mgmt, res, version; u32 selector; size_t i; const u8 *pmkid = NULL; if (wpa_auth == NULL || sm == NULL) return WPA_NOT_ENABLED; if (wpa_ie == NULL || wpa_ie_len < 1) return WPA_INVALID_IE; if (wpa_ie[0] == WLAN_EID_RSN) version = WPA_PROTO_RSN; else version = WPA_PROTO_WPA; if (!(wpa_auth->conf.wpa & version)) { wpa_printf(MSG_DEBUG, "Invalid WPA proto (%d) from " MACSTR, version, MAC2STR(sm->addr)); return WPA_INVALID_PROTO; } if (version == WPA_PROTO_RSN) { res = wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, &data); selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; if (0) { } #ifdef CONFIG_IEEE80211R else if (data.key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) selector = RSN_AUTH_KEY_MGMT_FT_802_1X; else if (data.key_mgmt & WPA_KEY_MGMT_FT_PSK) selector = RSN_AUTH_KEY_MGMT_FT_PSK; #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_IEEE80211W else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) selector = RSN_AUTH_KEY_MGMT_802_1X_SHA256; else if (data.key_mgmt & WPA_KEY_MGMT_PSK_SHA256) selector = RSN_AUTH_KEY_MGMT_PSK_SHA256; #endif /* CONFIG_IEEE80211W */ else if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) selector = RSN_AUTH_KEY_MGMT_UNSPEC_802_1X; else if (data.key_mgmt & WPA_KEY_MGMT_PSK) selector = RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X; wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector; selector = RSN_CIPHER_SUITE_CCMP; if (data.pairwise_cipher & WPA_CIPHER_CCMP) selector = RSN_CIPHER_SUITE_CCMP; else if (data.pairwise_cipher & WPA_CIPHER_TKIP) selector = RSN_CIPHER_SUITE_TKIP; else if (data.pairwise_cipher & WPA_CIPHER_WEP104) selector = RSN_CIPHER_SUITE_WEP104; else if (data.pairwise_cipher & WPA_CIPHER_WEP40) selector = RSN_CIPHER_SUITE_WEP40; else if (data.pairwise_cipher & WPA_CIPHER_NONE) selector = RSN_CIPHER_SUITE_NONE; wpa_auth->dot11RSNAPairwiseCipherSelected = selector; selector = RSN_CIPHER_SUITE_CCMP; if (data.group_cipher & WPA_CIPHER_CCMP) selector = RSN_CIPHER_SUITE_CCMP; else if (data.group_cipher & WPA_CIPHER_TKIP) selector = RSN_CIPHER_SUITE_TKIP; else if (data.group_cipher & WPA_CIPHER_WEP104) selector = RSN_CIPHER_SUITE_WEP104; else if (data.group_cipher & WPA_CIPHER_WEP40) selector = RSN_CIPHER_SUITE_WEP40; else if (data.group_cipher & WPA_CIPHER_NONE) selector = RSN_CIPHER_SUITE_NONE; wpa_auth->dot11RSNAGroupCipherSelected = selector; } else { res = wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, &data); selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X; if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) selector = WPA_AUTH_KEY_MGMT_UNSPEC_802_1X; else if (data.key_mgmt & WPA_KEY_MGMT_PSK) selector = WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X; wpa_auth->dot11RSNAAuthenticationSuiteSelected = selector; selector = WPA_CIPHER_SUITE_TKIP; if (data.pairwise_cipher & WPA_CIPHER_CCMP) selector = WPA_CIPHER_SUITE_CCMP; else if (data.pairwise_cipher & WPA_CIPHER_TKIP) selector = WPA_CIPHER_SUITE_TKIP; else if (data.pairwise_cipher & WPA_CIPHER_WEP104) selector = WPA_CIPHER_SUITE_WEP104; else if (data.pairwise_cipher & WPA_CIPHER_WEP40) selector = WPA_CIPHER_SUITE_WEP40; else if (data.pairwise_cipher & WPA_CIPHER_NONE) selector = WPA_CIPHER_SUITE_NONE; wpa_auth->dot11RSNAPairwiseCipherSelected = selector; selector = WPA_CIPHER_SUITE_TKIP; if (data.group_cipher & WPA_CIPHER_CCMP) selector = WPA_CIPHER_SUITE_CCMP; else if (data.group_cipher & WPA_CIPHER_TKIP) selector = WPA_CIPHER_SUITE_TKIP; else if (data.group_cipher & WPA_CIPHER_WEP104) selector = WPA_CIPHER_SUITE_WEP104; else if (data.group_cipher & WPA_CIPHER_WEP40) selector = WPA_CIPHER_SUITE_WEP40; else if (data.group_cipher & WPA_CIPHER_NONE) selector = WPA_CIPHER_SUITE_NONE; wpa_auth->dot11RSNAGroupCipherSelected = selector; } if (res) { wpa_printf(MSG_DEBUG, "Failed to parse WPA/RSN IE from " MACSTR " (res=%d)", MAC2STR(sm->addr), res); wpa_hexdump(MSG_DEBUG, "WPA/RSN IE", wpa_ie, wpa_ie_len); return WPA_INVALID_IE; } if (data.group_cipher != wpa_auth->conf.wpa_group) { wpa_printf(MSG_DEBUG, "Invalid WPA group cipher (0x%x) from " MACSTR, data.group_cipher, MAC2STR(sm->addr)); return WPA_INVALID_GROUP; } key_mgmt = data.key_mgmt & wpa_auth->conf.wpa_key_mgmt; if (!key_mgmt) { wpa_printf(MSG_DEBUG, "Invalid WPA key mgmt (0x%x) from " MACSTR, data.key_mgmt, MAC2STR(sm->addr)); return WPA_INVALID_AKMP; } if (0) { } #ifdef CONFIG_IEEE80211R else if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X) sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X; else if (key_mgmt & WPA_KEY_MGMT_FT_PSK) sm->wpa_key_mgmt = WPA_KEY_MGMT_FT_PSK; #endif /* CONFIG_IEEE80211R */ #ifdef CONFIG_IEEE80211W else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256) sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X_SHA256; else if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256) sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK_SHA256; #endif /* CONFIG_IEEE80211W */ else if (key_mgmt & WPA_KEY_MGMT_IEEE8021X) sm->wpa_key_mgmt = WPA_KEY_MGMT_IEEE8021X; else sm->wpa_key_mgmt = WPA_KEY_MGMT_PSK; if (version == WPA_PROTO_RSN) ciphers = data.pairwise_cipher & wpa_auth->conf.rsn_pairwise; else ciphers = data.pairwise_cipher & wpa_auth->conf.wpa_pairwise; if (!ciphers) { wpa_printf(MSG_DEBUG, "Invalid %s pairwise cipher (0x%x) " "from " MACSTR, version == WPA_PROTO_RSN ? "RSN" : "WPA", data.pairwise_cipher, MAC2STR(sm->addr)); return WPA_INVALID_PAIRWISE; } #ifdef CONFIG_IEEE80211W if (wpa_auth->conf.ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED) { if (!(data.capabilities & WPA_CAPABILITY_MFPC)) { wpa_printf(MSG_DEBUG, "Management frame protection " "required, but client did not enable it"); return WPA_MGMT_FRAME_PROTECTION_VIOLATION; } if (ciphers & WPA_CIPHER_TKIP) { wpa_printf(MSG_DEBUG, "Management frame protection " "cannot use TKIP"); return WPA_MGMT_FRAME_PROTECTION_VIOLATION; } if (data.mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC) { wpa_printf(MSG_DEBUG, "Unsupported management group " "cipher %d", data.mgmt_group_cipher); return WPA_INVALID_MGMT_GROUP_CIPHER; } } if (wpa_auth->conf.ieee80211w == NO_MGMT_FRAME_PROTECTION || !(data.capabilities & WPA_CAPABILITY_MFPC)) sm->mgmt_frame_prot = 0; else sm->mgmt_frame_prot = 1; #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { if (mdie == NULL || mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) { wpa_printf(MSG_DEBUG, "RSN: Trying to use FT, but " "MDIE not included"); return WPA_INVALID_MDIE; } if (os_memcmp(mdie, wpa_auth->conf.mobility_domain, MOBILITY_DOMAIN_ID_LEN) != 0) { wpa_hexdump(MSG_DEBUG, "RSN: Attempted to use unknown " "MDIE", mdie, MOBILITY_DOMAIN_ID_LEN); return WPA_INVALID_MDIE; } } #endif /* CONFIG_IEEE80211R */ if (ciphers & WPA_CIPHER_CCMP) sm->pairwise = WPA_CIPHER_CCMP; else sm->pairwise = WPA_CIPHER_TKIP; /* TODO: clear WPA/WPA2 state if STA changes from one to another */ if (wpa_ie[0] == WLAN_EID_RSN) sm->wpa = WPA_VERSION_WPA2; else sm->wpa = WPA_VERSION_WPA; sm->pmksa = NULL; for (i = 0; i < data.num_pmkid; i++) { wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID", &data.pmkid[i * PMKID_LEN], PMKID_LEN); sm->pmksa = pmksa_cache_auth_get(wpa_auth->pmksa, sm->addr, &data.pmkid[i * PMKID_LEN]); if (sm->pmksa) { pmkid = sm->pmksa->pmkid; break; } } for (i = 0; sm->pmksa == NULL && wpa_auth->conf.okc && i < data.num_pmkid; i++) { struct wpa_auth_okc_iter_data idata; idata.pmksa = NULL; idata.aa = wpa_auth->addr; idata.spa = sm->addr; idata.pmkid = &data.pmkid[i * PMKID_LEN]; wpa_auth_for_each_auth(wpa_auth, wpa_auth_okc_iter, &idata); if (idata.pmksa) { wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, "OKC match for PMKID"); sm->pmksa = pmksa_cache_add_okc(wpa_auth->pmksa, idata.pmksa, wpa_auth->addr, idata.pmkid); pmkid = idata.pmkid; break; } } if (sm->pmksa) { wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, "PMKID found from PMKSA cache " "eap_type=%d vlan_id=%d", sm->pmksa->eap_type_authsrv, sm->pmksa->vlan_id); os_memcpy(wpa_auth->dot11RSNAPMKIDUsed, pmkid, PMKID_LEN); } if (sm->wpa_ie == NULL || sm->wpa_ie_len < wpa_ie_len) { os_free(sm->wpa_ie); sm->wpa_ie = os_malloc(wpa_ie_len); if (sm->wpa_ie == NULL) return WPA_ALLOC_FAIL; } os_memcpy(sm->wpa_ie, wpa_ie, wpa_ie_len); sm->wpa_ie_len = wpa_ie_len; return WPA_IE_OK; }
int hostapd_init_wps(struct hostapd_data *hapd, struct hostapd_bss_config *conf) { struct wps_context *wps; struct wps_registrar_config cfg; if (conf->wps_state == 0) { hostapd_wps_clear_ies(hapd); return 0; } wps = os_zalloc(sizeof(*wps)); if (wps == NULL) return -1; wps->cred_cb = hostapd_wps_cred_cb; wps->event_cb = hostapd_wps_event_cb; wps->cb_ctx = hapd; os_memset(&cfg, 0, sizeof(cfg)); wps->wps_state = hapd->conf->wps_state; wps->ap_setup_locked = hapd->conf->ap_setup_locked; if (is_nil_uuid(hapd->conf->uuid)) { const u8 *uuid; uuid = get_own_uuid(hapd->iface); if (uuid) { os_memcpy(wps->uuid, uuid, UUID_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Clone UUID from another " "interface", wps->uuid, UUID_LEN); } else { uuid_gen_mac_addr(hapd->own_addr, wps->uuid); wpa_hexdump(MSG_DEBUG, "WPS: UUID based on MAC " "address", wps->uuid, UUID_LEN); } } else { os_memcpy(wps->uuid, hapd->conf->uuid, UUID_LEN); wpa_hexdump(MSG_DEBUG, "WPS: Use configured UUID", wps->uuid, UUID_LEN); } wps->ssid_len = hapd->conf->ssid.ssid_len; os_memcpy(wps->ssid, hapd->conf->ssid.ssid, wps->ssid_len); wps->ap = 1; os_memcpy(wps->dev.mac_addr, hapd->own_addr, ETH_ALEN); wps->dev.device_name = hapd->conf->device_name ? os_strdup(hapd->conf->device_name) : NULL; wps->dev.manufacturer = hapd->conf->manufacturer ? os_strdup(hapd->conf->manufacturer) : NULL; wps->dev.model_name = hapd->conf->model_name ? os_strdup(hapd->conf->model_name) : NULL; wps->dev.model_number = hapd->conf->model_number ? os_strdup(hapd->conf->model_number) : NULL; wps->dev.serial_number = hapd->conf->serial_number ? os_strdup(hapd->conf->serial_number) : NULL; wps->config_methods = wps_config_methods_str2bin(hapd->conf->config_methods); #ifdef CONFIG_WPS2 if ((wps->config_methods & (WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY | WPS_CONFIG_PHY_DISPLAY)) == WPS_CONFIG_DISPLAY) { wpa_printf(MSG_INFO, "WPS: Converting display to " "virtual_display for WPS 2.0 compliance"); wps->config_methods |= WPS_CONFIG_VIRT_DISPLAY; } if ((wps->config_methods & (WPS_CONFIG_PUSHBUTTON | WPS_CONFIG_VIRT_PUSHBUTTON | WPS_CONFIG_PHY_PUSHBUTTON)) == WPS_CONFIG_PUSHBUTTON) { wpa_printf(MSG_INFO, "WPS: Converting push_button to " "virtual_push_button for WPS 2.0 compliance"); wps->config_methods |= WPS_CONFIG_VIRT_PUSHBUTTON; } #endif /* CONFIG_WPS2 */ os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type, WPS_DEV_TYPE_LEN); if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) { os_free(wps); return -1; } wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version); if (conf->wps_rf_bands) { wps->dev.rf_bands = conf->wps_rf_bands; } else { wps->dev.rf_bands = hapd->iconf->hw_mode == HOSTAPD_MODE_IEEE80211A ? WPS_RF_50GHZ : WPS_RF_24GHZ; /* FIX: dualband AP */ } if (conf->wpa & WPA_PROTO_RSN) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPA2PSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA2; if (conf->rsn_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->rsn_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->wpa & WPA_PROTO_WPA) { if (conf->wpa_key_mgmt & WPA_KEY_MGMT_PSK) wps->auth_types |= WPS_AUTH_WPAPSK; if (conf->wpa_key_mgmt & WPA_KEY_MGMT_IEEE8021X) wps->auth_types |= WPS_AUTH_WPA; if (conf->wpa_pairwise & WPA_CIPHER_CCMP) wps->encr_types |= WPS_ENCR_AES; if (conf->wpa_pairwise & WPA_CIPHER_TKIP) wps->encr_types |= WPS_ENCR_TKIP; } if (conf->ssid.security_policy == SECURITY_PLAINTEXT) { wps->encr_types |= WPS_ENCR_NONE; wps->auth_types |= WPS_AUTH_OPEN; } else if (conf->ssid.security_policy == SECURITY_STATIC_WEP) { wps->encr_types |= WPS_ENCR_WEP; if (conf->auth_algs & WPA_AUTH_ALG_OPEN) wps->auth_types |= WPS_AUTH_OPEN; if (conf->auth_algs & WPA_AUTH_ALG_SHARED) wps->auth_types |= WPS_AUTH_SHARED; } else if (conf->ssid.security_policy == SECURITY_IEEE_802_1X) { wps->auth_types |= WPS_AUTH_OPEN; if (conf->default_wep_key_len) wps->encr_types |= WPS_ENCR_WEP; else wps->encr_types |= WPS_ENCR_NONE; } if (conf->ssid.wpa_psk_file) { /* Use per-device PSKs */ } else if (conf->ssid.wpa_passphrase) { wps->network_key = (u8 *) os_strdup(conf->ssid.wpa_passphrase); wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase); } else if (conf->ssid.wpa_psk) { wps->network_key = os_malloc(2 * PMK_LEN + 1); if (wps->network_key == NULL) { os_free(wps); return -1; } wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1, conf->ssid.wpa_psk->psk, PMK_LEN); wps->network_key_len = 2 * PMK_LEN; } else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) { wps->network_key = os_malloc(conf->ssid.wep.len[0]); if (wps->network_key == NULL) { os_free(wps); return -1; } os_memcpy(wps->network_key, conf->ssid.wep.key[0], conf->ssid.wep.len[0]); wps->network_key_len = conf->ssid.wep.len[0]; } if (conf->ssid.wpa_psk) { os_memcpy(wps->psk, conf->ssid.wpa_psk->psk, PMK_LEN); wps->psk_set = 1; } if (conf->wps_state == WPS_STATE_NOT_CONFIGURED) { /* Override parameters to enable security by default */ wps->auth_types = WPS_AUTH_WPA2PSK | WPS_AUTH_WPAPSK; wps->encr_types = WPS_ENCR_AES | WPS_ENCR_TKIP; } wps->ap_settings = conf->ap_settings; wps->ap_settings_len = conf->ap_settings_len; cfg.new_psk_cb = hostapd_wps_new_psk_cb; cfg.set_ie_cb = hostapd_wps_set_ie_cb; cfg.pin_needed_cb = hostapd_wps_pin_needed_cb; cfg.reg_success_cb = hostapd_wps_reg_success_cb; cfg.enrollee_seen_cb = hostapd_wps_enrollee_seen_cb; cfg.cb_ctx = hapd; cfg.skip_cred_build = conf->skip_cred_build; cfg.extra_cred = conf->extra_cred; cfg.extra_cred_len = conf->extra_cred_len; cfg.disable_auto_conf = (hapd->conf->wps_cred_processing == 1) && conf->skip_cred_build; if (conf->ssid.security_policy == SECURITY_STATIC_WEP) cfg.static_wep_only = 1; cfg.dualband = interface_count(hapd->iface) > 1; if (cfg.dualband) wpa_printf(MSG_DEBUG, "WPS: Dualband AP"); wps->registrar = wps_registrar_init(wps, &cfg); if (wps->registrar == NULL) { wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar"); os_free(wps->network_key); os_free(wps); return -1; } #ifdef CONFIG_WPS_UPNP wps->friendly_name = hapd->conf->friendly_name; wps->manufacturer_url = hapd->conf->manufacturer_url; wps->model_description = hapd->conf->model_description; wps->model_url = hapd->conf->model_url; wps->upc = hapd->conf->upc; #endif /* CONFIG_WPS_UPNP */ hostapd_register_probereq_cb(hapd, hostapd_wps_probe_req_rx, hapd); hapd->wps = wps; return 0; }
static int wpa_config_read_blobs(struct wpa_config *config, HKEY hk) { struct wpa_config_blob *blob; int errors = 0; HKEY bhk; LONG ret; DWORD i; ret = RegOpenKeyEx(hk, TEXT("blobs"), 0, KEY_QUERY_VALUE, &bhk); if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "Could not open wpa_supplicant config " "blobs key"); return 0; /* assume no blobs */ } for (i = 0; ; i++) { #define TNAMELEN 255 TCHAR name[TNAMELEN]; char data[4096]; DWORD namelen, datalen, type; namelen = TNAMELEN; datalen = sizeof(data); ret = RegEnumValue(bhk, i, name, &namelen, NULL, &type, (LPBYTE) data, &datalen); if (ret == ERROR_NO_MORE_ITEMS) break; if (ret != ERROR_SUCCESS) { wpa_printf(MSG_DEBUG, "RegEnumValue failed: 0x%x", (unsigned int) ret); break; } if (namelen >= TNAMELEN) namelen = TNAMELEN - 1; name[namelen] = TEXT('\0'); wpa_unicode2ascii_inplace(name); if (datalen >= sizeof(data)) datalen = sizeof(data) - 1; wpa_printf(MSG_MSGDUMP, "blob %d: field='%s' len %d", (int) i, name, (int) datalen); blob = os_zalloc(sizeof(*blob)); if (blob == NULL) { errors++; break; } blob->name = os_strdup((char *) name); blob->data = os_malloc(datalen); if (blob->name == NULL || blob->data == NULL) { wpa_config_free_blob(blob); errors++; break; } os_memcpy(blob->data, data, datalen); blob->len = datalen; wpa_config_set_blob(config, blob); } RegCloseKey(bhk); return errors ? -1 : 0; }
static void eap_psk_process_2(struct eap_sm *sm, struct eap_psk_data *data, struct wpabuf *respData) { const struct eap_psk_hdr_2 *resp; u8 *pos, mac[EAP_PSK_MAC_LEN], *buf; size_t left, buflen; int i; const u8 *cpos; if (data->state != PSK_1) return; wpa_printf(MSG_DEBUG, "EAP-PSK: Received PSK-2"); cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, respData, &left); if (cpos == NULL || left < sizeof(*resp)) { wpa_printf(MSG_INFO, "EAP-PSK: Invalid frame"); return; } resp = (const struct eap_psk_hdr_2 *) cpos; cpos = (const u8 *) (resp + 1); left -= sizeof(*resp); os_free(data->id_p); data->id_p = os_malloc(left); if (data->id_p == NULL) { wpa_printf(MSG_INFO, "EAP-PSK: Failed to allocate memory for " "ID_P"); return; } os_memcpy(data->id_p, cpos, left); data->id_p_len = left; wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-PSK: ID_P", data->id_p, data->id_p_len); if (eap_user_get(sm, data->id_p, data->id_p_len, 0) < 0) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: unknown ID_P", data->id_p, data->id_p_len); data->state = FAILURE; return; } for (i = 0; i < EAP_MAX_METHODS && (sm->user->methods[i].vendor != EAP_VENDOR_IETF || sm->user->methods[i].method != EAP_TYPE_NONE); i++) { if (sm->user->methods[i].vendor == EAP_VENDOR_IETF && sm->user->methods[i].method == EAP_TYPE_PSK) break; } if (i >= EAP_MAX_METHODS || sm->user->methods[i].vendor != EAP_VENDOR_IETF || sm->user->methods[i].method != EAP_TYPE_PSK) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: EAP-PSK not enabled for ID_P", data->id_p, data->id_p_len); data->state = FAILURE; return; } if (sm->user->password == NULL || sm->user->password_len != EAP_PSK_PSK_LEN) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: invalid password in " "user database for ID_P", data->id_p, data->id_p_len); data->state = FAILURE; return; } if (eap_psk_key_setup(sm->user->password, data->ak, data->kdk)) { data->state = FAILURE; return; } wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN); wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: RAND_P (client rand)", resp->rand_p, EAP_PSK_RAND_LEN); os_memcpy(data->rand_p, resp->rand_p, EAP_PSK_RAND_LEN); /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */ buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN; buf = os_malloc(buflen); if (buf == NULL) { data->state = FAILURE; return; } os_memcpy(buf, data->id_p, data->id_p_len); pos = buf + data->id_p_len; os_memcpy(pos, data->id_s, data->id_s_len); pos += data->id_s_len; os_memcpy(pos, data->rand_s, EAP_PSK_RAND_LEN); pos += EAP_PSK_RAND_LEN; os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN); if (omac1_aes_128(data->ak, buf, buflen, mac)) { os_free(buf); data->state = FAILURE; return; } os_free(buf); wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", resp->mac_p, EAP_PSK_MAC_LEN); if (os_memcmp(mac, resp->mac_p, EAP_PSK_MAC_LEN) != 0) { wpa_printf(MSG_INFO, "EAP-PSK: Invalid MAC_P"); wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: Expected MAC_P", mac, EAP_PSK_MAC_LEN); data->state = FAILURE; return; } data->state = PSK_3; }
static int set80211priv(struct wpa_driver_madwifi_data *drv, int op, void *data, int len, int show_err) { struct iwreq iwr; os_memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); if (len < IFNAMSIZ && op != IEEE80211_IOCTL_SET_APPIEBUF) { /* * Argument data fits inline; put it there. */ os_memcpy(iwr.u.name, data, len); } else { /* * Argument data too big for inline transfer; setup a * parameter block instead; the kernel will transfer * the data for the driver. */ iwr.u.data.pointer = data; iwr.u.data.length = len; } if (ioctl(drv->sock, op, &iwr) < 0) { if (show_err) { #ifdef MADWIFI_NG int first = IEEE80211_IOCTL_SETPARAM; int last = IEEE80211_IOCTL_KICKMAC; static const char *opnames[] = { "ioctl[IEEE80211_IOCTL_SETPARAM]", "ioctl[IEEE80211_IOCTL_GETPARAM]", "ioctl[IEEE80211_IOCTL_SETMODE]", "ioctl[IEEE80211_IOCTL_GETMODE]", "ioctl[IEEE80211_IOCTL_SETWMMPARAMS]", "ioctl[IEEE80211_IOCTL_GETWMMPARAMS]", "ioctl[IEEE80211_IOCTL_SETCHANLIST]", "ioctl[IEEE80211_IOCTL_GETCHANLIST]", "ioctl[IEEE80211_IOCTL_CHANSWITCH]", NULL, "ioctl[IEEE80211_IOCTL_SET_APPIEBUF]", "ioctl[IEEE80211_IOCTL_GETSCANRESULTS]", NULL, "ioctl[IEEE80211_IOCTL_GETCHANINFO]", "ioctl[IEEE80211_IOCTL_SETOPTIE]", "ioctl[IEEE80211_IOCTL_GETOPTIE]", "ioctl[IEEE80211_IOCTL_SETMLME]", NULL, "ioctl[IEEE80211_IOCTL_SETKEY]", NULL, "ioctl[IEEE80211_IOCTL_DELKEY]", NULL, "ioctl[IEEE80211_IOCTL_ADDMAC]", NULL, "ioctl[IEEE80211_IOCTL_DELMAC]", NULL, "ioctl[IEEE80211_IOCTL_WDSMAC]", NULL, "ioctl[IEEE80211_IOCTL_WDSDELMAC]", NULL, "ioctl[IEEE80211_IOCTL_KICKMAC]", }; #else /* MADWIFI_NG */ int first = IEEE80211_IOCTL_SETPARAM; int last = IEEE80211_IOCTL_CHANLIST; static const char *opnames[] = { "ioctl[IEEE80211_IOCTL_SETPARAM]", "ioctl[IEEE80211_IOCTL_GETPARAM]", "ioctl[IEEE80211_IOCTL_SETKEY]", "ioctl[IEEE80211_IOCTL_GETKEY]", "ioctl[IEEE80211_IOCTL_DELKEY]", NULL, "ioctl[IEEE80211_IOCTL_SETMLME]", NULL, "ioctl[IEEE80211_IOCTL_SETOPTIE]", "ioctl[IEEE80211_IOCTL_GETOPTIE]", "ioctl[IEEE80211_IOCTL_ADDMAC]", NULL, "ioctl[IEEE80211_IOCTL_DELMAC]", NULL, "ioctl[IEEE80211_IOCTL_CHANLIST]", }; #endif /* MADWIFI_NG */ int idx = op - first; if (first <= op && op <= last && idx < (int) (sizeof(opnames) / sizeof(opnames[0])) && opnames[idx]) perror(opnames[idx]); else perror("ioctl[unknown???]"); } return -1; } return 0; }
static struct wpabuf * eap_psk_build_3(struct eap_sm *sm, struct eap_psk_data *data, u8 id) { struct wpabuf *req; struct eap_psk_hdr_3 *psk; u8 *buf, *pchannel, nonce[16]; size_t buflen; wpa_printf(MSG_DEBUG, "EAP-PSK: PSK-3 (sending)"); req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, sizeof(*psk) + 4 + 16 + 1, EAP_CODE_REQUEST, id); if (req == NULL) { wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory " "request"); data->state = FAILURE; return NULL; } psk = wpabuf_put(req, sizeof(*psk)); psk->flags = EAP_PSK_FLAGS_SET_T(2); /* T=2 */ os_memcpy(psk->rand_s, data->rand_s, EAP_PSK_RAND_LEN); /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */ buflen = data->id_s_len + EAP_PSK_RAND_LEN; buf = os_malloc(buflen); if (buf == NULL) goto fail; os_memcpy(buf, data->id_s, data->id_s_len); os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN); if (omac1_aes_128(data->ak, buf, buflen, psk->mac_s)) goto fail; os_free(buf); if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek, data->msk, data->emsk)) goto fail; wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN); wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN); os_memset(nonce, 0, sizeof(nonce)); pchannel = wpabuf_put(req, 4 + 16 + 1); os_memcpy(pchannel, nonce + 12, 4); os_memset(pchannel + 4, 0, 16); /* Tag */ pchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6; wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (plaintext)", pchannel, 4 + 16 + 1); if (aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce), wpabuf_head(req), 22, pchannel + 4 + 16, 1, pchannel + 4)) goto fail; wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL (encrypted)", pchannel, 4 + 16 + 1); return req; fail: wpabuf_free(req); data->state = FAILURE; return NULL; }
static int wpa_driver_madwifi_set_key(const char *ifname, void *priv, enum wpa_alg alg, const u8 *addr, int key_idx, int set_tx, const u8 *seq, size_t seq_len, const u8 *key, size_t key_len) { struct wpa_driver_madwifi_data *drv = priv; struct ieee80211req_key wk; char *alg_name; u_int8_t cipher; if (alg == WPA_ALG_NONE) return wpa_driver_madwifi_del_key(drv, key_idx, addr); switch (alg) { case WPA_ALG_WEP: if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) { /* * madwifi did not seem to like static WEP key * configuration with IEEE80211_IOCTL_SETKEY, so use * Linux wireless extensions ioctl for this. */ return wpa_driver_wext_set_key(ifname, drv->wext, alg, addr, key_idx, set_tx, seq, seq_len, key, key_len); } alg_name = "WEP"; cipher = IEEE80211_CIPHER_WEP; break; case WPA_ALG_TKIP: alg_name = "TKIP"; cipher = IEEE80211_CIPHER_TKIP; break; case WPA_ALG_CCMP: alg_name = "CCMP"; cipher = IEEE80211_CIPHER_AES_CCM; break; default: wpa_printf(MSG_DEBUG, "%s: unknown/unsupported algorithm %d", __FUNCTION__, alg); return -1; } wpa_printf(MSG_DEBUG, "%s: alg=%s key_idx=%d set_tx=%d seq_len=%lu " "key_len=%lu", __FUNCTION__, alg_name, key_idx, set_tx, (unsigned long) seq_len, (unsigned long) key_len); if (seq_len > sizeof(u_int64_t)) { wpa_printf(MSG_DEBUG, "%s: seq_len %lu too big", __FUNCTION__, (unsigned long) seq_len); return -2; } if (key_len > sizeof(wk.ik_keydata)) { wpa_printf(MSG_DEBUG, "%s: key length %lu too big", __FUNCTION__, (unsigned long) key_len); return -3; } os_memset(&wk, 0, sizeof(wk)); wk.ik_type = cipher; wk.ik_flags = IEEE80211_KEY_RECV; if (addr == NULL || os_memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0) wk.ik_flags |= IEEE80211_KEY_GROUP; if (set_tx) { wk.ik_flags |= IEEE80211_KEY_XMIT | IEEE80211_KEY_DEFAULT; os_memcpy(wk.ik_macaddr, addr, IEEE80211_ADDR_LEN); } else os_memset(wk.ik_macaddr, 0, IEEE80211_ADDR_LEN); wk.ik_keyix = key_idx; wk.ik_keylen = key_len; #ifdef WORDS_BIGENDIAN if (seq) { size_t i; u8 tmp[WPA_KEY_RSC_LEN]; os_memset(tmp, 0, sizeof(tmp)); for (i = 0; i < seq_len; i++) tmp[WPA_KEY_RSC_LEN - i - 1] = seq[i]; os_memcpy(&wk.ik_keyrsc, tmp, WPA_KEY_RSC_LEN); } #else /* WORDS_BIGENDIAN */ if (seq) os_memcpy(&wk.ik_keyrsc, seq, seq_len); #endif /* WORDS_BIGENDIAN */ os_memcpy(wk.ik_keydata, key, key_len); return set80211priv(drv, IEEE80211_IOCTL_SETKEY, &wk, sizeof(wk), 1); }
static void eap_gtc_process(struct eap_sm *sm, void *priv, struct wpabuf *respData) { struct eap_gtc_data *data = priv; const u8 *pos; size_t rlen; pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC, respData, &rlen); if (pos == NULL || rlen < 1) return; /* Should not happen - frame already validated */ wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen); #ifdef EAP_FAST if (data->prefix) { const u8 *pos2, *end; /* "RESPONSE=<user>\0<password>" */ if (rlen < 10) { wpa_printf(MSG_DEBUG, "EAP-GTC: Too short response " "for EAP-FAST prefix"); data->state = FAILURE; return; } end = pos + rlen; pos += 9; pos2 = pos; while (pos2 < end && *pos2) pos2++; if (pos2 == end) { wpa_printf(MSG_DEBUG, "EAP-GTC: No password in " "response to EAP-FAST prefix"); data->state = FAILURE; return; } wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Response user", pos, pos2 - pos); if (sm->identity && sm->require_identity_match && (pos2 - pos != (int) sm->identity_len || os_memcmp(pos, sm->identity, sm->identity_len))) { wpa_printf(MSG_DEBUG, "EAP-GTC: Phase 2 Identity did " "not match with required Identity"); wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Expected " "identity", sm->identity, sm->identity_len); data->state = FAILURE; return; } else { os_free(sm->identity); sm->identity_len = pos2 - pos; sm->identity = os_malloc(sm->identity_len); if (sm->identity == NULL) { data->state = FAILURE; return; } os_memcpy(sm->identity, pos, sm->identity_len); } if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) { wpa_hexdump_ascii(MSG_DEBUG, "EAP-GTC: Phase2 " "Identity not found in the user " "database", sm->identity, sm->identity_len); data->state = FAILURE; return; } pos = pos2 + 1; rlen = end - pos; wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response password", pos, rlen); } #endif /* EAP_FAST */ if (sm->user == NULL || sm->user->password == NULL || sm->user->password_hash) { wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not " "configured"); data->state = FAILURE; return; } if (rlen != sm->user->password_len || os_memcmp(pos, sm->user->password, rlen) != 0) { wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Failure"); data->state = FAILURE; } else { wpa_printf(MSG_DEBUG, "EAP-GTC: Done - Success"); data->state = SUCCESS; } }
static int wpa_driver_madwifi_associate(void *priv, struct wpa_driver_associate_params *params) { struct wpa_driver_madwifi_data *drv = priv; struct ieee80211req_mlme mlme; int ret = 0, privacy = 1; wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); if (set80211param(drv, IEEE80211_PARAM_DROPUNENCRYPTED, params->drop_unencrypted, 1) < 0) ret = -1; if (wpa_driver_madwifi_set_auth_alg(drv, params->auth_alg) < 0) ret = -1; /* * NB: Don't need to set the freq or cipher-related state as * this is implied by the bssid which is used to locate * the scanned node state which holds it. The ssid is * needed to disambiguate an AP that broadcasts multiple * ssid's but uses the same bssid. */ /* XXX error handling is wrong but unclear what to do... */ if (wpa_driver_madwifi_set_wpa_ie(drv, params->wpa_ie, params->wpa_ie_len) < 0) ret = -1; if (params->pairwise_suite == CIPHER_NONE && params->group_suite == CIPHER_NONE && params->key_mgmt_suite == KEY_MGMT_NONE && params->wpa_ie_len == 0) privacy = 0; if (set80211param(drv, IEEE80211_PARAM_PRIVACY, privacy, 1) < 0) ret = -1; if (params->wpa_ie_len && set80211param(drv, IEEE80211_PARAM_WPA, params->wpa_ie[0] == WLAN_EID_RSN ? 2 : 1, 1) < 0) ret = -1; if (params->bssid == NULL) { /* ap_scan=2 mode - driver takes care of AP selection and * roaming */ /* FIX: this does not seem to work; would probably need to * change something in the driver */ if (set80211param(drv, IEEE80211_PARAM_ROAMING, 0, 1) < 0) ret = -1; if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) < 0) ret = -1; } else { if (set80211param(drv, IEEE80211_PARAM_ROAMING, 2, 1) < 0) ret = -1; if (wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len) < 0) ret = -1; os_memset(&mlme, 0, sizeof(mlme)); mlme.im_op = IEEE80211_MLME_ASSOC; os_memcpy(mlme.im_macaddr, params->bssid, IEEE80211_ADDR_LEN); if (set80211priv(drv, IEEE80211_IOCTL_SETMLME, &mlme, sizeof(mlme), 1) < 0) { wpa_printf(MSG_DEBUG, "%s: SETMLME[ASSOC] failed", __func__); ret = -1; } } return ret; }
static int radius_change_server(struct radius_client_data *radius, struct hostapd_radius_server *nserv, struct hostapd_radius_server *oserv, int sock, int sock6, int auth) { struct sockaddr_in serv, claddr; #ifdef CONFIG_IPV6 struct sockaddr_in6 serv6, claddr6; #endif /* CONFIG_IPV6 */ struct sockaddr *addr, *cl_addr; socklen_t addrlen, claddrlen; char abuf[50]; int sel_sock; struct radius_msg_list *entry; struct hostapd_radius_servers *conf = radius->conf; hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS, HOSTAPD_LEVEL_INFO, "%s server %s:%d", auth ? "Authentication" : "Accounting", hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)), nserv->port); if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len || os_memcmp(nserv->shared_secret, oserv->shared_secret, nserv->shared_secret_len) != 0) { /* Pending RADIUS packets used different shared secret, so * they need to be modified. Update accounting message * authenticators here. Authentication messages are removed * since they would require more changes and the new RADIUS * server may not be prepared to receive them anyway due to * missing state information. Client will likely retry * authentication, so this should not be an issue. */ if (auth) radius_client_flush(radius, 1); else { radius_client_update_acct_msgs( radius, nserv->shared_secret, nserv->shared_secret_len); } } /* Reset retry counters for the new server */ for (entry = radius->msgs; entry; entry = entry->next) { if ((auth && entry->msg_type != RADIUS_AUTH) || (!auth && entry->msg_type != RADIUS_ACCT)) continue; entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT; entry->attempts = 0; entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2; } if (radius->msgs) { eloop_cancel_timeout(radius_client_timer, radius, NULL); eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0, radius_client_timer, radius, NULL); } switch (nserv->addr.af) { case AF_INET: os_memset(&serv, 0, sizeof(serv)); serv.sin_family = AF_INET; serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr; serv.sin_port = htons(nserv->port); addr = (struct sockaddr *) &serv; addrlen = sizeof(serv); sel_sock = sock; break; #ifdef CONFIG_IPV6 case AF_INET6: os_memset(&serv6, 0, sizeof(serv6)); serv6.sin6_family = AF_INET6; os_memcpy(&serv6.sin6_addr, &nserv->addr.u.v6, sizeof(struct in6_addr)); serv6.sin6_port = htons(nserv->port); addr = (struct sockaddr *) &serv6; addrlen = sizeof(serv6); sel_sock = sock6; break; #endif /* CONFIG_IPV6 */ default: return -1; } if (conf->force_client_addr) { switch (conf->client_addr.af) { case AF_INET: os_memset(&claddr, 0, sizeof(claddr)); claddr.sin_family = AF_INET; claddr.sin_addr.s_addr = conf->client_addr.u.v4.s_addr; claddr.sin_port = htons(0); cl_addr = (struct sockaddr *) &claddr; claddrlen = sizeof(claddr); break; #ifdef CONFIG_IPV6 case AF_INET6: os_memset(&claddr6, 0, sizeof(claddr6)); claddr6.sin6_family = AF_INET6; os_memcpy(&claddr6.sin6_addr, &conf->client_addr.u.v6, sizeof(struct in6_addr)); claddr6.sin6_port = htons(0); cl_addr = (struct sockaddr *) &claddr6; claddrlen = sizeof(claddr6); break; #endif /* CONFIG_IPV6 */ default: return -1; } if (bind(sel_sock, cl_addr, claddrlen) < 0) { perror("bind[radius]"); return -1; } } if (connect(sel_sock, addr, addrlen) < 0) { perror("connect[radius]"); return -1; } #ifndef CONFIG_NATIVE_WINDOWS switch (nserv->addr.af) { case AF_INET: claddrlen = sizeof(claddr); getsockname(sel_sock, (struct sockaddr *) &claddr, &claddrlen); wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", inet_ntoa(claddr.sin_addr), ntohs(claddr.sin_port)); break; #ifdef CONFIG_IPV6 case AF_INET6: { claddrlen = sizeof(claddr6); getsockname(sel_sock, (struct sockaddr *) &claddr6, &claddrlen); wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", inet_ntop(AF_INET6, &claddr6.sin6_addr, abuf, sizeof(abuf)), ntohs(claddr6.sin6_port)); break; } #endif /* CONFIG_IPV6 */ } #endif /* CONFIG_NATIVE_WINDOWS */ if (auth) radius->auth_sock = sel_sock; else radius->acct_sock = sel_sock; return 0; }
static void wpa_priv_send_old_scan_results(struct wpa_priv_interface *iface, struct sockaddr_un *from) { #define SCAN_AP_LIMIT 128 int i, res, val; struct wpa_scan_result *results = NULL; u8 *buf = NULL, *pos, *end; struct wpa_scan_res nres; results = os_malloc(SCAN_AP_LIMIT * sizeof(*results)); if (results == NULL) goto fail; res = iface->driver->get_scan_results(iface->drv_priv, results, SCAN_AP_LIMIT); if (res < 0 || res > SCAN_AP_LIMIT) goto fail; buf = os_malloc(60000); if (buf == NULL) goto fail; pos = buf; end = buf + 60000; os_memcpy(pos, &res, sizeof(int)); pos += sizeof(int); os_memset(&nres, 0, sizeof(nres)); for (i = 0; i < res; i++) { struct wpa_scan_result *r = &results[i]; size_t ie_len; ie_len = 2 + r->ssid_len + r->rsn_ie_len + r->wpa_ie_len; if (r->maxrate) ie_len += 3; if (r->mdie_present) ie_len += 5; val = sizeof(nres) + ie_len; if (end - pos < (int) sizeof(int) + val) break; os_memcpy(pos, &val, sizeof(int)); pos += sizeof(int); os_memcpy(nres.bssid, r->bssid, ETH_ALEN); nres.freq = r->freq; nres.caps = r->caps; nres.qual = r->qual; nres.noise = r->noise; nres.level = r->level; nres.tsf = r->tsf; nres.ie_len = ie_len; os_memcpy(pos, &nres, sizeof(nres)); pos += sizeof(nres); /* SSID IE */ *pos++ = WLAN_EID_SSID; *pos++ = r->ssid_len; os_memcpy(pos, r->ssid, r->ssid_len); pos += r->ssid_len; if (r->maxrate) { /* Fake Supported Rate IE to include max rate */ *pos++ = WLAN_EID_SUPP_RATES; *pos++ = 1; *pos++ = r->maxrate; } if (r->rsn_ie_len) { os_memcpy(pos, r->rsn_ie, r->rsn_ie_len); pos += r->rsn_ie_len; } if (r->mdie_present) { os_memcpy(pos, r->mdie, 5); pos += 5; } if (r->wpa_ie_len) { os_memcpy(pos, r->wpa_ie, r->wpa_ie_len); pos += r->wpa_ie_len; } } sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, sizeof(*from)); os_free(buf); os_free(results); return; fail: os_free(buf); os_free(results); sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); }