Exemple #1
0
void hostapd_2040_coex_action(struct hostapd_data *hapd,
			      const struct ieee80211_mgmt *mgmt, size_t len)
{
	struct hostapd_iface *iface = hapd->iface;
	struct ieee80211_2040_bss_coex_ie *bc_ie;
	struct ieee80211_2040_intol_chan_report *ic_report;
	int is_ht40_allowed = 1;
	int i;
	const u8 *start = (const u8 *) mgmt;
	const u8 *data = start + IEEE80211_HDRLEN + 2;

	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
		       HOSTAPD_LEVEL_DEBUG, "hostapd_public_action - action=%d",
		       mgmt->u.action.u.public_action.action);

	if (!(iface->conf->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
		return;

	if (len < IEEE80211_HDRLEN + 2 + sizeof(*bc_ie))
		return;

	bc_ie = (struct ieee80211_2040_bss_coex_ie *) data;
	if (bc_ie->element_id != WLAN_EID_20_40_BSS_COEXISTENCE ||
	    bc_ie->length < 1) {
		wpa_printf(MSG_DEBUG, "Unexpected IE (%u,%u) in coex report",
			   bc_ie->element_id, bc_ie->length);
		return;
	}
	if (len < IEEE80211_HDRLEN + 2 + 2 + bc_ie->length)
		return;
	data += 2 + bc_ie->length;

	wpa_printf(MSG_DEBUG, "20/40 BSS Coexistence Information field: 0x%x",
		   bc_ie->coex_param);
	if (bc_ie->coex_param & WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ) {
		hostapd_logger(hapd, mgmt->sa,
			       HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "20 MHz BSS width request bit is set in BSS coexistence information field");
		is_ht40_allowed = 0;
	}

	if (bc_ie->coex_param & WLAN_20_40_BSS_COEX_40MHZ_INTOL) {
		hostapd_logger(hapd, mgmt->sa,
			       HOSTAPD_MODULE_IEEE80211,
			       HOSTAPD_LEVEL_DEBUG,
			       "40 MHz intolerant bit is set in BSS coexistence information field");
		is_ht40_allowed = 0;
	}

	if (start + len - data >= 3 &&
	    data[0] == WLAN_EID_20_40_BSS_INTOLERANT && data[1] >= 1) {
		u8 ielen = data[1];

		if (ielen > start + len - data - 2)
			return;
		ic_report = (struct ieee80211_2040_intol_chan_report *) data;
		wpa_printf(MSG_DEBUG,
			   "20/40 BSS Intolerant Channel Report: Operating Class %u",
			   ic_report->op_class);

		/* Go through the channel report to find any BSS there in the
		 * affected channel range */
		for (i = 0; i < ielen - 1; i++) {
			u8 chan = ic_report->variable[i];

			if (is_40_allowed(iface, chan))
				continue;
			hostapd_logger(hapd, mgmt->sa,
				       HOSTAPD_MODULE_IEEE80211,
				       HOSTAPD_LEVEL_DEBUG,
				       "20_40_INTOLERANT channel %d reported",
				       chan);
			is_ht40_allowed = 0;
		}
	}
	wpa_printf(MSG_DEBUG, "is_ht40_allowed=%d num_sta_ht40_intolerant=%d",
		   is_ht40_allowed, iface->num_sta_ht40_intolerant);

	if (!is_ht40_allowed &&
	    (iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX)) {
		if (iface->conf->secondary_channel) {
			hostapd_logger(hapd, mgmt->sa,
				       HOSTAPD_MODULE_IEEE80211,
				       HOSTAPD_LEVEL_INFO,
				       "Switching to 20 MHz operation");
			iface->conf->secondary_channel = 0;
			ieee802_11_set_beacons(iface);
		}
		if (!iface->num_sta_ht40_intolerant &&
		    iface->conf->obss_interval) {
			unsigned int delay_time;
			delay_time = OVERLAPPING_BSS_TRANS_DELAY_FACTOR *
				iface->conf->obss_interval;
			eloop_cancel_timeout(ap_ht2040_timeout, hapd->iface,
					     NULL);
			eloop_register_timeout(delay_time, 0, ap_ht2040_timeout,
					       hapd->iface, NULL);
			wpa_printf(MSG_DEBUG,
				   "Reschedule HT 20/40 timeout to occur in %u seconds",
				   delay_time);
		}
	}
}
Exemple #2
0
int main(int argc, char *argv[])
{
	struct hapd_interfaces interfaces;
	int ret = 1;
	size_t i, j;
	int c, debug = 0, daemonize = 0;
	char *pid_file = NULL;
	const char *log_file = NULL;
	const char *entropy_file = NULL;
	char **bss_config = NULL, **tmp_bss;
	size_t num_bss_configs = 0;
#ifdef CONFIG_DEBUG_LINUX_TRACING
	int enable_trace_dbg = 0;
#endif /* CONFIG_DEBUG_LINUX_TRACING */

	if (os_program_init())
		return -1;
	wpa_printf(MSG_INFO, "Pavan edit: os program initialized");
	os_memset(&interfaces, 0, sizeof(interfaces));
	interfaces.reload_config = hostapd_reload_config;
	interfaces.config_read_cb = hostapd_config_read;
	interfaces.for_each_interface = hostapd_for_each_interface;
	interfaces.ctrl_iface_init = hostapd_ctrl_iface_init;
	interfaces.ctrl_iface_deinit = hostapd_ctrl_iface_deinit;
	interfaces.driver_init = hostapd_driver_init;
	interfaces.global_iface_path = NULL;
	interfaces.global_iface_name = NULL;
	interfaces.global_ctrl_sock = -1;
	interfaces.global_ctrl_dst = NULL;

	for (;;) {
		c = getopt(argc, argv, "b:Bde:f:hKP:Ttu:vg:G:");
		if (c < 0)
			break;
		switch (c) {
		case 'h':
			usage();
			break;
		case 'd':
			debug++;
			if (wpa_debug_level > 0)
				wpa_debug_level--;
			break;
		case 'B':
			daemonize++;
			break;
		case 'e':
			entropy_file = optarg;
			break;
		case 'f':
			log_file = optarg;
			break;
		case 'K':
			wpa_debug_show_keys++;
			break;
		case 'P':
			os_free(pid_file);
			pid_file = os_rel2abs_path(optarg);
			break;
		case 't':
			wpa_debug_timestamp++;
			break;
#ifdef CONFIG_DEBUG_LINUX_TRACING
		case 'T':
			enable_trace_dbg = 1;
			break;
#endif /* CONFIG_DEBUG_LINUX_TRACING */
		case 'v':
			show_version();
			exit(1);
			break;
		case 'g':
			if (hostapd_get_global_ctrl_iface(&interfaces, optarg))
				return -1;
			break;
		case 'G':
			if (hostapd_get_ctrl_iface_group(&interfaces, optarg))
				return -1;
			break;
		case 'b':
			tmp_bss = os_realloc_array(bss_config,
						   num_bss_configs + 1,
						   sizeof(char *));
			if (tmp_bss == NULL)
				goto out;
			bss_config = tmp_bss;
			bss_config[num_bss_configs++] = optarg;
			break;
#ifdef CONFIG_WPS
		case 'u':
			return gen_uuid(optarg);
#endif /* CONFIG_WPS */
		default:
			usage();
			break;
		}
	}

	if (optind == argc && interfaces.global_iface_path == NULL &&
	    num_bss_configs == 0)
		usage();

	wpa_msg_register_ifname_cb(hostapd_msg_ifname_cb);

	if (log_file)
		wpa_debug_open_file(log_file);
	else
		wpa_debug_setup_stdout();
#ifdef CONFIG_DEBUG_LINUX_TRACING
	if (enable_trace_dbg) {
		int tret = wpa_debug_open_linux_tracing();
		if (tret) {
			wpa_printf(MSG_ERROR, "Failed to enable trace logging");
			return -1;
		}
	}
#endif /* CONFIG_DEBUG_LINUX_TRACING */

	interfaces.count = argc - optind;
	if (interfaces.count || num_bss_configs) {
		interfaces.iface = os_calloc(interfaces.count + num_bss_configs,
					     sizeof(struct hostapd_iface *));
		if (interfaces.iface == NULL) {
			wpa_printf(MSG_ERROR, "malloc failed");
			return -1;
		}
	}

	if (hostapd_global_init(&interfaces, entropy_file)) {
		wpa_printf(MSG_ERROR, "Failed to initialize global context");
		return -1;
	}

	eloop_register_timeout(HOSTAPD_CLEANUP_INTERVAL, 0,
			       hostapd_periodic, &interfaces, NULL);

	/*Timeout event is triggered after 5 seconds of start of hostapd. The parameters are pulled after the event is triggered in the handler*/
        eloop_register_timeout(2, 0, get_params_handler, &interfaces, NULL);


	if (fst_global_init()) {
		wpa_printf(MSG_ERROR,
			   "Failed to initialize global FST context");
		goto out;
	}

#if defined(CONFIG_FST) && defined(CONFIG_CTRL_IFACE)
	if (!fst_global_add_ctrl(fst_ctrl_cli))
		wpa_printf(MSG_WARNING, "Failed to add CLI FST ctrl");
#endif /* CONFIG_FST && CONFIG_CTRL_IFACE */

	/* Allocate and parse configuration for full interface files */
	wpa_printf(MSG_INFO, "Pavan edit: interfaces.count = %d",interfaces.count);
	for (i = 0; i < interfaces.count; i++) {
		interfaces.iface[i] = hostapd_interface_init(&interfaces,
							     argv[optind + i],
							     debug);
		if (!interfaces.iface[i]) {
			wpa_printf(MSG_ERROR, "Failed to initialize interface");
			goto out;
		}
	}
	wpa_printf(MSG_INFO, "Pavan edit: num_bss_configs = %d", num_bss_configs);
	/* Allocate and parse configuration for per-BSS files */
	for (i = 0; i < num_bss_configs; i++) {
		struct hostapd_iface *iface;
		char *fname;

		wpa_printf(MSG_INFO, "BSS config: %s", bss_config[i]);
		fname = os_strchr(bss_config[i], ':');
		if (fname == NULL) {
			wpa_printf(MSG_ERROR,
				   "Invalid BSS config identifier '%s'",
				   bss_config[i]);
			goto out;
		}
		*fname++ = '\0';
		iface = hostapd_interface_init_bss(&interfaces, bss_config[i],
						   fname, debug);
		if (iface == NULL)
			goto out;
		for (j = 0; j < interfaces.count; j++) {
			if (interfaces.iface[j] == iface)
				break;
		}
		if (j == interfaces.count) {
			struct hostapd_iface **tmp;
			tmp = os_realloc_array(interfaces.iface,
					       interfaces.count + 1,
					       sizeof(struct hostapd_iface *));
			if (tmp == NULL) {
				hostapd_interface_deinit_free(iface);
				goto out;
			}
			interfaces.iface = tmp;
			interfaces.iface[interfaces.count++] = iface;
		}
	}

	/*
	 * Enable configured interfaces. Depending on channel configuration,
	 * this may complete full initialization before returning or use a
	 * callback mechanism to complete setup in case of operations like HT
	 * co-ex scans, ACS, or DFS are needed to determine channel parameters.
	 * In such case, the interface will be enabled from eloop context within
	 * hostapd_global_run().
	 */
	interfaces.terminate_on_error = interfaces.count;
	for (i = 0; i < interfaces.count; i++) {
		wpa_printf(MSG_INFO, "Pavan edit: initializing driver and setting up interface");
		if (hostapd_driver_init(interfaces.iface[i]) ||
		    hostapd_setup_interface(interfaces.iface[i])) {
			wpa_printf(MSG_INFO, "Pavan edit: goto out called, hostapd_global_ctrl_iface_deinit called");
			goto out;
		}
	}

	hostapd_global_ctrl_iface_init(&interfaces);

	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
		wpa_printf(MSG_ERROR, "Failed to start eloop");
		goto out;
	}

	ret = 0;

 out:
	hostapd_global_ctrl_iface_deinit(&interfaces);
	/* Deinitialize all interfaces */
	for (i = 0; i < interfaces.count; i++) {
		if (!interfaces.iface[i])
			continue;
		interfaces.iface[i]->driver_ap_teardown =
			!!(interfaces.iface[i]->drv_flags &
			   WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
		hostapd_interface_deinit_free(interfaces.iface[i]);
	}
	os_free(interfaces.iface);

	eloop_cancel_timeout(hostapd_periodic, &interfaces, NULL);
	hostapd_global_deinit(pid_file);
	os_free(pid_file);

	if (log_file)
		wpa_debug_close_file();
	wpa_debug_close_linux_tracing();

	os_free(bss_config);

	fst_global_deinit();

	os_program_deinit();

	return ret;
}
Exemple #3
0
/**
 * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
 * @wpa_s: Pointer to wpa_supplicant data
 *
 * This function is used to cancel a scan request scheduled with
 * wpa_supplicant_req_scan().
 */
void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
{
	wpa_dbg(wpa_s, MSG_DEBUG, "Cancelling scan request");
	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
	wpas_p2p_continue_after_scan(wpa_s);
}
void hs20_parse_rx_hs20_anqp_resp(struct wpa_supplicant *wpa_s,
				  struct wpa_bss *bss, const u8 *sa,
				  const u8 *data, size_t slen, u8 dialog_token)
{
	const u8 *pos = data;
	u8 subtype;
	struct wpa_bss_anqp *anqp = NULL;
	int ret;

	if (slen < 2)
		return;

	if (bss)
		anqp = bss->anqp;

	subtype = *pos++;
	slen--;

	pos++; /* Reserved */
	slen--;

	switch (subtype) {
	case HS20_STYPE_CAPABILITY_LIST:
		wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
			" HS Capability List", MAC2STR(sa));
		wpa_hexdump_ascii(MSG_DEBUG, "HS Capability List", pos, slen);
		if (anqp) {
			wpabuf_free(anqp->hs20_capability_list);
			anqp->hs20_capability_list =
				wpabuf_alloc_copy(pos, slen);
		}
		break;
	case HS20_STYPE_OPERATOR_FRIENDLY_NAME:
		wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
			" Operator Friendly Name", MAC2STR(sa));
		wpa_hexdump_ascii(MSG_DEBUG, "oper friendly name", pos, slen);
		if (anqp) {
			wpabuf_free(anqp->hs20_operator_friendly_name);
			anqp->hs20_operator_friendly_name =
				wpabuf_alloc_copy(pos, slen);
		}
		break;
	case HS20_STYPE_WAN_METRICS:
		wpa_hexdump(MSG_DEBUG, "WAN Metrics", pos, slen);
		if (slen < 13) {
			wpa_dbg(wpa_s, MSG_DEBUG, "HS 2.0: Too short WAN "
				"Metrics value from " MACSTR, MAC2STR(sa));
			break;
		}
		wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
			" WAN Metrics %02x:%u:%u:%u:%u:%u", MAC2STR(sa),
			pos[0], WPA_GET_LE32(pos + 1), WPA_GET_LE32(pos + 5),
			pos[9], pos[10], WPA_GET_LE16(pos + 11));
		if (anqp) {
			wpabuf_free(anqp->hs20_wan_metrics);
			anqp->hs20_wan_metrics = wpabuf_alloc_copy(pos, slen);
		}
		break;
	case HS20_STYPE_CONNECTION_CAPABILITY:
		wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
			" Connection Capability", MAC2STR(sa));
		wpa_hexdump_ascii(MSG_DEBUG, "conn capability", pos, slen);
		if (anqp) {
			wpabuf_free(anqp->hs20_connection_capability);
			anqp->hs20_connection_capability =
				wpabuf_alloc_copy(pos, slen);
		}
		break;
	case HS20_STYPE_OPERATING_CLASS:
		wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
			" Operating Class", MAC2STR(sa));
		wpa_hexdump_ascii(MSG_DEBUG, "Operating Class", pos, slen);
		if (anqp) {
			wpabuf_free(anqp->hs20_operating_class);
			anqp->hs20_operating_class =
				wpabuf_alloc_copy(pos, slen);
		}
		break;
	case HS20_STYPE_OSU_PROVIDERS_LIST:
		wpa_msg(wpa_s, MSG_INFO, RX_HS20_ANQP MACSTR
			" OSU Providers list", MAC2STR(sa));
		wpa_s->num_prov_found++;
		if (anqp) {
			wpabuf_free(anqp->hs20_osu_providers_list);
			anqp->hs20_osu_providers_list =
				wpabuf_alloc_copy(pos, slen);
		}
		break;
	case HS20_STYPE_ICON_BINARY_FILE:
		ret = hs20_process_icon_binary_file(wpa_s, sa, pos, slen,
						    dialog_token);
		if (wpa_s->fetch_osu_icon_in_progress) {
			hs20_osu_icon_fetch_result(wpa_s, ret);
			eloop_cancel_timeout(hs20_continue_icon_fetch,
					     wpa_s, NULL);
			eloop_register_timeout(0, 0, hs20_continue_icon_fetch,
					       wpa_s, NULL);
		}
		break;
	default:
		wpa_printf(MSG_DEBUG, "HS20: Unsupported subtype %u", subtype);
		break;
	}
}
Exemple #5
0
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
	int set_beacon = 0;

	accounting_sta_stop(hapd, sta);

	/* just in case */
	ap_sta_set_authorized(hapd, sta, 0);

	if (sta->flags & WLAN_STA_WDS)
		hostapd_set_wds_sta(hapd, sta->addr, sta->aid, 0);

	if (!(sta->flags & WLAN_STA_PREAUTH))
		hostapd_drv_sta_remove(hapd, sta->addr);

	ap_sta_hash_del(hapd, sta);
	ap_sta_list_del(hapd, sta);

	if (sta->aid > 0)
		hapd->sta_aid[(sta->aid - 1) / 32] &=
			~BIT((sta->aid - 1) % 32);

	hapd->num_sta--;
	if (sta->nonerp_set) {
		sta->nonerp_set = 0;
		hapd->iface->num_sta_non_erp--;
		if (hapd->iface->num_sta_non_erp == 0)
			set_beacon++;
	}

	if (sta->no_short_slot_time_set) {
		sta->no_short_slot_time_set = 0;
		hapd->iface->num_sta_no_short_slot_time--;
		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
		    && hapd->iface->num_sta_no_short_slot_time == 0)
			set_beacon++;
	}

	if (sta->no_short_preamble_set) {
		sta->no_short_preamble_set = 0;
		hapd->iface->num_sta_no_short_preamble--;
		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
		    && hapd->iface->num_sta_no_short_preamble == 0)
			set_beacon++;
	}

	if (sta->no_ht_gf_set) {
		sta->no_ht_gf_set = 0;
		hapd->iface->num_sta_ht_no_gf--;
	}

	if (sta->no_ht_set) {
		sta->no_ht_set = 0;
		hapd->iface->num_sta_no_ht--;
	}

	if (sta->ht_20mhz_set) {
		sta->ht_20mhz_set = 0;
		hapd->iface->num_sta_ht_20mhz--;
	}

