/* subscr_addr_add_url -- add address(es) for one url to subscription */ static void subscr_addr_add_url(struct subscription *s, const char *url, size_t url_len) { int alloc_len; char *scratch_mem = NULL; char *mem; char *domain_and_port; char *delim; char *path; char *domain; int port = 80; /* port to send to (default is port 80) */ struct addrinfo hints; struct addrinfo *result = NULL; struct addrinfo *rp; int rerr; /* url MUST begin with http: */ if (url_len < 7 || os_strncasecmp(url, "http://", 7)) goto fail; url += 7; url_len -= 7; /* allocate memory for the extra stuff we need */ alloc_len = 2 * (url_len + 1); scratch_mem = os_zalloc(alloc_len); if (scratch_mem == NULL) goto fail; mem = scratch_mem; os_strncpy(mem, url, url_len); wpa_printf(MSG_DEBUG, "WPS UPnP: Adding URL '%s'", mem); domain_and_port = mem; mem += 1 + os_strlen(mem); delim = os_strchr(domain_and_port, '/'); if (delim) { *delim++ = 0; /* null terminate domain and port */ path = delim; } else { path = domain_and_port + os_strlen(domain_and_port); } domain = mem; strcpy(domain, domain_and_port); delim = os_strchr(domain, ':'); if (delim) { *delim++ = 0; /* null terminate domain */ if (isdigit(*delim)) port = atol(delim); } /* * getaddrinfo does the right thing with dotted decimal notations, or * will resolve domain names. Resolving domain names will unfortunately * hang the entire program until it is resolved or it times out * internal to getaddrinfo; fortunately we think that the use of actual * domain names (vs. dotted decimal notations) should be uncommon. */ os_memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET; /* IPv4 */ hints.ai_socktype = SOCK_STREAM; #if NO_DOMAIN_NAME_RESOLUTION /* Suppress domain name resolutions that would halt * the program for periods of time */ hints.ai_flags = AI_NUMERICHOST; #else /* Allow domain name resolution. */ hints.ai_flags = 0; #endif hints.ai_protocol = 0; /* Any protocol? */ rerr = getaddrinfo(domain, NULL /* fill in port ourselves */, &hints, &result); if (rerr) { wpa_printf(MSG_INFO, "WPS UPnP: Resolve error %d (%s) on: %s", rerr, gai_strerror(rerr), domain); goto fail; } for (rp = result; rp; rp = rp->ai_next) { struct subscr_addr *a; /* Limit no. of address to avoid denial of service attack */ if (dl_list_len(&s->addr_list) >= MAX_ADDR_PER_SUBSCRIPTION) { wpa_printf(MSG_INFO, "WPS UPnP: subscr_addr_add_url: " "Ignoring excessive addresses"); break; } a = os_zalloc(sizeof(*a) + alloc_len); if (a == NULL) continue; mem = (void *) (a + 1); a->domain_and_port = mem; strcpy(mem, domain_and_port); mem += 1 + strlen(mem); a->path = mem; if (path[0] != '/') *mem++ = '/'; strcpy(mem, path); mem += 1 + os_strlen(mem); os_memcpy(&a->saddr, rp->ai_addr, sizeof(a->saddr)); a->saddr.sin_port = htons(port); dl_list_add(&s->addr_list, &a->list); } fail: if (result) freeaddrinfo(result); os_free(scratch_mem); }
static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, struct sta_info *sta, const struct ieee80211_mgmt *req, int is_p2p, size_t *resp_len) { struct ieee80211_mgmt *resp; u8 *pos, *epos; size_t buflen; #define MAX_PROBERESP_LEN 768 buflen = MAX_PROBERESP_LEN; #ifdef CONFIG_WPS if (hapd->wps_probe_resp_ie) buflen += wpabuf_len(hapd->wps_probe_resp_ie); #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if (hapd->p2p_probe_resp_ie) buflen += wpabuf_len(hapd->p2p_probe_resp_ie); #endif /* CONFIG_P2P */ if (hapd->conf->vendor_elements) buflen += wpabuf_len(hapd->conf->vendor_elements); if (hapd->conf->vendor_vht) { buflen += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) + 2 + sizeof(struct ieee80211_vht_operation); } resp = os_zalloc(buflen); if (resp == NULL) return NULL; epos = ((u8 *) resp) + MAX_PROBERESP_LEN; resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_PROBE_RESP); if (req) os_memcpy(resp->da, req->sa, ETH_ALEN); os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN); os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN); resp->u.probe_resp.beacon_int = host_to_le16(hapd->iconf->beacon_int); /* hardware or low-level driver will setup seq_ctrl and timestamp */ resp->u.probe_resp.capab_info = host_to_le16(hostapd_own_capab_info(hapd, sta, 1)); pos = resp->u.probe_resp.variable; *pos++ = WLAN_EID_SSID; *pos++ = hapd->conf->ssid.ssid_len; os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len); pos += hapd->conf->ssid.ssid_len; /* Supported rates */ pos = hostapd_eid_supp_rates(hapd, pos); /* DS Params */ pos = hostapd_eid_ds_params(hapd, pos); pos = hostapd_eid_country(hapd, pos, epos - pos); /* Power Constraint element */ pos = hostapd_eid_pwr_constraint(hapd, pos); /* ERP Information element */ pos = hostapd_eid_erp_info(hapd, pos); /* Extended supported rates */ pos = hostapd_eid_ext_supp_rates(hapd, pos); /* RSN, MDIE, WPA */ pos = hostapd_eid_wpa(hapd, pos, epos - pos); pos = hostapd_eid_bss_load(hapd, pos, epos - pos); pos = hostapd_eid_rm_enabled_capab(hapd, pos, epos - pos); #ifdef CONFIG_IEEE80211N pos = hostapd_eid_ht_capabilities(hapd, pos); pos = hostapd_eid_ht_operation(hapd, pos); //DRIVER_RTW ADD if(hapd->iconf->ieee80211n) hapd->conf->wmm_enabled = 1; #endif /* CONFIG_IEEE80211N */ pos = hostapd_eid_ext_capab(hapd, pos); pos = hostapd_eid_time_adv(hapd, pos); pos = hostapd_eid_time_zone(hapd, pos); pos = hostapd_eid_interworking(hapd, pos); pos = hostapd_eid_adv_proto(hapd, pos); pos = hostapd_eid_roaming_consortium(hapd, pos); pos = hostapd_add_csa_elems(hapd, pos, (u8 *)resp, &hapd->cs_c_off_proberesp); #ifdef CONFIG_IEEE80211AC if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) { pos = hostapd_eid_vht_capabilities(hapd, pos); pos = hostapd_eid_vht_operation(hapd, pos); } if (hapd->conf->vendor_vht) pos = hostapd_eid_vendor_vht(hapd, pos); #endif /* CONFIG_IEEE80211AC */ /* Wi-Fi Alliance WMM */ pos = hostapd_eid_wmm(hapd, pos); #ifdef CONFIG_WPS if (hapd->conf->wps_state && hapd->wps_probe_resp_ie) { os_memcpy(pos, wpabuf_head(hapd->wps_probe_resp_ie), wpabuf_len(hapd->wps_probe_resp_ie)); pos += wpabuf_len(hapd->wps_probe_resp_ie); } #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if ((hapd->conf->p2p & P2P_ENABLED) && is_p2p && hapd->p2p_probe_resp_ie) { os_memcpy(pos, wpabuf_head(hapd->p2p_probe_resp_ie), wpabuf_len(hapd->p2p_probe_resp_ie)); pos += wpabuf_len(hapd->p2p_probe_resp_ie); } #endif /* CONFIG_P2P */ #ifdef CONFIG_P2P_MANAGER if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == P2P_MANAGE) pos = hostapd_eid_p2p_manage(hapd, pos); #endif /* CONFIG_P2P_MANAGER */ #ifdef CONFIG_HS20 pos = hostapd_eid_hs20_indication(hapd, pos); pos = hostapd_eid_osen(hapd, pos); #endif /* CONFIG_HS20 */ if (hapd->conf->vendor_elements) { os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements), wpabuf_len(hapd->conf->vendor_elements)); pos += wpabuf_len(hapd->conf->vendor_elements); } *resp_len = pos - (u8 *) resp; return (u8 *) resp; }
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_drivers[i]; i++) { if (os_strcmp(iface->driver_name, wpa_drivers[i]->name) == 0) { iface->driver = wpa_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; }
static int wpa_driver_hostap_set_key(void *priv, 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_hostap_data *drv = priv; struct prism2_hostapd_param *param; u8 *buf; size_t blen; int ret = 0; char *alg_name; switch (alg) { case WPA_ALG_NONE: alg_name = "none"; break; case WPA_ALG_WEP: alg_name = "WEP"; break; case WPA_ALG_TKIP: alg_name = "TKIP"; break; case WPA_ALG_CCMP: alg_name = "CCMP"; break; default: 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 > 8) return -2; blen = sizeof(*param) + key_len; buf = os_zalloc(blen); if (buf == NULL) return -1; param = (struct prism2_hostapd_param *) buf; param->cmd = PRISM2_SET_ENCRYPTION; /* TODO: In theory, STA in client mode can use five keys; four default * keys for receiving (with keyidx 0..3) and one individual key for * both transmitting and receiving (keyidx 0) _unicast_ packets. Now, * keyidx 0 is reserved for this unicast use and default keys can only * use keyidx 1..3 (i.e., default key with keyidx 0 is not supported). * This should be fine for more or less all cases, but for completeness * sake, the driver could be enhanced to support the missing key. */ #if 0 if (addr == NULL) os_memset(param->sta_addr, 0xff, ETH_ALEN); else os_memcpy(param->sta_addr, addr, ETH_ALEN); #else os_memset(param->sta_addr, 0xff, ETH_ALEN); #endif os_strncpy((char *) param->u.crypt.alg, alg_name, HOSTAP_CRYPT_ALG_NAME_LEN); param->u.crypt.flags = set_tx ? HOSTAP_CRYPT_FLAG_SET_TX_KEY : 0; param->u.crypt.idx = key_idx; os_memcpy(param->u.crypt.seq, seq, seq_len); param->u.crypt.key_len = key_len; os_memcpy((u8 *) (param + 1), key, key_len); if (hostapd_ioctl(drv, param, blen, 1)) { wpa_printf(MSG_WARNING, "Failed to set encryption."); show_set_key_error(param); ret = -1; } os_free(buf); return ret; }
int main(int argc, char *argv[]) { struct wpa_supplicant wpa_s; int c, ret = 1, wait_for_monitor = 0, save_config = 0; char *as_addr = "127.0.0.1"; int as_port = 1812; char *as_secret = "radius"; char *cli_addr = NULL; char *conf = NULL; int timeout = 30; char *pos; struct extra_radius_attr *p = NULL, *p1; if (os_program_init()) return -1; hostapd_logger_register_cb(hostapd_logger_cb); os_memset(&eapol_test, 0, sizeof(eapol_test)); eapol_test.connect_info = "CONNECT 11Mbps 802.11b"; os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN); wpa_debug_level = 0; wpa_debug_show_keys = 1; for (;;) { c = getopt(argc, argv, "a:A:c:C:M:nN:o:p:r:s:St:W"); if (c < 0) break; switch (c) { case 'a': as_addr = optarg; break; case 'A': cli_addr = optarg; break; case 'c': conf = optarg; break; case 'C': eapol_test.connect_info = optarg; break; case 'M': if (hwaddr_aton(optarg, eapol_test.own_addr)) { usage(); return -1; } break; case 'n': eapol_test.no_mppe_keys++; break; case 'o': if (eapol_test.server_cert_file) fclose(eapol_test.server_cert_file); eapol_test.server_cert_file = fopen(optarg, "w"); if (eapol_test.server_cert_file == NULL) { printf("Could not open '%s' for writing\n", optarg); return -1; } break; case 'p': as_port = atoi(optarg); break; case 'r': eapol_test.eapol_test_num_reauths = atoi(optarg); break; case 's': as_secret = optarg; break; case 'S': save_config++; break; case 't': timeout = atoi(optarg); break; case 'W': wait_for_monitor++; break; case 'N': p1 = os_zalloc(sizeof(p1)); if (p1 == NULL) break; if (!p) eapol_test.extra_attrs = p1; else p->next = p1; p = p1; p->type = atoi(optarg); pos = os_strchr(optarg, ':'); if (pos == NULL) { p->syntax = 'n'; p->data = NULL; break; } pos++; if (pos[0] == '\0' || pos[1] != ':') { printf("Incorrect format of attribute " "specification\n"); break; } p->syntax = pos[0]; p->data = pos + 2; break; default: usage(); return -1; } } if (argc > optind && os_strcmp(argv[optind], "scard") == 0) { return scard_test(); } if (argc > optind && os_strcmp(argv[optind], "sim") == 0) { return scard_get_triplets(argc - optind - 1, &argv[optind + 1]); } if (conf == NULL) { usage(); printf("Configuration file is required.\n"); return -1; } if (eap_register_methods()) { wpa_printf(MSG_ERROR, "Failed to register EAP methods"); return -1; } if (eloop_init()) { wpa_printf(MSG_ERROR, "Failed to initialize event loop"); return -1; } os_memset(&wpa_s, 0, sizeof(wpa_s)); eapol_test.wpa_s = &wpa_s; wpa_s.conf = wpa_config_read(conf); if (wpa_s.conf == NULL) { printf("Failed to parse configuration file '%s'.\n", conf); return -1; } if (wpa_s.conf->ssid == NULL) { printf("No networks defined.\n"); return -1; } wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret, cli_addr); wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s); if (wpa_s.ctrl_iface == NULL) { printf("Failed to initialize control interface '%s'.\n" "You may have another eapol_test process already " "running or the file was\n" "left by an unclean termination of eapol_test in " "which case you will need\n" "to manually remove this file before starting " "eapol_test again.\n", wpa_s.conf->ctrl_interface); return -1; } if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid)) return -1; if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid)) return -1; if (wait_for_monitor) wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface); eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test, NULL); eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL); eloop_register_signal_terminate(eapol_test_terminate, &wpa_s); eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s); eloop_run(); eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL); eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL); if (eapol_test_compare_pmk(&eapol_test) == 0 || eapol_test.no_mppe_keys) ret = 0; if (eapol_test.auth_timed_out) ret = -2; if (eapol_test.radius_access_reject_received) ret = -3; if (save_config) wpa_config_write(conf, wpa_s.conf); test_eapol_clean(&eapol_test, &wpa_s); eap_peer_unregister_methods(); #ifdef CONFIG_AP eap_server_unregister_methods(); #endif /* CONFIG_AP */ eloop_destroy(); if (eapol_test.server_cert_file) fclose(eapol_test.server_cert_file); printf("MPPE keys OK: %d mismatch: %d\n", eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch); if (eapol_test.num_mppe_mismatch) ret = -4; if (ret) printf("FAILURE\n"); else printf("SUCCESS\n"); os_program_deinit(); return ret; }
//Cgi that check the request has the correct HOST header //Using it we can ensure our server has a domain of our choice int cgi_check_host(http_connection *connData) { http_server_config *config = (http_server_config*)connData->cgi.argument; if(config==NULL) return HTTPD_CGI_NEXT_RULE; if(config->host_domain==NULL) return HTTPD_CGI_NEXT_RULE; if(connData->state==HTTPD_STATE_ON_URL) { http_set_save_header(connData,HTTP_HOST); return HTTPD_CGI_NEXT_RULE; } if(connData->state==HTTPD_STATE_HEADERS_END) { header *hostHeader = http_get_header(connData,HTTP_HOST); if(hostHeader==NULL) { NODE_ERR("Host header not found\n"); http_response_BAD_REQUEST(connData); return HTTPD_CGI_DONE; } const char * domain = config->host_domain; HTTP_CGI_DBG("Host header: %s, domain: %s\n",hostHeader->value,domain); if(strncmp(hostHeader->value,domain,strlen(domain))==0) //compare ignoring http:// and last / { HTTP_CGI_DBG("Domain match\n"); return HTTPD_CGI_NEXT_RULE; } else{ uint8_t op = wifi_get_opmode(); char ipaddrstr[17]; os_bzero(ipaddrstr, sizeof(ipaddrstr)); struct ip_info ipConfig; switch (op) { case STATIONAP_MODE: { wifi_get_ip_info(SOFTAP_IF,&ipConfig); //0x01 ipaddr_ntoa_r(&ipConfig.ip,ipaddrstr, sizeof(ipaddrstr)); if(strncmp(hostHeader->value,ipaddrstr,strlen(ipaddrstr))==0) { HTTP_CGI_DBG("SoftAp ip match"); return HTTPD_CGI_NEXT_RULE; } } case STATION_MODE: { os_bzero(ipaddrstr, sizeof(ipaddrstr)); wifi_get_ip_info(STATION_IF,&ipConfig); //0x00 ipaddr_ntoa_r(&ipConfig.ip,ipaddrstr, sizeof(ipaddrstr)); if(strncmp(hostHeader->value,ipaddrstr,strlen(ipaddrstr))==0) { HTTP_CGI_DBG("Station ip match"); return HTTPD_CGI_NEXT_RULE; } } } HTTP_CGI_DBG("Hosts don't match\n"); if(config->enable_captive) { //to enable a captive portal we should redirect here char * redirectUrl = (char *)os_zalloc(strlen(domain)+9); // domain length + http:// + / + \0 strcpy(redirectUrl,"http://"); os_strcat(redirectUrl,domain); os_strcat(redirectUrl,"/"); http_response_REDIRECT(connData, redirectUrl); os_free(redirectUrl); HTTP_CGI_DBG("Redirect URL = %s\n", redirectUrl); } else { //bad request else http_response_BAD_REQUEST(connData); } return HTTPD_CGI_DONE; } } return HTTPD_CGI_NEXT_RULE; }
/** * hostapd_allowed_address - Check whether a specified STA can be authenticated * @hapd: hostapd BSS data * @addr: MAC address of the STA * @msg: Authentication message * @len: Length of msg in octets * @session_timeout: Buffer for returning session timeout (from RADIUS) * @acct_interim_interval: Buffer for returning account interval (from RADIUS) * @vlan_id: Buffer for returning VLAN ID * @psk: Linked list buffer for returning WPA PSK * @identity: Buffer for returning identity (from RADIUS) * @radius_cui: Buffer for returning CUI (from RADIUS) * Returns: HOSTAPD_ACL_ACCEPT, HOSTAPD_ACL_REJECT, or HOSTAPD_ACL_PENDING * * The caller is responsible for freeing the returned *identity and *radius_cui * values with os_free(). */ int hostapd_allowed_address(struct hostapd_data *hapd, const u8 *addr, const u8 *msg, size_t len, u32 *session_timeout, u32 *acct_interim_interval, int *vlan_id, struct hostapd_sta_wpa_psk_short **psk, char **identity, char **radius_cui) { if (session_timeout) *session_timeout = 0; if (acct_interim_interval) *acct_interim_interval = 0; if (vlan_id) *vlan_id = 0; if (psk) *psk = NULL; if (identity) *identity = NULL; if (radius_cui) *radius_cui = NULL; if (hostapd_maclist_found(hapd->conf->accept_mac, hapd->conf->num_accept_mac, addr, vlan_id)) return HOSTAPD_ACL_ACCEPT; if (hostapd_maclist_found(hapd->conf->deny_mac, hapd->conf->num_deny_mac, addr, vlan_id)) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == ACCEPT_UNLESS_DENIED) return HOSTAPD_ACL_ACCEPT; if (hapd->conf->macaddr_acl == DENY_UNLESS_ACCEPTED) return HOSTAPD_ACL_REJECT; if (hapd->conf->macaddr_acl == USE_EXTERNAL_RADIUS_AUTH) { #ifdef CONFIG_NO_RADIUS return HOSTAPD_ACL_REJECT; #else /* CONFIG_NO_RADIUS */ struct hostapd_acl_query_data *query; struct os_time t; /* Check whether ACL cache has an entry for this station */ int res = hostapd_acl_cache_get(hapd, addr, session_timeout, acct_interim_interval, vlan_id, psk, identity, radius_cui); if (res == HOSTAPD_ACL_ACCEPT || res == HOSTAPD_ACL_ACCEPT_TIMEOUT) return res; if (res == HOSTAPD_ACL_REJECT) return HOSTAPD_ACL_REJECT; query = hapd->acl_queries; while (query) { if (os_memcmp(query->addr, addr, ETH_ALEN) == 0) { /* pending query in RADIUS retransmit queue; * do not generate a new one */ if (identity) { os_free(*identity); *identity = NULL; } if (radius_cui) { os_free(*radius_cui); *radius_cui = NULL; } return HOSTAPD_ACL_PENDING; } query = query->next; } if (!hapd->conf->radius->auth_server) return HOSTAPD_ACL_REJECT; /* No entry in the cache - query external RADIUS server */ query = os_zalloc(sizeof(*query)); if (query == NULL) { wpa_printf(MSG_ERROR, "malloc for query data failed"); return HOSTAPD_ACL_REJECT; } os_get_time(&t); query->timestamp = t.sec; os_memcpy(query->addr, addr, ETH_ALEN); if (hostapd_radius_acl_query(hapd, addr, query)) { wpa_printf(MSG_DEBUG, "Failed to send Access-Request " "for ACL query."); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } query->auth_msg = os_malloc(len); if (query->auth_msg == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "auth frame."); hostapd_acl_query_free(query); return HOSTAPD_ACL_REJECT; } os_memcpy(query->auth_msg, msg, len); query->auth_msg_len = len; query->next = hapd->acl_queries; hapd->acl_queries = query; /* Queued data will be processed in hostapd_acl_recv_radius() * when RADIUS server replies to the sent Access-Request. */ return HOSTAPD_ACL_PENDING; #endif /* CONFIG_NO_RADIUS */ } return HOSTAPD_ACL_REJECT; }
static int tls_write_server_key_exchange(struct tlsv1_server *conn, u8 **msgpos, u8 *end) { tls_key_exchange keyx; const struct tls_cipher_suite *suite; #ifdef EAP_FAST u8 *pos, *rhdr, *hs_start, *hs_length; size_t rlen; u8 *dh_ys; size_t dh_ys_len; #endif /* EAP_FAST */ suite = tls_get_cipher_suite(conn->rl.cipher_suite); if (suite == NULL) keyx = TLS_KEY_X_NULL; else keyx = suite->key_exchange; if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: No ServerKeyExchange needed"); return 0; } if (keyx != TLS_KEY_X_DH_anon) { /* TODO? */ asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: ServerKeyExchange not yet " "supported with key exchange type %d", keyx); return -1; } #ifdef EAP_FAST if (conn->cred == NULL || conn->cred->dh_p == NULL || conn->cred->dh_g == NULL) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: No DH parameters available for " "ServerKeyExhcange"); return -1; } os_free(conn->dh_secret); conn->dh_secret_len = conn->cred->dh_p_len; conn->dh_secret = os_zalloc(conn->dh_secret_len); if (conn->dh_secret == NULL) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Failed to allocate " "memory for secret (Diffie-Hellman)"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); return -1; } if (os_get_random(conn->dh_secret, conn->dh_secret_len)) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Failed to get random " "data for Diffie-Hellman"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); os_free(conn->dh_secret); conn->dh_secret = NULL; return -1; } if (os_memcmp(conn->dh_secret, conn->cred->dh_p, conn->dh_secret_len) > 0) conn->dh_secret[0] = 0; /* make sure secret < p */ pos = conn->dh_secret; while (pos + 1 < conn->dh_secret + conn->dh_secret_len && *pos == 0) pos++; if (pos != conn->dh_secret) { os_memmove(conn->dh_secret, pos, conn->dh_secret_len - (pos - conn->dh_secret)); conn->dh_secret_len -= pos - conn->dh_secret; } wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH server's secret value", conn->dh_secret, conn->dh_secret_len); /* Ys = g^secret mod p */ dh_ys_len = conn->cred->dh_p_len; dh_ys = os_zalloc(dh_ys_len); if (dh_ys == NULL) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Failed to allocate memory for " "Diffie-Hellman"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); return -1; } if (crypto_mod_exp(conn->cred->dh_g, conn->cred->dh_g_len, conn->dh_secret, conn->dh_secret_len, conn->cred->dh_p, conn->cred->dh_p_len, dh_ys, &dh_ys_len)) { tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); os_free(dh_ys); return -1; } wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)", dh_ys, dh_ys_len); /* * struct { * select (KeyExchangeAlgorithm) { * case diffie_hellman: * ServerDHParams params; * Signature signed_params; * case rsa: * ServerRSAParams params; * Signature signed_params; * }; * } ServerKeyExchange; * * struct { * opaque dh_p<1..2^16-1>; * opaque dh_g<1..2^16-1>; * opaque dh_Ys<1..2^16-1>; * } ServerDHParams; */ pos = *msgpos; asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Send ServerKeyExchange"); rhdr = pos; pos += TLS_RECORD_HEADER_LEN; /* opaque fragment[TLSPlaintext.length] */ /* Handshake */ hs_start = pos; /* HandshakeType msg_type */ *pos++ = TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE; /* uint24 length (to be filled) */ hs_length = pos; pos += 3; /* body - ServerDHParams */ /* dh_p */ if (pos + 2 + conn->cred->dh_p_len > end) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Not enough buffer space for " "dh_p"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); os_free(dh_ys); return -1; } WPA_PUT_BE16(pos, conn->cred->dh_p_len); pos += 2; os_memcpy(pos, conn->cred->dh_p, conn->cred->dh_p_len); pos += conn->cred->dh_p_len; /* dh_g */ if (pos + 2 + conn->cred->dh_g_len > end) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Not enough buffer space for " "dh_g"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); os_free(dh_ys); return -1; } WPA_PUT_BE16(pos, conn->cred->dh_g_len); pos += 2; os_memcpy(pos, conn->cred->dh_g, conn->cred->dh_g_len); pos += conn->cred->dh_g_len; /* dh_Ys */ if (pos + 2 + dh_ys_len > end) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Not enough buffer space for " "dh_Ys"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); os_free(dh_ys); return -1; } WPA_PUT_BE16(pos, dh_ys_len); pos += 2; os_memcpy(pos, dh_ys, dh_ys_len); pos += dh_ys_len; os_free(dh_ys); WPA_PUT_BE24(hs_length, pos - hs_length - 3); if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE, rhdr, end - rhdr, pos - hs_start, &rlen) < 0) { asd_printf(ASD_DEFAULT,MSG_DEBUG, "TLSv1: Failed to generate a record"); tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR); return -1; } pos = rhdr + rlen; tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start); *msgpos = pos; return 0; #else /* EAP_FAST */ return -1; #endif /* EAP_FAST */ }
static int hostapd_config_read_wpa_psk(const char *fname, struct hostapd_ssid *ssid) { FILE *f; char buf[128], *pos; int line = 0, ret = 0, len, ok; u8 addr[ETH_ALEN]; struct hostapd_wpa_psk *psk; if (!fname) return 0; f = fopen(fname, "r"); if (!f) { wpa_printf(MSG_ERROR, "WPA PSK file '%s' not found.", fname); return -1; } while (fgets(buf, sizeof(buf), f)) { line++; if (buf[0] == '#') continue; pos = buf; while (*pos != '\0') { if (*pos == '\n') { *pos = '\0'; break; } pos++; } if (buf[0] == '\0') continue; if (hwaddr_aton(buf, addr)) { wpa_printf(MSG_ERROR, "Invalid MAC address '%s' on " "line %d in '%s'", buf, line, fname); ret = -1; break; } psk = os_zalloc(sizeof(*psk)); if (psk == NULL) { wpa_printf(MSG_ERROR, "WPA PSK allocation failed"); ret = -1; break; } if (is_zero_ether_addr(addr)) psk->group = 1; else os_memcpy(psk->addr, addr, ETH_ALEN); pos = buf + 17; if (*pos == '\0') { wpa_printf(MSG_ERROR, "No PSK on line %d in '%s'", line, fname); os_free(psk); ret = -1; break; } pos++; ok = 0; len = os_strlen(pos); if (len == 64 && hexstr2bin(pos, psk->psk, PMK_LEN) == 0) ok = 1; else if (len >= 8 && len < 64) { pbkdf2_sha1(pos, ssid->ssid, ssid->ssid_len, 4096, psk->psk, PMK_LEN); ok = 1; } if (!ok) { wpa_printf(MSG_ERROR, "Invalid PSK '%s' on line %d in " "'%s'", pos, line, fname); os_free(psk); ret = -1; break; } psk->next = ssid->wpa_psk; ssid->wpa_psk = psk; } fclose(f); return ret; }
static void * bsd_init(struct hostapd_data *hapd, struct wpa_init_params *params) { struct bsd_driver_data *drv; drv = os_zalloc(sizeof(struct bsd_driver_data)); if (drv == NULL) { printf("Could not allocate memory for bsd driver data\n"); goto bad; } drv->hapd = hapd; drv->sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } os_strlcpy(drv->ifname, params->ifname, sizeof(drv->ifname)); /* * NB: We require the interface name be mappable to an index. * This implies we do not support having wpa_supplicant * wait for an interface to appear. This seems ok; that * doesn't belong here; it's really the job of devd. * XXXSCW: devd is FreeBSD-specific. */ drv->ifindex = if_nametoindex(drv->ifname); if (drv->ifindex == 0) { printf("%s: interface %s does not exist", __func__, drv->ifname); goto bad; } drv->sock_xmit = l2_packet_init(drv->ifname, NULL, ETH_P_EAPOL, handle_read, drv, 0); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) goto bad; /* mark down during setup */ if (bsd_ctrl_iface(drv, 0) < 0) goto bad; drv->route = socket(PF_ROUTE, SOCK_RAW, 0); if (drv->route < 0) { perror("socket(PF_ROUTE,SOCK_RAW)"); goto bad; } eloop_register_read_sock(drv->route, bsd_wireless_event_receive, drv, NULL); return drv; bad: if (drv == NULL) return NULL; if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->sock >= 0) close(drv->sock); os_free(drv); return NULL; }
static int wpa_driver_atmel_set_key(void *priv, 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_atmel_data *drv = priv; int ret = 0; struct atmel_param *param; u8 *buf; u8 alg_type; size_t blen; char *alg_name; switch (alg) { case WPA_ALG_NONE: alg_name = "none"; alg_type = 0; break; case WPA_ALG_WEP: alg_name = "WEP"; alg_type = 1; break; case WPA_ALG_TKIP: alg_name = "TKIP"; alg_type = 2; break; case WPA_ALG_CCMP: alg_name = "CCMP"; alg_type = 3; break; default: 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 > 8) return -2; blen = sizeof(*param) + key_len; buf = os_zalloc(blen); if (buf == NULL) return -1; param = (struct atmel_param *) buf; param->cmd = SET_WPA_ENCRYPTION; if (addr == NULL) os_memset(param->sta_addr, 0xff, ETH_ALEN); else os_memcpy(param->sta_addr, addr, ETH_ALEN); param->alg = alg_type; param->key_idx = key_idx; param->set_tx = set_tx; os_memcpy(param->seq, seq, seq_len); param->seq_len = seq_len; param->key_len = key_len; os_memcpy((u8 *)param->key, key, key_len); if (atmel_ioctl(drv, param, blen, 1)) { wpa_printf(MSG_WARNING, "Failed to set encryption."); /* TODO: show key error*/ ret = -1; } os_free(buf); return ret; }
static void * madwifi_init(struct hostapd_data *hapd, struct wpa_init_params *params) { struct madwifi_driver_data *drv; struct ifreq ifr; struct iwreq iwr; char brname[IFNAMSIZ]; drv = os_zalloc(sizeof(struct madwifi_driver_data)); if (drv == NULL) { printf("Could not allocate memory for madwifi driver data\n"); return NULL; } drv->hapd = hapd; drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0); if (drv->ioctl_sock < 0) { perror("socket[PF_INET,SOCK_DGRAM]"); goto bad; } memcpy(drv->iface, params->ifname, sizeof(drv->iface)); memset(&ifr, 0, sizeof(ifr)); os_strlcpy(ifr.ifr_name, drv->iface, sizeof(ifr.ifr_name)); if (ioctl(drv->ioctl_sock, SIOCGIFINDEX, &ifr) != 0) { perror("ioctl(SIOCGIFINDEX)"); goto bad; } drv->ifindex = ifr.ifr_ifindex; drv->sock_xmit = l2_packet_init(drv->iface, NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_xmit == NULL) goto bad; if (l2_packet_get_own_addr(drv->sock_xmit, params->own_addr)) goto bad; if (params->bridge[0]) { wpa_printf(MSG_DEBUG, "Configure bridge %s for EAPOL traffic.", params->bridge[0]); drv->sock_recv = l2_packet_init(params->bridge[0], NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_recv == NULL) goto bad; } else if (linux_br_get(brname, drv->iface) == 0) { wpa_printf(MSG_DEBUG, "Interface in bridge %s; configure for " "EAPOL receive", brname); drv->sock_recv = l2_packet_init(brname, NULL, ETH_P_EAPOL, handle_read, drv, 1); if (drv->sock_recv == NULL) goto bad; } else drv->sock_recv = drv->sock_xmit; memset(&iwr, 0, sizeof(iwr)); os_strlcpy(iwr.ifr_name, drv->iface, IFNAMSIZ); iwr.u.mode = IW_MODE_MASTER; if (ioctl(drv->ioctl_sock, SIOCSIWMODE, &iwr) < 0) { perror("ioctl[SIOCSIWMODE]"); printf("Could not set interface to master mode!\n"); goto bad; } /* mark down during setup */ linux_set_iface_flags(drv->ioctl_sock, drv->iface, 0); madwifi_set_privacy(drv, 0); /* default to no privacy */ madwifi_receive_probe_req(drv); if (madwifi_wireless_event_init(drv)) goto bad; return drv; bad: if (drv->sock_xmit != NULL) l2_packet_deinit(drv->sock_xmit); if (drv->ioctl_sock >= 0) close(drv->ioctl_sock); if (drv != NULL) free(drv); return NULL; }
static void ICACHE_FLASH_ATTR handle_dhcp(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, uint16_t port) { struct dhcps_msg *pmsg_dhcps = NULL; sint16_t tlen = 0; u16_t i = 0; u16_t dhcps_msg_cnt = 0; u8_t *p_dhcps_msg = NULL; u8_t *data = NULL; #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> receive a packet\n"); #endif if (p==NULL) return; pmsg_dhcps = (struct dhcps_msg *)os_zalloc(sizeof(struct dhcps_msg)); if (NULL == pmsg_dhcps){ pbuf_free(p); return; } p_dhcps_msg = (u8_t *)pmsg_dhcps; tlen = p->tot_len; data = p->payload; #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> p->tot_len = %d\n", tlen); os_printf("dhcps: handle_dhcp-> p->len = %d\n", p->len); #endif for(i=0; i<p->len; i++){ p_dhcps_msg[dhcps_msg_cnt++] = data[i]; #if DHCPS_DEBUG os_printf("%02x ",data[i]); if((i+1)%16 == 0){ os_printf("\n"); } #endif } if(p->next != NULL) { #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> p->next != NULL\n"); os_printf("dhcps: handle_dhcp-> p->next->tot_len = %d\n",p->next->tot_len); os_printf("dhcps: handle_dhcp-> p->next->len = %d\n",p->next->len); #endif data = p->next->payload; for(i=0; i<p->next->len; i++){ p_dhcps_msg[dhcps_msg_cnt++] = data[i]; #if DHCPS_DEBUG os_printf("%02x ",data[i]); if((i+1)%16 == 0){ os_printf("\n"); } #endif } } /* * DHCP �ͻ���������Ϣ���� */ #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> parse_msg(p)\n"); #endif switch(parse_msg(pmsg_dhcps, tlen - 240)) { case DHCPS_STATE_OFFER://1 #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> DHCPD_STATE_OFFER\n"); #endif send_offer(pmsg_dhcps); break; case DHCPS_STATE_ACK://3 #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> DHCPD_STATE_ACK\n"); #endif send_ack(pmsg_dhcps); break; case DHCPS_STATE_NAK://4 #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> DHCPD_STATE_NAK\n"); #endif send_nak(pmsg_dhcps); break; default : break; } #if DHCPS_DEBUG os_printf("dhcps: handle_dhcp-> pbuf_free(p)\n"); #endif pbuf_free(p); os_free(pmsg_dhcps); pmsg_dhcps = NULL; }
static sint16_t ICACHE_FLASH_ATTR parse_msg(struct dhcps_msg *m, u16_t len) { /* if(os_memcmp((char *)m->options, (char *)magic_cookie, sizeof(magic_cookie)) == 0){ */ //#define magic_cookie 0x63538263 if((m->options[0] == 0x63) && (m->options[1] == 0x82) && (m->options[2] == 0x53) && (m->options[3]==0x63)) { // if(*((uint32 *)m->options) == magic_cookie) { #if DHCPS_DEBUG os_printf("dhcps: len = %d\n", len); #endif /* * ��¼��ǰ��xid���ﴦ���? * �˺�ΪDHCP�ͻ����������û�ͳһ��ȡIPʱ�� */ // if((old_xid[0] == 0) && // (old_xid[1] == 0) && // (old_xid[2] == 0) && // (old_xid[3] == 0)){ // /* // * old_xidδ��¼�κ����? // * �϶��ǵ�һ��ʹ�� // */ // os_memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); // }else{ // /* // * ���δ����DHCP msg��Я���xid���ϴμ�¼�IJ�ͬ�� // * �϶�Ϊ��ͬ��DHCP�ͻ��˷��ͣ���ʱ����Ҫ����Ŀͻ���IP // * ���� 192.168.4.100(0x6404A8C0) <--> 192.168.4.200(0xC804A8C0) // * // */ // if(os_memcmp((char *)old_xid, (char *)m->xid, sizeof(m->xid)) != 0){ /* * ��¼���ε�xid�ţ�ͬʱ�����IP���� */ // struct ip_addr addr_tmp; os_memcpy((char *)old_xid, (char *)m->xid, sizeof(m->xid)); { struct dhcps_pool *pdhcps_pool = NULL; list_node *pnode = NULL; list_node *pback_node = NULL; // POOL_START: client_address.addr = client_address_plus.addr; // addr_tmp.addr = htonl(client_address_plus.addr); // addr_tmp.addr++; // client_address_plus.addr = htonl(addr_tmp.addr); for (pback_node = plist; pback_node != NULL;pback_node = pback_node->pnext) { pdhcps_pool = pback_node->pnode; if (os_memcmp(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)) == 0){ // os_printf("the same device request ip\n"); client_address.addr = pdhcps_pool->ip.addr; pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; goto POOL_CHECK; } else if (pdhcps_pool->ip.addr == client_address_plus.addr){ // client_address.addr = client_address_plus.addr; // os_printf("the ip addr has been request\n"); /* htonl addr_tmp.addr = htonl(client_address_plus.addr); addr_tmp.addr++; client_address_plus.addr = htonl(addr_tmp.addr); */ client_address.addr = client_address_plus.addr + 0x1000000; } } pdhcps_pool = (struct dhcps_pool *)os_zalloc(sizeof(struct dhcps_pool)); pdhcps_pool->ip.addr = client_address.addr; os_memcpy(pdhcps_pool->mac, m->chaddr, sizeof(pdhcps_pool->mac)); pdhcps_pool->lease_timer = DHCPS_LEASE_TIMER; pnode = (list_node *)os_zalloc(sizeof(list_node )); pnode->pnode = pdhcps_pool; node_insert_to_list(&plist,pnode); POOL_CHECK: if ((client_address_plus.addr > dhcps_lease.end_ip.addr) || (client_address.addr == IPADDR_ANY)){ os_printf("client_address_plus.addr %x %d\n", client_address_plus.addr, system_get_free_heap_size()); node_remove_from_list(&plist,pnode); os_free(pdhcps_pool); pdhcps_pool = NULL; os_free(pnode); pnode = NULL; // client_address_plus.addr = dhcps_lease.start_ip.addr; return 4; } if (wifi_softap_set_station_info(m->chaddr, &client_address) == false) { return 0; } } #if DHCPS_DEBUG os_printf("dhcps: xid changed\n"); os_printf("dhcps: client_address.addr = %x\n", client_address.addr); #endif // } // } return parse_options(&m->options[4], len); } return 0; }
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_AP: case WPAS_MODE_P2P_GO: case WPAS_MODE_P2P_GROUP_FORMATION: params.mode = IEEE80211_MODE_AP; break; default: return -1; } if (ssid->frequency == 0) ssid->frequency = 2462; /* default channel 11 */ params.freq.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 = wpa_s->key_mgmt; wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher, 1); if (wpa_s->pairwise_cipher < 0) { wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise " "cipher."); return -1; } params.pairwise_suite = 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 if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD)) params.uapsd = 1; /* mandatory for P2P GO */ else params.uapsd = -1; if (ieee80211_is_dfs(params.freq.freq)) params.freq.freq = 0; /* set channel after CAC */ 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; hapd_iface->smps_modes = wpa_s->drv_smps_modes; hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads; hapd_iface->extended_capa = wpa_s->extended_capa; hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask; hapd_iface->extended_capa_len = wpa_s->extended_capa_len; wpa_s->ap_iface->conf = conf = hostapd_config_defaults(); if (conf == NULL) { wpa_supplicant_ap_deinit(wpa_s); return -1; } os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params, wpa_s->conf->wmm_ac_params, sizeof(wpa_s->conf->wmm_ac_params)); if (params.uapsd > 0) { conf->bss[0]->wmm_enabled = 1; conf->bss[0]->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_calloc(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]->new_psk_cb = ap_new_psk_cb; hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s; hapd_iface->bss[i]->p2p = wpa_s->global->p2p; hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s, 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; #ifdef CONFIG_TESTING_OPTIONS hapd_iface->bss[i]->ext_eapol_frame_io = wpa_s->ext_eapol_frame_io; #endif /* CONFIG_TESTING_OPTIONS */ } 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; eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); 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; }
struct hostapd_config * hostapd_config_defaults(void) { #define ecw2cw(ecw) ((1 << (ecw)) - 1) struct hostapd_config *conf; struct hostapd_bss_config *bss; const int aCWmin = 4, aCWmax = 10; const struct hostapd_wmm_ac_params ac_bk = { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */ const struct hostapd_wmm_ac_params ac_be = { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */ const struct hostapd_wmm_ac_params ac_vi = /* video traffic */ { aCWmin - 1, aCWmin, 2, 3008 / 32, 0 }; const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */ { aCWmin - 2, aCWmin - 1, 2, 1504 / 32, 0 }; const struct hostapd_tx_queue_params txq_bk = { 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 }; const struct hostapd_tx_queue_params txq_be = { 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0}; const struct hostapd_tx_queue_params txq_vi = { 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30}; const struct hostapd_tx_queue_params txq_vo = { 1, (ecw2cw(aCWmin) + 1) / 4 - 1, (ecw2cw(aCWmin) + 1) / 2 - 1, 15}; #undef ecw2cw conf = os_zalloc(sizeof(*conf)); bss = os_zalloc(sizeof(*bss)); if (conf == NULL || bss == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "configuration data."); os_free(conf); os_free(bss); return NULL; } conf->bss = os_calloc(1, sizeof(struct hostapd_bss_config *)); if (conf->bss == NULL) { os_free(conf); os_free(bss); return NULL; } conf->bss[0] = bss; bss->radius = os_zalloc(sizeof(*bss->radius)); if (bss->radius == NULL) { os_free(conf->bss); os_free(conf); os_free(bss); return NULL; } hostapd_config_defaults_bss(bss); conf->num_bss = 1; conf->beacon_int = 100; conf->rts_threshold = -1; /* use driver default: 2347 */ conf->fragm_threshold = -1; /* user driver default: 2346 */ conf->send_probe_response = 1; /* Set to invalid value means do not add Power Constraint IE */ conf->local_pwr_constraint = -1; conf->wmm_ac_params[0] = ac_be; conf->wmm_ac_params[1] = ac_bk; conf->wmm_ac_params[2] = ac_vi; conf->wmm_ac_params[3] = ac_vo; conf->tx_queue[0] = txq_vo; conf->tx_queue[1] = txq_vi; conf->tx_queue[2] = txq_be; conf->tx_queue[3] = txq_bk; conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED; conf->ap_table_max_size = 255; conf->ap_table_expiration_time = 60; #ifdef CONFIG_TESTING_OPTIONS conf->ignore_probe_probability = 0.0; conf->ignore_auth_probability = 0.0; conf->ignore_assoc_probability = 0.0; conf->ignore_reassoc_probability = 0.0; conf->corrupt_gtk_rekey_mic_probability = 0.0; conf->ecsa_ie_only = 0; #endif /* CONFIG_TESTING_OPTIONS */ conf->acs = 0; conf->acs_ch_list.num = 0; #ifdef CONFIG_ACS conf->acs_num_scans = 5; #endif /* CONFIG_ACS */ conf->hw_mode = HOSTAPD_MODE_IEEE80211G; return conf; }
void ICACHE_FLASH_ATTR QUEUE_Init(QUEUE *queue, int bufferSize) { queue->buf = (uint8_t*)os_zalloc(bufferSize); RINGBUF_Init(&queue->rb, queue->buf, bufferSize); }
/** * @brief Client received callback function. * @param arg: contain the ip link information * @param pdata: received data * @param len: the lenght of received data * @retval None */ void ICACHE_FLASH_ATTR at_tcpclient_recv(void *arg, char *pdata, unsigned short len) { struct espconn *pespconn = (struct espconn *) arg; at_linkConType *s = (at_linkConType *) pespconn->reverse; /**************************************************************** * Data sendet to ESP shuld look like this {[^{}]*} eg: {do something: 1} * ****************************************************************/ // it is first packet of data from this client // the packet shuld start with '{' if (s->len == 0 && len > 0 && *pdata != '{') { my_espconn_sent(s, INVALID_START_OF_TRANSMISION, sizeof(INVALID_START_OF_TRANSMISION)); espconn_disconnect(pespconn); return; } if (len + s->len > MAX_RECEIVE) { my_espconn_sent(s, TO_MANY_DATA, sizeof(TO_MANY_DATA)); espconn_disconnect(pespconn); return; } if (len > 0) { // received data and previous data are copied in to // new location // old location will be removed uint8_t *data = (uint8_t *) os_zalloc(sizeof(uint8_t) * (len + s->len)); uint16_t i = 0; if (s->len > 0) { for (i = 0; i < s->len; i++) *(data + i) = *(s->data + i); os_free(s->data); } for (i = s->len; i < s->len + len; i++) *(data + i) = *(pdata + i - s->len); s->data = data; s->len = s->len + len; } // if end of packet reach then send the data to exec if (*(s->data + s->len - 1) == '}') { // uart0_sendStr("END OF PACKET!"); // debug_print_str("TCP: Packet received: \r\n"); // debug_print_bfr(s->data, s->len); tcp_data_to_exec_t *dte = (tcp_data_to_exec_t *) os_zalloc(sizeof(tcp_data_to_exec_t)); dte->len = s->len; dte->data = s->data; dte->link = s; dte->header = NULL; dte->content = NULL; //--------------------------------------------------------------- // get substring of header uint8_t *endOfHeader = strchr(dte->data, '|'); if (endOfHeader != NULL) { uint8_t sizeOfHeader = endOfHeader - &dte->data[1]; uint8_t *header = (uint8_t *) os_zalloc(sizeOfHeader + 1); // + 1 because string end char needed memcpy(header, &dte->data[1], sizeOfHeader); header[sizeOfHeader] = '\0'; dte->header = header; } //--------------------------------------------------------------- if (endOfHeader != NULL) { uint8_t sizeOfHeader = endOfHeader - dte->data; uint8_t sizeOfMsg = dte->len - sizeOfHeader; uint8_t *content = (uint8_t *) os_zalloc(sizeOfMsg + 1); // + 1 because string end char needed memcpy(content, endOfHeader, sizeOfMsg); content[0] = '{'; content[sizeOfMsg] = '\0'; dte->content = content; } else { uint8_t *content = (uint8_t *) os_zalloc(dte->len + 1); // + 1 because string end char needed memcpy(content, dte->data, dte->len); content[dte->len] = '\0'; dte->content = content; } //--------------------------------------------------------------- // now the executing process have to remove this data s->len = 0; system_os_post(my_taskPrio, my_tcp_msg_comme, (uint32_t) dte); } }
/** * wpa_supplicant_req_sched_scan - Start a periodic scheduled scan * @wpa_s: Pointer to wpa_supplicant data * * This function is used to schedule periodic scans for neighboring * access points repeating the scan continuously. */ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) { struct wpa_driver_scan_params params; enum wpa_states prev_state; struct wpa_ssid *ssid = NULL; struct wpabuf *extra_ie = NULL; int ret; unsigned int max_sched_scan_ssids; if (!wpa_s->sched_scan_supported) return -1; if (wpa_s->max_sched_scan_ssids > WPAS_MAX_SCAN_SSIDS) max_sched_scan_ssids = WPAS_MAX_SCAN_SSIDS; else max_sched_scan_ssids = wpa_s->max_sched_scan_ssids; if (wpa_s->sched_scanning) return 0; os_memset(¶ms, 0, sizeof(params)); /* If we can't allocate space for the filters, we just don't filter */ params.filter_ssids = os_zalloc(wpa_s->max_match_sets * sizeof(struct wpa_driver_scan_filter)); prev_state = wpa_s->wpa_state; if (wpa_s->wpa_state == WPA_DISCONNECTED || wpa_s->wpa_state == WPA_INACTIVE) wpa_supplicant_set_state(wpa_s, WPA_SCANNING); /* Find the starting point from which to continue scanning */ ssid = wpa_s->conf->ssid; if (wpa_s->prev_sched_ssid) { while (ssid) { if (ssid == wpa_s->prev_sched_ssid) { ssid = ssid->next; break; } ssid = ssid->next; } } if (!ssid || !wpa_s->prev_sched_ssid) { wpa_dbg(wpa_s, MSG_DEBUG, "Beginning of SSID list"); wpa_s->sched_scan_interval = 2; wpa_s->sched_scan_timeout = max_sched_scan_ssids * 2; wpa_s->first_sched_scan = 1; ssid = wpa_s->conf->ssid; wpa_s->prev_sched_ssid = ssid; } while (ssid) { if (ssid->disabled) { wpa_s->prev_sched_ssid = ssid; ssid = ssid->next; continue; } if (params.filter_ssids && ssid->ssid && ssid->ssid_len) { os_memcpy(params.filter_ssids[params.num_filter_ssids].ssid, ssid->ssid, ssid->ssid_len); params.filter_ssids[params.num_filter_ssids].ssid_len = ssid->ssid_len; params.num_filter_ssids++; } if (ssid->scan_ssid) { params.ssids[params.num_ssids].ssid = ssid->ssid; params.ssids[params.num_ssids].ssid_len = ssid->ssid_len; params.num_ssids++; if (params.num_ssids >= max_sched_scan_ssids) { wpa_s->prev_sched_ssid = ssid; break; } } if (params.num_filter_ssids >= wpa_s->max_match_sets) break; wpa_s->prev_sched_ssid = ssid; ssid = ssid->next; } if (!params.num_ssids) { os_free(params.filter_ssids); return 0; } extra_ie = wpa_supplicant_extra_ies(wpa_s); if (extra_ie) { params.extra_ies = wpabuf_head(extra_ie); params.extra_ies_len = wpabuf_len(extra_ie); } wpa_dbg(wpa_s, MSG_DEBUG, "Starting sched scan: interval %d timeout %d", wpa_s->sched_scan_interval, wpa_s->sched_scan_timeout); ret = wpa_supplicant_start_sched_scan(wpa_s, ¶ms, wpa_s->sched_scan_interval); wpabuf_free(extra_ie); os_free(params.filter_ssids); if (ret) { wpa_msg(wpa_s, MSG_WARNING, "Failed to initiate sched scan"); if (prev_state != wpa_s->wpa_state) wpa_supplicant_set_state(wpa_s, prev_state); return ret; } /* If we have more SSIDs to scan, add a timeout so we scan them too */ if (ssid || !wpa_s->first_sched_scan) { wpa_s->sched_scan_timed_out = 0; eloop_register_timeout(wpa_s->sched_scan_timeout, 0, wpa_supplicant_sched_scan_timeout, wpa_s, NULL); wpa_s->first_sched_scan = 0; wpa_s->sched_scan_timeout /= 2; wpa_s->sched_scan_interval *= 2; } return 0; }
struct rsn_pmksa_cache_entry * pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa, struct wpa_ssid *ssid) { struct rsn_pmksa_cache_entry *entry, *pos, *prev; struct os_time now; if (pmksa->sm->proto != WPA_PROTO_RSN || pmk_len > PMK_LEN) return NULL; entry = os_zalloc(sizeof(*entry)); if (entry == NULL) return NULL; os_memcpy(entry->pmk, pmk, pmk_len); entry->pmk_len = pmk_len; rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid); os_get_time(&now); entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime; entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime * pmksa->sm->dot11RSNAConfigPMKReauthThreshold / 100; entry->akmp = WPA_KEY_MGMT_IEEE8021X; os_memcpy(entry->aa, aa, ETH_ALEN); entry->ssid = ssid; /* Replace an old entry for the same Authenticator (if found) with the * new entry */ pos = pmksa->pmksa; prev = NULL; while (pos) { if (os_memcmp(aa, pos->aa, ETH_ALEN) == 0) { if (pos->pmk_len == pmk_len && os_memcmp(pos->pmk, pmk, pmk_len) == 0 && os_memcmp(pos->pmkid, entry->pmkid, PMKID_LEN) == 0) { wpa_printf(MSG_DEBUG, "WPA: reusing previous " "PMKSA entry"); os_free(entry); return pos; } if (prev == NULL) pmksa->pmksa = pos->next; else prev->next = pos->next; if (pos == pmksa->sm->cur_pmksa) { /* We are about to replace the current PMKSA * cache entry. This happens when the PMKSA * caching attempt fails, so we don't want to * force pmksa_cache_free_entry() to disconnect * at this point. Let's just make sure the old * PMKSA cache entry will not be used in the * future. */ wpa_printf(MSG_DEBUG, "RSN: replacing current " "PMKSA entry"); pmksa->sm->cur_pmksa = NULL; } wpa_printf(MSG_DEBUG, "RSN: Replace PMKSA entry for " "the current AP"); pmksa_cache_free_entry(pmksa, pos, 1); break; } prev = pos; pos = pos->next; } if (pmksa->pmksa_count >= pmksa_cache_max_entries && pmksa->pmksa) { /* Remove the oldest entry to make room for the new entry */ pos = pmksa->pmksa; pmksa->pmksa = pos->next; wpa_printf(MSG_DEBUG, "RSN: removed the oldest PMKSA cache " "entry (for " MACSTR ") to make room for new one", MAC2STR(pos->aa)); wpa_sm_remove_pmkid(pmksa->sm, pos->aa, pos->pmkid); pmksa_cache_free_entry(pmksa, pos, 0); } /* Add the new entry; order by expiration time */ pos = pmksa->pmksa; prev = NULL; while (pos) { if (pos->expiration > entry->expiration) break; prev = pos; pos = pos->next; } if (prev == NULL) { entry->next = pmksa->pmksa; pmksa->pmksa = entry; pmksa_cache_set_expiration(pmksa); } else { entry->next = prev->next; prev->next = entry; } pmksa->pmksa_count++; wpa_printf(MSG_DEBUG, "RSN: added PMKSA cache entry for " MACSTR, MAC2STR(entry->aa)); wpa_sm_add_pmkid(pmksa->sm, entry->aa, entry->pmkid); return entry; }
/** * hostapd_acl_recv_radius - Process incoming RADIUS Authentication messages * @msg: RADIUS response message * @req: RADIUS request message * @shared_secret: RADIUS shared secret * @shared_secret_len: Length of shared_secret in octets * @data: Context data (struct hostapd_data *) * Returns: RADIUS_RX_PROCESSED if RADIUS message was a reply to ACL query (and * was processed here) or RADIUS_RX_UNKNOWN if not. */ static RadiusRxResult hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, const u8 *shared_secret, size_t shared_secret_len, void *data) { struct hostapd_data *hapd = data; struct hostapd_acl_query_data *query, *prev; struct hostapd_cached_radius_acl *cache; struct radius_hdr *hdr = radius_msg_get_hdr(msg); struct os_time t; query = hapd->acl_queries; prev = NULL; while (query) { if (query->radius_id == hdr->identifier) break; prev = query; query = query->next; } if (query == NULL) return RADIUS_RX_UNKNOWN; wpa_printf(MSG_DEBUG, "Found matching Access-Request for RADIUS " "message (id=%d)", query->radius_id); if (radius_msg_verify(msg, shared_secret, shared_secret_len, req, 0)) { wpa_printf(MSG_INFO, "Incoming RADIUS packet did not have " "correct authenticator - dropped\n"); return RADIUS_RX_INVALID_AUTHENTICATOR; } if (hdr->code != RADIUS_CODE_ACCESS_ACCEPT && hdr->code != RADIUS_CODE_ACCESS_REJECT) { wpa_printf(MSG_DEBUG, "Unknown RADIUS message code %d to ACL " "query", hdr->code); return RADIUS_RX_UNKNOWN; } /* Insert Accept/Reject info into ACL cache */ cache = os_zalloc(sizeof(*cache)); if (cache == NULL) { wpa_printf(MSG_DEBUG, "Failed to add ACL cache entry"); goto done; } os_get_time(&t); cache->timestamp = t.sec; os_memcpy(cache->addr, query->addr, sizeof(cache->addr)); if (hdr->code == RADIUS_CODE_ACCESS_ACCEPT) { u8 *buf; size_t len; if (radius_msg_get_attr_int32(msg, RADIUS_ATTR_SESSION_TIMEOUT, &cache->session_timeout) == 0) cache->accepted = HOSTAPD_ACL_ACCEPT_TIMEOUT; else cache->accepted = HOSTAPD_ACL_ACCEPT; if (radius_msg_get_attr_int32( msg, RADIUS_ATTR_ACCT_INTERIM_INTERVAL, &cache->acct_interim_interval) == 0 && cache->acct_interim_interval < 60) { wpa_printf(MSG_DEBUG, "Ignored too small " "Acct-Interim-Interval %d for STA " MACSTR, cache->acct_interim_interval, MAC2STR(query->addr)); cache->acct_interim_interval = 0; } cache->vlan_id = radius_msg_get_vlanid(msg); decode_tunnel_passwords(hapd, shared_secret, shared_secret_len, msg, req, cache); if (radius_msg_get_attr_ptr(msg, RADIUS_ATTR_USER_NAME, &buf, &len, NULL) == 0) { cache->identity = os_zalloc(len + 1); if (cache->identity) os_memcpy(cache->identity, buf, len); } if (radius_msg_get_attr_ptr( msg, RADIUS_ATTR_CHARGEABLE_USER_IDENTITY, &buf, &len, NULL) == 0) { cache->radius_cui = os_zalloc(len + 1); if (cache->radius_cui) os_memcpy(cache->radius_cui, buf, len); } if (hapd->conf->wpa_psk_radius == PSK_RADIUS_REQUIRED && !cache->psk) cache->accepted = HOSTAPD_ACL_REJECT; } else cache->accepted = HOSTAPD_ACL_REJECT; cache->next = hapd->acl_cache; hapd->acl_cache = cache; #ifdef CONFIG_DRIVER_RADIUS_ACL hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted, cache->session_timeout); #else /* CONFIG_DRIVER_RADIUS_ACL */ #ifdef NEED_AP_MLME /* Re-send original authentication frame for 802.11 processing */ wpa_printf(MSG_DEBUG, "Re-sending authentication frame after " "successful RADIUS ACL query"); ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL); #endif /* NEED_AP_MLME */ #endif /* CONFIG_DRIVER_RADIUS_ACL */ done: if (prev == NULL) hapd->acl_queries = query->next; else prev->next = query->next; hostapd_acl_query_free(query); return RADIUS_RX_PROCESSED; }
static void * wpa_driver_wired_init(void *ctx, const char *ifname) { struct wpa_driver_wired_data *drv; int flags; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) return NULL; os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)); drv->ctx = ctx; #ifdef __linux__ drv->pf_sock = socket(PF_PACKET, SOCK_DGRAM, 0); if (drv->pf_sock < 0) perror("socket(PF_PACKET)"); #else /* __linux__ */ drv->pf_sock = -1; #endif /* __linux__ */ if (wpa_driver_wired_get_ifflags(ifname, &flags) == 0 && !(flags & IFF_UP) && wpa_driver_wired_set_ifflags(ifname, flags | IFF_UP) == 0) { drv->iff_up = 1; } if (wired_multicast_membership(drv->pf_sock, if_nametoindex(drv->ifname), pae_group_addr, 1) == 0) { wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " "packet socket", __func__); drv->membership = 1; } else if (wpa_driver_wired_multi(ifname, pae_group_addr, 1) == 0) { wpa_printf(MSG_DEBUG, "%s: Added multicast membership with " "SIOCADDMULTI", __func__); drv->multi = 1; } else if (wpa_driver_wired_get_ifflags(ifname, &flags) < 0) { wpa_printf(MSG_INFO, "%s: Could not get interface " "flags", __func__); os_free(drv); return NULL; } else if (flags & IFF_ALLMULTI) { wpa_printf(MSG_DEBUG, "%s: Interface is already configured " "for multicast", __func__); } else if (wpa_driver_wired_set_ifflags(ifname, flags | IFF_ALLMULTI) < 0) { wpa_printf(MSG_INFO, "%s: Failed to enable allmulti", __func__); os_free(drv); return NULL; } else { wpa_printf(MSG_DEBUG, "%s: Enabled allmulti mode", __func__); drv->iff_allmulti = 1; } #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) { int status; wpa_printf(MSG_DEBUG, "%s: waiting for link to become active", __func__); while (wpa_driver_wired_get_ifstatus(ifname, &status) == 0 && status == 0) sleep(1); } #endif /* defined(__FreeBSD__) || defined(__DragonFly__) || defined(FreeBSD_kernel__) */ return drv; }
ICACHE_FLASH_ATTR void WebConnection::received_data(char* data, unsigned short length) { if (!request) request = new WebRequest(); request->received_data(data, length); if (!request->is_complete()) return; if (request->type == WebRequest::BAD) { static const char bad_request[] = "400 Bad Request\r\n\r\n"; espconn_send(connection, (uint8*) bad_request, strlen(bad_request)); reset(); return; } const char* url = request->url; if (strcmp(url, "/") == 0) url = "index.html"; while (url[0] == '/') url += 1; static const char not_found[] = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"; if (request->type == WebRequest::GET) { HTMLFile cur_file; cur_file.load(url); if (cur_file.is_valid()) { log("Sending %s...\n", url); const char* content_type = "text/plain"; const char* dot = strrchr(url, '.'); if (dot) { const char* suffix = dot + 1; if (strcmp(suffix, "html") == 0) content_type = "text/html"; else if (strcmp(suffix, "css") == 0) content_type = "text/css"; else if (strcmp(suffix, "js") == 0) content_type = "application/javascript"; } char headers[256]; static const char* headers_fmt = "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %d\r\n" "\r\n"; os_sprintf(headers, headers_fmt, content_type, cur_file.size); int headers_length = strlen(headers); int message_length = headers_length + cur_file.size; char* message = (char*) os_zalloc(message_length); strcpy(message, headers); os_memcpy(message + headers_length, cur_file.contents, cur_file.size); espconn_send(connection, (uint8*) message, message_length); os_free(message); } else espconn_send(connection, (uint8*) not_found, strlen(not_found)); } else if (request->type == WebRequest::POST) { if (strcmp(url, "message") == 0) { display_message(request->body, request->body_length); static const char* generic_ok = "HTTP/1.1 200 OK\r\n" "Content-Length: 0\r\n" "\r\n"; espconn_send(connection, (uint8*) generic_ok, strlen(generic_ok)); } else espconn_send(connection, (uint8*) not_found, strlen(not_found)); } else { static const char method_not_allowed[] = "HTTP/1.1 405 Method Not Allowed\r\n\r\n"; espconn_send( connection, (uint8*) method_not_allowed, strlen(method_not_allowed)); } reset(); }
void web_fini(const uint8 * fname) { struct buf_fini *p = (struct buf_fini *) os_zalloc(sizeof(struct buf_fini)); if(p == NULL) { #if DEBUGSOO > 1 os_printf("Error mem!\n"); #endif return; } TCP_SERV_CONN * ts_conn = &p->ts_conn; WEB_SRV_CONN * web_conn = &p->web_conn; web_conn->bffiles[0]=WEBFS_INVALID_HANDLE; web_conn->bffiles[1]=WEBFS_INVALID_HANDLE; web_conn->bffiles[2]=WEBFS_INVALID_HANDLE; web_conn->bffiles[3]=WEBFS_INVALID_HANDLE; ts_conn->linkd = (uint8 *)web_conn; ts_conn->sizeo = FINI_BUF_SIZE; ts_conn->pbufo = p->buf; rom_strcpy(ts_conn->pbufo, (void *)fname, MAX_FILE_NAME_SIZE); #if DEBUGSOO > 1 os_printf("Run ini file: %s\n", ts_conn->pbufo); #endif if(!web_inc_fopen(ts_conn, ts_conn->pbufo)) { #if DEBUGSOO > 1 os_printf("file not found!\n"); #endif return; } if(fatCache.flags & WEBFS_FLAG_ISZIPPED) { #if DEBUGSOO > 1 os_printf("\nError: file is ZIPped!\n"); #endif web_inc_fclose(web_conn); return; } user_uart_wait_tx_fifo_empty(1,1000); while(1) { web_conn->msgbufsize = ts_conn->sizeo; web_conn->msgbuflen = 0; uint8 *pstr = web_conn->msgbuf = ts_conn->pbufo; if(CheckSCB(SCB_RETRYCB)) { // повторный callback? да #if DEBUGSOO > 2 os_printf("rcb "); #endif if(web_conn->func_web_cb != NULL) web_conn->func_web_cb(ts_conn); if(CheckSCB(SCB_RETRYCB)) break; // повторить ещё раз? да. } uint16 len = WEBFSGetArray(web_conn->webfile, pstr, FINI_BUF_SIZE); #if DEBUGSOO > 3 os_printf("ReadF[%u]=%u\n",web_conn->webfile, len); #endif if(len) { // есть байты в файле uint8 *pend = web_strnstr(pstr, CRLF, FINI_BUF_SIZE); if(pend != NULL) { int cmp = pend - pstr; if(cmp >= 0) { // найден CRLF // откат файла WEBFSStubs[web_conn->webfile].addr -= len; WEBFSStubs[web_conn->webfile].bytesRem += len; // передвинуть указатель в файле на считанные байты с учетом маркера, без добавки длины для передачи WEBFSStubs[web_conn->webfile].addr += cmp+2; WEBFSStubs[web_conn->webfile].bytesRem -= cmp+2; if(cmp != 0) { pstr[cmp] = '\0'; // закрыть string calback-а #if DEBUGSOO > 3 os_printf("String:%s\n", pstr); #endif if(!os_memcmp((void*)pstr, "inc:", 4)) { // "inc:file_name" if(!web_inc_fopen(ts_conn, &pstr[4])) { #if DEBUGSOO > 1 os_printf("file not found!"); #endif }; } else web_int_callback(ts_conn); }; }; }; } else if(web_inc_fclose(web_conn)) { if(web_conn->web_disc_cb != NULL) web_conn->web_disc_cb(web_conn->web_disc_par); return; } } }
static void * wpa_driver_roboswitch_init(void *ctx, const char *ifname) { struct wpa_driver_roboswitch_data *drv; char *sep; u16 vlan = 0, _read[2]; drv = os_zalloc(sizeof(*drv)); if (drv == NULL) return NULL; drv->ctx = ctx; drv->own_addr[0] = '\0'; /* copy ifname and take a pointer to the second to last character */ sep = drv->ifname + os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname)) - 2; /* find the '.' separating <interface> and <vlan> */ while (sep > drv->ifname && *sep != '.') sep--; if (sep <= drv->ifname) { wpa_printf(MSG_INFO, "%s: No <interface>.<vlan> pair in " "interface name %s", __func__, drv->ifname); os_free(drv); return NULL; } *sep = '\0'; while (*++sep) { if (*sep < '0' || *sep > '9') { wpa_printf(MSG_INFO, "%s: Invalid vlan specification " "in interface name %s", __func__, ifname); os_free(drv); return NULL; } vlan *= 10; vlan += *sep - '0'; if (vlan > ROBO_VLAN_MAX) { wpa_printf(MSG_INFO, "%s: VLAN out of range in " "interface name %s", __func__, ifname); os_free(drv); return NULL; } } drv->fd = socket(PF_INET, SOCK_DGRAM, 0); if (drv->fd < 0) { wpa_printf(MSG_INFO, "%s: Unable to create socket", __func__); os_free(drv); return NULL; } os_memset(&drv->ifr, 0, sizeof(drv->ifr)); os_strlcpy(drv->ifr.ifr_name, drv->ifname, IFNAMSIZ); if (ioctl(drv->fd, SIOCGMIIPHY, &drv->ifr) < 0) { perror("ioctl[SIOCGMIIPHY]"); os_free(drv); return NULL; } if (if_mii(&drv->ifr)->phy_id != ROBO_PHY_ADDR) { wpa_printf(MSG_INFO, "%s: Invalid phy address (not a " "RoboSwitch?)", __func__); os_free(drv); return NULL; } /* set and read back to see if the register can be used */ _read[0] = ROBO_VLAN_MAX; wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350, _read, 1); wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_ACCESS_5350, _read + 1, 1); drv->is_5350 = _read[0] == _read[1]; /* set the read bit */ vlan |= 1 << 13; wpa_driver_roboswitch_write(drv, ROBO_VLAN_PAGE, drv->is_5350 ? ROBO_VLAN_ACCESS_5350 : ROBO_VLAN_ACCESS, &vlan, 1); wpa_driver_roboswitch_read(drv, ROBO_VLAN_PAGE, ROBO_VLAN_READ, _read, drv->is_5350 ? 2 : 1); if (!(drv->is_5350 ? _read[1] & (1 << 4) : _read[0] & (1 << 14))) { wpa_printf(MSG_INFO, "%s: Could not get port information for " "VLAN %d", __func__, vlan & ~(1 << 13)); os_free(drv); return NULL; } drv->ports = _read[0] & 0x001F; /* add the MII port */ drv->ports |= 1 << 8; if (wpa_driver_roboswitch_join(drv, drv->ports, pae_group_addr) < 0) { wpa_printf(MSG_INFO, "%s: Unable to join PAE group", __func__); os_free(drv); return NULL; } else { wpa_printf(MSG_DEBUG, "%s: Added PAE group address to " "RoboSwitch ARL", __func__); } return drv; }
struct wowlan_triggers * wpa_get_wowlan_triggers(const char *wowlan_triggers, const struct wpa_driver_capa *capa) { struct wowlan_triggers *triggers; char *start, *end, *buf; int last; if (!wowlan_triggers) return NULL; buf = os_strdup(wowlan_triggers); if (buf == NULL) return NULL; triggers = os_zalloc(sizeof(*triggers)); if (triggers == NULL) goto out; #define CHECK_TRIGGER(trigger) \ wpa_check_wowlan_trigger(start, #trigger, \ capa->wowlan_triggers.trigger, \ &triggers->trigger) start = buf; while (*start != '\0') { while (isblank((unsigned char) *start)) start++; if (*start == '\0') break; end = start; while (!isblank((unsigned char) *end) && *end != '\0') end++; last = *end == '\0'; *end = '\0'; if (!CHECK_TRIGGER(any) && !CHECK_TRIGGER(disconnect) && !CHECK_TRIGGER(magic_pkt) && !CHECK_TRIGGER(gtk_rekey_failure) && !CHECK_TRIGGER(eap_identity_req) && !CHECK_TRIGGER(four_way_handshake) && !CHECK_TRIGGER(rfkill_release)) { wpa_printf(MSG_DEBUG, "Unknown/unsupported wowlan trigger '%s'", start); os_free(triggers); triggers = NULL; goto out; } if (last) break; start = end + 1; } #undef CHECK_TRIGGER out: os_free(buf); return triggers; }
int ieee802_11_build_ap_params(struct hostapd_data *hapd, struct wpa_driver_ap_params *params) { struct ieee80211_mgmt *head = NULL; u8 *tail = NULL; size_t head_len = 0, tail_len = 0; u8 *resp = NULL; size_t resp_len = 0; #ifdef NEED_AP_MLME u16 capab_info; u8 *pos, *tailpos; #define BEACON_HEAD_BUF_SIZE 256 #define BEACON_TAIL_BUF_SIZE 512 head = os_zalloc(BEACON_HEAD_BUF_SIZE); tail_len = BEACON_TAIL_BUF_SIZE; #ifdef CONFIG_WPS if (hapd->conf->wps_state && hapd->wps_beacon_ie) tail_len += wpabuf_len(hapd->wps_beacon_ie); #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if (hapd->p2p_beacon_ie) tail_len += wpabuf_len(hapd->p2p_beacon_ie); #endif /* CONFIG_P2P */ if (hapd->conf->vendor_elements) tail_len += wpabuf_len(hapd->conf->vendor_elements); #ifdef CONFIG_IEEE80211AC if (hapd->conf->vendor_vht) { tail_len += 5 + 2 + sizeof(struct ieee80211_vht_capabilities) + 2 + sizeof(struct ieee80211_vht_operation); } #endif /* CONFIG_IEEE80211AC */ tailpos = tail = os_malloc(tail_len); if (head == NULL || tail == NULL) { wpa_printf(MSG_ERROR, "Failed to set beacon data"); os_free(head); os_free(tail); return -1; } head->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_BEACON); head->duration = host_to_le16(0); os_memset(head->da, 0xff, ETH_ALEN); os_memcpy(head->sa, hapd->own_addr, ETH_ALEN); os_memcpy(head->bssid, hapd->own_addr, ETH_ALEN); head->u.beacon.beacon_int = host_to_le16(hapd->iconf->beacon_int); /* hardware or low-level driver will setup seq_ctrl and timestamp */ capab_info = hostapd_own_capab_info(hapd, NULL, 0); head->u.beacon.capab_info = host_to_le16(capab_info); pos = &head->u.beacon.variable[0]; /* SSID */ *pos++ = WLAN_EID_SSID; if (hapd->conf->ignore_broadcast_ssid == 2) { /* clear the data, but keep the correct length of the SSID */ *pos++ = hapd->conf->ssid.ssid_len; os_memset(pos, 0, hapd->conf->ssid.ssid_len); pos += hapd->conf->ssid.ssid_len; } else if (hapd->conf->ignore_broadcast_ssid) { *pos++ = 0; /* empty SSID */ } else { *pos++ = hapd->conf->ssid.ssid_len; os_memcpy(pos, hapd->conf->ssid.ssid, hapd->conf->ssid.ssid_len); pos += hapd->conf->ssid.ssid_len; } /* Supported rates */ pos = hostapd_eid_supp_rates(hapd, pos); /* DS Params */ pos = hostapd_eid_ds_params(hapd, pos); head_len = pos - (u8 *) head; tailpos = hostapd_eid_country(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE - tailpos); /* Power Constraint element */ tailpos = hostapd_eid_pwr_constraint(hapd, tailpos); /* ERP Information element */ tailpos = hostapd_eid_erp_info(hapd, tailpos); /* Extended supported rates */ tailpos = hostapd_eid_ext_supp_rates(hapd, tailpos); /* RSN, MDIE, WPA */ tailpos = hostapd_eid_wpa(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE - tailpos); tailpos = hostapd_eid_rm_enabled_capab(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE - tailpos); tailpos = hostapd_eid_bss_load(hapd, tailpos, tail + BEACON_TAIL_BUF_SIZE - tailpos); #ifdef CONFIG_IEEE80211N tailpos = hostapd_eid_ht_capabilities(hapd, tailpos); tailpos = hostapd_eid_ht_operation(hapd, tailpos); #endif /* CONFIG_IEEE80211N */ tailpos = hostapd_eid_ext_capab(hapd, tailpos); /* * TODO: Time Advertisement element should only be included in some * DTIM Beacon frames. */ tailpos = hostapd_eid_time_adv(hapd, tailpos); tailpos = hostapd_eid_interworking(hapd, tailpos); tailpos = hostapd_eid_adv_proto(hapd, tailpos); tailpos = hostapd_eid_roaming_consortium(hapd, tailpos); tailpos = hostapd_add_csa_elems(hapd, tailpos, tail, &hapd->cs_c_off_beacon); #ifdef CONFIG_IEEE80211AC if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac) { tailpos = hostapd_eid_vht_capabilities(hapd, tailpos); tailpos = hostapd_eid_vht_operation(hapd, tailpos); } if (hapd->conf->vendor_vht) tailpos = hostapd_eid_vendor_vht(hapd, tailpos); #endif /* CONFIG_IEEE80211AC */ /* Wi-Fi Alliance WMM */ tailpos = hostapd_eid_wmm(hapd, tailpos); #ifdef CONFIG_WPS if (hapd->conf->wps_state && hapd->wps_beacon_ie) { os_memcpy(tailpos, wpabuf_head(hapd->wps_beacon_ie), wpabuf_len(hapd->wps_beacon_ie)); tailpos += wpabuf_len(hapd->wps_beacon_ie); } #endif /* CONFIG_WPS */ #ifdef CONFIG_P2P if ((hapd->conf->p2p & P2P_ENABLED) && hapd->p2p_beacon_ie) { os_memcpy(tailpos, wpabuf_head(hapd->p2p_beacon_ie), wpabuf_len(hapd->p2p_beacon_ie)); tailpos += wpabuf_len(hapd->p2p_beacon_ie); } #endif /* CONFIG_P2P */ #ifdef CONFIG_P2P_MANAGER if ((hapd->conf->p2p & (P2P_MANAGE | P2P_ENABLED | P2P_GROUP_OWNER)) == P2P_MANAGE) tailpos = hostapd_eid_p2p_manage(hapd, tailpos); #endif /* CONFIG_P2P_MANAGER */ #ifdef CONFIG_HS20 tailpos = hostapd_eid_hs20_indication(hapd, tailpos); tailpos = hostapd_eid_osen(hapd, tailpos); #endif /* CONFIG_HS20 */ if (hapd->conf->vendor_elements) { os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements), wpabuf_len(hapd->conf->vendor_elements)); tailpos += wpabuf_len(hapd->conf->vendor_elements); } tail_len = tailpos > tail ? tailpos - tail : 0; resp = hostapd_probe_resp_offloads(hapd, &resp_len); #endif /* NEED_AP_MLME */ os_memset(params, 0, sizeof(*params)); params->head = (u8 *) head; params->head_len = head_len; params->tail = tail; params->tail_len = tail_len; params->proberesp = resp; params->proberesp_len = resp_len; params->dtim_period = hapd->conf->dtim_period; params->beacon_int = hapd->iconf->beacon_int; params->basic_rates = hapd->iface->basic_rates; params->ssid = hapd->conf->ssid.ssid; params->ssid_len = hapd->conf->ssid.ssid_len; params->pairwise_ciphers = hapd->conf->wpa_pairwise | hapd->conf->rsn_pairwise; params->group_cipher = hapd->conf->wpa_group; params->key_mgmt_suites = hapd->conf->wpa_key_mgmt; params->auth_algs = hapd->conf->auth_algs; params->wpa_version = hapd->conf->wpa; params->privacy = hapd->conf->ssid.wep.keys_set || hapd->conf->wpa || (hapd->conf->ieee802_1x && (hapd->conf->default_wep_key_len || hapd->conf->individual_wep_key_len)); switch (hapd->conf->ignore_broadcast_ssid) { case 0: params->hide_ssid = NO_SSID_HIDING; break; case 1: params->hide_ssid = HIDDEN_SSID_ZERO_LEN; break; case 2: params->hide_ssid = HIDDEN_SSID_ZERO_CONTENTS; break; } params->isolate = hapd->conf->isolate; params->smps_mode = hapd->iconf->ht_capab & HT_CAP_INFO_SMPS_MASK; #ifdef NEED_AP_MLME params->cts_protect = !!(ieee802_11_erp_info(hapd) & ERP_INFO_USE_PROTECTION); params->preamble = hapd->iface->num_sta_no_short_preamble == 0 && hapd->iconf->preamble == SHORT_PREAMBLE; if (hapd->iface->current_mode && hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G) params->short_slot_time = hapd->iface->num_sta_no_short_slot_time > 0 ? 0 : 1; else params->short_slot_time = -1; if (!hapd->iconf->ieee80211n || hapd->conf->disable_11n) params->ht_opmode = -1; else params->ht_opmode = hapd->iface->ht_op_mode; #endif /* NEED_AP_MLME */ params->interworking = hapd->conf->interworking; if (hapd->conf->interworking && !is_zero_ether_addr(hapd->conf->hessid)) params->hessid = hapd->conf->hessid; params->access_network_type = hapd->conf->access_network_type; params->ap_max_inactivity = hapd->conf->ap_max_inactivity; #ifdef CONFIG_P2P params->p2p_go_ctwindow = hapd->iconf->p2p_go_ctwindow; #endif /* CONFIG_P2P */ #ifdef CONFIG_HS20 params->disable_dgaf = hapd->conf->disable_dgaf; if (hapd->conf->osen) { params->privacy = 1; params->osen = 1; } #endif /* CONFIG_HS20 */ return 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]; conf->driver = wpa_s->driver; os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface)); conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency, &conf->channel); if (conf->hw_mode == NUM_HOSTAPD_MODES) { wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz", ssid->frequency); return -1; } wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf); if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) { conf->ieee80211h = 1; conf->ieee80211d = 1; conf->country[0] = wpa_s->conf->country[0]; conf->country[1] = wpa_s->conf->country[1]; } #ifdef CONFIG_P2P if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G && (ssid->mode == WPAS_MODE_P2P_GO || ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) { /* 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; bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk; if (ssid->p2p_group) { os_memcpy(bss->ip_addr_go, wpa_s->parent->conf->ip_addr_go, 4); os_memcpy(bss->ip_addr_mask, wpa_s->parent->conf->ip_addr_mask, 4); os_memcpy(bss->ip_addr_start, wpa_s->parent->conf->ip_addr_start, 4); os_memcpy(bss->ip_addr_end, wpa_s->parent->conf->ip_addr_end, 4); } #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_len = ssid->ssid_len; bss->ssid.ssid_set = 1; bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid; 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->psk_set) { bin_clear_free(bss->ssid.wpa_psk, sizeof(*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->passphrase) { bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase); } 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; } if (ssid->ap_max_inactivity) bss->ap_max_inactivity = ssid->ap_max_inactivity; if (ssid->dtim_period) bss->dtim_period = ssid->dtim_period; else if (wpa_s->conf->dtim_period) bss->dtim_period = wpa_s->conf->dtim_period; if (ssid->beacon_int) conf->beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int) conf->beacon_int = wpa_s->conf->beacon_int; #ifdef CONFIG_P2P if (wpa_s->conf->p2p_go_ctwindow > conf->beacon_int) { wpa_printf(MSG_INFO, "CTWindow (%d) is bigger than beacon interval (%d) - avoid configuring it", wpa_s->conf->p2p_go_ctwindow, conf->beacon_int); conf->p2p_go_ctwindow = 0; } else { conf->p2p_go_ctwindow = wpa_s->conf->p2p_go_ctwindow; } #endif /* CONFIG_P2P */ if ((bss->wpa & 2) && bss->rsn_pairwise == 0) bss->rsn_pairwise = bss->wpa_pairwise; bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise, bss->rsn_pairwise); 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; } if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) && (bss->wpa_group == WPA_CIPHER_CCMP || bss->wpa_group == WPA_CIPHER_GCMP || bss->wpa_group == WPA_CIPHER_CCMP_256 || bss->wpa_group == WPA_CIPHER_GCMP_256)) { /* * Strong ciphers do not need frequent rekeying, so increase * the default GTK rekeying period to 24 hours. */ bss->wpa_group_rekey = 86400; } #ifdef CONFIG_IEEE80211W if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT) bss->ieee80211w = ssid->ieee80211w; #endif /* CONFIG_IEEE80211W */ #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; if (bss->ssid.security_policy == SECURITY_WPA_PSK && (!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) || !(bss->wpa & 2))) goto no_wps; /* WPS2 does not allow WPA/TKIP-only * configuration */ bss->eap_server = 1; if (!ssid->ignore_broadcast_ssid) 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); bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1; 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; if (wpa_s->conf->ap_vendor_elements) { bss->vendor_elements = wpabuf_dup(wpa_s->conf->ap_vendor_elements); } return 0; }
struct hostapd_config * hostapd_config_defaults(void) { #define ecw2cw(ecw) ((1 << (ecw)) - 1) struct hostapd_config *conf; struct hostapd_bss_config *bss; const int aCWmin = 4, aCWmax = 10; const struct hostapd_wmm_ac_params ac_bk = { aCWmin, aCWmax, 7, 0, 0 }; /* background traffic */ const struct hostapd_wmm_ac_params ac_be = { aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */ const struct hostapd_wmm_ac_params ac_vi = /* video traffic */ { aCWmin - 1, aCWmin, 2, 3000 / 32, 1 }; const struct hostapd_wmm_ac_params ac_vo = /* voice traffic */ { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 }; const struct hostapd_tx_queue_params txq_bk = { 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 }; const struct hostapd_tx_queue_params txq_be = { 3, ecw2cw(aCWmin), 4 * (ecw2cw(aCWmin) + 1) - 1, 0}; const struct hostapd_tx_queue_params txq_vi = { 1, (ecw2cw(aCWmin) + 1) / 2 - 1, ecw2cw(aCWmin), 30}; const struct hostapd_tx_queue_params txq_vo = { 1, (ecw2cw(aCWmin) + 1) / 4 - 1, (ecw2cw(aCWmin) + 1) / 2 - 1, 15}; #undef ecw2cw conf = os_zalloc(sizeof(*conf)); bss = os_zalloc(sizeof(*bss)); if (conf == NULL || bss == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate memory for " "configuration data."); os_free(conf); os_free(bss); return NULL; } bss->radius = os_zalloc(sizeof(*bss->radius)); if (bss->radius == NULL) { os_free(conf); os_free(bss); return NULL; } hostapd_config_defaults_bss(bss); conf->num_bss = 1; conf->bss = bss; conf->beacon_int = 100; conf->rts_threshold = -1; /* use driver default: 2347 */ conf->fragm_threshold = -1; /* user driver default: 2346 */ conf->send_probe_response = 1; conf->wmm_ac_params[0] = ac_be; conf->wmm_ac_params[1] = ac_bk; conf->wmm_ac_params[2] = ac_vi; conf->wmm_ac_params[3] = ac_vo; conf->tx_queue[0] = txq_vo; conf->tx_queue[1] = txq_vi; conf->tx_queue[2] = txq_be; conf->tx_queue[3] = txq_bk; conf->ht_capab = HT_CAP_INFO_SMPS_DISABLED; hostapd_config_acs_defaults(conf); return conf; }
time_t expire = now + UPNP_SUBSCRIBE_SEC; /* Get rid of expired subscriptions so we have room */ subscription_list_age(sm, now); /* If too many subscriptions, remove oldest */ if (dl_list_len(&sm->subscriptions) >= MAX_SUBSCRIPTIONS) { s = dl_list_first(&sm->subscriptions, struct subscription, list); wpa_printf(MSG_INFO, "WPS UPnP: Too many subscriptions, " "trashing oldest"); dl_list_del(&s->list); subscription_destroy(s); } s = os_zalloc(sizeof(*s)); if (s == NULL) return NULL; dl_list_init(&s->addr_list); dl_list_init(&s->event_queue); s->sm = sm; s->timeout_time = expire; uuid_make(s->uuid); subscr_addr_list_create(s, callback_urls); if (dl_list_empty(&s->addr_list)) { wpa_printf(MSG_DEBUG, "WPS UPnP: No valid callback URLs in " "'%s' - drop subscription", callback_urls); subscription_destroy(s); return NULL; }