Beispiel #1
0
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]);
	}
}
Beispiel #3
0
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);
}
Beispiel #4
0
/**
 * 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;
}
Beispiel #5
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;
}
Beispiel #6
0
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;
}
Beispiel #7
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, *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;
}
Beispiel #8
0
//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;
	}
}
Beispiel #10
0
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;
}
Beispiel #13
0
//***********************************************************************
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");
}
Beispiel #14
0
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;
	}
}
Beispiel #15
0
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);
			}
		}
	}
}
Beispiel #17
0
/******************************************************************************
 * 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);
        }
    }
}
Beispiel #18
0
/*	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;
}
Beispiel #19
0
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;
}
Beispiel #20
0
/************************************************
*	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
			}
		}
	}
}
Beispiel #21
0
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;
}
Beispiel #22
0
/************************************************
*	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);
		}
	}
}
Beispiel #24
0
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;
}
Beispiel #25
0
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 */
}
Beispiel #26
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;

	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;
}
Beispiel #27
0
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;
}
Beispiel #28
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;
}
Beispiel #30
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;
}