#ifdef CONFIG_P2P
	if (sta->no_p2p_set) {
		sta->no_p2p_set = 0;
		hapd->num_sta_no_p2p--;
		if (hapd->num_sta_no_p2p == 0)
			hostapd_p2p_non_p2p_sta_disconnected(hapd);
	}
#endif /* CONFIG_P2P */

#if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
	if (hostapd_ht_operation_update(hapd->iface) > 0)
		set_beacon++;
#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */

	if (set_beacon)
		ieee802_11_set_beacons(hapd->iface);

	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
	eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
	eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);

	ieee802_1x_free_station(sta);
	wpa_auth_sta_deinit(sta->wpa_sm);
	rsn_preauth_free_station(hapd, sta);
#ifndef CONFIG_NO_RADIUS
	radius_client_flush_auth(hapd->radius, sta->addr);
#endif /* CONFIG_NO_RADIUS */

	os_free(sta->last_assoc_req);
	os_free(sta->challenge);

#ifdef CONFIG_IEEE80211W
	os_free(sta->sa_query_trans_id);
	eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
#endif /* CONFIG_IEEE80211W */

#ifdef CONFIG_P2P
	p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
#endif /* CONFIG_P2P */

	wpabuf_free(sta->wps_ie);
	wpabuf_free(sta->p2p_ie);

	os_free(sta->ht_capabilities);

	os_free(sta);
}
Exemple #6
0
/**
 * offchannel_deinit - Deinit off-channel operations
 * @wpa_s: Pointer to wpa_supplicant data
 *
 * This function is used to free up any allocated resources for off-channel
 * operations.
 */
