static void wps_er_sta_start(struct wps_er_sta *sta, struct wpabuf *msg) { struct wps_config cfg; if (sta->wps) wps_deinit(sta->wps); os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = sta->ap->er->wps; cfg.registrar = 1; cfg.peer_addr = sta->addr; sta->wps = wps_init(&cfg); if (sta->wps == NULL) return; sta->wps->er = 1; sta->wps->use_cred = sta->ap->ap_settings; if (sta->ap->ap_settings) { os_free(sta->cred); sta->cred = os_malloc(sizeof(*sta->cred)); if (sta->cred) { os_memcpy(sta->cred, sta->ap->ap_settings, sizeof(*sta->cred)); sta->cred->cred_attr = NULL; os_memcpy(sta->cred->mac_addr, sta->addr, ETH_ALEN); sta->wps->use_cred = sta->cred; } } wps_er_sta_process(sta, msg, WSC_MSG); }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; int registrar; struct wps_config cfg; if (sm->identity && sm->identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(sm->identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 0; /* Supplicant is Registrar */ else if (sm->identity && sm->identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(sm->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 1; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", sm->identity, sm->identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? START : MSG; data->registrar = registrar; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = sm->wps; cfg.registrar = registrar; if (registrar) { if (sm->wps == NULL || sm->wps->registrar == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: WPS Registrar not " "initialized"); os_free(data); return NULL; } } else { if (sm->user == NULL || sm->user->password == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: No AP PIN (password) " "configured for Enrollee functionality"); os_free(data); return NULL; } cfg.pin = sm->user->password; cfg.pin_len = sm->user->password_len; } cfg.assoc_wps_ie = sm->assoc_wps_ie; data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } data->fragment_size = WSC_FRAGMENT_SIZE; return data; }
static enum http_reply_code web_process_get_device_info(struct upnp_wps_device_sm *sm, struct wpabuf **reply, const char **replyname) { static const char *name = "NewDeviceInfo"; struct wps_config cfg; struct upnp_wps_device_interface *iface; struct upnp_wps_peer *peer; iface = dl_list_first(&sm->interfaces, struct upnp_wps_device_interface, list); wpa_printf(MSG_DEBUG, "WPS UPnP: GetDeviceInfo"); if (!iface || iface->ctx->ap_pin == NULL) return HTTP_INTERNAL_SERVER_ERROR; peer = &iface->peer; /* * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS * registration over UPnP with the AP acting as an Enrollee. It should * be noted that this is frequently used just to get the device data, * i.e., there may not be any intent to actually complete the * registration. */ if (peer->wps) wps_deinit(peer->wps); os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = iface->wps; cfg.pin = (u8 *) iface->ctx->ap_pin; cfg.pin_len = os_strlen(iface->ctx->ap_pin); peer->wps = wps_init(&cfg); if (peer->wps) { enum wsc_op_code op_code; *reply = wps_get_msg(peer->wps, &op_code); if (*reply == NULL) { wps_deinit(peer->wps); peer->wps = NULL; } } else *reply = NULL; if (*reply == NULL) { wpa_printf(MSG_INFO, "WPS UPnP: Failed to get DeviceInfo"); return HTTP_INTERNAL_SERVER_ERROR; } *replyname = name; return HTTP_OK; }
static void wps_er_ap_learn_m1(struct wps_er_ap *ap, struct wpabuf *m1) { struct wps_config cfg; if (ap->wps) { wpa_printf(MSG_DEBUG, "WPS ER: Protocol run already in " "progress with this AP"); return; } os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = ap->er->wps; cfg.registrar = 1; ap->wps = wps_init(&cfg); if (ap->wps == NULL) return; ap->wps->ap_settings_cb = wps_er_ap_settings_cb; ap->wps->ap_settings_cb_ctx = ap; wps_er_ap_process(ap, m1); }
static struct wpabuf * hostapd_rx_req_get_device_info(void *priv, struct upnp_wps_peer *peer) { struct hostapd_data *hapd = priv; struct wps_config cfg; struct wps_data *wps; enum wsc_op_code op_code; struct wpabuf *m1; /* * Request for DeviceInfo, i.e., M1 TLVs. This is a start of WPS * registration over UPnP with the AP acting as an Enrollee. It should * be noted that this is frequently used just to get the device data, * i.e., there may not be any intent to actually complete the * registration. */ if (peer->wps) wps_deinit(peer->wps); os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = hapd->wps; cfg.pin = (u8 *) hapd->conf->ap_pin; cfg.pin_len = os_strlen(hapd->conf->ap_pin); wps = wps_init(&cfg); if (wps == NULL) return NULL; m1 = wps_get_msg(wps, &op_code); if (m1 == NULL) { wps_deinit(wps); return NULL; } peer->wps = wps; return m1; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; int registrar; struct wps_config cfg; if (sm->identity && sm->identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(sm->identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 0; /* Supplicant is Registrar */ else if (sm->identity && sm->identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(sm->identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 1; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", sm->identity, sm->identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? START : MESG; data->registrar = registrar; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = sm->wps; cfg.registrar = registrar; if (registrar) { if (sm->wps == NULL || sm->wps->registrar == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: WPS Registrar not " "initialized"); os_free(data); return NULL; } } else { if (sm->user == NULL || sm->user->password == NULL) { /* * In theory, this should not really be needed, but * Windows 7 uses Registrar mode to probe AP's WPS * capabilities before trying to use Enrollee and fails * if the AP does not allow that probing to happen.. */ wpa_printf(MSG_DEBUG, "EAP-WSC: No AP PIN (password) " "configured for Enrollee functionality - " "allow for probing capabilities (M1)"); } else { cfg.pin = sm->user->password; cfg.pin_len = sm->user->password_len; } } cfg.assoc_wps_ie = sm->assoc_wps_ie; cfg.peer_addr = sm->peer_addr; #ifdef CONFIG_P2P if (sm->assoc_p2p_ie) { wpa_printf(MSG_DEBUG, "EAP-WSC: Prefer PSK format for P2P " "client"); cfg.use_psk_key = 1; cfg.p2p_dev_addr = p2p_get_go_dev_addr(sm->assoc_p2p_ie); } #endif /* CONFIG_P2P */ cfg.pbc_in_m1 = sm->pbc_in_m1; data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } data->fragment_size = sm->fragment_size > 0 ? sm->fragment_size : WSC_FRAGMENT_SIZE; return data; }
/* WPS main processing thread * */ static void wps_main(os_thread_arg_t data) { #ifdef CONFIG_P2P struct timeval tv, now; WPS_DATA *wps_s = (WPS_DATA *) &wps_global; WFD_DATA *pwfd_data = &wps_global.wfd_data; bss_config_t bss_config; #endif int ret; #ifdef CONFIG_WPA2_ENTP struct wpa2_command *wpa2_cmd = NULL; WPS_DATA *wps_s = (WPS_DATA *) &wps_global; #else struct wps_command *wps_cmd = NULL; #endif #ifdef CONFIG_P2P memset(&bss_config, 0, sizeof(bss_config_t)); /* * Download Wfd configuration if supplied with -p command line. */ if (local_wcc->role == WFD_ROLE) { if (wfd_wlan_update_bss_mode(BSS_MODE_WIFIDIRECT_GO) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to initialize " "BSS Mode!\n"); goto fail; } /* Set WFD uAP configuration */ wifidirectapcmd_sys_config(); if (wfd_wlan_update_bss_mode(BSS_MODE_WIFIDIRECT_CLIENT) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to initialize " "BSS Mode!\n"); goto fail; } /* Set WFD configuration */ wifidirectcmd_config(); if (wfd_set_mode(WFD_MODE_START) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize WFD!\n"); goto fail; } if (auto_go) { if (wfd_wlan_update_bss_mode(BSS_MODE_WIFIDIRECT_GO) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize BSS Mode!\n"); goto fail; } if (wfd_set_mode(WFD_MODE_START_GROUP_OWNER) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize WFD!\n"); goto fail; } if (!wps_s->current_ssid.ssid_len) { apcmd_get_bss_config(&bss_config); load_cred_info(wps_s, gpwps_info, &bss_config); /* * For Wi-Fi Direct, we need to * convert the passphrase to PSK. * * Hence update the default * passphrase */ wlan_generate_psk(gpwps_info); } if (wps.cb(P2P_AUTO_GO_STARTED, &WFD_devicename, strlen(WFD_devicename)) == -WM_FAIL) P2P_LOG("WFD Callback failed for " "event: %d\r\n", P2P_AUTO_GO_STARTED); if (wlan_add_network(&p2p_uap_network) != WLAN_ERROR_NONE) { wps_printf(MSG_ERROR, "failed to add " "wfd network\r\n"); goto fail; } if (wlan_start_network(p2p_uap_network.name) != WLAN_ERROR_NONE) { wps_printf(MSG_ERROR, "failed to start " "wfd network\r\n"); goto fail; } } else { mlanconfig_bgscan(1); if (wfd_set_mode(WFD_MODE_START_FIND_PHASE) != WPS_STATUS_SUCCESS) { wps_printf(MSG_ERROR, "ERROR - Fail to " "initialize WFD!\n"); goto fail; } wps_set_wfd_cfg(); if (wps.cb(P2P_DEVICE_STARTED, &WFD_devicename, strlen(WFD_devicename)) == -WM_FAIL) P2P_LOG("WFD Callback failed for " "event: %d\r\n", P2P_DEVICE_STARTED); wfd_start_peer_ageout_timer(pwfd_data); p2p_scan_on = 1; } } #endif #ifndef CONFIG_P2P if (wps.cb(WPS_STARTED, NULL, 0) == -WM_FAIL) WPS_LOG("WPS Callback failed for event: %d\r\n", WPS_STARTED); #endif #ifndef CONFIG_WPA2_ENTP wps_register_rx_callback(WPSEAPoLRxDataHandler); #endif while (1) { #ifdef CONFIG_WPA2_ENTP ret = os_queue_recv(&wps.cmd_queue, &wpa2_cmd, RX_WAIT); if (ret != WM_SUCCESS || wpa2_cmd == NULL) continue; #else #ifdef CONFIG_P2P if (!auto_go && p2p_scan_on) { if (wps_loop.timeout) { now.tv_sec = os_ticks_to_msec(os_ticks_get()) / 1000; now.tv_usec = (os_ticks_to_msec (os_ticks_get()) % 1000) * 1000; if (timer_cmp(&now, &wps_loop.timeout->time)) timersub(&wps_loop.timeout->time, &now, &tv); else tv.tv_sec = tv.tv_usec = 0; } /* check if some registered timeouts have occurred */ if (wps_loop.timeout) { struct wps_timeout_s *tmp; now.tv_sec = os_ticks_to_msec(os_ticks_get()) / 1000; now.tv_usec = (os_ticks_to_msec (os_ticks_get()) % 1000) * 1000; if (!timer_cmp(&now, &wps_loop.timeout->time)) { tmp = wps_loop.timeout; wps_loop.timeout = wps_loop.timeout->next; tmp->handler(tmp->callback_data); wps_mem_free(tmp); } } } if (go_request) { p2p_scan_on = 0; g_method = CMD_WPS_PBC; wps_init(); go_request = 0; } ret = os_queue_recv(&wps.cmd_queue, &wps_cmd, os_msec_to_ticks(1000)); #else ret = os_queue_recv(&wps.cmd_queue, &wps_cmd, RX_WAIT); #endif if (ret != WM_SUCCESS || wps_cmd == NULL) continue; #endif #ifdef CONFIG_WPA2_ENTP memcpy(&wps_s->wpa2_network, &wpa2_cmd->wpa2_network, sizeof(struct wlan_network)); wps_mem_free(wpa2_cmd); g_method = CMD_WPS_PBC; ret = wps_private_info_allocate(&gpwps_info); ret = wps_init(); continue; #else g_method = wps_cmd->command; g_channel = wps_cmd->res.channel; #ifdef CONFIG_P2P g_bssid = (u8 *) wps_cmd->res.bssid; g_ssid = (u8 *) wps_cmd->res.ssid; #else memcpy(g_ssid, (u8 *) wps_cmd->res.ssid, MAX_SSID_LEN + 1); memcpy(g_bssid, (u8 *) wps_cmd->res.bssid, ETH_ALEN); #endif wps_mem_free(wps_cmd); switch (g_method) { case CMD_WPS_PIN: g_gen_pin = wps_cmd->wps_pin; wps_init(); break; case CMD_WPS_PBC: wps_init(); break; } #endif } #ifdef CONFIG_P2P fail: if (wps.cb(P2P_FAILED, NULL, 0) == -WM_FAIL) P2P_LOG("WPS Callback failed for event: %d\r\n", P2P_FAILED); wps_stop(); #endif }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos, *end; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; int nfc = 0; u8 pkhash[WPS_OOB_PUBKEY_HASH_LEN]; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; if (cfg.pin_len == 6 && os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) { cfg.pin = NULL; cfg.pin_len = 0; nfc = 1; } } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } pos = os_strstr(phase1, "dev_pw_id="); if (pos) { u16 id = atoi(pos + 10); if (id == DEV_PW_NFC_CONNECTION_HANDOVER) nfc = 1; if (cfg.pin || id == DEV_PW_NFC_CONNECTION_HANDOVER) cfg.dev_pw_id = id; } if (cfg.pin == NULL && !cfg.pbc && !nfc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, " pkhash="); if (pos) { size_t len; pos += 8; end = os_strchr(pos, ' '); if (end) len = end - pos; else len = os_strlen(pos); if (len != 2 * WPS_OOB_PUBKEY_HASH_LEN || hexstr2bin(pos, pkhash, WPS_OOB_PUBKEY_HASH_LEN)) { wpa_printf(MSG_INFO, "EAP-WSC: Invalid pkhash"); os_free(data); return NULL; } cfg.peer_pubkey_hash = pkhash; } res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to parse new AP " "settings"); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); wpa_printf(MSG_DEBUG, "EAP-WSC: wps_init failed"); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, NULL, cfg.pin, cfg.pin_len, 0); } /* Use reduced client timeout for WPS to avoid long wait */ if (sm->ClientTimeout > 30) sm->ClientTimeout = 30; return data; }
/* * Generates a wps_config structure which is passed to wps_init() to create * an initial wps_data structure. */ struct wps_data *initialize_wps_data() { struct wps_config *wpsconf = NULL; struct wps_data *wps = NULL; struct wps_registrar_config *reg_conf = NULL; wpsconf = malloc(sizeof(struct wps_config)); if(!wpsconf) { perror("malloc"); goto end; } memset(wpsconf, 0, sizeof(struct wps_config)); reg_conf = malloc(sizeof(struct wps_registrar_config)); if(!reg_conf) { perror("malloc"); goto end; } memset(reg_conf, 0, sizeof(struct wps_registrar_config)); /* Configure ourselves as a registrar */ wpsconf->registrar = 1; /* Tell the AP to not generate a random PSK */ reg_conf->disable_auto_conf = 1; /* Allocate space for the wps_context structure member */ wpsconf->wps = malloc(sizeof(struct wps_context)); if(!wpsconf->wps) { perror("malloc"); goto end; } memset(wpsconf->wps, 0, sizeof(struct wps_context)); /* * Initialize the registrar sub-structure. This is necessary when calling * wpa_supplicant functions to build registrar response payloads. */ wpsconf->wps->registrar = wps_registrar_init(wpsconf->wps, (const struct wps_registrar_config *) reg_conf); if(wpsconf->wps->registrar == NULL) { cprintf(CRITICAL, "[X] ERROR: Failed to initialize registrar structure!\n"); } /* * In registrar mode, only the uuid wps_context member needs to be * populated in order to call wps_init(). If acting as an enrollee, * the wps_device_data sub-structure must also be populated. */ if(os_get_random(wpsconf->wps->uuid, UUID_LEN) == -1) { memcpy(wpsconf->wps->uuid, DEFAULT_UUID, UUID_LEN); } wps = wps_init(wpsconf); if(wps) { /* Report that we are a Windows 7 registrar, if --win7 was specified on the command line */ if(wps->wps && get_win7_compat()) { wps->wps->dev.device_name = WPS_DEVICE_NAME; wps->wps->dev.manufacturer = WPS_MANUFACTURER; wps->wps->dev.model_name = WPS_MODEL_NAME; wps->wps->dev.model_number = WPS_MODEL_NUMBER; memcpy(wps->wps->dev.pri_dev_type, WPS_DEVICE_TYPE, WPS_DEV_TYPE_LEN); memcpy((void *) &wps->wps->dev.os_version, WPS_OS_VERSION, 4); wps->wps->dev.rf_bands = WPS_RF_BANDS; } } end: if(wpsconf) free(wpsconf); if(reg_conf) free(reg_conf); return wps; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN]; int nfc = 0; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; if (cfg.pin_len >= WPS_OOB_DEVICE_PASSWORD_MIN_LEN * 2 && cfg.pin_len <= WPS_OOB_DEVICE_PASSWORD_LEN * 2 && hexstr2bin((const char *) cfg.pin, dev_pw, cfg.pin_len / 2) == 0) { /* Convert OOB Device Password to binary */ cfg.pin = dev_pw; cfg.pin_len /= 2; } if (cfg.pin_len == 6 && os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) { cfg.pin = NULL; cfg.pin_len = 0; nfc = 1; } } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } if (cfg.pin == NULL && !cfg.pbc && !nfc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, "dev_pw_id="); if (pos && cfg.pin) cfg.dev_pw_id = atoi(pos + 10); res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, NULL, cfg.pin, cfg.pin_len, 0); } /* Use reduced client timeout for WPS to avoid long wait */ if (sm->ClientTimeout > 30) sm->ClientTimeout = 30; return data; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } if (cfg.pin == NULL && !cfg.pbc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, "dev_pw_id="); if (pos && cfg.pin) cfg.dev_pw_id = atoi(pos + 10); res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, cfg.pin, cfg.pin_len, 0); } return data; }
static int screenshot(char *model, char *wps, char *png) { char lib[255]; void *handle; FILE *out, *in; int res; in = fopen(wps, "rb"); if(in == NULL) { fprintf(stderr, "[ERR] Cannot open WPS: %s\n", wps); return -1; } fclose(in); out = fopen(png, "wb"); if(out == NULL) { fprintf(stderr, "[ERR] Cannot open PNG: %s\n", png); return -2; } snprintf(lib, 255, "%s/libwps_%s.so", (char*)get_current_dir_name(), (char*)model); handle = dlopen(lib, RTLD_LAZY); if (!handle) { fprintf(stderr, "[ERR] Cannot open library: %s\n", dlerror()); fclose(out); return -3; } wps_init = dlsym(handle, "wps_init"); wps_display = dlsym(handle, "wps_display"); wps_refresh = dlsym(handle, "wps_refresh"); if (!wps_init || !wps_display || !wps_refresh) { fprintf(stderr, "[ERR] Failed to resolve funcs!"); dlclose(handle); fclose(out); return -4; } memset(&api, 0, sizeof(struct proxy_api)); if(verbose) api.verbose = 3; else api.verbose = 0; api.putsxy = &_putsxy; api.transparent_bitmap_part = &_transparent_bitmap_part; api.bitmap_part = &_bitmap_part; api.drawpixel = &_drawpixel; api.fillrect = &_fillrect; api.hline = &_hline; api.vline = &_vline; api.clear_viewport = &_clear_viewport; api.load_wps_backdrop = &_load_wps_backdrop; api.read_bmp_file = &_read_bmp_file; api.debugf = &_debug; res = wps_init(wps, &api, true); if(res != 1) { fprintf(stderr, "[ERR] WPS wasn't correctly inited\n"); dlclose(handle); fclose(out); return -5; } framebuffer = gdImageCreateTrueColor(api.getwidth(), api.getheight()); _drawBackdrop(); fprintf(stdout, "[INFO] Model: %s\n", api.get_model_name()); wpsdata.fontheight = getFont()->h; wpsdata.fontwidth = getFont()->w; api.set_wpsstate(wpsdata); api.set_trackstate(mp3data); api.set_next_trackstate(mp3data); _drawBackdrop(); wps_refresh(); gdImagePng(framebuffer, out); fprintf(stdout, "[INFO] Image written\n"); dlclose(handle); fclose(out); gdImageDestroy(framebuffer); if(backdrop != NULL) gdImageDestroy(backdrop); wps_init = NULL; wps_display = NULL; wps_refresh = NULL; return 0; }