/* sta_pin must String format */ uint32 wpsap_start_registration_devpwid(void *mc_dev, char *sta_pin, uint8 *pub_key_hash, uint16 devicepwid) { WPSAPI_T *g_mc = (WPSAPI_T *)mc_dev; DevInfo *dev_info = g_mc->dev_info; if (!sta_pin) return WPS_ERR_INVALID_PARAMETERS; if (devicepwid == 0) { if (strcmp(sta_pin, "00000000") == 0) devicepwid = WPS_DEVICEPWDID_PUSH_BTN; else devicepwid = WPS_DEVICEPWDID_DEFAULT; } if (pub_key_hash) memcpy(dev_info->pub_key_hash, pub_key_hash, sizeof(dev_info->pub_key_hash)); dev_info->devPwdId = devicepwid; wps_strncpy(dev_info->pin, sta_pin, sizeof(dev_info->pin)); /* Start ap protocol */ return wpsap_start(g_mc, sta_pin); }
static int wps_pb_find_next() { char *value, *next; int next_id; int max_id = wps_hal_led_wl_max(); char tmp[100]; char ifname[IFNAMSIZ]; char *wlnames; int target_id = -1; int target_instance = 0; int i, imax; imax = wps_get_ess_num(); refind: for (i = 0; i < imax; i++) { sprintf(tmp, "ess%d_led_id", i); value = wps_get_conf(tmp); if (value == NULL) continue; next_id = atoi(value); if ((next_id > pb_last_led_id) && (next_id <= max_id)) { if ((target_id == -1) || (next_id < target_id)) { /* Save the candidate */ target_id = next_id; target_instance = i; } } } /* A candidate found ? */ if (target_id == -1) { pb_last_led_id = -1; goto refind; } pb_last_led_id = target_id; /* Take the first wl interface */ sprintf(tmp, "ess%d_wlnames", target_instance); wlnames = wps_safe_get_conf(tmp); foreach(ifname, wlnames, next) { wps_strncpy(pb_ifname, ifname, sizeof(pb_ifname)); break; }
uint32 wpsap_start_enrollment(void *mc_dev, char *ap_pin) { WPSAPI_T *g_mc = (WPSAPI_T *)mc_dev; DevInfo *dev_info = g_mc->dev_info; if (!ap_pin || !strlen(ap_pin)) return WPS_ERR_INVALID_PARAMETERS; /* AP enrollee, cannot use push button */ dev_info->devPwdId = WPS_DEVICEPWDID_DEFAULT; wps_strncpy(dev_info->pin, ap_pin, sizeof(dev_info->pin)); /* Start ap protocol */ return wpsap_start(g_mc, ap_pin); }
uint32 wpsap_start_registration(void *mc_dev, char *sta_pin) { WPSAPI_T *g_mc = (WPSAPI_T *)mc_dev; DevInfo *dev_info = g_mc->dev_info; int devicepwid; if (!sta_pin) return WPS_ERR_INVALID_PARAMETERS; if (strcmp(sta_pin, "00000000") == 0) devicepwid = WPS_DEVICEPWDID_PUSH_BTN; else devicepwid = WPS_DEVICEPWDID_DEFAULT; /* Save pin */ dev_info->devPwdId = devicepwid; wps_strncpy(dev_info->pin, sta_pin, sizeof(dev_info->pin)); /* Start ap protocol */ return wpsap_start(g_mc, sta_pin); }
static WPS_SSR_SCB * ap_ssr_find_scb(void *findobj, int type, int enter) { int i; int found = 0; char *mac; WPS_SSR_SCB *scb = ap_ssr_scb; if (type != WPS_SSR_SCB_FIND_ANY && findobj == NULL) return NULL; switch (type) { case WPS_SSR_SCB_FIND_ANY: /* Return first scb */ break; case WPS_SSR_SCB_FIND_IPADDR: /* String format */ while (scb) { if (strcmp(scb->ipaddr, (char *)findobj) == 0) break; /* Found */ scb = scb->next; } if (scb == NULL && enter == WPS_SSR_SCB_ENTER) { if ((scb = malloc(sizeof(WPS_SSR_SCB))) == NULL) return NULL; memset(scb, 0, sizeof(WPS_SSR_SCB)); /* Append to head */ scb->next = ap_ssr_scb; ap_ssr_scb = scb; /* Copy ipaddr string */ wps_strncpy(scb->ipaddr, (char *)findobj, sizeof(scb->ipaddr)); } break; case WPS_SSR_SCB_FIND_AUTHORIED_MAC: /* Mac format, <= 30B */ while (scb) { for (i = 0; i < scb->authorizedMacs_len; i += SIZE_MAC_ADDR) { mac = &scb->authorizedMacs[i]; if (memcmp(mac, (char *)findobj, SIZE_MAC_ADDR) == 0) { found = 1; break; /* Found */ } } if (found) break; scb = scb->next; } break; case WPS_SSR_SCB_FIND_UUID_R: /* UUID format, = 16B */ while (scb) { if (memcmp(scb->uuid_R, (char *)findobj, sizeof(scb->uuid_R)) == 0) break; /* Found */ scb = scb->next; } break; case WPS_SSR_SCB_FIND_VERSION1: while (scb) { if (scb->version == *(unsigned char *)findobj) break; /* Found */ scb = scb->next; } break; default: return NULL; } return scb; }
/* Add/Remove a SSR */ int ap_ssr_set_scb(char *ipaddr, CTlvSsrIE *ssrmsg, char *wps_ifname, unsigned long upd_time) { WPS_SSR_SCB *scb, *ptr; if (!ipaddr || !ssrmsg) return -1; /* Find scb by ipaddr */ scb = ap_ssr_find_scb(ipaddr, WPS_SSR_SCB_FIND_IPADDR, ssrmsg->selReg.m_data ? WPS_SSR_SCB_ENTER : WPS_SSR_SCB_SEARCH_ONLY); if (scb == NULL) { TUTRACE((TUTRACE_INFO, "Can not set SSR ipaddr, selReg %d!\n", ssrmsg->selReg.m_data)); return -1; } /* Update information */ if (ssrmsg->selReg.m_data) { scb->version = ssrmsg->version.m_data; scb->version2 = ssrmsg->version2.m_data; scb->scState = ssrmsg->scState.m_data; scb->upd_time = upd_time; if (wps_ifname) wps_strncpy(scb->wps_ifname, wps_ifname, sizeof(scb->wps_ifname)); /* MAC format, check authorizedMacs_len */ if (ssrmsg->authorizedMacs.subtlvbase.m_len) { scb->authorizedMacs_len = ssrmsg->authorizedMacs.subtlvbase.m_len; memcpy(scb->authorizedMacs, ssrmsg->authorizedMacs.m_data, ssrmsg->authorizedMacs.subtlvbase.m_len); } /* UUID format, check uuid_R_len */ if (ssrmsg->uuid_R.tlvbase.m_len) memcpy(scb->uuid_R, ssrmsg->uuid_R.m_data, SIZE_UUID); scb->selRegCfgMethods = ssrmsg->selRegCfgMethods.m_data; scb->devPwdId = ssrmsg->devPwdId.m_data; } else { /* Remove this scb */ if (scb == ap_ssr_scb) { ap_ssr_scb = ap_ssr_scb->next; free(scb); } else { ptr = ap_ssr_scb; while (ptr) { if (ptr->next == scb) { ptr->next = scb->next; free(scb); break; } ptr = ptr->next; } if (ptr == NULL) { TUTRACE((TUTRACE_INFO, "Can't remove scb from ap_ssr_scb list\n")); return -1; } } } return 0; }
/* * 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; } }