void offchannel_deinit(struct wpa_supplicant *wpa_s)
{
	offchannel_clear_pending_action_tx(wpa_s);
	eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
}
Exemple #7
0
/**
 * wpa_supplicant_cancel_scan - Cancel a scheduled scan request
 * @wpa_s: Pointer to wpa_supplicant data
 *
 * This function is used to cancel a scan request scheduled with
 * wpa_supplicant_req_scan().
 */
void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
{
	wpa_msg(wpa_s, MSG_DEBUG, "Cancelling scan request");
	eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
}
static int bgscan_learn_notify_scan(void *priv,
				    struct wpa_scan_results *scan_res)
{
	struct bgscan_learn_data *data = priv;
	size_t i, j;
#define MAX_BSS 50
	u8 bssid[MAX_BSS * ETH_ALEN];
	size_t num_bssid = 0;

	wpa_printf(MSG_DEBUG, "bgscan learn: scan result notification");

	eloop_cancel_timeout(bgscan_learn_timeout, data, NULL);
	eloop_register_timeout(data->scan_interval, 0, bgscan_learn_timeout,
			       data, NULL);

	for (i = 0; i < scan_res->num; i++) {
		struct wpa_scan_res *res = scan_res->res[i];
		if (!bgscan_learn_bss_match(data, res))
			continue;

		if (num_bssid < MAX_BSS) {
			os_memcpy(bssid + num_bssid * ETH_ALEN, res->bssid,
				  ETH_ALEN);
			num_bssid++;
		}
	}
	wpa_printf(MSG_DEBUG, "bgscan learn: %u matching BSSes in scan "
		   "results", (unsigned int) num_bssid);

	for (i = 0; i < scan_res->num; i++) {
		struct wpa_scan_res *res = scan_res->res[i];
		struct bgscan_learn_bss *bss;

		if (!bgscan_learn_bss_match(data, res))
			continue;

		bss = bgscan_learn_get_bss(data, res->bssid);
		if (bss && bss->freq != res->freq) {
			wpa_printf(MSG_DEBUG, "bgscan learn: Update BSS "
			   MACSTR " freq %d -> %d",
				   MAC2STR(res->bssid), bss->freq, res->freq);
			bss->freq = res->freq;
		} else if (!bss) {
			wpa_printf(MSG_DEBUG, "bgscan learn: Add BSS " MACSTR
				   " freq=%d", MAC2STR(res->bssid), res->freq);
			bss = os_zalloc(sizeof(*bss));
			if (!bss)
				continue;
			os_memcpy(bss->bssid, res->bssid, ETH_ALEN);
			bss->freq = res->freq;
			dl_list_add(&data->bss, &bss->list);
		}

		for (j = 0; j < num_bssid; j++) {
			u8 *addr = bssid + j * ETH_ALEN;
			bgscan_learn_add_neighbor(bss, addr);
		}
	}

	/*
	 * A more advanced bgscan could process scan results internally, select
	 * the BSS and request roam if needed. This sample uses the existing
	 * BSS/ESS selection routine. Change this to return 1 if selection is
	 * done inside the bgscan module.
	 */

	return 0;
}
Exemple #9
0
static void connection_setup_remove_timeout(struct ctrl_iface_dbus_priv *iface,
					    DBusTimeout *timeout)
{
	eloop_cancel_timeout(process_timeout, iface, timeout);
	dbus_timeout_set_data(timeout, NULL, NULL);
}
Exemple #10
0
/* httpread_read_handler -- called when socket ready to read
 *
 * Note: any extra data we read past end of transmitted file is ignored;
 * if we were to support keeping connections open for multiple files then
 * this would have to be addressed.
 */
