static int wpssta_start(wpssta_wksp_t *sta_wksp) { char *val; char user_bssid = false; uint32 len; uint band_num, active_band; int pbc = WPS_UI_PBC_SW; unsigned char *env_bssid = NULL; uint8 assoc_bssid[6]; val = wps_ui_get_env("wps_pbc_method"); if (val) pbc = atoi(val); /* Retrieve user specified bssid ENV */ if (pbc != WPS_UI_PBC_HW) { env_bssid = wps_ui_get_env("wps_enr_bssid"); if (env_bssid) user_bssid = true; } /* update specific RF band */ wps_get_bands(&band_num, &active_band); if (active_band == WLC_BAND_5G) active_band = WPS_RFBAND_50GHZ; else if (active_band == WLC_BAND_2G) active_band = WPS_RFBAND_24GHZ; else active_band = WPS_RFBAND_24GHZ; wps_update_RFBand((uint8)active_band); /* * We always retrieve bssid from associated AP. If driver support join network * with bssid, the retrieved bssid should be same as user specified. Otherwise * there might be problems with roaming. */ /* If user_bssid not defined, use associated AP's */ if (wps_get_bssid(assoc_bssid)) { TUTRACE((TUTRACE_ERR, "Can not get [%s] BSSID, Quit....\n", ssid)); goto err_exit; } /* check associated bssid consistent with user specified */ if (user_bssid && memcmp(assoc_bssid, bssid, 6) != 0) { /* warning to user */ TUTRACE((TUTRACE_INFO, "User specified BSSID %02x:%02x:%02x:%02x:%02x:%02x, but " "connect to %02x:%02x:%02x:%02x:%02x:%02x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], assoc_bssid[0], assoc_bssid[1], assoc_bssid[2], assoc_bssid[3], assoc_bssid[4], assoc_bssid[5])); memcpy(bssid, assoc_bssid, 6); } /* setup raw 802.1X socket with "bssid" destination */ if (wps_osl_init(bssid) != WPS_SUCCESS) { TUTRACE((TUTRACE_ERR, "Initializing 802.1x raw socket failed. \n")); goto err_exit; } wpsenr_osl_proc_states(WPS_ASSOCIATED); /* START ENROLLING */ if (sta_wksp->mode == WPSM_STA_BUILTINREG) { TUTRACE((TUTRACE_INFO, "Start registration for BSSID: %02x:%02x:%02x:%02x:%02x:%02x [Mode:%s]\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5], (sta_wksp->configap == true) ? " config AP":" get AP config")); if (wps_start_registration(pin, start_time) != WPS_SUCCESS) { TUTRACE((TUTRACE_ERR, "Start registration failed!\n")); goto err_exit; } } else { TUTRACE((TUTRACE_INFO, "Start enrollment for BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5])); if (wps_start_enrollment(pin, start_time) != WPS_SUCCESS) { TUTRACE((TUTRACE_INFO, "Start enrollment failed!\n")); goto err_exit; } } /* * start the process by sending the eapol start . Created from the * Enrollee SM Initialize. */ len = wps_get_msg_to_send(&val, start_time); if (val) { send_eapol_packet(val, len); TUTRACE((TUTRACE_INFO, "Send EAPOL-Start\n")); } else { /* this means the system is not initialized */ return WPS_ERR_NOT_INITIALIZED; } return WPS_SUCCESS; err_exit: /* Do cleanup */ wpsenr_osl_restore_wsec(); return WPS_ERR_SYSTEM; }
/* * Name : wpsenr_wksp_mainloop * Description : Main loop point for the WPS stack * Arguments : wpsenr_param_t *param - argument set * Return type : int */ static wpssta_wksp_t * wpssta_init(char *ifname) { wpssta_wksp_t *sta_wksp = NULL; int pbc = WPS_UI_PBC_SW; char start_ok = false; wps_ap_list_info_t *wpsaplist; char scan = false; char *val, *next; char op[6] = {0}; int oob = 0; int i, imax; int wps_action; char *env_ssid = NULL; char *env_sec = NULL; char *env_bssid = NULL; char *env_pin = NULL; #ifdef __CONFIG_WFI__ char *ui_env_pin = NULL; #endif /* __CONFIG_WFI__ */ char tmp[100]; char *wlnames, name[256]; TUTRACE((TUTRACE_INFO, "*********************************************\n")); TUTRACE((TUTRACE_INFO, "WPS - Enrollee App Broacom Corp.\n")); TUTRACE((TUTRACE_INFO, "Version: %s\n", MOD_VERSION_STR)); TUTRACE((TUTRACE_INFO, "*********************************************\n")); /* we need to specify the if name before anything else */ if (!ifname) { TUTRACE((TUTRACE_INFO, "no ifname exist!! return\n")); return 0; } /* WSC 2.0, support WPS V2 or not */ if (strcmp(wps_safe_get_conf("wps_version2"), "enabled") == 0) b_wps_version2 = true; wps_set_ifname(ifname); wps_osl_set_ifname(ifname); /* reset assoc_state in INIT state */ assoc_state = WPS_ASSOC_STATE_INIT; /* reset enroll_again */ enroll_again = false; /* Check whether scan needed */ val = wps_ui_get_env("wps_enr_scan"); if (val) scan = atoi(val); /* if scan requested : display and exit */ if (scan) { /* do scan and wait the scan results */ do_wps_scan(); while (get_wps_scan_results() == NULL) WpsSleep(1); /* use scan result to create ap list */ wpsaplist = create_aplist(); if (wpsaplist) { wpssta_display_aplist(wpsaplist); wps_get_aplist(wpsaplist, wpsaplist); TUTRACE((TUTRACE_INFO, "WPS Enabled AP list :\n")); wpssta_display_aplist(wpsaplist); } goto exit; } /* init workspace */ if ((sta_wksp = (wpssta_wksp_t *)alloc_init(sizeof(wpssta_wksp_t))) == NULL) { TUTRACE((TUTRACE_INFO, "Can not allocate memory for wps workspace...\n")); return NULL; } memset(sta_wksp, 0, sizeof(wpssta_wksp_t)); wps_action = atoi(wps_ui_get_env("wps_action")); /* Setup STA action */ if (wps_action == WPS_UI_ACT_STA_CONFIGAP || wps_action == WPS_UI_ACT_STA_GETAPCONFIG) { sta_wksp->mode = WPSM_STA_BUILTINREG; if (wps_action == WPS_UI_ACT_STA_CONFIGAP) sta_wksp->configap = true; } else sta_wksp->mode = WPSM_STA_ENROLL; val = wps_ui_get_env("wps_pbc_method"); if (val) pbc = atoi(val); /* Save maximum instance number, and probe if any wl interface */ imax = wps_get_ess_num(); for (i = 0; i < imax; i++) { sprintf(tmp, "ess%d_wlnames", i); wlnames = wps_safe_get_conf(tmp); foreach(name, wlnames, next) { if (!strcmp(name, ifname)) { sta_wksp->ess_id = i; goto found; } } } goto exit; found: /* Retrieve ENV */ if (pbc == WPS_UI_PBC_HW) { strcat(op, "pb"); } else { /* SW PBC */ if (atoi(wps_ui_get_env("wps_method")) == WPS_UI_METHOD_PBC) { strcat(op, "pb"); } else { /* PIN */ strcat(op, "pin"); env_pin = wps_get_conf("wps_device_pin"); env_sec = wps_ui_get_env("wps_enr_wsec"); if (env_sec[0] != 0) { wsec = atoi(env_sec); } env_ssid = wps_ui_get_env("wps_enr_ssid"); if (env_ssid[0] == 0) { TUTRACE((TUTRACE_ERR, "\n\nPlease specify ssid or use pbc method\n\n")); goto exit; } wps_strncpy(ssid, env_ssid, sizeof(ssid)); env_bssid = wps_ui_get_env("wps_enr_bssid"); if (env_bssid[0] == 0) { /* * WARNING : this "bssid" is used only to create an 802.1X socket. * * Normally, it should be the bssid of the AP we will associate to. * * Setting this manually means that we might be proceeding to * eapol exchange with a different AP than the one we are associated to, * which might work ... or not. * * When implementing an application, one might want to enforce association * with the AP with that particular BSSID. In case of multiple AP * on the ESS, this might not be stable with roaming enabled. */ ether_atoe(env_bssid, bssid); } #ifdef __CONFIG_WFI__ /* For WiFi-Invite session PIN */ ui_env_pin = wps_ui_get_env("wps_device_pin"); if (ui_env_pin[0] != '\0') env_pin = ui_env_pin; #endif /* __CONFIG_WFI__ */ if (sta_wksp->mode == WPSM_STA_BUILTINREG) { env_pin = wps_ui_get_env("wps_stareg_ap_pin"); if (wps_validate_pin(env_pin) == FALSE) { TUTRACE((TUTRACE_INFO, "Not a valid PIN [%s]\n", env_pin ? (char *)env_pin : "")); goto exit; } sprintf(tmp, "ess%d_wps_oob", sta_wksp->ess_id); val = wps_ui_get_env(tmp); if (strcmp(val, "enabled") == 0) oob = 1; } /* If we want to get AP config and the AP is unconfigured, * configure the AP directly */ if (sta_wksp->mode == WPSM_STA_BUILTINREG && sta_wksp->configap == false) { val = wps_ui_get_env("wps_scstate"); if (strcmp(val, "unconfigured") == 0) { sta_wksp->configap = true; TUTRACE((TUTRACE_INFO, "AP-%s is unconfigure, " "using our security settings to configre it.\n")); } } } } TUTRACE((TUTRACE_INFO, "pbc = %s, wpsenr param: ifname = %s, mode= %s, op = %s, sec = %s, " "ssid = %s, bssid = %s, pin = %s, oob = %s\n", (pbc == 1? "HW_PBC": "SW_PBC"), ifname, (sta_wksp->mode == WPSM_STA_BUILTINREG) ? "STA_REG" : "STA_ENR", op, (env_sec? (char *)env_sec : "NULL"), (env_ssid? (char *)env_ssid : "NULL"), (env_bssid? (char *)env_bssid : "NULL"), (env_pin? (char *)env_pin : "NULL"), (oob == 1? "Enabled": "Disabled"))); /* * setup device configuration for WPS * needs to be done before eventual scan for PBC. */ if (sta_wksp->mode == WPSM_STA_BUILTINREG) { if (wpssta_reg_config_init(sta_wksp, ifname, bssid, oob) != WPS_SUCCESS) { TUTRACE((TUTRACE_ERR, "wpssta_reg_config_init failed, exit.\n")); goto exit; } } else { if (wpssta_enr_config_init() != WPS_SUCCESS) { TUTRACE((TUTRACE_ERR, "wpssta_enr_config_init failed, exit.\n")); goto exit; } } /* if ssid specified, use it */ if (!strcmp(op, "pin")) { pin = env_pin; if (!pin) { pin = def_pin; TUTRACE((TUTRACE_ERR, "\n\nStation Pin not specified, use default Pin %s\n\n", def_pin)); } start_ok = true; /* WSC 2.0, Test Plan 5.1.1 step 8 must add wps ie to probe request */ if (b_wps_version2) add_wps_ie(NULL, 0, 0, b_wps_version2); } else { pin = NULL; wpsenr_osl_proc_states(WPS_FIND_PBC_AP); /* add wps ie to probe */ add_wps_ie(NULL, 0, TRUE, b_wps_version2); do_wps_scan(); assoc_state_time = get_current_time(); assoc_state = WPS_ASSOC_STATE_SCANNING; start_ok = false; } /* start WPS two minutes period at Finding a PBC AP or Associating with AP */ start_time = get_current_time(); if (start_ok) { /* clear current security setting */ wpsenr_osl_clear_wsec(); /* * join. If user_bssid is specified, it might not * match the actual associated AP. * An implementation might want to make sure * it associates to the same bssid. * There might be problems with roaming. */ wpssta_do_join(false); return sta_wksp; } else if (assoc_state == WPS_ASSOC_STATE_SCANNING) { return sta_wksp; } exit: wpssta_deinit(sta_wksp); return NULL; }
static uint32 wpssta_reg_config_init(wpssta_wksp_t *sta_wksp, char *ifname, char *bssid, char oob) { DevInfo info; char *value, *next; int auth = 0; char mac[6]; char ssid[MAX_SSID_LEN + 1] = {0}; char psk[MAX_USER_KEY_LEN + 1] = {0}; char akmstr[32]; char key[8]; unsigned int akm = 0; unsigned int wsec = 0; int wep_index = 0; /* wep key index */ char *wep_key = NULL; /* user-supplied wep key */ char dev_akm[64] = {0}; char dev_crypto[64] = {0}; char prefix[] = "wlXXXXXXXXXX_"; char tmp[100]; /* TBD, is going to use osname only */ sprintf(prefix, "%s_", ifname); /* fill in device specific info. */ memset((char *)(&info), 0, sizeof(info)); info.version = WPS_VERSION; /* MAC addr */ wps_osl_get_mac(mac); memcpy(info.macAddr, mac, 6); memcpy(info.uuid, wps_get_uuid(), SIZE_16_BYTES); if ((value = wps_get_conf("wps_sta_device_name")) == NULL) value = "ASUSTeK Registrar"; wps_strncpy(info.deviceName, value, sizeof(info.deviceName)); info.primDeviceCategory = WPS_DEVICE_TYPE_CAT_NW_INFRA; info.primDeviceOui = 0x0050F204; info.primDeviceSubCategory = WPS_DEVICE_TYPE_SUB_CAT_NW_GATEWAY; strcpy(info.manufacturer, "ASUSTeK"); strcpy(info.modelName, "WPS Wireless Registrar"); strcpy(info.modelNumber, "1234"); strcpy(info.serialNumber, "5678"); if (b_wps_version2) { info.configMethods = (WPS_CONFMET_VIRT_PBC | WPS_CONFMET_PHY_PBC | WPS_CONFMET_VIRT_DISPLAY); } else { info.configMethods = WPS_CONFMET_PBC | WPS_CONFMET_DISPLAY; } /* WSC 2.0, WPS-PSK and SHARED are deprecated. * When both the Registrar and the Enrollee are using protocol version 2.0 * or newer, this variable can use the value 0x0022 to indicate mixed mode * operation (both WPA-Personal and WPA2-Personal enabled) */ if (b_wps_version2) { info.authTypeFlags = (uint16)(WPS_AUTHTYPE_OPEN | WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_WPA2PSK); } else { info.authTypeFlags = (uint16)(WPS_AUTHTYPE_OPEN | WPS_AUTHTYPE_WPAPSK | WPS_AUTHTYPE_SHARED | WPS_AUTHTYPE_WPA2PSK); } /* ENCR_TYPE_FLAGS */ /* * WSC 2.0, deprecated WEP. TKIP can only be advertised on the AP when * Mixed Mode is enabled (Encryption Type is 0x000c) */ if (b_wps_version2) { info.encrTypeFlags = (uint16)(WPS_ENCRTYPE_NONE | WPS_ENCRTYPE_TKIP | WPS_ENCRTYPE_AES); } else { info.encrTypeFlags = (uint16)(WPS_ENCRTYPE_NONE | WPS_ENCRTYPE_WEP | WPS_ENCRTYPE_TKIP | WPS_ENCRTYPE_AES); } info.connTypeFlags = WPS_CONNTYPE_ESS; info.rfBand = WPS_RFBAND_24GHZ; info.osVersion = 0x80000000; info.featureId = 0x80000000; /* WSC 2.0 */ if (b_wps_version2) { value = wps_get_conf("wps_version2_num"); info.version2 = (uint8)(strtoul(value, NULL, 16)); info.settingsDelayTime = WPS_SETTING_DELAY_TIME_ROUTER; info.b_reqToEnroll = FALSE; info.b_nwKeyShareable = FALSE; } if (!sta_wksp->configap) { /* We don't care about our settings. All we want is get ap credential, * so, empty sta credential is okay. The state machine sends NACK, * when M7AP received. */ return wpssta_reg_init(&info, NULL, NULL); } /* Want to config AP with the STA registrar's crendentials */ if ((value = wps_ui_get_env("wps_ssid")) && strcmp(value, "") != 0) { /* SSID */ value = wps_ui_get_env("wps_ssid"); strncpy(ssid, value, MAX_SSID_LEN); /* AKM */ value = wps_ui_get_env("wps_akm"); foreach(akmstr, value, next) { if (!strcmp(akmstr, "psk")) akm |= WPA_AUTH_PSK; if (!strcmp(akmstr, "psk2")) akm |= WPA2_AUTH_PSK; } switch (akm) { case 0: case WPA2_AUTH_PSK: case (WPA_AUTH_PSK | WPA2_AUTH_PSK): break; default: TUTRACE((TUTRACE_INFO, "wpsap_readConfigure: Error in AKM\n")); return MC_ERR_CFGFILE_CONTENT; } /* Crypto */ if (akm) { value = wps_ui_get_env("wps_crypto"); if (!strcmp(value, "aes")) wsec = AES_ENABLED; else if (!strcmp(value, "tkip+aes")) wsec = TKIP_ENABLED|AES_ENABLED; else { TUTRACE((TUTRACE_INFO, "wpsap_readConfigure: Error in crypto\n")); return MC_ERR_CFGFILE_CONTENT; } /* Set PSK key */ value = wps_ui_get_env("wps_psk"); strncpy(psk, value, MAX_USER_KEY_LEN); psk[MAX_USER_KEY_LEN] = 0; } }