LOCAL ICACHE_FLASH_ATTR char *save_data(char *precv, uint16 length) { LOCAL char *precvbuffer; LOCAL uint32 dat_sumlength = 0; LOCAL uint32 totallength = 0; bool flag = false; char length_buf[10] = {0}; char *ptemp = NULL; char *pdata = NULL; uint16 headlength = 0; ptemp = (char *)os_strstr(precv, "\r\n\r\n"); if (ptemp != NULL) { length -= ptemp - precv; length -= 4; totallength += length; headlength = ptemp - precv + 4; pdata = (char *)os_strstr(precv, "Content-Length: "); if (pdata != NULL) { pdata += 16; precvbuffer = (char *)os_strstr(pdata, "\r\n"); if (precvbuffer != NULL) { os_memcpy(length_buf, pdata, precvbuffer - pdata); dat_sumlength = atoi(length_buf); } } else { if (totallength != 0x00) { totallength = 0; dat_sumlength = 0; return NULL; } } if ((dat_sumlength + headlength) >= 1024) { precvbuffer = (char *)os_zalloc(headlength + 1); os_memcpy(precvbuffer, precv, headlength + 1); } else { precvbuffer = (char *)os_zalloc(dat_sumlength + headlength + 1); os_memcpy(precvbuffer, precv, os_strlen(precv)); } } else { if (precvbuffer != NULL) { totallength += length; os_memcpy(precvbuffer + os_strlen(precvbuffer), precv, length); } else { totallength = 0; dat_sumlength = 0; return NULL; } } if (totallength == dat_sumlength) { totallength = 0; dat_sumlength = 0; return precvbuffer; } else { return NULL; } }
static void clean_past_ated(){ pid_t pid = getpid(); pid_t fork_pid; int pipefd[2];//0:reading, 1:writing pipe(pipefd); ate_printf(MSG_INFO,"Pid of ated: %d\n",pid); fork_pid = fork(); if(fork_pid==0){ char *argv[] = {"ps",NULL/*"-AL"*/,NULL}; close(pipefd[0]); //children only DO write data dup2(pipefd[1],1); dup2(pipefd[1],2); execvp("ps", argv); exit(0); }else{ /* Wait exec finish */ char buffer[2048]; char line[256]; char ate_pid[16]; unsigned char exist_ate = 0; close(pipefd[1]); while(read(pipefd[0],buffer, sizeof(buffer)) != 0){ char *eol = os_strchr(buffer, '\n'); char *tmp = buffer; while(eol){ int dif = eol - tmp + 1; os_memset(line, '\0', 256); os_memcpy(line, tmp, dif); if(os_strstr(line, "ated")){ int distance = 0; int dif2 = 0; char *l; ate_printf(MSG_DEBUG,"Parsing line: %s\n", line); repeat_parse: l = os_strchr(line+distance,' '); if(!l) break; ate_printf(MSG_DEBUG,"Line: 0x%x, l: 0x%x\n", line, l); dif2 = l - line -distance; distance += dif2; /* The first char is space */ if(dif2 == 0){ distance += 1; goto repeat_parse; } if((dif2) > 16){ ate_printf(MSG_DEBUG,"String too long for pid, continue to parse, [%s]\n",ate_pid); goto repeat_parse; } os_memset(ate_pid, 0, 16); os_memcpy(ate_pid, l - dif2, dif2); //For delete appending space ate_printf(MSG_DEBUG,"ate_pid: %s\n",ate_pid); exist_ate = 1; do{ int pid_found = 0; int ret = -1; sscanf(ate_pid,"%d", &pid_found); if(pid_found != pid){ ate_printf(MSG_DEBUG,"!pid_found: %d\n",pid_found); ret = kill((pid_t)pid_found, SIGHUP); if(ret) ate_printf(MSG_ERROR,"kill process %d fail\n",pid_found); else ate_printf(MSG_INFO, "kill process %d success\n",pid_found); } }while(0); } tmp += dif; eol = os_strchr(tmp, '\n'); } } close(pipefd[0]); waitpid(fork_pid, 0, 0); close(pipefd[1]); } }
static void wps_er_ssdp_rx(int sd, void *eloop_ctx, void *sock_ctx) { struct wps_er *er = eloop_ctx; struct sockaddr_in addr; /* client address */ socklen_t addr_len; int nread; char buf[MULTICAST_MAX_READ], *pos, *pos2, *start; int wfa = 0, byebye = 0; int max_age = -1; char *location = NULL; u8 uuid[WPS_UUID_LEN]; addr_len = sizeof(addr); nread = recvfrom(sd, buf, sizeof(buf) - 1, 0, (struct sockaddr *) &addr, &addr_len); if (nread <= 0) return; buf[nread] = '\0'; if (er->filter_addr.s_addr && er->filter_addr.s_addr != addr.sin_addr.s_addr) return; wpa_printf(MSG_DEBUG, "WPS ER: Received SSDP from %s", inet_ntoa(addr.sin_addr)); wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Received SSDP contents", (u8 *) buf, nread); if (sd == er->multicast_sd) { /* Reply to M-SEARCH */ if (os_strncmp(buf, "HTTP/1.1 200 OK", 15) != 0) return; /* unexpected response header */ } else { /* Unsolicited message (likely NOTIFY or M-SEARCH) */ if (os_strncmp(buf, "NOTIFY ", 7) != 0) return; /* only process notifications */ } os_memset(uuid, 0, sizeof(uuid)); for (start = buf; start && *start; start = pos) { pos = os_strchr(start, '\n'); if (pos) { if (pos[-1] == '\r') pos[-1] = '\0'; *pos++ = '\0'; } if (os_strstr(start, "schemas-wifialliance-org:device:" "WFADevice:1")) wfa = 1; if (os_strstr(start, "schemas-wifialliance-org:service:" "WFAWLANConfig:1")) wfa = 1; if (os_strncasecmp(start, "LOCATION:", 9) == 0) { start += 9; while (*start == ' ') start++; location = start; } else if (os_strncasecmp(start, "NTS:", 4) == 0) { if (os_strstr(start, "ssdp:byebye")) byebye = 1; } else if (os_strncasecmp(start, "CACHE-CONTROL:", 14) == 0) { start += 9; while (*start == ' ') start++; pos2 = os_strstr(start, "max-age="); if (pos2 == NULL) continue; pos2 += 8; max_age = atoi(pos2); } else if (os_strncasecmp(start, "USN:", 4) == 0) { start += 4; pos2 = os_strstr(start, "uuid:"); if (pos2) { pos2 += 5; while (*pos2 == ' ') pos2++; if (uuid_str2bin(pos2, uuid) < 0) { wpa_printf(MSG_DEBUG, "WPS ER: " "Invalid UUID in USN: %s", pos2); return; } } } } if (!wfa) return; /* Not WPS advertisement/reply */ if (byebye) { wps_er_ap_cache_settings(er, &addr.sin_addr); wps_er_ap_remove(er, &addr.sin_addr); return; } if (!location) return; /* Unknown location */ if (max_age < 1) return; /* No max-age reported */ wpa_printf(MSG_DEBUG, "WPS ER: AP discovered: %s " "(packet source: %s max-age: %d)", location, inet_ntoa(addr.sin_addr), max_age); wps_er_ap_add(er, uuid, &addr.sin_addr, location, max_age); }
/** * eap_peer_select_phase2_methods - Select phase 2 EAP method * @config: Pointer to the network configuration * @prefix: 'phase2' configuration prefix, e.g., "auth=" * @types: Buffer for returning allocated list of allowed EAP methods * @num_types: Buffer for returning number of allocated EAP methods * Returns: 0 on success, -1 on failure * * This function is used to parse EAP method list and select allowed methods * for Phase2 authentication. */ int eap_peer_select_phase2_methods(struct eap_peer_config *config, const char *prefix, struct eap_method_type **types, size_t *num_types) { char *start, *pos, *buf; struct eap_method_type *methods = NULL, *_methods; u32 method; size_t num_methods = 0, prefix_len; if (config == NULL || config->phase2 == NULL) goto get_defaults; start = buf = os_strdup(config->phase2); if (buf == NULL) return -1; prefix_len = os_strlen(prefix); while (start && *start != '\0') { int vendor; pos = os_strstr(start, prefix); if (pos == NULL) break; if (start != pos && *(pos - 1) != ' ') { start = pos + prefix_len; continue; } start = pos + prefix_len; pos = os_strchr(start, ' '); if (pos) *pos++ = '\0'; method = eap_get_phase2_type(start, &vendor); if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) { wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP " "method '%s'", start); } else { num_methods++; _methods = os_realloc_array(methods, num_methods, sizeof(*methods)); if (_methods == NULL) { os_free(methods); os_free(buf); return -1; } methods = _methods; methods[num_methods - 1].vendor = vendor; methods[num_methods - 1].method = method; } start = pos; } os_free(buf); get_defaults: if (methods == NULL) methods = eap_get_phase2_types(config, &num_methods); if (methods == NULL) { wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available"); return -1; } wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types", (u8 *) methods, num_methods * sizeof(struct eap_method_type)); *types = methods; *num_types = num_methods; return 0; }
static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, struct eap_method_ret *ret, const struct wpabuf *reqData) { const struct eap_hdr *req; size_t left; int res; u8 flags, id; struct wpabuf *resp; const u8 *pos; struct eap_fast_data *data = priv; pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_FAST, ret, reqData, &left, &flags); if (pos == NULL) return NULL; req = wpabuf_head(reqData); id = req->identifier; if (flags & EAP_TLS_FLAGS_START) { if (eap_fast_process_start(sm, data, flags, pos, left) < 0) return NULL; left = 0; /* A-ID is not used in further packet processing */ } resp = NULL; if (tls_connection_established(sm->ssl_ctx, data->ssl.conn) && !data->resuming) { /* Process tunneled (encrypted) phase 2 data. */ struct wpabuf msg; wpabuf_set(&msg, pos, left); res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp); if (res < 0) { ret->methodState = METHOD_DONE; ret->decision = DECISION_FAIL; /* * Ack possible Alert that may have caused failure in * decryption. */ res = 1; } } else { /* Continue processing TLS handshake (phase 1). */ res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST, data->fast_version, id, pos, left, &resp); if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { char cipher[80]; wpa_printf(MSG_DEBUG, "EAP-FAST: TLS done, proceed to Phase 2"); if (data->provisioning && (!(data->provisioning_allowed & EAP_FAST_PROV_AUTH) || tls_get_cipher(sm->ssl_ctx, data->ssl.conn, cipher, sizeof(cipher)) < 0 || os_strstr(cipher, "ADH-") || os_strstr(cipher, "anon"))) { wpa_printf(MSG_DEBUG, "EAP-FAST: Using " "anonymous (unauthenticated) " "provisioning"); data->anon_provisioning = 1; } else data->anon_provisioning = 0; data->resuming = 0; eap_fast_derive_keys(sm, data); } if (res == 2) { struct wpabuf msg; /* * Application data included in the handshake message. */ wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = resp; resp = NULL; wpabuf_set(&msg, pos, left); res = eap_fast_decrypt(sm, data, ret, req, &msg, &resp); } } if (res == 1) { wpabuf_free(resp); return eap_peer_tls_build_ack(id, EAP_TYPE_FAST, data->fast_version); } return resp; }
u16 wps_config_methods_str2bin(const char *str) { u16 methods = 0; if (str == NULL || str[0] == '\0') { /* Default to enabling methods based on build configuration */ methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD; methods |= WPS_CONFIG_VIRT_DISPLAY; #ifdef CONFIG_WPS_NFC methods |= WPS_CONFIG_NFC_INTERFACE; #endif /* CONFIG_WPS_NFC */ #ifdef CONFIG_P2P methods |= WPS_CONFIG_P2PS; #endif /* CONFIG_P2P */ } else { if (os_strstr(str, "ethernet")) methods |= WPS_CONFIG_ETHERNET; if (os_strstr(str, "label")) methods |= WPS_CONFIG_LABEL; if (os_strstr(str, "display")) methods |= WPS_CONFIG_DISPLAY; if (os_strstr(str, "ext_nfc_token")) methods |= WPS_CONFIG_EXT_NFC_TOKEN; if (os_strstr(str, "int_nfc_token")) methods |= WPS_CONFIG_INT_NFC_TOKEN; if (os_strstr(str, "nfc_interface")) methods |= WPS_CONFIG_NFC_INTERFACE; if (os_strstr(str, "push_button")) methods |= WPS_CONFIG_PUSHBUTTON; if (os_strstr(str, "keypad")) methods |= WPS_CONFIG_KEYPAD; if (os_strstr(str, "virtual_display")) methods |= WPS_CONFIG_VIRT_DISPLAY; if (os_strstr(str, "physical_display")) methods |= WPS_CONFIG_PHY_DISPLAY; if (os_strstr(str, "virtual_push_button")) methods |= WPS_CONFIG_VIRT_PUSHBUTTON; if (os_strstr(str, "physical_push_button")) methods |= WPS_CONFIG_PHY_PUSHBUTTON; if (os_strstr(str, "p2ps")) methods |= WPS_CONFIG_P2PS; } return methods; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos, *end; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; int nfc = 0; u8 pkhash[WPS_OOB_PUBKEY_HASH_LEN]; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; if (cfg.pin_len == 6 && os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) { cfg.pin = NULL; cfg.pin_len = 0; nfc = 1; } } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } pos = os_strstr(phase1, "dev_pw_id="); if (pos) { u16 id = atoi(pos + 10); if (id == DEV_PW_NFC_CONNECTION_HANDOVER) nfc = 1; if (cfg.pin || id == DEV_PW_NFC_CONNECTION_HANDOVER) cfg.dev_pw_id = id; } if (cfg.pin == NULL && !cfg.pbc && !nfc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, " pkhash="); if (pos) { size_t len; pos += 8; end = os_strchr(pos, ' '); if (end) len = end - pos; else len = os_strlen(pos); if (len != 2 * WPS_OOB_PUBKEY_HASH_LEN || hexstr2bin(pos, pkhash, WPS_OOB_PUBKEY_HASH_LEN)) { wpa_printf(MSG_INFO, "EAP-WSC: Invalid pkhash"); os_free(data); return NULL; } cfg.peer_pubkey_hash = pkhash; } res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); wpa_printf(MSG_DEBUG, "EAP-WSC: Failed to parse new AP " "settings"); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); wpa_printf(MSG_DEBUG, "EAP-WSC: wps_init failed"); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, NULL, cfg.pin, cfg.pin_len, 0); } /* Use reduced client timeout for WPS to avoid long wait */ if (sm->ClientTimeout > 30) sm->ClientTimeout = 30; return data; }
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding //path in the filesystem and if it exists, passes the file through. This simulates what a normal //webserver would do with static files. int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) { EspFsFile *file=connData->cgiData; int len; char buff[1024]; char acceptEncodingBuffer[64]; int isGzip; if (connData->conn==NULL) { //Connection aborted. Clean up. espFsClose(file); return HTTPD_CGI_DONE; } if (file==NULL) { //First call to this cgi. Open the file so we can read it. file=espFsOpen(connData->url); if (file==NULL) { return HTTPD_CGI_NOTFOUND; } // The gzip checking code is intentionally without #ifdefs because checking // for FLAG_GZIP (which indicates gzip compressed file) is very easy, doesn't // mean additional overhead and is actually safer to be on at all times. // If there are no gzipped files in the image, the code bellow will not cause any harm. // Check if requested file was GZIP compressed isGzip = espFsFlags(file) & FLAG_GZIP; if (isGzip) { // Check the browser's "Accept-Encoding" header. If the client does not // advertise that he accepts GZIP send a warning message (telnet users for e.g.) httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64); if (os_strstr(acceptEncodingBuffer, "gzip") == NULL) { //No Accept-Encoding: gzip header present httpdSend(connData, gzipNonSupportedMessage, -1); espFsClose(file); return HTTPD_CGI_DONE; } } connData->cgiData=file; httpdStartResponse(connData, 200); httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url)); if (isGzip) { httpdHeader(connData, "Content-Encoding", "gzip"); } httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate"); httpdEndHeaders(connData); return HTTPD_CGI_MORE; } len=espFsRead(file, buff, 1024); if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len); if (len!=1024) { //We're done. espFsClose(file); return HTTPD_CGI_DONE; } else { //Ok, till next time. return HTTPD_CGI_MORE; } }
static void wpa_cli_action_process(const char *msg) { const char *pos; char *copy = NULL, *id, *pos2; pos = msg; if (*pos == '<') { /* skip priority */ pos = os_strchr(pos, '>'); if (pos) pos++; else pos = msg; } if (str_match(pos, WPA_EVENT_CONNECTED)) { int new_id = -1; os_unsetenv("WPA_ID"); os_unsetenv("WPA_ID_STR"); os_unsetenv("WPA_CTRL_DIR"); pos = os_strstr(pos, "[id="); if (pos) copy = os_strdup(pos + 4); if (copy) { pos2 = id = copy; while (*pos2 && *pos2 != ' ') pos2++; *pos2++ = '\0'; new_id = atoi(id); os_setenv("WPA_ID", id, 1); while (*pos2 && *pos2 != '=') pos2++; if (*pos2 == '=') pos2++; id = pos2; while (*pos2 && *pos2 != ']') pos2++; *pos2 = '\0'; os_setenv("WPA_ID_STR", id, 1); os_free(copy); } os_setenv("WPA_CTRL_DIR", ctrl_iface_dir, 1); if (!wpa_cli_connected || new_id != wpa_cli_last_id) { wpa_cli_connected = 1; wpa_cli_last_id = new_id; wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED"); } } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { if (wpa_cli_connected) { wpa_cli_connected = 0; wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED"); } } else if (str_match(pos, WPA_EVENT_TERMINATING)) { printf("wpa_supplicant is terminating - stop monitoring\n"); wpa_cli_quit = 1; } }
struct ctrl_iface_priv * wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) { struct ctrl_iface_priv *priv; struct sockaddr_un addr; char *fname = NULL; gid_t gid = 0; int gid_set = 0; char *buf, *dir = NULL, *gid_str = NULL; struct group *grp; char *endp; priv = os_zalloc(sizeof(*priv)); if (priv == NULL) return NULL; priv->wpa_s = wpa_s; priv->sock = -1; if (wpa_s->conf->ctrl_interface == NULL) return priv; buf = os_strdup(wpa_s->conf->ctrl_interface); if (buf == NULL) goto fail; if (os_strncmp(buf, "DIR=", 4) == 0) { dir = buf + 4; gid_str = os_strstr(dir, " GROUP="); if (gid_str) { *gid_str = '\0'; gid_str += 7; } } else { dir = buf; gid_str = wpa_s->conf->ctrl_interface_group; } wpa_supplicant_create_directory_path(dir); if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) { if (errno == EEXIST) { wpa_printf(MSG_DEBUG, "Using existing control " "interface directory."); } else { perror("mkdir[ctrl_interface]"); goto fail; } } if (gid_str) { grp = getgrnam(gid_str); if (grp) { gid = grp->gr_gid; gid_set = 1; wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" " (from group name '%s')", (int) gid, gid_str); } else { /* Group name not found - try to parse this as gid */ gid = strtol(gid_str, &endp, 10); if (*gid_str == '\0' || *endp != '\0') { wpa_printf(MSG_DEBUG, "CTRL: Invalid group " "'%s'", gid_str); goto fail; } gid_set = 1; wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", (int) gid); } } if (gid_set && chown(dir, -1, gid) < 0) { perror("chown[ctrl_interface]"); goto fail; } if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >= sizeof(addr.sun_path)) goto fail; priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); if (priv->sock < 0) { perror("socket(PF_UNIX)"); goto fail; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; fname = wpa_supplicant_ctrl_iface_path(wpa_s); if (fname == NULL) goto fail; /* An existing socket could indicate that we are trying to run * program twice, but more likely it is left behind when a previous * instance crashed... remove it to be safe. */ (void) unlink(fname); wpa_supplicant_create_directory_path(fname); os_strncpy(addr.sun_path, fname, sizeof(addr.sun_path)); if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", strerror(errno)); if (connect(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" " allow connections - assuming it was left" "over from forced program termination"); if (unlink(fname) < 0) { perror("unlink[ctrl_iface]"); wpa_printf(MSG_ERROR, "Could not unlink " "existing ctrl_iface socket '%s'", fname); goto fail; } if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("bind(PF_UNIX)"); goto fail; } wpa_printf(MSG_DEBUG, "Successfully replaced leftover " "ctrl_iface socket '%s'", fname); } else { wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " "be in use - cannot override it"); wpa_printf(MSG_INFO, "Delete '%s' manually if it is " "not used anymore", fname); os_free(fname); fname = NULL; goto fail; } } if (gid_set && chown(fname, -1, gid) < 0) { perror("chown[ctrl_interface/ifname]"); goto fail; } if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { perror("chmod[ctrl_interface/ifname]"); goto fail; } os_free(fname); eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, wpa_s, priv); wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); os_free(buf); return priv; fail: if (priv->sock >= 0) close(priv->sock); os_free(priv); if (fname) { unlink(fname); os_free(fname); } os_free(buf); return NULL; }
static void wps_er_parse_device_description(struct wps_er_ap *ap, struct wpabuf *reply) { /* Note: reply includes null termination after the buffer data */ const char *tmp, *data = wpabuf_head(reply); char *pos; wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Device info", wpabuf_head(reply), wpabuf_len(reply)); /* * The root device description may include multiple devices, so first * find the beginning of the WFADevice description to allow the * simplistic parser to pick the correct entries. */ tmp = wps_er_find_wfadevice(data); if (tmp == NULL) { wpa_printf(MSG_DEBUG, "WPS ER: WFADevice:1 device not found - " "trying to parse invalid data"); } else data = tmp; ap->friendly_name = xml_get_first_item(data, "friendlyName"); wpa_printf(MSG_DEBUG, "WPS ER: friendlyName='%s'", ap->friendly_name); ap->manufacturer = xml_get_first_item(data, "manufacturer"); wpa_printf(MSG_DEBUG, "WPS ER: manufacturer='%s'", ap->manufacturer); ap->manufacturer_url = xml_get_first_item(data, "manufacturerURL"); wpa_printf(MSG_DEBUG, "WPS ER: manufacturerURL='%s'", ap->manufacturer_url); ap->model_description = xml_get_first_item(data, "modelDescription"); wpa_printf(MSG_DEBUG, "WPS ER: modelDescription='%s'", ap->model_description); ap->model_name = xml_get_first_item(data, "modelName"); wpa_printf(MSG_DEBUG, "WPS ER: modelName='%s'", ap->model_name); ap->model_number = xml_get_first_item(data, "modelNumber"); wpa_printf(MSG_DEBUG, "WPS ER: modelNumber='%s'", ap->model_number); ap->model_url = xml_get_first_item(data, "modelURL"); wpa_printf(MSG_DEBUG, "WPS ER: modelURL='%s'", ap->model_url); ap->serial_number = xml_get_first_item(data, "serialNumber"); wpa_printf(MSG_DEBUG, "WPS ER: serialNumber='%s'", ap->serial_number); ap->udn = xml_get_first_item(data, "UDN"); wpa_printf(MSG_DEBUG, "WPS ER: UDN='%s'", ap->udn); pos = os_strstr(ap->udn, "uuid:"); if (pos) { pos += 5; if (uuid_str2bin(pos, ap->uuid) < 0) wpa_printf(MSG_DEBUG, "WPS ER: Invalid UUID in UDN"); } ap->upc = xml_get_first_item(data, "UPC"); wpa_printf(MSG_DEBUG, "WPS ER: UPC='%s'", ap->upc); ap->scpd_url = http_link_update( xml_get_first_item(data, "SCPDURL"), ap->location); wpa_printf(MSG_DEBUG, "WPS ER: SCPDURL='%s'", ap->scpd_url); ap->control_url = http_link_update( xml_get_first_item(data, "controlURL"), ap->location); wpa_printf(MSG_DEBUG, "WPS ER: controlURL='%s'", ap->control_url); ap->event_sub_url = http_link_update( xml_get_first_item(data, "eventSubURL"), ap->location); wpa_printf(MSG_DEBUG, "WPS ER: eventSubURL='%s'", ap->event_sub_url); }
static void * eap_ttls_init(struct eap_sm *sm) { struct eap_ttls_data *data; struct wpa_ssid *config = eap_get_config(sm); char *selected; data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->ttls_version = EAP_TTLS_VERSION; data->force_ttls_version = -1; selected = "EAP"; data->phase2_type = EAP_TTLS_PHASE2_EAP; if (config && config->phase1) { char *pos = os_strstr(config->phase1, "ttlsver="); if (pos) { data->force_ttls_version = atoi(pos + 8); data->ttls_version = data->force_ttls_version; wpa_printf(MSG_DEBUG, "EAP-TTLS: Forced TTLS version " "%d", data->force_ttls_version); } } if (config && config->phase2) { if (os_strstr(config->phase2, "autheap=")) { selected = "EAP"; data->phase2_type = EAP_TTLS_PHASE2_EAP; } else if (os_strstr(config->phase2, "auth=MSCHAPV2")) { selected = "MSCHAPV2"; data->phase2_type = EAP_TTLS_PHASE2_MSCHAPV2; } else if (os_strstr(config->phase2, "auth=MSCHAP")) { selected = "MSCHAP"; data->phase2_type = EAP_TTLS_PHASE2_MSCHAP; } else if (os_strstr(config->phase2, "auth=PAP")) { selected = "PAP"; data->phase2_type = EAP_TTLS_PHASE2_PAP; } else if (os_strstr(config->phase2, "auth=CHAP")) { selected = "CHAP"; data->phase2_type = EAP_TTLS_PHASE2_CHAP; } } wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 type: %s", selected); if (data->phase2_type == EAP_TTLS_PHASE2_EAP) { if (config && config->phase2) { char *start, *pos, *buf; struct eap_method_type *methods = NULL, *_methods; u8 method; size_t num_methods = 0; start = buf = os_strdup(config->phase2); if (buf == NULL) { eap_ttls_deinit(sm, data); return NULL; } while (start && *start != '\0') { int vendor; pos = os_strstr(start, "autheap="); if (pos == NULL) break; if (start != pos && *(pos - 1) != ' ') { start = pos + 8; continue; } start = pos + 8; pos = os_strchr(start, ' '); if (pos) *pos++ = '\0'; method = eap_get_phase2_type(start, &vendor); if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) { wpa_printf(MSG_ERROR, "EAP-TTLS: " "Unsupported Phase2 EAP " "method '%s'", start); } else { num_methods++; _methods = os_realloc( methods, num_methods * sizeof(*methods)); if (_methods == NULL) { os_free(methods); os_free(buf); eap_ttls_deinit(sm, data); return NULL; } methods = _methods; methods[num_methods - 1].vendor = vendor; methods[num_methods - 1].method = method; } start = pos; } os_free(buf); data->phase2_eap_types = methods; data->num_phase2_eap_types = num_methods; } if (data->phase2_eap_types == NULL) { data->phase2_eap_types = eap_get_phase2_types( config, &data->num_phase2_eap_types); } if (data->phase2_eap_types == NULL) { wpa_printf(MSG_ERROR, "EAP-TTLS: No Phase2 EAP method " "available"); eap_ttls_deinit(sm, data); return NULL; } wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Phase2 EAP types", (u8 *) data->phase2_eap_types, data->num_phase2_eap_types * sizeof(struct eap_method_type)); data->phase2_eap_type.vendor = EAP_VENDOR_IETF; data->phase2_eap_type.method = EAP_TYPE_NONE; } if (!(tls_capabilities(sm->ssl_ctx) & TLS_CAPABILITY_IA) && data->ttls_version > 0) { if (data->force_ttls_version > 0) { wpa_printf(MSG_INFO, "EAP-TTLS: Forced TTLSv%d and " "TLS library does not support TLS/IA.", data->force_ttls_version); eap_ttls_deinit(sm, data); return NULL; } data->ttls_version = 0; } return data; }
//*********************************************************************** void ICACHE_FLASH_ATTR webSocketRecvCb(void *arg, char *data, unsigned short len) { espconn *esp_connection = (espconn*)arg; //received some data from webSocket connection //webSocketDebug("In webSocketRecvCb\n"); // webSocketDebug("webSocket recv--->%s<----\n", data); WSConnection *wsConnection = getWsConnection(esp_connection); if (wsConnection == NULL) { webSocketDebug("webSocket Heh?\n"); return; } //get the first occurrence of the key identifier char *key = os_strstr(data, WS_KEY_IDENTIFIER); // webSocketDebug("key-->%s<--\n", key ); if (key != NULL) { // ------------------------ Handle the Handshake ------------------------ // webSocketDebug("In Handle the Handshake\n"); //Skip the identifier (that contains the space already) key += os_strlen(WS_KEY_IDENTIFIER); // webSocketDebug("keynow-->%s<--\n", key); //the key ends at the newline char *endSequence = os_strstr(key, HTML_HEADER_LINEEND); // webSocketDebug("endSequency-->%s<--\n", endSequence); if (endSequence != NULL) { int keyLastChar = endSequence - key; //we can throw away all the other data, only the key is interesting key[keyLastChar] = '\0'; // webSocketDebug("keyTrimmed-->%s<--\n", key); char acceptKey[100]; createWsAcceptKey(key, acceptKey, 100); // webSocketDebug("acceptKey-->%s<--\n", acceptKey); //now construct our message and send it back to the client char responseMessage[strlen(WS_RESPONSE) + 100]; os_sprintf(responseMessage, WS_RESPONSE, acceptKey); // webSocketDebug("responseMessage-->%s<--\n", responseMessage); //send the response espconn_sent(esp_connection, (uint8_t *)responseMessage, strlen(responseMessage)); wsConnection->status = STATUS_OPEN; //call the connection callback if (wsOnConnectionCallback != NULL) { // webSocketDebug("Handle the Handshake 5\n"); wsOnConnectionCallback(); } } } else { // ------------------------ Handle a Frame ------------------------ // webSocketDebug("In Handle a Frame\n"); WSFrame frame; parseWsFrame(data, &frame); if (frame.isMasked) { unmaskWsPayload(frame.payloadData, frame.payloadLength, frame.maskingKey); } else { //we are the server, and need to shut down the connection //if we receive an unmasked packet // webSocketDebug("frame.isMasked=false closing connection\n"); closeWsConnection(wsConnection); return; } // webSocketDebug("frame.payloadData-->%s<--\n", frame.payloadData); if (frame.opcode == OPCODE_PING) { // webSocketDebug("frame.opcode=OPCODE_PING\n"); sendWsMessage(wsConnection, frame.payloadData, frame.payloadLength, FLAG_FIN | OPCODE_PONG); return; } if (frame.opcode == OPCODE_CLOSE) { //gracefully shut down the connection // webSocketDebug("frame.opcode=OPCODE_CLOSE, closeing connection\n"); closeWsConnection(wsConnection); return; } if (wsConnection->onMessage != NULL) { wsConnection->onMessage(frame.payloadData); } } // webSocketDebug("Leaving webSocketRecvCb\n"); }
LOCAL ICACHE_FLASH_ATTR void parse_url(char *precv, URL_Frame *purl_frame) { char *str = NULL; uint8 length = 0; char *pbuffer = NULL; char *pbufer = NULL; if (purl_frame == NULL || precv == NULL) { return; } pbuffer = (char *)os_strstr(precv, "Host:"); if (pbuffer != NULL) { length = pbuffer - precv; pbufer = (char *)os_zalloc(length + 1); pbuffer = pbufer; os_memcpy(pbuffer, precv, length); os_memset(purl_frame->pSelect, 0, URLSize); os_memset(purl_frame->pCommand, 0, URLSize); os_memset(purl_frame->pFilename, 0, URLSize); if (os_strncmp(pbuffer, "GET ", 4) == 0) { purl_frame->Type = GET; pbuffer += 4; } else if (os_strncmp(pbuffer, "POST ", 5) == 0) { purl_frame->Type = POST; pbuffer += 5; } pbuffer ++; str = (char *)os_strstr(pbuffer, "?"); if (str != NULL) { length = str - pbuffer; os_memcpy(purl_frame->pSelect, pbuffer, length); str ++; pbuffer = (char *)os_strstr(str, "="); if (pbuffer != NULL) { length = pbuffer - str; os_memcpy(purl_frame->pCommand, str, length); pbuffer ++; str = (char *)os_strstr(pbuffer, "&"); if (str != NULL) { length = str - pbuffer; os_memcpy(purl_frame->pFilename, pbuffer, length); } else { str = (char *)os_strstr(pbuffer, " HTTP"); if (str != NULL) { length = str - pbuffer; os_memcpy(purl_frame->pFilename, pbuffer, length); } } } } os_free(pbufer); } else { return; } }
static int eap_wsc_new_ap_settings(struct wps_credential *cred, const char *params) { const char *pos, *end; size_t len; os_memset(cred, 0, sizeof(*cred)); pos = os_strstr(params, "new_ssid="); if (pos == NULL) return 0; pos += 9; end = os_strchr(pos, ' '); if (end == NULL) len = os_strlen(pos); else len = end - pos; if ((len & 1) || len > 2 * sizeof(cred->ssid) || hexstr2bin(pos, cred->ssid, len / 2)) return -1; cred->ssid_len = len / 2; pos = os_strstr(params, "new_auth="); if (pos == NULL) return -1; if (os_strncmp(pos + 9, "OPEN", 4) == 0) cred->auth_type = WPS_AUTH_OPEN; else if (os_strncmp(pos + 9, "WPAPSK", 6) == 0) cred->auth_type = WPS_AUTH_WPAPSK; else if (os_strncmp(pos + 9, "WPA2PSK", 7) == 0) cred->auth_type = WPS_AUTH_WPA2PSK; else return -1; pos = os_strstr(params, "new_encr="); if (pos == NULL) return -1; if (os_strncmp(pos + 9, "NONE", 4) == 0) cred->encr_type = WPS_ENCR_NONE; else if (os_strncmp(pos + 9, "WEP", 3) == 0) cred->encr_type = WPS_ENCR_WEP; else if (os_strncmp(pos + 9, "TKIP", 4) == 0) cred->encr_type = WPS_ENCR_TKIP; else if (os_strncmp(pos + 9, "CCMP", 4) == 0) cred->encr_type = WPS_ENCR_AES; else return -1; pos = os_strstr(params, "new_key="); if (pos == NULL) return 0; pos += 8; end = os_strchr(pos, ' '); if (end == NULL) len = os_strlen(pos); else len = end - pos; if ((len & 1) || len > 2 * sizeof(cred->key) || hexstr2bin(pos, cred->key, len / 2)) return -1; cred->key_len = len / 2; return 1; }
//Parse a line of header data and modify the connection data accordingly. static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { int i; char first_line = false; if (os_strncmp(h, "GET ", 4)==0) { conn->requestType = HTTPD_METHOD_GET; first_line = true; } else if (os_strncmp(h, "POST ", 5)==0) { conn->requestType = HTTPD_METHOD_POST; first_line = true; } if (first_line) { char *e; //Skip past the space after POST/GET i=0; while (h[i]!=' ') i++; conn->url=h+i+1; //Figure out end of url. e=(char*)os_strstr(conn->url, " "); if (e==NULL) return; //wtf? *e=0; //terminate url part os_printf("URL = %s\n", conn->url); //Parse out the URL part before the GET parameters. conn->getArgs=(char*)os_strstr(conn->url, "?"); if (conn->getArgs!=0) { *conn->getArgs=0; conn->getArgs++; os_printf("GET args = %s\n", conn->getArgs); } else { conn->getArgs=NULL; } } else if (os_strncmp(h, "Content-Length:", 15)==0) { i=15; //Skip trailing spaces while (h[i]==' ') i++; //Get POST data length conn->post->len=atoi(h+i); // Allocate the buffer if (conn->post->len > MAX_POST) { // we'll stream this in in chunks conn->post->buffSize = MAX_POST; } else { conn->post->buffSize = conn->post->len; } os_printf("Mallocced buffer for %d + 1 bytes of post data.\n", conn->post->buffSize); conn->post->buff=(char*)os_malloc(conn->post->buffSize + 1); conn->post->buffLen=0; } else if (os_strncmp(h, "Content-Type: ", 14)==0) { if (os_strstr(h, "multipart/form-data")) { // It's multipart form data so let's pull out the boundary for future use char *b; if ((b = os_strstr(h, "boundary=")) != NULL) { conn->post->multipartBoundary = b + 7; // move the pointer 2 chars before boundary then fill them with dashes conn->post->multipartBoundary[0] = '-'; conn->post->multipartBoundary[1] = '-'; os_printf("boundary = %s\n", conn->post->multipartBoundary); } } } }
/****************************************************************************** * FunctionName : user_devicefind_recv * Description : Processing the received data from the host * Parameters : arg -- Additional argument to pass to the callback function * pusrdata -- The received data (or NULL when the connection has been closed!) * length -- The length of received data * Returns : none *******************************************************************************/ LOCAL void ICACHE_FLASH_ATTR discovery_recv(void *arg, char *pusrdata, unsigned short length) { int packet_len; int8 ip[16] = { 0 }; struct ip_info ipconfig; DISCOVERY_OBJECT *handle = instance(); if ((NULL == handle) || (NULL == pusrdata)) { return; } /* 收到的消息格式 没有ts { "method":"down_msg", "req_id":123456789, "cmd":"dev_search" } */ if (NULL == os_strstr(pusrdata, "dev_search")) { os_printf("wrong msg format %s \n", pusrdata); return; } /* { "method":"up_msg", "req_id":123456789, "code":0, "attribute": { "dev_uuid":"01001122334455", "ip":"192.168.10.10", "port":60018 } } */ #define JSON_DISCOVERY_RESPONSE "{\ \"method\":\"up_msg\",\ \"req_id\":%d,\ \"code\":0,\ \"attribute\":\ {\ \"dev_uuid\":\"%s\",\ \"ip\":\"%s\",\ \"port\":%d\ }\ }" // send to local network(staticon). os_memset(&ipconfig, 0, sizeof(struct ip_info)); wifi_get_ip_info(STATION_IF, &ipconfig); os_memset(ip, 0, sizeof(ip)); os_sprintf(ip, "%d.%d.%d.%d", IP2STR(&ipconfig.ip)); //os_printf("discovery: ip \n"); //os_printf(ip); if (os_strlen(ip) > 0) { os_memet(handle->out_buf, 0, MAX_RECV_BUF_LEN); os_sprintf(handle->out_buf, JSON_DISCOVERY_RESPONSE, (int)rand(), handle->dev_uuid, ip, handle->port); /* 不需要加密 */ packet_len = strlen(handle->out_buf); if (packet_len > 0) { espconn_sent(&handle->udp_conn, handle->out_buf, packet_len); } } // send to local network(ap mode). os_memset(&ipconfig, 0, sizeof(struct ip_info)); wifi_get_ip_info(SOFTAP_IF, &ipconfig); // os_memset(ip, 0, sizeof(ip)); os_sprintf(ip, "%d.%d.%d.%d", IP2STR(&ipconfig.ip)); if (os_strlen(ip) > 0) { os_memet(handle->out_buf, 0, MAX_RECV_BUF_LEN); os_sprintf(handle->out_buf, JSON_DISCOVERY_RESPONSE, (int)rand(), handle->dev_uuid, ip, handle->port); /* 不需要加密 */ packet_len = strlen(handle->out_buf); if (packet_len > 0) { espconn_sent(&handle->udp_conn, handle->out_buf, packet_len); } } }
/* httpdFindArg */ int ICACHE_FLASH_ATTR httpdFindArg(char * pszLine, char * pszArgument, char * pszBuffer, int cbBufferLength) { /* initialization */ int iRet = -1; char * pbBeginningOfArg = NULL; char * pbEndOfArg = NULL; if (NULL == pszLine) { iRet = 0; goto lblCleanup; } pbBeginningOfArg = pszLine; while ((NULL_STRING != pbBeginningOfArg) && ((*NEWLINE_SYMBOL_STRING) != *pbBeginningOfArg) && ((*NEWLINE_R_SYMBOL_STRING) != *pbBeginningOfArg) && (NULL_STRING != *pbBeginningOfArg)) { #ifdef HTTPD_DEBUG os_printf("httpdFindArg: %s\n", pbBeginningOfArg); #endif if ((0 == os_strncmp(pbBeginningOfArg, pszArgument, os_strlen(pszArgument))) && ((*EQUAL_SYMBOL_STRING) == pbBeginningOfArg[strlen(pszArgument)])) { pbBeginningOfArg += os_strlen(pszArgument) + 1; //move pbBeginningOfArg to start of value pbEndOfArg = (char *)os_strstr(pbBeginningOfArg, AMPERSAND_SYMBOL_STRING); if (NULL == pbEndOfArg) { pbEndOfArg = pbBeginningOfArg + os_strlen(pbBeginningOfArg); } #ifdef HTTPD_DEBUG os_printf("httpdFindArg: value: %s length: %d\n", pbBeginningOfArg, (pbEndOfArg - pbBeginningOfArg)); #endif iRet = httpdUrlDecode(pbBeginningOfArg, (pbEndOfArg - pbBeginningOfArg), pszBuffer, cbBufferLength); goto lblCleanup; } pbBeginningOfArg = (char *)os_strstr(pbBeginningOfArg, AMPERSAND_SYMBOL_STRING); if (NULL != pbBeginningOfArg) { pbBeginningOfArg += 1; } } /* not found */ #ifdef HTTPD_DEBUG os_printf("httpdFindArg: didn't find %s in %s\n", pszArgument, pszLine); #endif lblCleanup: return iRet; }
enum tncs_process_res tncs_process_if_tnccs(struct tncs_data *tncs, const u8 *msg, size_t len) { char *buf, *start, *end, *pos, *pos2, *payload; unsigned int batch_id; unsigned char *decoded; size_t decoded_len; buf = os_malloc(len + 1); if (buf == NULL) return TNCCS_PROCESS_ERROR; os_memcpy(buf, msg, len); buf[len] = '\0'; start = os_strstr(buf, "<TNCCS-Batch "); end = os_strstr(buf, "</TNCCS-Batch>"); if (start == NULL || end == NULL || start > end) { os_free(buf); return TNCCS_PROCESS_ERROR; } start += 13; while (*start == ' ') start++; *end = '\0'; pos = os_strstr(start, "BatchId="); if (pos == NULL) { os_free(buf); return TNCCS_PROCESS_ERROR; } pos += 8; if (*pos == '"') pos++; batch_id = atoi(pos); wpa_printf(MSG_DEBUG, "TNC: Received IF-TNCCS BatchId=%u", batch_id); if (batch_id != tncs->last_batchid + 1) { wpa_printf(MSG_DEBUG, "TNC: Unexpected IF-TNCCS BatchId " "%u (expected %u)", batch_id, tncs->last_batchid + 1); os_free(buf); return TNCCS_PROCESS_ERROR; } tncs->last_batchid = batch_id; while (*pos != '\0' && *pos != '>') pos++; if (*pos == '\0') { os_free(buf); return TNCCS_PROCESS_ERROR; } pos++; payload = start; /* * <IMC-IMV-Message> * <Type>01234567</Type> * <Base64>foo==</Base64> * </IMC-IMV-Message> */ while (*start) { char *endpos; unsigned int type; pos = os_strstr(start, "<IMC-IMV-Message>"); if (pos == NULL) break; start = pos + 17; end = os_strstr(start, "</IMC-IMV-Message>"); if (end == NULL) break; *end = '\0'; endpos = end; end += 18; if (tncs_get_type(start, &type) < 0) { *endpos = '<'; start = end; continue; } wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type); decoded = tncs_get_base64(start, &decoded_len); if (decoded == NULL) { *endpos = '<'; start = end; continue; } tncs_send_to_imvs(tncs, type, decoded, decoded_len); os_free(decoded); start = end; } /* * <TNCC-TNCS-Message> * <Type>01234567</Type> * <XML><TNCCS-Foo type="foo"></TNCCS-Foo></XML> * <Base64>foo==</Base64> * </TNCC-TNCS-Message> */ start = payload; while (*start) { unsigned int type; char *xml, *xmlend, *endpos; pos = os_strstr(start, "<TNCC-TNCS-Message>"); if (pos == NULL) break; start = pos + 19; end = os_strstr(start, "</TNCC-TNCS-Message>"); if (end == NULL) break; *end = '\0'; endpos = end; end += 20; if (tncs_get_type(start, &type) < 0) { *endpos = '<'; start = end; continue; } wpa_printf(MSG_DEBUG, "TNC: TNCC-TNCS-Message Type 0x%x", type); /* Base64 OR XML */ decoded = NULL; xml = NULL; xmlend = NULL; pos = os_strstr(start, "<XML>"); if (pos) { pos += 5; pos2 = os_strstr(pos, "</XML>"); if (pos2 == NULL) { *endpos = '<'; start = end; continue; } xmlend = pos2; xml = pos; } else { decoded = tncs_get_base64(start, &decoded_len); if (decoded == NULL) { *endpos = '<'; start = end; continue; } } if (decoded) { wpa_hexdump_ascii(MSG_MSGDUMP, "TNC: TNCC-TNCS-Message Base64", decoded, decoded_len); os_free(decoded); } if (xml) { wpa_hexdump_ascii(MSG_MSGDUMP, "TNC: TNCC-TNCS-Message XML", (unsigned char *) xml, xmlend - xml); } start = end; } os_free(buf); tncs_batch_ending(tncs); if (tncs_total_send_len(tncs) == 0) return tncs_derive_recommendation(tncs); return TNCCS_PROCESS_OK_NO_RECOMMENDATION; }
/************************************************ * name: httpdParseHeader * parameters: pszHeader - header data * ptConnection - connection data * return value: none * purpose: parse a line of header data and modify connection data accordingly ************************************************/ static void ICACHE_FLASH_ATTR httpdParseHeader(char * pszHeader, HttpdConnection * ptConnection) { /* initialization */ int iIndex = 0; char bIsFirstLine = false; if (0 == os_strncmp(pszHeader, "GET ", 4)) { ptConnection->bRequestType = HTTPD_METHOD_GET; bIsFirstLine = true; } else if (0 == os_strncmp(pszHeader, "POST ", 5)) { ptConnection->bRequestType = HTTPD_METHOD_POST; bIsFirstLine = true; } if (bIsFirstLine) { char * pbEndOfURL = NULL; /* skip past the space after POST/GET */ for (iIndex = 0; (*SPACE_SYMBOL_STRING) != pszHeader[iIndex]; ++iIndex); ptConnection->pszUrl = pszHeader + iIndex + 1; /* figure out end of url */ pbEndOfURL = (char *)os_strstr(ptConnection->pszUrl, SPACE_SYMBOL_STRING); if (NULL == pbEndOfURL) { return; } /* terminate url part */ *pbEndOfURL = 0; #ifdef HTTPD_DEBUG os_printf("httpdParseHeader: URL is %s\n", ptConnection->pszUrl); #endif /* parse URL part before the GET parameters */ ptConnection->pbGetArguments=(char *)os_strstr(ptConnection->pszUrl, QUERY_SYMBOL_STRING); if (0 != ptConnection->pbGetArguments) { *ptConnection->pbGetArguments = 0; ptConnection->pbGetArguments++; #ifdef HTTPD_DEBUG os_printf("httpdParseHeader: GET arguments are %s\n", ptConnection->pbGetArguments); #endif } else { ptConnection->pbGetArguments = NULL; } /* check if url is in url table */ for (iIndex = 0; (NULL != g_ptSupportedUrls[iIndex].pszUrl) && (NULL != ptConnection->pszUrl); ++iIndex) { char bIsMatch = 0; if (0 == os_strcmp(g_ptSupportedUrls[iIndex].pszUrl, ptConnection->pszUrl)) { bIsMatch = 1; } if (((*ASTERISK_SYMBOL_STRING) == g_ptSupportedUrls[iIndex].pszUrl[os_strlen(g_ptSupportedUrls[iIndex].pszUrl) - 1]) && ( 0 == os_strncmp(g_ptSupportedUrls[iIndex].pszUrl, ptConnection->pszUrl, os_strlen(g_ptSupportedUrls[iIndex].pszUrl) - 1))) { bIsMatch = 1; } if (1 == bIsMatch) { #ifdef HTTPD_DEBUG os_printf("httpdParseHeader: URL index is %d\n", iIndex); #endif ptConnection->pbCgiData = NULL; ptConnection->pfnCgi = g_ptSupportedUrls[iIndex].pfnCgi; ptConnection->pbCgiArguments = g_ptSupportedUrls[iIndex].pbCgiArguments; return; } } } else if (0 == os_strncmp(pszHeader, "Content-Length: ", 16)) { /* skip trailing spaces */ for (iIndex = 0; (*SPACE_SYMBOL_STRING) != pszHeader[iIndex]; ++iIndex); /* get POST data length */ ptConnection->ptPost->cbPostLength = atoi(pszHeader + iIndex + 1); /* allocate the buffer */ if(HTTPD_MAX_POST_LENGTH < ptConnection->ptPost->cbPostLength) { /* stream in chunks */ ptConnection->ptPost->cbMaxBufferSize = HTTPD_MAX_POST_LENGTH; } else { ptConnection->ptPost->cbMaxBufferSize = ptConnection->ptPost->cbPostLength; } #ifdef HTTPD_DEBUG os_printf("httpdParseHeader: allocated buffer for %d + 1 bytes of post data\n", ptConnection->ptPost->cbMaxBufferSize); #endif ptConnection->ptPost->pbBuffer=(char *)os_malloc(ptConnection->ptPost->cbMaxBufferSize + 1); ptConnection->ptPost->cbBufferLength = 0; } else if (0 == os_strncmp(pszHeader, "Content-Type: ", 14)) { if (0 != os_strstr(pszHeader, "multipart/form-data")) { /* multipart form data so let's pull out the boundary for future use */ char * pbBoundaryOffset = NULL; pbBoundaryOffset = os_strstr(pszHeader, "boundary="); if (NULL != pbBoundaryOffset) { /* move pointer 2 chars before boundary then fill with dashes */ ptConnection->ptPost->pbMultipartBoundary = pbBoundaryOffset + 7; ptConnection->ptPost->pbMultipartBoundary[0] = *DASH_SYMBOL_STRING; ptConnection->ptPost->pbMultipartBoundary[1] = *DASH_SYMBOL_STRING; #ifdef HTTPD_DEBUG os_printf("httpdParseHeader: boundary %s\n", ptConnection->ptPost->pbMultipartBoundary); #endif } } } }
static int eap_wsc_new_ap_settings(struct wps_credential *cred, const char *params) { const char *pos, *end; size_t len; os_memset(cred, 0, sizeof(*cred)); pos = os_strstr(params, "new_ssid="); if (pos == NULL) return 0; pos += 9; end = os_strchr(pos, ' '); if (end == NULL) len = os_strlen(pos); else len = end - pos; if ((len & 1) || len > 2 * sizeof(cred->ssid) || hexstr2bin(pos, cred->ssid, len / 2)) { wpa_printf(MSG_DEBUG, "EAP-WSC: Invalid new_ssid"); return -1; } cred->ssid_len = len / 2; pos = os_strstr(params, "new_auth="); if (pos == NULL) { wpa_printf(MSG_DEBUG, "EAP-WSC: Missing new_auth"); return -1; } if (os_strncmp(pos + 9, "OPEN", 4) == 0) cred->auth_type = WPS_AUTH_OPEN; else if (os_strncmp(pos + 9, "WPAPSK", 6) == 0) cred->auth_type = WPS_AUTH_WPAPSK; else if (os_strncmp(pos + 9, "WPA2PSK", 7) == 0) cred->auth_type = WPS_AUTH_WPA2PSK; else { wpa_printf(MSG_DEBUG, "EAP-WSC: Unknown new_auth"); return -1; } pos = os_strstr(params, "new_encr="); if (pos == NULL) { wpa_printf(MSG_DEBUG, "EAP-WSC: Missing new_encr"); return -1; } if (os_strncmp(pos + 9, "NONE", 4) == 0) cred->encr_type = WPS_ENCR_NONE; #ifdef CONFIG_TESTING_OPTIONS else if (os_strncmp(pos + 9, "WEP", 3) == 0) cred->encr_type = WPS_ENCR_WEP; #endif /* CONFIG_TESTING_OPTIONS */ else if (os_strncmp(pos + 9, "TKIP", 4) == 0) cred->encr_type = WPS_ENCR_TKIP; else if (os_strncmp(pos + 9, "CCMP", 4) == 0) cred->encr_type = WPS_ENCR_AES; else { wpa_printf(MSG_DEBUG, "EAP-WSC: Unknown new_encr"); return -1; } pos = os_strstr(params, "new_key="); if (pos == NULL) return 0; pos += 8; end = os_strchr(pos, ' '); if (end == NULL) len = os_strlen(pos); else len = end - pos; if ((len & 1) || len > 2 * sizeof(cred->key) || hexstr2bin(pos, cred->key, len / 2)) { wpa_printf(MSG_DEBUG, "EAP-WSC: Invalid new_key"); return -1; } cred->key_len = len / 2; return 1; }
/************************************************ * name: httpdRecvCb * parameters: ptArgument - connection data * pbData - data available * cbDataLength - data length * return value: none * purpose: callback when data available on a socket ************************************************/ static void ICACHE_FLASH_ATTR httpdRecvCb(void * ptArgument, char * pbData, unsigned short cbDataLength) { /* initialization */ int iIndex = 0; char * pbTmpHeader = NULL; char * pbEndOfHeader = NULL; char pbSendBuffer[HTTPD_MAX_SEND_BUFFER_LENGTH] = { 0 }; HttpdConnection * ptConnection = NULL; ptConnection = httpdFindConnData(ptArgument); if (NULL == ptConnection) { return; } ptConnection->ptPrivate->pbSendBuffer = pbSendBuffer; ptConnection->ptPrivate->cbSendBufferLength = 0; for (iIndex = 0; iIndex < cbDataLength; iIndex++) { if (0 > ptConnection->ptPost->cbPostLength) { /* header byte */ if (HTTPD_MAX_HEADER_LENGTH != ptConnection->ptPrivate->cbHeaderLength) { ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength++]=pbData[iIndex]; } ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength] = 0; /* scan for /r/n/r/n */ if (((*NEWLINE_SYMBOL_STRING) == pbData[iIndex]) && (NULL != (char *)os_strstr(ptConnection->ptPrivate->pbHeader, "\r\n\r\n"))) { /* indicate we're done with the headers */ ptConnection->ptPost->cbPostLength = 0; /* reset url data */ ptConnection->pszUrl = NULL; /* find end of next header line */ pbTmpHeader = ptConnection->ptPrivate->pbHeader; while (pbTmpHeader < (&ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength-4])) { pbEndOfHeader = (char *)os_strstr(pbTmpHeader, "\r\n"); if (NULL == pbEndOfHeader) { break; } pbEndOfHeader[0] = 0; httpdParseHeader(pbTmpHeader, ptConnection); pbTmpHeader = pbEndOfHeader + 2; } /* if receive post data unncessary send the response */ if (0 == ptConnection->ptPost->cbPostLength) { httpdProcessRequest(ptConnection); } } } else if (0 != ptConnection->ptPost->cbPostLength) { /* this is a POST byte */ ptConnection->ptPost->pbBuffer[ptConnection->ptPost->cbBufferLength++] = pbData[iIndex]; ptConnection->ptPost->cbReceived++; if ((ptConnection->ptPost->cbBufferLength >= ptConnection->ptPost->cbMaxBufferSize) || (ptConnection->ptPost->cbReceived == ptConnection->ptPost->cbPostLength)) { /* received a chunk of post data */ /* zero-terminate, in case the cgi handler knows it can use strings */ ptConnection->ptPost->pbBuffer[ptConnection->ptPost->cbBufferLength] = 0; /* send the response */ httpdProcessRequest(ptConnection); ptConnection->ptPost->cbBufferLength = 0; } } } }
static void ICACHE_FLASH_ATTR wsRecvCb(void *esp_connection, char *data, unsigned short len) { char *key = (char *)os_strstr(data, WS_KEY_IDENTIFIER); WSConnection *wsConnection = getWsConnection(esp_connection); /*if (wsConnection == NULL) { //huh? return; }*/ //get the first occurrence of the key identifier if (key != NULL) { // ------------------------ Handle the Handshake ------------------------ //Skip the identifier (that contains the space already) key += os_strlen(WS_KEY_IDENTIFIER); //the key ends at the newline char *endSequence = (char *)os_strstr(key, HTML_HEADER_LINEEND); if (endSequence != NULL) { int keyLastChar = endSequence - key; //we can throw away all the other data, only the key is interesting key[keyLastChar] = '\0'; char acceptKey[100]; createWsAcceptKey(key, acceptKey, 100); //now construct our message and send it back to the client char responseMessage[strlen(WS_RESPONSE) + 100]; os_sprintf(responseMessage, WS_RESPONSE, acceptKey); //send the response espconn_sent(esp_connection, (uint8_t *)responseMessage, strlen(responseMessage)); wsConnection->status = STATUS_OPEN; //call the connection callback if (wsOnConnectionCallback != NULL) { wsOnConnectionCallback(wsConnection); } } } else { // ------------------------ Handle a Frame ------------------------ WSFrame frame; parseWsFrame(data, &frame); if (frame.isMasked) { unmaskWsPayload(frame.payloadData, frame.payloadLength, frame.maskingKey); } else { //we are the server, and need to shut down the connection //if we receive an unmasked packet closeWsConnection(wsConnection); return; } if (frame.opcode == OPCODE_PING) { sendWsMessage(wsConnection, frame.payloadData, frame.payloadLength, FLAG_FIN | OPCODE_PONG); return; } if(frame.opcode == OPCODE_CLOSE){ //gracefully shut down the connection closeWsConnection(wsConnection); return; } if(wsConnection->onMessage != NULL){ wsConnection->onMessage(wsConnection, &frame); } } }
static void * eap_eke_init(struct eap_sm *sm) { struct eap_eke_data *data; const u8 *identity, *password; size_t identity_len, password_len; const char *phase1; password = eap_get_config_password(sm, &password_len); if (!password) { wpa_printf(MSG_INFO, "EAP-EKE: No password configured"); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; eap_eke_state(data, IDENTITY); identity = eap_get_config_identity(sm, &identity_len); if (identity) { data->peerid = os_malloc(identity_len); if (data->peerid == NULL) { eap_eke_deinit(sm, data); return NULL; } os_memcpy(data->peerid, identity, identity_len); data->peerid_len = identity_len; } phase1 = eap_get_config_phase1(sm); if (phase1) { const char *pos; pos = os_strstr(phase1, "dhgroup="); if (pos) { data->dhgroup = atoi(pos + 8); wpa_printf(MSG_DEBUG, "EAP-EKE: Forced dhgroup %u", data->dhgroup); } pos = os_strstr(phase1, "encr="); if (pos) { data->encr = atoi(pos + 5); wpa_printf(MSG_DEBUG, "EAP-EKE: Forced encr %u", data->encr); } pos = os_strstr(phase1, "prf="); if (pos) { data->prf = atoi(pos + 4); wpa_printf(MSG_DEBUG, "EAP-EKE: Forced prf %u", data->prf); } pos = os_strstr(phase1, "mac="); if (pos) { data->mac = atoi(pos + 4); wpa_printf(MSG_DEBUG, "EAP-EKE: Forced mac %u", data->mac); } } return data; }
static void eap_peap_parse_phase1(struct eap_peap_data *data, const char *phase1) { const char *pos; pos = os_strstr(phase1, "peapver="); if (pos) { data->force_peap_version = atoi(pos + 8); data->peap_version = data->force_peap_version; wpa_printf(MSG_DEBUG, "EAP-PEAP: Forced PEAP version %d", data->force_peap_version); } if (os_strstr(phase1, "peaplabel=1")) { data->force_new_label = 1; wpa_printf(MSG_DEBUG, "EAP-PEAP: Force new label for key " "derivation"); } if (os_strstr(phase1, "peap_outer_success=0")) { data->peap_outer_success = 0; wpa_printf(MSG_DEBUG, "EAP-PEAP: terminate authentication on " "tunneled EAP-Success"); } else if (os_strstr(phase1, "peap_outer_success=1")) { data->peap_outer_success = 1; wpa_printf(MSG_DEBUG, "EAP-PEAP: send tunneled EAP-Success " "after receiving tunneled EAP-Success"); } else if (os_strstr(phase1, "peap_outer_success=2")) { data->peap_outer_success = 2; wpa_printf(MSG_DEBUG, "EAP-PEAP: send PEAP/TLS ACK after " "receiving tunneled EAP-Success"); } if (os_strstr(phase1, "crypto_binding=0")) { data->crypto_binding = NO_BINDING; wpa_printf(MSG_DEBUG, "EAP-PEAP: Do not use cryptobinding"); } else if (os_strstr(phase1, "crypto_binding=1")) { data->crypto_binding = OPTIONAL_BINDING; wpa_printf(MSG_DEBUG, "EAP-PEAP: Optional cryptobinding"); } else if (os_strstr(phase1, "crypto_binding=2")) { data->crypto_binding = REQUIRE_BINDING; wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding"); } #ifdef EAP_TNC if (os_strstr(phase1, "tnc=soh2")) { data->soh = 2; wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled"); } else if (os_strstr(phase1, "tnc=soh1")) { data->soh = 1; wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 1 enabled"); } else if (os_strstr(phase1, "tnc=soh")) { data->soh = 2; wpa_printf(MSG_DEBUG, "EAP-PEAP: SoH version 2 enabled"); } #endif /* EAP_TNC */ }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } if (cfg.pin == NULL && !cfg.pbc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, "dev_pw_id="); if (pos && cfg.pin) cfg.dev_pw_id = atoi(pos + 10); res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, cfg.pin, cfg.pin_len, 0); } return data; }
static int wpa_driver_privsep_set_param(void *priv, const char *param) { struct wpa_driver_privsep_data *drv = priv; const char *pos; char *own_dir, *priv_dir; static unsigned int counter = 0; size_t len; struct sockaddr_un addr; wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param); if (param == NULL) pos = NULL; else pos = os_strstr(param, "own_dir="); if (pos) { char *end; own_dir = os_strdup(pos + 8); if (own_dir == NULL) return -1; end = os_strchr(own_dir, ' '); if (end) *end = '\0'; } else { own_dir = os_strdup("/tmp"); if (own_dir == NULL) return -1; } if (param == NULL) pos = NULL; else pos = os_strstr(param, "priv_dir="); if (pos) { char *end; priv_dir = os_strdup(pos + 9); if (priv_dir == NULL) { os_free(own_dir); return -1; } end = os_strchr(priv_dir, ' '); if (end) *end = '\0'; } else { priv_dir = os_strdup("/var/run/wpa_priv"); if (priv_dir == NULL) { os_free(own_dir); return -1; } } len = os_strlen(own_dir) + 50; drv->own_socket_path = os_malloc(len); if (drv->own_socket_path == NULL) { os_free(priv_dir); os_free(own_dir); return -1; } os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d", own_dir, getpid(), counter++); len = os_strlen(own_dir) + 50; drv->own_cmd_path = os_malloc(len); if (drv->own_cmd_path == NULL) { os_free(drv->own_socket_path); drv->own_socket_path = NULL; os_free(priv_dir); os_free(own_dir); return -1; } os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d", own_dir, getpid(), counter++); os_free(own_dir); drv->priv_addr.sun_family = AF_UNIX; os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path), "%s/%s", priv_dir, drv->ifname); os_free(priv_dir); drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->priv_socket < 0) { wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path)); if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_ERROR, "privsep-set-params priv-sock: bind(PF_UNIX): %s", strerror(errno)); close(drv->priv_socket); drv->priv_socket = -1; unlink(drv->own_socket_path); os_free(drv->own_socket_path); drv->own_socket_path = NULL; return -1; } eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive, drv, NULL); drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0); if (drv->cmd_socket < 0) { wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); os_free(drv->own_cmd_path); drv->own_cmd_path = NULL; return -1; } os_memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path)); if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0) { wpa_printf(MSG_ERROR, "privsep-set-params cmd-sock: bind(PF_UNIX): %s", strerror(errno)); close(drv->cmd_socket); drv->cmd_socket = -1; unlink(drv->own_cmd_path); os_free(drv->own_cmd_path); drv->own_cmd_path = NULL; return -1; } if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) { wpa_printf(MSG_ERROR, "Failed to register with wpa_priv"); return -1; } return 0; }
static void * eap_wsc_init(struct eap_sm *sm) { struct eap_wsc_data *data; const u8 *identity; size_t identity_len; int registrar; struct wps_config cfg; const char *pos; const char *phase1; struct wps_context *wps; struct wps_credential new_ap_settings; int res; u8 dev_pw[WPS_OOB_DEVICE_PASSWORD_LEN]; int nfc = 0; wps = sm->wps; if (wps == NULL) { wpa_printf(MSG_ERROR, "EAP-WSC: WPS context not available"); return NULL; } identity = eap_get_config_identity(sm, &identity_len); if (identity && identity_len == WSC_ID_REGISTRAR_LEN && os_memcmp(identity, WSC_ID_REGISTRAR, WSC_ID_REGISTRAR_LEN) == 0) registrar = 1; /* Supplicant is Registrar */ else if (identity && identity_len == WSC_ID_ENROLLEE_LEN && os_memcmp(identity, WSC_ID_ENROLLEE, WSC_ID_ENROLLEE_LEN) == 0) registrar = 0; /* Supplicant is Enrollee */ else { wpa_hexdump_ascii(MSG_INFO, "EAP-WSC: Unexpected identity", identity, identity_len); return NULL; } data = os_zalloc(sizeof(*data)); if (data == NULL) return NULL; data->state = registrar ? MESG : WAIT_START; data->registrar = registrar; data->wps_ctx = wps; os_memset(&cfg, 0, sizeof(cfg)); cfg.wps = wps; cfg.registrar = registrar; phase1 = eap_get_config_phase1(sm); if (phase1 == NULL) { wpa_printf(MSG_INFO, "EAP-WSC: phase1 configuration data not " "set"); os_free(data); return NULL; } pos = os_strstr(phase1, "pin="); if (pos) { pos += 4; cfg.pin = (const u8 *) pos; while (*pos != '\0' && *pos != ' ') pos++; cfg.pin_len = pos - (const char *) cfg.pin; if (cfg.pin_len >= WPS_OOB_DEVICE_PASSWORD_MIN_LEN * 2 && cfg.pin_len <= WPS_OOB_DEVICE_PASSWORD_LEN * 2 && hexstr2bin((const char *) cfg.pin, dev_pw, cfg.pin_len / 2) == 0) { /* Convert OOB Device Password to binary */ cfg.pin = dev_pw; cfg.pin_len /= 2; } if (cfg.pin_len == 6 && os_strncmp((const char *) cfg.pin, "nfc-pw", 6) == 0) { cfg.pin = NULL; cfg.pin_len = 0; nfc = 1; } } else { pos = os_strstr(phase1, "pbc=1"); if (pos) cfg.pbc = 1; } if (cfg.pin == NULL && !cfg.pbc && !nfc) { wpa_printf(MSG_INFO, "EAP-WSC: PIN or PBC not set in phase1 " "configuration data"); os_free(data); return NULL; } pos = os_strstr(phase1, "dev_pw_id="); if (pos && cfg.pin) cfg.dev_pw_id = atoi(pos + 10); res = eap_wsc_new_ap_settings(&new_ap_settings, phase1); if (res < 0) { os_free(data); return NULL; } if (res == 1) { wpa_printf(MSG_DEBUG, "EAP-WSC: Provide new AP settings for " "WPS"); cfg.new_ap_settings = &new_ap_settings; } data->wps = wps_init(&cfg); if (data->wps == NULL) { os_free(data); return NULL; } res = eap_get_config_fragment_size(sm); if (res > 0) data->fragment_size = res; else data->fragment_size = WSC_FRAGMENT_SIZE; wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment size limit %u", (unsigned int) data->fragment_size); if (registrar && cfg.pin) { wps_registrar_add_pin(data->wps_ctx->registrar, NULL, NULL, cfg.pin, cfg.pin_len, 0); } /* Use reduced client timeout for WPS to avoid long wait */ if (sm->ClientTimeout > 30) sm->ClientTimeout = 30; return data; }
int hostapd_ctrl_iface_disassociate(struct hostapd_data *hapd, const char *txtaddr) { u8 addr[ETH_ALEN]; struct sta_info *sta; const char *pos; u16 reason = WLAN_REASON_PREV_AUTH_NOT_VALID; wpa_dbg(hapd->msg_ctx, MSG_DEBUG, "CTRL_IFACE DISASSOCIATE %s", txtaddr); if (hwaddr_aton(txtaddr, addr)) return -1; pos = os_strstr(txtaddr, " reason="); if (pos) reason = atoi(pos + 8); pos = os_strstr(txtaddr, " test="); if (pos) { struct ieee80211_mgmt mgmt; int encrypt; if (!hapd->drv_priv || !hapd->driver->send_frame) return -1; pos += 6; encrypt = atoi(pos); os_memset(&mgmt, 0, sizeof(mgmt)); mgmt.frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DISASSOC); os_memcpy(mgmt.da, addr, ETH_ALEN); os_memcpy(mgmt.sa, hapd->own_addr, ETH_ALEN); os_memcpy(mgmt.bssid, hapd->own_addr, ETH_ALEN); mgmt.u.disassoc.reason_code = host_to_le16(reason); if (hapd->driver->send_frame(hapd->drv_priv, (u8 *) &mgmt, IEEE80211_HDRLEN + sizeof(mgmt.u.deauth), encrypt) < 0) return -1; return 0; } #ifdef CONFIG_P2P_MANAGER pos = os_strstr(txtaddr, " p2p="); if (pos) { return p2p_manager_disconnect(hapd, WLAN_FC_STYPE_DISASSOC, atoi(pos + 5), addr); } #endif /* CONFIG_P2P_MANAGER */ if (os_strstr(txtaddr, " tx=0")) hostapd_drv_sta_remove(hapd, addr); else hostapd_drv_sta_disassoc(hapd, addr, reason); sta = ap_get_sta(hapd, addr); if (sta) ap_sta_disassociate(hapd, sta, reason); else if (addr[0] == 0xff) hostapd_free_stas(hapd); return 0; }
static int eap_mschapv2_failure_txt(struct eap_sm *sm, struct eap_mschapv2_data *data, char *txt) { char *pos, *msg = ""; int retry = 1; struct eap_peer_config *config = eap_get_config(sm); /* For example: * E=691 R=1 C=<32 octets hex challenge> V=3 M=Authentication Failure */ pos = txt; if (pos && os_strncmp(pos, "E=", 2) == 0) { pos += 2; data->prev_error = atoi(pos); wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: error %d", data->prev_error); pos = os_strchr(pos, ' '); if (pos) pos++; } if (pos && os_strncmp(pos, "R=", 2) == 0) { pos += 2; retry = atoi(pos); wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: retry is %sallowed", retry == 1 ? "" : "not "); pos = os_strchr(pos, ' '); if (pos) pos++; } if (pos && os_strncmp(pos, "C=", 2) == 0) { int hex_len; pos += 2; hex_len = os_strchr(pos, ' ') - (char *) pos; if (hex_len == PASSWD_CHANGE_CHAL_LEN * 2) { if (hexstr2bin(pos, data->passwd_change_challenge, PASSWD_CHANGE_CHAL_LEN)) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: invalid " "failure challenge"); } else { wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: failure " "challenge", data->passwd_change_challenge, PASSWD_CHANGE_CHAL_LEN); data->passwd_change_challenge_valid = 1; } } else { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: invalid failure " "challenge len %d", hex_len); } pos = os_strchr(pos, ' '); if (pos) pos++; } else { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: required challenge field " "was not present in failure message"); } if (pos && os_strncmp(pos, "V=", 2) == 0) { pos += 2; data->passwd_change_version = atoi(pos); wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: password changing " "protocol version %d", data->passwd_change_version); pos = os_strchr(pos, ' '); if (pos) pos++; } if (pos && os_strncmp(pos, "M=", 2) == 0) { pos += 2; msg = pos; } if (data->prev_error == ERROR_AUTHENTICATION_FAILURE && retry && config && config->phase2 && os_strstr(config->phase2, "mschapv2_retry=0")) { wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: mark password retry disabled based on local configuration"); retry = 0; } wpa_msg(sm->msg_ctx, MSG_WARNING, "EAP-MSCHAPV2: failure message: '%s' (retry %sallowed, error " "%d)", msg, retry == 1 ? "" : "not ", data->prev_error); if (data->prev_error == ERROR_PASSWD_EXPIRED && data->passwd_change_version == 3 && config) { if (config->new_password == NULL) { wpa_msg(sm->msg_ctx, MSG_INFO, "EAP-MSCHAPV2: Password expired - password " "change required"); eap_sm_request_new_password(sm); } } else if (retry == 1 && config) { /* TODO: could prevent the current password from being used * again at least for some period of time */ if (!config->mschapv2_retry) eap_sm_request_identity(sm); eap_sm_request_password(sm); config->mschapv2_retry = 1; } else if (config) { /* TODO: prevent retries using same username/password */ config->mschapv2_retry = 0; } return retry == 1; }