static void httpread_read_handler(int sd, void *eloop_ctx, void *sock_ctx)
{
    struct httpread *h = sock_ctx;
    int nread;
    char *rbp;      /* pointer into read buffer */
    char *hbp;      /* pointer into header buffer */
    char *bbp;      /* pointer into body buffer */
    char readbuf[HTTPREAD_READBUF_SIZE];  /* temp use to read into */

    if (httpread_debug >= 20)
        wpa_printf(MSG_DEBUG, "ENTER httpread_read_handler(%p)", h);

    /* read some at a time, then search for the interal
     * boundaries between header and data and etc.
     */
    nread = read(h->sd, readbuf, sizeof(readbuf));
    if (nread < 0)
        goto bad;
    if (nread == 0) {
        /* end of transmission... this may be normal
         * or may be an error... in some cases we can't
         * tell which so we must assume it is normal then.
         */
        if (!h->got_hdr) {
            /* Must at least have completed header */
            wpa_printf(MSG_DEBUG, "httpread premature eof(%p)", h);
            goto bad;
        }
        if (h->chunked || h->got_content_length) {
            /* Premature EOF; e.g. dropped connection */
            wpa_printf(MSG_DEBUG,
                       "httpread premature eof(%p) %d/%d",
                       h, h->body_nbytes,
                       h->content_length);
            goto bad;
        }
        /* No explicit length, hopefully we have all the data
         * although dropped connections can cause false
         * end
         */
        if (httpread_debug >= 10)
            wpa_printf(MSG_DEBUG, "httpread ok eof(%p)", h);
        h->got_body = 1;
        goto got_file;
    }
    rbp = readbuf;

    /* Header consists of text lines (terminated by both CR and LF)
     * and an empty line (CR LF only).
     */
    if (!h->got_hdr) {
        hbp = h->hdr + h->hdr_nbytes;
        /* add to headers until:
         *      -- we run out of data in read buffer
         *      -- or, we run out of header buffer room
         *      -- or, we get double CRLF in headers
         */
        for (;;) {
            if (nread == 0)
                goto get_more;
            if (h->hdr_nbytes == HTTPREAD_HEADER_MAX_SIZE) {
                goto bad;
            }
            *hbp++ = *rbp++;
            nread--;
            h->hdr_nbytes++;
            if (h->hdr_nbytes >= 4 &&
                    hbp[-1] == '\n' &&
                    hbp[-2] == '\r' &&
                    hbp[-3] == '\n' &&
                    hbp[-4] == '\r' ) {
                h->got_hdr = 1;
                *hbp = 0;       /* null terminate */
                break;
            }
        }
        /* here we've just finished reading the header */
        if (httpread_hdr_analyze(h)) {
            wpa_printf(MSG_DEBUG, "httpread bad hdr(%p)", h);
            goto bad;
        }
        if (h->max_bytes == 0) {
            if (httpread_debug >= 10)
                wpa_printf(MSG_DEBUG,
                           "httpread no body hdr end(%p)", h);
            goto got_file;
        }
        if (h->got_content_length && h->content_length == 0) {
            if (httpread_debug >= 10)
                wpa_printf(MSG_DEBUG,
                           "httpread zero content length(%p)",
                           h);
            goto got_file;
        }
    }

    /* Certain types of requests never have data and so
     * must be specially recognized.
     */
    if (!os_strncasecmp(h->hdr, "SUBSCRIBE", 9) ||
            !os_strncasecmp(h->hdr, "UNSUBSCRIBE", 11) ||
            !os_strncasecmp(h->hdr, "HEAD", 4) ||
            !os_strncasecmp(h->hdr, "GET", 3)) {
        if (!h->got_body) {
            if (httpread_debug >= 10)
                wpa_printf(MSG_DEBUG,
                           "httpread NO BODY for sp. type");
        }
        h->got_body = 1;
        goto got_file;
    }

    /* Data can be just plain binary data, or if "chunked"
     * consists of chunks each with a header, ending with
     * an ending header.
     */
    if (!h->got_body) {
        /* Here to get (more of) body */
        /* ensure we have enough room for worst case for body
         * plus a null termination character
         */
        if (h->body_alloc_nbytes < (h->body_nbytes + nread + 1)) {
            char *new_body;
            int new_alloc_nbytes;

            if (h->body_nbytes >= h->max_bytes)
                goto bad;
            new_alloc_nbytes = h->body_alloc_nbytes +
                               HTTPREAD_BODYBUF_DELTA;
            /* For content-length case, the first time
             * through we allocate the whole amount
             * we need.
             */
            if (h->got_content_length &&
                    new_alloc_nbytes < (h->content_length + 1))
                new_alloc_nbytes = h->content_length + 1;
            if ((new_body = os_realloc(h->body, new_alloc_nbytes))
                    == NULL)
                goto bad;

            h->body = new_body;
            h->body_alloc_nbytes = new_alloc_nbytes;
        }
        /* add bytes */
        bbp = h->body + h->body_nbytes;
        for (;;) {
            int ncopy;
            /* See if we need to stop */
            if (h->chunked && h->in_chunk_data == 0) {
                /* in chunk header */
                char *cbp = h->body + h->chunk_start;
                if (bbp-cbp >= 2 && bbp[-2] == '\r' &&
                        bbp[-1] == '\n') {
                    /* end of chunk hdr line */
                    /* hdr line consists solely
                     * of a hex numeral and CFLF
                     */
                    if (!isxdigit(*cbp))
                        goto bad;
                    h->chunk_size = strtoul(cbp, NULL, 16);
                    /* throw away chunk header
                     * so we have only real data
                     */
                    h->body_nbytes = h->chunk_start;
                    bbp = cbp;
                    if (h->chunk_size == 0) {
                        /* end of chunking */
                        /* trailer follows */
                        h->in_trailer = 1;
                        if (httpread_debug >= 20)
                            wpa_printf(
                                MSG_DEBUG,
                                "httpread end chunks(%p)", h);
                        break;
                    }
                    h->in_chunk_data = 1;
                    /* leave chunk_start alone */
                }
            } else if (h->chunked) {
                /* in chunk data */
                if ((h->body_nbytes - h->chunk_start) ==
                        (h->chunk_size + 2)) {
                    /* end of chunk reached,
                     * new chunk starts
                     */
                    /* check chunk ended w/ CRLF
                     * which we'll throw away
                     */
                    if (bbp[-1] == '\n' &&
                            bbp[-2] == '\r') {
                    } else
                        goto bad;
                    h->body_nbytes -= 2;
                    bbp -= 2;
                    h->chunk_start = h->body_nbytes;
                    h->in_chunk_data = 0;
                    h->chunk_size = 0; /* just in case */
                }
            } else if (h->got_content_length &&
                       h->body_nbytes >= h->content_length) {
                h->got_body = 1;
                if (httpread_debug >= 10)
                    wpa_printf(
                        MSG_DEBUG,
                        "httpread got content(%p)", h);
                goto got_file;
            }
            if (nread <= 0)
                break;
            /* Now transfer. Optimize using memcpy where we can. */
            if (h->chunked && h->in_chunk_data) {
                /* copy up to remainder of chunk data
                 * plus the required CR+LF at end
                 */
                ncopy = (h->chunk_start + h->chunk_size + 2) -
                        h->body_nbytes;
            } else if (h->chunked) {
                /*in chunk header -- don't optimize */
                *bbp++ = *rbp++;
                nread--;
                h->body_nbytes++;
                continue;
            } else if (h->got_content_length) {
                ncopy = h->content_length - h->body_nbytes;
            } else {
                ncopy = nread;
            }
            /* Note: should never be 0 */
            if (ncopy > nread)
                ncopy = nread;
            os_memcpy(bbp, rbp, ncopy);
            bbp += ncopy;
            h->body_nbytes += ncopy;
            rbp += ncopy;
            nread -= ncopy;
        }       /* body copy loop */
    }       /* !got_body */
    if (h->chunked && h->in_trailer) {
        /* If "chunked" then there is always a trailer,
         * consisting of zero or more non-empty lines
         * ending with CR LF and then an empty line w/ CR LF.
         * We do NOT support trailers except to skip them --
         * this is supported (generally) by the http spec.
         */
        bbp = h->body + h->body_nbytes;
        for (;;) {
            int c;
            if (nread <= 0)
                break;
            c = *rbp++;
            nread--;
            switch (h->trailer_state) {
            case trailer_line_begin:
                if (c == '\r')
                    h->trailer_state = trailer_empty_cr;
                else
                    h->trailer_state = trailer_nonempty;
                break;
            case trailer_empty_cr:
                /* end empty line */
                if (c == '\n') {
                    h->trailer_state = trailer_line_begin;
                    h->in_trailer = 0;
                    if (httpread_debug >= 10)
                        wpa_printf(
                            MSG_DEBUG,
                            "httpread got content(%p)", h);
                    h->got_body = 1;
                    goto got_file;
                }
                h->trailer_state = trailer_nonempty;
                break;
            case trailer_nonempty:
                if (c == '\r')
                    h->trailer_state = trailer_nonempty_cr;
                break;
            case trailer_nonempty_cr:
                if (c == '\n')
                    h->trailer_state = trailer_line_begin;
                else
                    h->trailer_state = trailer_nonempty;
                break;
            }
        }
    }
    goto get_more;

bad:
    /* Error */
    wpa_printf(MSG_DEBUG, "httpread read/parse failure (%p)", h);
    (*h->cb)(h, h->cookie, HTTPREAD_EVENT_ERROR);
    return;

get_more:
    return;

got_file:
    if (httpread_debug >= 10)
        wpa_printf(MSG_DEBUG,
                   "httpread got file %d bytes type %d",
                   h->body_nbytes, h->hdr_type);
    /* Null terminate for convenience of some applications */
    if (h->body)
        h->body[h->body_nbytes] = 0; /* null terminate */
    h->got_file = 1;
    /* Assume that we do NOT support keeping connection alive,
     * and just in case somehow we don't get destroyed right away,
     * unregister now.
     */
    if (h->sd_registered)
        eloop_unregister_sock(h->sd, EVENT_TYPE_READ);
    h->sd_registered = 0;
    /* The application can destroy us whenever they feel like...
     * cancel timeout.
     */
    if (h->to_registered)
        eloop_cancel_timeout(httpread_timeout_handler, NULL, h);
    h->to_registered = 0;
    (*h->cb)(h, h->cookie, HTTPREAD_EVENT_FILE_READY);
}
Exemple #11
0
void hostapd_deinit_ht(struct hostapd_iface *iface)
{
	eloop_cancel_timeout(hostapd_restore_40mhz, iface, NULL);
}
static int
radius_change_server(struct radius_client_data *radius,
		     struct hostapd_radius_server *nserv,
		     struct hostapd_radius_server *oserv,
		     int sock, int sock6, int auth)
{
	struct sockaddr_in serv;
#ifdef CONFIG_IPV6
	struct sockaddr_in6 serv6;
#endif /* CONFIG_IPV6 */
	struct sockaddr *addr;
	socklen_t addrlen;
	char abuf[50];
	int sel_sock;
	struct radius_msg_list *entry;

	hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
		       HOSTAPD_LEVEL_INFO,
		       "%s server %s:%d",
		       auth ? "Authentication" : "Accounting",
		       hostapd_ip_txt(&nserv->addr, abuf, sizeof(abuf)),
		       nserv->port);

	if (!oserv || nserv->shared_secret_len != oserv->shared_secret_len ||
	    os_memcmp(nserv->shared_secret, oserv->shared_secret,
		      nserv->shared_secret_len) != 0) {
		/* Pending RADIUS packets used different shared secret, so
		 * they need to be modified. Update accounting message
		 * authenticators here. Authentication messages are removed
		 * since they would require more changes and the new RADIUS
		 * server may not be prepared to receive them anyway due to
		 * missing state information. Client will likely retry
		 * authentication, so this should not be an issue. */
		if (auth)
			radius_client_flush(radius, 1);
		else {
			radius_client_update_acct_msgs(
				radius, nserv->shared_secret,
				nserv->shared_secret_len);
		}
	}

	/* Reset retry counters for the new server */
	for (entry = radius->msgs; entry; entry = entry->next) {
		if ((auth && entry->msg_type != RADIUS_AUTH) ||
		    (!auth && entry->msg_type != RADIUS_ACCT))
			continue;
		entry->next_try = entry->first_try + RADIUS_CLIENT_FIRST_WAIT;
		entry->attempts = 0;
		entry->next_wait = RADIUS_CLIENT_FIRST_WAIT * 2;
	}

	if (radius->msgs) {
		eloop_cancel_timeout(radius_client_timer, radius, NULL);
		eloop_register_timeout(RADIUS_CLIENT_FIRST_WAIT, 0,
				       radius_client_timer, radius, NULL);
	}

	switch (nserv->addr.af) {
	case AF_INET:
		os_memset(&serv, 0, sizeof(serv));
		serv.sin_family = AF_INET;
		serv.sin_addr.s_addr = nserv->addr.u.v4.s_addr;
		serv.sin_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv;
		addrlen = sizeof(serv);
		sel_sock = sock;
		break;
#ifdef CONFIG_IPV6
	case AF_INET6:
		os_memset(&serv6, 0, sizeof(serv6));
		serv6.sin6_family = AF_INET6;
		os_memcpy(&serv6.sin6_addr, &nserv->addr.u.v6,
			  sizeof(struct in6_addr));
		serv6.sin6_port = htons(nserv->port);
		addr = (struct sockaddr *) &serv6;
		addrlen = sizeof(serv6);
		sel_sock = sock6;
		break;
#endif /* CONFIG_IPV6 */
	default:
		return -1;
	}

	if (connect(sel_sock, addr, addrlen) < 0) {
		perror("connect[radius]");
		return -1;
	}

	if (auth)
		radius->auth_sock = sel_sock;
	else
		radius->acct_sock = sel_sock;

	return 0;
}
Exemple #13
0
void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
{
	const u8 *ie;
	struct wpa_bss *bss = wpa_s->current_bss;
	struct wpa_ssid *ssid = wpa_s->current_ssid;
	struct hostapd_hw_modes *hw_mode = NULL;
	int i;

	eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
	wpa_s->sme.sched_obss_scan = 0;
	if (!enable)
		return;

	/*
	 * Schedule OBSS scan if driver is using station SME in wpa_supplicant
	 * or it expects OBSS scan to be performed by wpa_supplicant.
	 */
	if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
	      (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) ||
	    ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA)
		return;

	if (!wpa_s->hw.modes)
		return;

	/* only HT caps in 11g mode are relevant */
	for (i = 0; i < wpa_s->hw.num_modes; i++) {
		hw_mode = &wpa_s->hw.modes[i];
		if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G)
			break;
	}

	/* Driver does not support HT40 for 11g or doesn't have 11g. */
	if (i == wpa_s->hw.num_modes || !hw_mode ||
	    !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
		return;

	if (bss == NULL || bss->freq < 2400 || bss->freq > 2500)
		return; /* Not associated on 2.4 GHz band */

	/* Check whether AP supports HT40 */
	ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP);
	if (!ie || ie[1] < 2 ||
	    !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
		return; /* AP does not support HT40 */

	ie = wpa_bss_get_ie(wpa_s->current_bss,
			    WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS);
	if (!ie || ie[1] < 14)
		return; /* AP does not request OBSS scans */

	wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6);
	if (wpa_s->sme.obss_scan_int < 10) {
		wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u "
			   "replaced with the minimum 10 sec",
			   wpa_s->sme.obss_scan_int);
		wpa_s->sme.obss_scan_int = 10;
	}
	wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec",
		   wpa_s->sme.obss_scan_int);
	eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
			       sme_obss_scan_timeout, wpa_s, NULL);
}
Exemple #14
0
void offchannel_deinit(struct wpa_supplicant *wpa_s)
{
	wpabuf_free(wpa_s->pending_action_tx);
	wpa_s->pending_action_tx = NULL;
	eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
}
Exemple #15
0
static void eap_wsc_process(struct eap_sm *sm, void *priv,
			    struct wpabuf *respData)
{
	struct eap_wsc_data *data = priv;
	const u8 *start, *pos, *end;
	size_t len;
	u8 op_code, flags;
	u16 message_length = 0;
	enum wps_process_res res;
	struct wpabuf tmpbuf;

	eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
	if (data->ext_reg_timeout) {
		eap_wsc_state(data, FAIL);
		return;
	}

	pos = eap_hdr_validate(EAP_VENDOR_WFA, EAP_VENDOR_TYPE_WSC,
			       respData, &len);
	if (pos == NULL || len < 2)
		return; /* Should not happen; message already verified */

	start = pos;
	end = start + len;

	op_code = *pos++;
	flags = *pos++;
	if (flags & WSC_FLAGS_LF) {
		if (end - pos < 2) {
			wpa_printf(MSG_DEBUG, "EAP-WSC: Message underflow");
			return;
		}
		message_length = WPA_GET_BE16(pos);
		pos += 2;

		if (message_length < end - pos) {
			wpa_printf(MSG_DEBUG, "EAP-WSC: Invalid Message "
				   "Length");
			return;
		}
	}

	wpa_printf(MSG_DEBUG, "EAP-WSC: Received packet: Op-Code %d "
		   "Flags 0x%x Message Length %d",
		   op_code, flags, message_length);

	if (data->state == WAIT_FRAG_ACK) {
		if (op_code != WSC_FRAG_ACK) {
			wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d "
				   "in WAIT_FRAG_ACK state", op_code);
			eap_wsc_state(data, FAIL);
			return;
		}
		wpa_printf(MSG_DEBUG, "EAP-WSC: Fragment acknowledged");
		eap_wsc_state(data, MESG);
		return;
	}

	if (op_code != WSC_ACK && op_code != WSC_NACK && op_code != WSC_MSG &&
	    op_code != WSC_Done) {
		wpa_printf(MSG_DEBUG, "EAP-WSC: Unexpected Op-Code %d",
			   op_code);
		eap_wsc_state(data, FAIL);
		return;
	}

	if (data->in_buf &&
	    eap_wsc_process_cont(data, pos, end - pos, op_code) < 0) {
		eap_wsc_state(data, FAIL);
		return;
	}

	if (flags & WSC_FLAGS_MF) {
		if (eap_wsc_process_fragment(data, flags, op_code,
					     message_length, pos, end - pos) <
		    0)
			eap_wsc_state(data, FAIL);
		else
			eap_wsc_state(data, FRAG_ACK);
		return;
	}

	if (data->in_buf == NULL) {
		/* Wrap unfragmented messages as wpabuf without extra copy */
		wpabuf_set(&tmpbuf, pos, end - pos);
		data->in_buf = &tmpbuf;
	}

	res = wps_process_msg(data->wps, op_code, data->in_buf);
	switch (res) {
	case WPS_DONE:
		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing completed "
			   "successfully - report EAP failure");
		eap_wsc_state(data, FAIL);
		break;
	case WPS_CONTINUE:
		eap_wsc_state(data, MESG);
		break;
	case WPS_FAILURE:
		wpa_printf(MSG_DEBUG, "EAP-WSC: WPS processing failed");
		eap_wsc_state(data, FAIL);
		break;
	case WPS_PENDING:
		eap_wsc_state(data, MESG);
		sm->method_pending = METHOD_PENDING_WAIT;
		eloop_cancel_timeout(eap_wsc_ext_reg_timeout, sm, data);
		eloop_register_timeout(5, 0, eap_wsc_ext_reg_timeout,
				       sm, data);
		break;
	}

	if (data->in_buf != &tmpbuf)
		wpabuf_free(data->in_buf);
	data->in_buf = NULL;
}
Exemple #16
0
void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
{
	struct wpa_ssid *ssid = wpa_s->current_ssid;

	if (ssid == NULL) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
			"when network is not selected");
		return;
	}

	if (wpa_s->wpa_state != WPA_AUTHENTICATING) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
			"when not in authenticating state");
		return;
	}

	if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with "
			"unexpected peer " MACSTR,
			MAC2STR(data->auth.peer));
		return;
	}

	wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR
		" auth_type=%d status_code=%d",
		MAC2STR(data->auth.peer), data->auth.auth_type,
		data->auth.status_code);
	wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
		    data->auth.ies, data->auth.ies_len);

	eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);

	if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication failed (status "
			"code %d)", data->auth.status_code);

		if (data->auth.status_code !=
		    WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
		    wpa_s->sme.auth_alg == data->auth.auth_type ||
		    wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
			wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
			return;
		}

		switch (data->auth.auth_type) {
		case WLAN_AUTH_OPEN:
			wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;

			wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth");
			wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
						 wpa_s->current_ssid);
			return;

		case WLAN_AUTH_SHARED_KEY:
			wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP;

			wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth");
			wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
						 wpa_s->current_ssid);
			return;

		default:
			return;
		}
	}

#ifdef CONFIG_IEEE80211R
	if (data->auth.auth_type == WLAN_AUTH_FT) {
		union wpa_event_data edata;
		os_memset(&edata, 0, sizeof(edata));
		edata.ft_ies.ies = data->auth.ies;
		edata.ft_ies.ies_len = data->auth.ies_len;
		os_memcpy(edata.ft_ies.target_ap, data->auth.peer, ETH_ALEN);
		wpa_supplicant_event(wpa_s, EVENT_FT_RESPONSE, &edata);
	}
#endif /* CONFIG_IEEE80211R */

	sme_associate(wpa_s, ssid->mode, data->auth.peer,
		      data->auth.auth_type);
}
Exemple #17
0
/**
 * offchannel_send_action - Request off-channel Action frame TX
 * @wpa_s: Pointer to wpa_supplicant data
 * @freq: The frequency in MHz indicating the channel on which the frame is to
 *	transmitted or 0 for the current channel (only if associated)
 * @dst: Action frame destination MAC address
 * @src: Action frame source MAC address
 * @bssid: Action frame BSSID
 * @buf: Frame to transmit starting from the Category field
 * @len: Length of @buf in bytes
 * @wait_time: Wait time for response in milliseconds
 * @tx_cb: Callback function for indicating TX status or %NULL for now callback
 * @no_cck: Whether CCK rates are to be disallowed for TX rate selection
 * Returns: 0 on success or -1 on failure
 *
 * This function is used to request an Action frame to be transmitted on the
 * current operating channel or on another channel (off-channel). The actual
 * frame transmission will be delayed until the driver is ready on the specified
 * channel. The @wait_time parameter can be used to request the driver to remain
 * awake on the channel to wait for a response.
 */
int offchannel_send_action(struct wpa_supplicant *wpa_s, unsigned int freq,
			   const u8 *dst, const u8 *src, const u8 *bssid,
			   const u8 *buf, size_t len, unsigned int wait_time,
			   void (*tx_cb)(struct wpa_supplicant *wpa_s,
					 unsigned int freq, const u8 *dst,
					 const u8 *src, const u8 *bssid,
					 const u8 *data, size_t data_len,
					 enum offchannel_send_action_result
					 result),
			   int no_cck)
{
	wpa_printf(MSG_DEBUG, "Off-channel: Send action frame: freq=%d dst="
		   MACSTR " src=" MACSTR " bssid=" MACSTR " len=%d",
		   freq, MAC2STR(dst), MAC2STR(src), MAC2STR(bssid),
		   (int) len);

	wpa_s->pending_action_tx_status_cb = tx_cb;

	if (wpa_s->pending_action_tx) {
		wpa_printf(MSG_DEBUG, "Off-channel: Dropped pending Action "
			   "frame TX to " MACSTR,
			   MAC2STR(wpa_s->pending_action_dst));
		wpabuf_free(wpa_s->pending_action_tx);
	}
	wpa_s->pending_action_tx_done = 0;
	wpa_s->pending_action_tx = wpabuf_alloc(len);
	if (wpa_s->pending_action_tx == NULL) {
		wpa_printf(MSG_DEBUG, "Off-channel: Failed to allocate Action "
			   "frame TX buffer (len=%llu)",
			   (unsigned long long) len);
		return -1;
	}
	wpabuf_put_data(wpa_s->pending_action_tx, buf, len);
	os_memcpy(wpa_s->pending_action_src, src, ETH_ALEN);
	os_memcpy(wpa_s->pending_action_dst, dst, ETH_ALEN);
	os_memcpy(wpa_s->pending_action_bssid, bssid, ETH_ALEN);
	wpa_s->pending_action_freq = freq;
	wpa_s->pending_action_no_cck = no_cck;

	if (freq != 0 && wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX) {
		struct wpa_supplicant *iface;
		int ret;

		iface = wpas_get_tx_interface(wpa_s, src);
		wpa_s->action_tx_wait_time = wait_time;

		ret = wpa_drv_send_action(
			iface, wpa_s->pending_action_freq,
			wait_time, wpa_s->pending_action_dst,
			wpa_s->pending_action_src, wpa_s->pending_action_bssid,
			wpabuf_head(wpa_s->pending_action_tx),
			wpabuf_len(wpa_s->pending_action_tx),
			wpa_s->pending_action_no_cck);
		if (ret == 0)
			wpa_s->pending_action_tx_done = 1;
		return ret;
	}

	if (freq) {
		struct wpa_supplicant *tx_iface;
		tx_iface = wpas_get_tx_interface(wpa_s, src);
		if (tx_iface->assoc_freq == freq) {
			wpa_printf(MSG_DEBUG, "Off-channel: Already on "
				   "requested channel (TX interface operating "
				   "channel)");
			freq = 0;
		}
	}

	if (wpa_s->off_channel_freq == freq || freq == 0) {
		wpa_printf(MSG_DEBUG, "Off-channel: Already on requested "
			   "channel; send Action frame immediately");
		/* TODO: Would there ever be need to extend the current
		 * duration on the channel? */
		wpa_s->pending_action_without_roc = 1;
		eloop_cancel_timeout(wpas_send_action_cb, wpa_s, NULL);
		eloop_register_timeout(0, 0, wpas_send_action_cb, wpa_s, NULL);
		return 0;
	}
	wpa_s->pending_action_without_roc = 0;

	if (wpa_s->roc_waiting_drv_freq == freq) {
		wpa_printf(MSG_DEBUG, "Off-channel: Already waiting for "
			   "driver to get to frequency %u MHz; continue "
			   "waiting to send the Action frame", freq);
		return 0;
	}

	wpa_printf(MSG_DEBUG, "Off-channel: Schedule Action frame to be "
		   "transmitted once the driver gets to the requested "
		   "channel");
	if (wait_time > wpa_s->max_remain_on_chan)
		wait_time = wpa_s->max_remain_on_chan;
	else if (wait_time == 0)
		wait_time = 20;
#ifdef CONFIG_TESTING_OPTIONS
	if (wpa_s->extra_roc_dur) {
		wpa_printf(MSG_DEBUG, "TESTING: Increase ROC duration %u -> %u",
			   wait_time, wait_time + wpa_s->extra_roc_dur);
		wait_time += wpa_s->extra_roc_dur;
	}
#endif /* CONFIG_TESTING_OPTIONS */
	if (wpa_drv_remain_on_channel(wpa_s, freq, wait_time) < 0) {
		wpa_printf(MSG_DEBUG, "Off-channel: Failed to request driver "
			   "to remain on channel (%u MHz) for Action "
			   "Frame TX", freq);
		return -1;
	}
	wpa_s->off_channel_freq = 0;
	wpa_s->roc_waiting_drv_freq = freq;

	return 0;
}
Exemple #18
0
void ap_list_deinit(struct hostapd_iface *iface)
{
	eloop_cancel_timeout(ap_list_timer, iface, NULL);
	hostapd_free_aps(iface);
}
void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd)
{
	eloop_cancel_timeout(ieee80211_tkip_countermeasures_stop, hapd, NULL);
}
Exemple #20
0
void hostapd_stop_setup_timers(struct hostapd_iface *iface)
{
	eloop_cancel_timeout(ap_ht40_scan_retry, iface, NULL);
}
void hs20_icon_fetch_failed(struct wpa_supplicant *wpa_s)
{
	hs20_osu_icon_fetch_result(wpa_s, -1);
	eloop_cancel_timeout(hs20_continue_icon_fetch, wpa_s, NULL);
	eloop_register_timeout(0, 0, hs20_continue_icon_fetch, wpa_s, NULL);
}
Exemple #22
0
int main(int argc, char *argv[])
{
	struct wpa_supplicant wpa_s;
	int c, ret = 1, wait_for_monitor = 0, save_config = 0;
	char *as_addr = "127.0.0.1";
	int as_port = 1812;
	char *as_secret = "radius";
	char *cli_addr = NULL;
	char *conf = NULL;
	int timeout = 30;
	char *pos;
	struct extra_radius_attr *p = NULL, *p1;

	if (os_program_init())
		return -1;

	hostapd_logger_register_cb(hostapd_logger_cb);

	os_memset(&eapol_test, 0, sizeof(eapol_test));
	eapol_test.connect_info = "CONNECT 11Mbps 802.11b";
	os_memcpy(eapol_test.own_addr, "\x02\x00\x00\x00\x00\x01", ETH_ALEN);

	wpa_debug_level = 0;
	wpa_debug_show_keys = 1;

	for (;;) {
		c = getopt(argc, argv, "a:A:c:C:M:nN:p:r:s:St:W");
		if (c < 0)
			break;
		switch (c) {
		case 'a':
			as_addr = optarg;
			break;
		case 'A':
			cli_addr = optarg;
			break;
		case 'c':
			conf = optarg;
			break;
		case 'C':
			eapol_test.connect_info = optarg;
			break;
		case 'M':
			if (hwaddr_aton(optarg, eapol_test.own_addr)) {
				usage();
				return -1;
			}
			break;
		case 'n':
			eapol_test.no_mppe_keys++;
			break;
		case 'p':
			as_port = atoi(optarg);
			break;
		case 'r':
			eapol_test.eapol_test_num_reauths = atoi(optarg);
			break;
		case 's':
			as_secret = optarg;
			break;
		case 'S':
			save_config++;
			break;
		case 't':
			timeout = atoi(optarg);
			break;
		case 'W':
			wait_for_monitor++;
			break;
		case 'N':
			p1 = os_zalloc(sizeof(p1));
			if (p1 == NULL)
				break;
			if (!p)
				eapol_test.extra_attrs = p1;
			else
				p->next = p1;
			p = p1;

			p->type = atoi(optarg);
			pos = os_strchr(optarg, ':');
			if (pos == NULL) {
				p->syntax = 'n';
				p->data = NULL;
				break;
			}

			pos++;
			if (pos[0] == '\0' || pos[1] != ':') {
				printf("Incorrect format of attribute "
				       "specification\n");
				break;
			}

			p->syntax = pos[0];
			p->data = pos + 2;
			break;
		default:
			usage();
			return -1;
		}
	}

	if (argc > optind && os_strcmp(argv[optind], "scard") == 0) {
		return scard_test();
	}

	if (argc > optind && os_strcmp(argv[optind], "sim") == 0) {
		return scard_get_triplets(argc - optind - 1,
					  &argv[optind + 1]);
	}

	if (conf == NULL) {
		usage();
		printf("Configuration file is required.\n");
		return -1;
	}

	if (eap_register_methods()) {
		wpa_printf(MSG_ERROR, "Failed to register EAP methods");
		return -1;
	}

	if (eloop_init()) {
		wpa_printf(MSG_ERROR, "Failed to initialize event loop");
		return -1;
	}

	os_memset(&wpa_s, 0, sizeof(wpa_s));
	eapol_test.wpa_s = &wpa_s;
	wpa_s.conf = wpa_config_read(conf);
	if (wpa_s.conf == NULL) {
		printf("Failed to parse configuration file '%s'.\n", conf);
		return -1;
	}
	if (wpa_s.conf->ssid == NULL) {
		printf("No networks defined.\n");
		return -1;
	}

	wpa_init_conf(&eapol_test, &wpa_s, as_addr, as_port, as_secret,
		      cli_addr);
	wpa_s.ctrl_iface = wpa_supplicant_ctrl_iface_init(&wpa_s);
	if (wpa_s.ctrl_iface == NULL) {
		printf("Failed to initialize control interface '%s'.\n"
		       "You may have another eapol_test process already "
		       "running or the file was\n"
		       "left by an unclean termination of eapol_test in "
		       "which case you will need\n"
		       "to manually remove this file before starting "
		       "eapol_test again.\n",
		       wpa_s.conf->ctrl_interface);
		return -1;
	}
	if (wpa_supplicant_scard_init(&wpa_s, wpa_s.conf->ssid))
		return -1;

	if (test_eapol(&eapol_test, &wpa_s, wpa_s.conf->ssid))
		return -1;

	if (wait_for_monitor)
		wpa_supplicant_ctrl_iface_wait(wpa_s.ctrl_iface);

	eloop_register_timeout(timeout, 0, eapol_test_timeout, &eapol_test,
			       NULL);
	eloop_register_timeout(0, 0, send_eap_request_identity, &wpa_s, NULL);
	eloop_register_signal_terminate(eapol_test_terminate, &wpa_s);
	eloop_register_signal_reconfig(eapol_test_terminate, &wpa_s);
	eloop_run();

	eloop_cancel_timeout(eapol_test_timeout, &eapol_test, NULL);
	eloop_cancel_timeout(eapol_sm_reauth, &eapol_test, NULL);

	if (eapol_test_compare_pmk(&eapol_test) == 0 ||
	    eapol_test.no_mppe_keys)
		ret = 0;
	if (eapol_test.auth_timed_out)
		ret = -2;
	if (eapol_test.radius_access_reject_received)
		ret = -3;

	if (save_config)
		wpa_config_write(conf, wpa_s.conf);

	test_eapol_clean(&eapol_test, &wpa_s);

	eap_peer_unregister_methods();

	eloop_destroy();

	printf("MPPE keys OK: %d  mismatch: %d\n",
	       eapol_test.num_mppe_ok, eapol_test.num_mppe_mismatch);
	if (eapol_test.num_mppe_mismatch)
		ret = -4;
	if (ret)
		printf("FAILURE\n");
	else
		printf("SUCCESS\n");

	os_program_deinit();

	return ret;
}
void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
{
	int set_beacon = 0;

	accounting_sta_stop(hapd, sta);

	/* just in case */
	ap_sta_set_authorized(hapd, sta, 0);

	if (sta->flags & WLAN_STA_WDS)
		hostapd_set_wds_sta(hapd, NULL, sta->addr, sta->aid, 0);

	if (!hapd->iface->driver_ap_teardown &&
	    !(sta->flags & WLAN_STA_PREAUTH))
		hostapd_drv_sta_remove(hapd, sta->addr);

	ap_sta_hash_del(hapd, sta);
	ap_sta_list_del(hapd, sta);

	if (sta->aid > 0)
		hapd->sta_aid[(sta->aid - 1) / 32] &=
			~BIT((sta->aid - 1) % 32);

	hapd->num_sta--;
	if (sta->nonerp_set) {
		sta->nonerp_set = 0;
		hapd->iface->num_sta_non_erp--;
		if (hapd->iface->num_sta_non_erp == 0)
			set_beacon++;
	}

	if (sta->no_short_slot_time_set) {
		sta->no_short_slot_time_set = 0;
		hapd->iface->num_sta_no_short_slot_time--;
		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
		    && hapd->iface->num_sta_no_short_slot_time == 0)
			set_beacon++;
	}

	if (sta->no_short_preamble_set) {
		sta->no_short_preamble_set = 0;
		hapd->iface->num_sta_no_short_preamble--;
		if (hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
		    && hapd->iface->num_sta_no_short_preamble == 0)
			set_beacon++;
	}

	if (sta->no_ht_gf_set) {
		sta->no_ht_gf_set = 0;
		hapd->iface->num_sta_ht_no_gf--;
	}

	if (sta->no_ht_set) {
		sta->no_ht_set = 0;
		hapd->iface->num_sta_no_ht--;
	}

	if (sta->ht_20mhz_set) {
		sta->ht_20mhz_set = 0;
		hapd->iface->num_sta_ht_20mhz--;
	}

#ifdef CONFIG_IEEE80211N
	ht40_intolerant_remove(hapd->iface, sta);
#endif /* CONFIG_IEEE80211N */

#ifdef CONFIG_P2P
	if (sta->no_p2p_set) {
		sta->no_p2p_set = 0;
		hapd->num_sta_no_p2p--;
		if (hapd->num_sta_no_p2p == 0)
			hostapd_p2p_non_p2p_sta_disconnected(hapd);
	}
#endif /* CONFIG_P2P */

#if defined(NEED_AP_MLME) && defined(CONFIG_IEEE80211N)
	if (hostapd_ht_operation_update(hapd->iface) > 0)
		set_beacon++;
#endif /* NEED_AP_MLME && CONFIG_IEEE80211N */

	if (set_beacon)
		ieee802_11_set_beacons(hapd->iface);

	wpa_printf(MSG_DEBUG, "%s: cancel ap_handle_timer for " MACSTR,
		   __func__, MAC2STR(sta->addr));
	eloop_cancel_timeout(ap_handle_timer, hapd, sta);
	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
	eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
	eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
	eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);

	ieee802_1x_free_station(sta);
	wpa_auth_sta_deinit(sta->wpa_sm);
	rsn_preauth_free_station(hapd, sta);
#ifndef CONFIG_NO_RADIUS
	if (hapd->radius)
		radius_client_flush_auth(hapd->radius, sta->addr);
#endif /* CONFIG_NO_RADIUS */

	os_free(sta->challenge);

#ifdef CONFIG_IEEE80211W
	os_free(sta->sa_query_trans_id);
	eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
#endif /* CONFIG_IEEE80211W */

#ifdef CONFIG_P2P
	p2p_group_notif_disassoc(hapd->p2p_group, sta->addr);
#endif /* CONFIG_P2P */

#ifdef CONFIG_INTERWORKING
	if (sta->gas_dialog) {
		int i;
		for (i = 0; i < GAS_DIALOG_MAX; i++)
			gas_serv_dialog_clear(&sta->gas_dialog[i]);
		os_free(sta->gas_dialog);
	}
#endif /* CONFIG_INTERWORKING */

	wpabuf_free(sta->wps_ie);
	wpabuf_free(sta->p2p_ie);
	wpabuf_free(sta->hs20_ie);

	os_free(sta->ht_capabilities);
	os_free(sta->vht_capabilities);
	hostapd_free_psk_list(sta->psk);
	os_free(sta->identity);
	os_free(sta->radius_cui);
	os_free(sta->remediation_url);
	wpabuf_free(sta->hs20_deauth_req);
	os_free(sta->hs20_session_info_url);

#ifdef CONFIG_SAE
	sae_clear_data(sta->sae);
	os_free(sta->sae);
#endif /* CONFIG_SAE */

	os_free(sta);
}
static int radius_server_request(struct radius_server_data *data,
				 struct radius_msg *msg,
				 struct sockaddr *from, socklen_t fromlen,
				 struct radius_client *client,
				 const char *from_addr, int from_port,
				 struct radius_session *force_sess)
{
	u8 *eap = NULL;
	size_t eap_len;
	int res, state_included = 0;
	u8 statebuf[4];
	unsigned int state;
	struct radius_session *sess;
	struct radius_msg *reply;
	int is_complete = 0;

	if (force_sess)
		sess = force_sess;
	else {
		res = radius_msg_get_attr(msg, RADIUS_ATTR_STATE, statebuf,
					  sizeof(statebuf));
		state_included = res >= 0;
		if (res == sizeof(statebuf)) {
			state = WPA_GET_BE32(statebuf);
			sess = radius_server_get_session(client, state);
		} else {
			sess = NULL;
		}
	}

	if (sess) {
		RADIUS_DEBUG("Request for session 0x%x", sess->sess_id);
	} else if (state_included) {
		RADIUS_DEBUG("State attribute included but no session found");
		radius_server_reject(data, client, msg, from, fromlen,
				     from_addr, from_port);
		return -1;
	} else {
		sess = radius_server_get_new_session(data, client, msg);
		if (sess == NULL) {
			RADIUS_DEBUG("Could not create a new session");
			radius_server_reject(data, client, msg, from, fromlen,
					     from_addr, from_port);
			return -1;
		}
	}

	if (sess->last_from_port == from_port &&
	    sess->last_identifier == msg->hdr->identifier &&
	    os_memcmp(sess->last_authenticator, msg->hdr->authenticator, 16) ==
	    0) {
		RADIUS_DEBUG("Duplicate message from %s", from_addr);
		data->counters.dup_access_requests++;
		client->counters.dup_access_requests++;

		if (sess->last_reply) {
			res = sendto(data->auth_sock, sess->last_reply->buf,
				     sess->last_reply->buf_used, 0,
				     (struct sockaddr *) from, fromlen);
			if (res < 0) {
				perror("sendto[RADIUS SRV]");
			}
			return 0;
		}

		RADIUS_DEBUG("No previous reply available for duplicate "
			     "message");
		return -1;
	}
		      
	eap = radius_msg_get_eap(msg, &eap_len);
	if (eap == NULL) {
		RADIUS_DEBUG("No EAP-Message in RADIUS packet from %s",
			     from_addr);
		data->counters.packets_dropped++;
		client->counters.packets_dropped++;
		return -1;
	}

	RADIUS_DUMP("Received EAP data", eap, eap_len);

	/* FIX: if Code is Request, Success, or Failure, send Access-Reject;
	 * RFC3579 Sect. 2.6.2.
	 * Include EAP-Response/Nak with no preferred method if
	 * code == request.
	 * If code is not 1-4, discard the packet silently.
	 * Or is this already done by the EAP state machine? */

	wpabuf_free(sess->eap_if->eapRespData);
	sess->eap_if->eapRespData = wpabuf_alloc_ext_data(eap, eap_len);
	if (sess->eap_if->eapRespData == NULL)
		os_free(eap);
	eap = NULL;
	sess->eap_if->eapResp = TRUE;
	eap_server_sm_step(sess->eap);

	if ((sess->eap_if->eapReq || sess->eap_if->eapSuccess ||
	     sess->eap_if->eapFail) && sess->eap_if->eapReqData) {
		RADIUS_DUMP("EAP data from the state machine",
			    wpabuf_head(sess->eap_if->eapReqData),
			    wpabuf_len(sess->eap_if->eapReqData));
	} else if (sess->eap_if->eapFail) {
		RADIUS_DEBUG("No EAP data from the state machine, but eapFail "
			     "set");
	} else if (eap_sm_method_pending(sess->eap)) {
		if (sess->last_msg) {
			radius_msg_free(sess->last_msg);
			os_free(sess->last_msg);
		}
		sess->last_msg = msg;
		sess->last_from_port = from_port;
		os_free(sess->last_from_addr);
		sess->last_from_addr = os_strdup(from_addr);
		sess->last_fromlen = fromlen;
		os_memcpy(&sess->last_from, from, fromlen);
		return -2;
	} else {
		RADIUS_DEBUG("No EAP data from the state machine - ignore this"
			     " Access-Request silently (assuming it was a "
			     "duplicate)");
		data->counters.packets_dropped++;
		client->counters.packets_dropped++;
		return -1;
	}

	if (sess->eap_if->eapSuccess || sess->eap_if->eapFail)
		is_complete = 1;

	reply = radius_server_encapsulate_eap(data, client, sess, msg);

	if (reply) {
		RADIUS_DEBUG("Reply to %s:%d", from_addr, from_port);
		if (wpa_debug_level <= MSG_MSGDUMP) {
			radius_msg_dump(reply);
		}

		switch (reply->hdr->code) {
		case RADIUS_CODE_ACCESS_ACCEPT:
			data->counters.access_accepts++;
			client->counters.access_accepts++;
			break;
		case RADIUS_CODE_ACCESS_REJECT:
			data->counters.access_rejects++;
			client->counters.access_rejects++;
			break;
		case RADIUS_CODE_ACCESS_CHALLENGE:
			data->counters.access_challenges++;
			client->counters.access_challenges++;
			break;
		}
		res = sendto(data->auth_sock, reply->buf, reply->buf_used, 0,
			     (struct sockaddr *) from, fromlen);
		if (res < 0) {
			perror("sendto[RADIUS SRV]");
		}
		if (sess->last_reply) {
			radius_msg_free(sess->last_reply);
			os_free(sess->last_reply);
		}
		sess->last_reply = reply;
		sess->last_from_port = from_port;
		sess->last_identifier = msg->hdr->identifier;
		os_memcpy(sess->last_authenticator, msg->hdr->authenticator,
			  16);
	} else {
		data->counters.packets_dropped++;
		client->counters.packets_dropped++;
	}

	if (is_complete) {
		RADIUS_DEBUG("Removing completed session 0x%x after timeout",
			     sess->sess_id);
		eloop_cancel_timeout(radius_server_session_remove_timeout,
				     data, sess);
		eloop_register_timeout(10, 0,
				       radius_server_session_remove_timeout,
				       data, sess);
	}

	return 0;
}
Exemple #25
0
void ap_sta_no_session_timeout(struct hostapd_data *hapd, struct sta_info *sta)
{
	eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
}
Exemple #26
0
static void remove_timeout(DBusTimeout *timeout, void *data)
{
	struct wpas_dbus_priv *priv = data;
	eloop_cancel_timeout(process_timeout, priv, timeout);
	dbus_timeout_set_data(timeout, NULL, NULL);
}
/* event_send_stop_all -- cleanup */
void event_send_stop_all(struct upnp_wps_device_sm *sm)
{
	if (sm->event_send_all_queued)
		eloop_cancel_timeout(event_send_all_later_handler, NULL, sm);
	sm->event_send_all_queued = 0;
}
int hs20_web_browser(const char *url)
{
	struct http_server *http;
	struct in_addr addr;
	struct browser_data data;
	pid_t pid;

	wpa_printf(MSG_INFO, "Launching Android browser to %s", url);

	os_memset(&data, 0, sizeof(data));

	if (eloop_init() < 0) {
		wpa_printf(MSG_ERROR, "eloop_init failed");
		return -1;
	}
	addr.s_addr = htonl((127 << 24) | 1);
	http = http_server_init(&addr, 12345, http_req, &data);
	if (http == NULL) {
		wpa_printf(MSG_ERROR, "http_server_init failed");
		eloop_destroy();
		return -1;
	}

	pid = fork();
	if (pid < 0) {
		wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
		http_server_deinit(http);
		eloop_destroy();
		return -1;
	}

	if (pid == 0) {
		/* run the external command in the child process */
		char *argv[7];

		argv[0] = "browser-android";
		argv[1] = "start";
		argv[2] = "-a";
		argv[3] = "android.intent.action.VIEW";
		argv[4] = "-d";
		argv[5] = (void *) url;
		argv[6] = NULL;

		execv("/system/bin/am", argv);
		wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
		exit(0);
		return -1;
	}

	eloop_register_timeout(30, 0, browser_timeout, &data, NULL);
	eloop_run();
	eloop_cancel_timeout(browser_timeout, &data, NULL);
	http_server_deinit(http);
	eloop_destroy();

	wpa_printf(MSG_INFO, "Closing Android browser");
	if (system("/system/bin/input keyevent KEYCODE_HOME") != 0) {
		wpa_printf(MSG_INFO, "Failed to inject keyevent");
	}

	return data.success;
}
Exemple #29
0
static void
wpa_supplicant_event_michael_mic_failure(struct wpa_supplicant *wpa_s,
					 union wpa_event_data *data)
{
	int pairwise;
	struct os_time t;

	wpa_msg(wpa_s, MSG_WARNING, "Michael MIC failure detected");
	pairwise = (data && data->michael_mic_failure.unicast);
	os_get_time(&t);
	if ((wpa_s->last_michael_mic_error &&
	     t.sec - wpa_s->last_michael_mic_error <= 60) ||
	    wpa_s->pending_mic_error_report) {
		if (wpa_s->pending_mic_error_report) {
			/*
			 * Send the pending MIC error report immediately since
			 * we are going to start countermeasures and AP better
			 * do the same.
			 */
			wpa_sm_key_request(wpa_s->wpa, 1,
					   wpa_s->pending_mic_error_pairwise);
		}

		/* Send the new MIC error report immediately since we are going
		 * to start countermeasures and AP better do the same.
		 */
		wpa_sm_key_request(wpa_s->wpa, 1, pairwise);

		/* initialize countermeasures */
		wpa_s->countermeasures = 1;
		wpa_msg(wpa_s, MSG_WARNING, "TKIP countermeasures started");

		/*
		 * Need to wait for completion of request frame. We do not get
		 * any callback for the message completion, so just wait a
		 * short while and hope for the best. */
		os_sleep(0, 10000);

		wpa_drv_set_countermeasures(wpa_s, 1);
		wpa_supplicant_deauthenticate(wpa_s,
					      WLAN_REASON_MICHAEL_MIC_FAILURE);
		eloop_cancel_timeout(wpa_supplicant_stop_countermeasures,
				     wpa_s, NULL);
		eloop_register_timeout(60, 0,
				       wpa_supplicant_stop_countermeasures,
				       wpa_s, NULL);
		/* TODO: mark the AP rejected for 60 second. STA is
		 * allowed to associate with another AP.. */
	} else {
#ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
		if (wpa_s->mic_errors_seen) {
			/*
			 * Reduce the effectiveness of Michael MIC error
			 * reports as a means for attacking against TKIP if
			 * more than one MIC failure is noticed with the same
			 * PTK. We delay the transmission of the reports by a
			 * random time between 0 and 60 seconds in order to
			 * force the attacker wait 60 seconds before getting
			 * the information on whether a frame resulted in a MIC
			 * failure.
			 */
			u8 rval[4];
			int sec;

			if (os_get_random(rval, sizeof(rval)) < 0)
				sec = os_random() % 60;
			else
				sec = WPA_GET_BE32(rval) % 60;
			wpa_printf(MSG_DEBUG, "WPA: Delay MIC error report %d "
				   "seconds", sec);
			wpa_s->pending_mic_error_report = 1;
			wpa_s->pending_mic_error_pairwise = pairwise;
			eloop_cancel_timeout(
				wpa_supplicant_delayed_mic_error_report,
				wpa_s, NULL);
			eloop_register_timeout(
				sec, os_random() % 1000000,
				wpa_supplicant_delayed_mic_error_report,
				wpa_s, NULL);
		} else {
			wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
		}
#else /* CONFIG_DELAYED_MIC_ERROR_REPORT */
		wpa_sm_key_request(wpa_s->wpa, 1, pairwise);
#endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */
	}
	wpa_s->last_michael_mic_error = t.sec;
	wpa_s->mic_errors_seen++;
}
Exemple #30
0
int hs20_web_browser(const char *url)
{
	struct http_server *http;
	struct in_addr addr;
	struct browser_data data;
	pid_t pid;

	wpa_printf(MSG_INFO, "Launching wpadebug browser to %s", url);

	os_memset(&data, 0, sizeof(data));

	if (eloop_init() < 0) {
		wpa_printf(MSG_ERROR, "eloop_init failed");
		return -1;
	}
	addr.s_addr = htonl((127 << 24) | 1);
	http = http_server_init(&addr, 12345, http_req, &data);
	if (http == NULL) {
		wpa_printf(MSG_ERROR, "http_server_init failed");
		eloop_destroy();
		return -1;
	}

	pid = fork();
	if (pid < 0) {
		wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
		http_server_deinit(http);
		eloop_destroy();
		return -1;
	}

	if (pid == 0) {
		/* run the external command in the child process */
		char *argv[14];

		argv[0] = "browser-wpadebug";
		argv[1] = "start";
		argv[2] = "-a";
		argv[3] = "android.action.MAIN";
		argv[4] = "-c";
		argv[5] = "android.intent.category.LAUNCHER";
		argv[6] = "-n";
		argv[7] = "w1.fi.wpadebug/.WpaWebViewActivity";
		argv[8] = "-e";
		argv[9] = "w1.fi.wpadebug.URL";
		argv[10] = (void *) url;
		argv[11] = "--user";
		argv[12] = "-3"; /* USER_CURRENT_OR_SELF */
		argv[13] = NULL;

		execv("/system/bin/am", argv);
		wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
		exit(0);
		return -1;
	}

	eloop_register_timeout(300, 0, browser_timeout, &data, NULL);
	eloop_run();
	eloop_cancel_timeout(browser_timeout, &data, NULL);
	http_server_deinit(http);
	eloop_destroy();

	wpa_printf(MSG_INFO, "Closing Android browser");
	if (os_exec("/system/bin/am",
		    "start -a android.action.MAIN "
		    "-c android.intent.category.LAUNCHER "
		    "-n w1.fi.wpadebug/.WpaWebViewActivity "
		    "-e w1.fi.wpadebug.URL FINISH", 1) != 0) {
		wpa_printf(MSG_INFO, "Failed to close wpadebug browser");
	}

	return data.success;
}