コード例 #1
0
ファイル: ctrl_iface.c プロジェクト: mrtos/Logitech-Revue
static int wpa_supplicant_ctrl_iface_remove_network(
	struct wpa_supplicant *wpa_s, char *cmd)
{
	int id;
	struct wpa_ssid *ssid;

	/* cmd: "<network id>" */
	id = atoi(cmd);
	wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_NETWORK id=%d", id);

	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL ||
	    wpa_config_remove_network(wpa_s->conf, id) < 0) {
		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find network "
			   "id=%d", id);
		return -1;
	}

	if (ssid == wpa_s->current_ssid) {
		/*
		 * Invalidate the EAP session cache if the current network is
		 * removed.
		 */
		eapol_sm_invalidate_cached_session(wpa_s->eapol);

		wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);
	}

	return 0;
}
コード例 #2
0
static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
{
	int id;
	struct wpa_ssid *ssid, *remove_ssid = NULL;

	eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);

	/* Remove any existing WPS network from configuration */
	ssid = wpa_s->conf->ssid;
	while (ssid) {
		if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
			if (ssid == wpa_s->current_ssid) {
				wpa_s->current_ssid = NULL;
				if (ssid != NULL)
					wpas_notify_network_changed(wpa_s);
			}
			id = ssid->id;
			remove_ssid = ssid;
		} else
			id = -1;
		ssid = ssid->next;
		if (id >= 0) {
			wpas_notify_network_removed(wpa_s, remove_ssid);
			wpa_config_remove_network(wpa_s->conf, id);
		}
	}
}
コード例 #3
0
/**
 * wpas_dbus_iface_remove_network - Remove a configured network
 * @message: Pointer to incoming dbus message
 * @wpa_s: wpa_supplicant structure for a network interface
 * Returns: A dbus message containing a UINT32 indicating success (1) or
 *          failure (0)
 *
 * Handler function for "removeNetwork" method call of a network interface.
 */
DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
					     struct wpa_supplicant *wpa_s)
{
	DBusMessage *reply = NULL;
	const char *op;
	char *iface = NULL, *net_id = NULL;
	int id;
	struct wpa_ssid *ssid;

	if (!dbus_message_get_args(message, NULL,
	                           DBUS_TYPE_OBJECT_PATH, &op,
	                           DBUS_TYPE_INVALID)) {
		reply = wpas_dbus_new_invalid_opts_error(message, NULL);
		goto out;
	}

	/* Extract the network ID */
	iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
	if (iface == NULL) {
		reply = wpas_dbus_new_invalid_network_error(message);
		goto out;
	}

	/* Ensure the network is actually a child of this interface */
	if (os_strcmp(iface, wpa_s->dbus_path) != 0) {
		reply = wpas_dbus_new_invalid_network_error(message);
		goto out;
	}

	id = strtoul(net_id, NULL, 10);
	ssid = wpa_config_get_network(wpa_s->conf, id);
	if (ssid == NULL) {
		reply = wpas_dbus_new_invalid_network_error(message);
		goto out;
	}

	wpas_notify_network_removed(wpa_s, ssid);

	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
		reply = dbus_message_new_error(message,
					       WPAS_ERROR_REMOVE_NETWORK_ERROR,
					       "error removing the specified "
					       "on this interface.");
		goto out;
	}

	if (ssid == wpa_s->current_ssid)
		wpa_supplicant_deauthenticate(wpa_s,
					      WLAN_REASON_DEAUTH_LEAVING);
	reply = wpas_dbus_new_success_reply(message);

out:
	os_free(iface);
	os_free(net_id);
	return reply;
}
コード例 #4
0
static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
					      int registrar, const u8 *bssid)
{
	struct wpa_ssid *ssid;

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL)
		return NULL;
	wpas_notify_network_added(wpa_s, ssid);
	wpa_config_set_network_defaults(ssid);
	if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
	    wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
	    wpa_config_set(ssid, "identity", registrar ?
			   "\"" WSC_ID_REGISTRAR "\"" :
			   "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
		wpas_notify_network_removed(wpa_s, ssid);
		wpa_config_remove_network(wpa_s->conf, ssid->id);
		return NULL;
	}

	if (bssid) {
		struct wpa_bss *bss;
		int count = 0;

		os_memcpy(ssid->bssid, bssid, ETH_ALEN);
		ssid->bssid_set = 1;

		dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
			if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
				continue;

			os_free(ssid->ssid);
			ssid->ssid = os_malloc(bss->ssid_len);
			if (ssid->ssid == NULL)
				break;
			os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
			ssid->ssid_len = bss->ssid_len;
			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
					  "scan results",
					  ssid->ssid, ssid->ssid_len);
			count++;
		}

		if (count > 1) {
			wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
				   "for the AP; use wildcard");
			os_free(ssid->ssid);
			ssid->ssid = NULL;
			ssid->ssid_len = 0;
		}
	}

	return ssid;
}
コード例 #5
0
ファイル: wps_supplicant.c プロジェクト: smx-smx/dsl-n55u
static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
					      int registrar, const u8 *bssid)
{
	struct wpa_ssid *ssid;

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL)
		return NULL;
	wpa_config_set_network_defaults(ssid);
	if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
	    wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
	    wpa_config_set(ssid, "identity", registrar ?
			   "\"" WSC_ID_REGISTRAR "\"" :
			   "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
		wpa_config_remove_network(wpa_s->conf, ssid->id);
		return NULL;
	}

	if (bssid) {
		size_t i;
		struct wpa_scan_res *res;

		os_memcpy(ssid->bssid, bssid, ETH_ALEN);
		ssid->bssid_set = 1;

		/* Try to get SSID from scan results */
		if (wpa_s->scan_res == NULL &&
		    wpa_supplicant_get_scan_results(wpa_s) < 0)
			return ssid; /* Could not find any scan results */

		for (i = 0; i < wpa_s->scan_res->num; i++) {
			const u8 *ie;

			res = wpa_s->scan_res->res[i];
			if (os_memcmp(bssid, res->bssid, ETH_ALEN) != 0)
				continue;

			ie = wpa_scan_get_ie(res, WLAN_EID_SSID);
			if (ie == NULL)
				break;
			os_free(ssid->ssid);
			ssid->ssid = os_malloc(ie[1]);
			if (ssid->ssid == NULL)
				break;
			os_memcpy(ssid->ssid, ie + 2, ie[1]);
			ssid->ssid_len = ie[1];
			break;
		}
	}

	return ssid;
}
コード例 #6
0
ファイル: interworking.c プロジェクト: pombredanne/NetBSD
int interworking_connect(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
{
	struct wpa_ssid *ssid;
	struct nai_realm *realm;
	struct nai_realm_eap *eap = NULL;
	u16 count, i;
	char buf[100];
	const u8 *ie;

	if (bss == NULL)
		return -1;
	ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
	if (ie == NULL || ie[1] == 0) {
		wpa_printf(MSG_DEBUG, "Interworking: No SSID known for "
			   MACSTR, MAC2STR(bss->bssid));
		return -1;
	}

	realm = nai_realm_parse(bss->anqp_nai_realm, &count);
	if (realm == NULL) {
		wpa_printf(MSG_DEBUG, "Interworking: Could not parse NAI "
			   "Realm list from " MACSTR, MAC2STR(bss->bssid));
		count = 0;
	}

	for (i = 0; i < count; i++) {
		if (!nai_realm_match(&realm[i], wpa_s->conf->home_realm))
			continue;
		eap = nai_realm_find_eap(wpa_s, &realm[i]);
		if (eap)
			break;
	}

	if (!eap) {
		if (interworking_connect_3gpp(wpa_s, bss) == 0) {
			if (realm)
				nai_realm_free(realm, count);
			return 0;
		}

		wpa_printf(MSG_DEBUG, "Interworking: No matching credentials "
			   "and EAP method found for " MACSTR,
			   MAC2STR(bss->bssid));
		nai_realm_free(realm, count);
		return -1;
	}

	wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR,
		   MAC2STR(bss->bssid));

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL) {
		nai_realm_free(realm, count);
		return -1;
	}
	wpas_notify_network_added(wpa_s, ssid);
	wpa_config_set_network_defaults(ssid);
	ssid->temporary = 1;
	ssid->ssid = os_zalloc(ie[1] + 1);
	if (ssid->ssid == NULL)
		goto fail;
	os_memcpy(ssid->ssid, ie + 2, ie[1]);
	ssid->ssid_len = ie[1];

	if (wpa_config_set(ssid, "eap", eap_get_name(EAP_VENDOR_IETF,
						     eap->method), 0) < 0)
		goto fail;

	if (wpa_s->conf->home_username && wpa_s->conf->home_username[0] &&
	    wpa_config_set_quoted(ssid, "identity",
				  wpa_s->conf->home_username) < 0)
		goto fail;

	if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
	    wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
	    < 0)
		goto fail;

	switch (eap->method) {
	case EAP_TYPE_TTLS:
		if (eap->inner_method) {
			os_snprintf(buf, sizeof(buf), "\"autheap=%s\"",
				    eap_get_name(EAP_VENDOR_IETF,
						 eap->inner_method));
			if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
				goto fail;
			break;
		}
		switch (eap->inner_non_eap) {
		case NAI_REALM_INNER_NON_EAP_PAP:
			if (wpa_config_set(ssid, "phase2", "\"auth=PAP\"", 0) <
			    0)
				goto fail;
			break;
		case NAI_REALM_INNER_NON_EAP_CHAP:
			if (wpa_config_set(ssid, "phase2", "\"auth=CHAP\"", 0)
			    < 0)
				goto fail;
			break;
		case NAI_REALM_INNER_NON_EAP_MSCHAP:
			if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAP\"",
					   0) < 0)
				goto fail;
			break;
		case NAI_REALM_INNER_NON_EAP_MSCHAPV2:
			if (wpa_config_set(ssid, "phase2", "\"auth=MSCHAPV2\"",
					   0) < 0)
				goto fail;
			break;
		}
		break;
	case EAP_TYPE_PEAP:
		os_snprintf(buf, sizeof(buf), "\"auth=%s\"",
			    eap_get_name(EAP_VENDOR_IETF, eap->inner_method));
		if (wpa_config_set(ssid, "phase2", buf, 0) < 0)
			goto fail;
		break;
	}

	if (wpa_s->conf->home_ca_cert && wpa_s->conf->home_ca_cert[0] &&
	    wpa_config_set_quoted(ssid, "ca_cert", wpa_s->conf->home_ca_cert) <
	    0)
		goto fail;

	nai_realm_free(realm, count);

	wpa_supplicant_select_network(wpa_s, ssid);

	return 0;

fail:
	wpas_notify_network_removed(wpa_s, ssid);
	wpa_config_remove_network(wpa_s->conf, ssid->id);
	nai_realm_free(realm, count);
	return -1;
}
コード例 #7
0
ファイル: interworking.c プロジェクト: pombredanne/NetBSD
static int interworking_connect_3gpp(struct wpa_supplicant *wpa_s,
				     struct wpa_bss *bss)
{
#ifdef INTERWORKING_3GPP
	struct wpa_ssid *ssid;
	const u8 *ie;

	ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
	if (ie == NULL)
		return -1;
	wpa_printf(MSG_DEBUG, "Interworking: Connect with " MACSTR " (3GPP)",
		   MAC2STR(bss->bssid));

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL)
		return -1;

	wpas_notify_network_added(wpa_s, ssid);
	wpa_config_set_network_defaults(ssid);
	ssid->temporary = 1;
	ssid->ssid = os_zalloc(ie[1] + 1);
	if (ssid->ssid == NULL)
		goto fail;
	os_memcpy(ssid->ssid, ie + 2, ie[1]);
	ssid->ssid_len = ie[1];

	/* TODO: figure out whether to use EAP-SIM, EAP-AKA, or EAP-AKA' */
	if (wpa_config_set(ssid, "eap", "SIM", 0) < 0) {
		wpa_printf(MSG_DEBUG, "EAP-SIM not supported");
		goto fail;
	}
	if (set_root_nai(ssid, wpa_s->conf->home_imsi, '1') < 0) {
		wpa_printf(MSG_DEBUG, "Failed to set Root NAI");
		goto fail;
	}

	if (wpa_s->conf->home_milenage && wpa_s->conf->home_milenage[0]) {
		if (wpa_config_set_quoted(ssid, "password",
					  wpa_s->conf->home_milenage) < 0)
			goto fail;
	} else {
		/* TODO: PIN */
		if (wpa_config_set_quoted(ssid, "pcsc", "") < 0)
			goto fail;
	}

	if (wpa_s->conf->home_password && wpa_s->conf->home_password[0] &&
	    wpa_config_set_quoted(ssid, "password", wpa_s->conf->home_password)
	    < 0)
		goto fail;

	wpa_supplicant_select_network(wpa_s, ssid);

	return 0;

fail:
	wpas_notify_network_removed(wpa_s, ssid);
	wpa_config_remove_network(wpa_s->conf, ssid->id);
#endif /* INTERWORKING_3GPP */
	return -1;
}
コード例 #8
0
ファイル: wps_config.c プロジェクト: KHATEEBNSIT/AP
struct wpa_scan_result *wps_select_ssid(struct wpa_supplicant *wpa_s,
		struct wpa_scan_result *results,
		int num, struct wpa_ssid **ssid)
{
	struct wpa_scan_result *bss;
	struct wpa_scan_result *selected = 0;
	int num_good;
	struct wpa_scan_result *maybe = 0;
        int num_maybe;
	struct wpa_ssid *tmp;
	int ret = -1;
	char *var, *value;
	struct wps_data *data = 0;
	char bssid_str[18+1];
	char ssid_str[32+3];
    u8 uuidSel[SIZE_UUID];
    u8 uuidBss[SIZE_UUID];
    size_t length;
	struct wps_config *wps;
	int i;
        int is_push_button;

	do {
		if (!wpa_s || !wpa_s->conf || !results || !num || !ssid)
			break;

		wps = wpa_s->conf->wps;
                is_push_button = (wps->dev_pwd_len == 8 && 
                        memcmp(wps->dev_pwd, "00000000", 8) == 0);

		if (wps->nwid_trying_wps != -1) {
			(void)wpa_config_remove_network(wpa_s->conf, wps->nwid_trying_wps);
			wps->nwid_trying_wps = -1;
		}

		*ssid = 0;

		num_good = 0;
		num_maybe = 0;
		for (i = 0; i < num; i++) {
			bss = &results[i];
            if (wps->filter_bssid_flag && memcmp(
                        wps->filter_bssid, bss->bssid, 6) != 0) {
                continue;
            }
            if (wps->filter_ssid_length > 0 && memcmp(
                        wps->filter_ssid, bss->ssid, 
                        wps->filter_ssid_length) != 0) {
                continue;
            }
			if (bss->wps_ie_len) {
				u16 dev_pwd_id;

				do {
					if (wps_create_wps_data(&data))
						break;

					if (wps_parse_wps_ie(bss->wps_ie, bss->wps_ie_len, data))
						break;

		            length = sizeof(uuidBss);
                    /* selected bss UUID-E */
		            if (wps_get_value(data, WPS_TYPE_UUID_E, uuidBss, &length))
			            break;

					if (wps_get_value(data, WPS_TYPE_DEVICE_PWD_ID, &dev_pwd_id, 0))
						break;

                    if (is_push_button) {
                        if (WPS_DEVICEPWDID_PUSH_BTN != dev_pwd_id) 
                            break;
                    } else {        /* PIN mode */
                        if (WPS_DEVICEPWDID_DEFAULT != dev_pwd_id) {
                            break;
                        }
                    }
                    
                    /* In the case of a dual-band AP and a dual-band station,
                     * the station may discover more than one Registrar in PBC mode.
                     * If the dual-band station does discover more than one Registrar
                     * in PBC mode, one each RF band, and the UUID in the Beacon and
                     * Probe-Response are the same for all RF bands, then the station 
                     * shall not consider this to be a session overlap.
                     */
					if (num_good) {
					    /* check dual-band concurrent AP case */
					    if (((selected->freq >= 4000) && (bss->freq <= 3000)) ||
					        ((selected->freq <= 3000) && (bss->freq >= 4000)))
					    {
                    		/* one is 2.4GHz and another is 5GHz */
                    		if (memcmp(uuidSel, uuidBss, length) == 0)
                    		{
                    		    /* UUID-E of them are totally the same */
                    		    /* Select the 5GHz one */
                    		    if (bss->freq >= 4000)
					                selected = bss;
                    		    break;
                    		}
					    }
					}
				    selected = bss;
            		memcpy(&uuidSel, &uuidBss, length);
					num_good++;
				} while (0);

				(void)wps_destroy_wps_data(&data);

                /* If we have WPS at all then it's a maybe
                 * for PIN
                 */
                if (!is_push_button) {
                    num_maybe++;
					if ((!maybe) || (bss->qual > maybe->qual)) {
						maybe = bss;
					}
                }
			} else {
                /* No WPS IE */
                /* If in open mode, it may support WPS...
                 * (some microsoft products)
                 * take it as a maybe
                 */
                if ((bss->caps & IEEE80211_CAP_PRIVACY) == 0) {
                    num_maybe++;
                    if ((!maybe) || (bss->qual > maybe->qual)) {
                        maybe = bss;
                    }
                }
            }
		}

        /* Push button mode must have exact explicit match.
         * For PIN mode, due to greater security, we are willing
         * to be more lenient; and due to the ambiguity of the WPS
         * standard, it is not actually required that the AP
         * advertise it's PIN mode (as versus PB mode
         * which requires such advertisement).
         * But we want either one good match, or if no good match,
         * then just one maybe... otherwise the user should have
         * done pre-filtering.... 
         * for best results, the user should do pre-filtering!
         */
        if (is_push_button) {
		    if (num_good > 1) {
		        wpa_msg(wpa_s, MSG_INFO, 
                        "Must be only one AP enabled WPS-PBC");
                break;
            } else if (num_good == 1) {
                /* good */
            } else if (num_good == 0) {
		        wpa_msg(wpa_s, MSG_INFO, 
                        "There are no APs which are enabled WPS-PBC");
                break;
            }
		} else { /* PIN mode */
		    if (num_good > 1) {
			    wpa_msg(wpa_s, MSG_INFO, 
                        "Must be only one AP enabled WPS-PIN");
                break;
            } else if (num_good == 1) {
                /* good */
            } else if (num_maybe > 1) {
			    wpa_msg(wpa_s, MSG_INFO, 
                        "There are no APs which are enabled WPS-PIN"
                        " but attaching WPS IE, concern some microsoft products,"
                        " try to connect strongest RSSI one");
				selected = maybe;
            } else if (num_maybe == 1) {
                /* select this one */
                selected = maybe;
            } else {
			    wpa_msg(wpa_s, MSG_INFO, 
                        "There are no APs available for WPS");
                break;
            }
        }

		if (!selected)
			break;

		*ssid = wpa_config_add_network(wpa_s->conf);
		if (!*ssid)
			break;
		wpa_config_set_network_defaults(*ssid);
		(*ssid)->disabled = 1;

		/* bssid */
		var = "bssid";
		os_snprintf(bssid_str, sizeof(bssid_str), "%02X:%02X:%02X:%02X:%02X:%02X",
					selected->bssid[0], selected->bssid[1],
					selected->bssid[2], selected->bssid[3],
					selected->bssid[4], selected->bssid[5]);
		bssid_str[18] = 0;
		if (wpa_config_set(*ssid, var, bssid_str, 0))
			break;

		/* ssid */
		var = "ssid";
		ssid_str[0] = '"';
		os_memcpy(ssid_str + 1, selected->ssid, selected->ssid_len);
		ssid_str[selected->ssid_len + 1] = '"';
		ssid_str[selected->ssid_len + 2] = 0;
		if (wpa_config_set(*ssid, var, ssid_str, 0))
			break;

		/* auth_alg */
		var = "auth_alg";
		value = "OPEN";
		if (wpa_config_set(*ssid, var, value, 0))
			break;

		/* key_mgmt */
		var = "key_mgmt";
		value = "IEEE8021X";
		if (wpa_config_set(*ssid, var, value, 0))
			break;

		/* eap */
		var = "eap";
		value = "WPS";
		if (wpa_config_set(*ssid, var, value, 0))
			break;

		/* identity */
		var = "identity";
		free((*ssid)->identity);
		switch (wps->reg_mode) {
		case WPS_SUPPLICANT_REGMODE_NONE:
			value = WPS_IDENTITY_ENROLLEE;
			break;
		default:
			value = WPS_IDENTITY_REGISTRAR;
			break;
		}
		(*ssid)->identity = (u8 *)os_strdup(value);
		(*ssid)->identity_len = os_strlen(value);

		ret = 0;
	} while (0);

	if (ret) {
		if (*ssid)
			(void)wpa_config_remove_network(wpa_s->conf, (*ssid)->id);
		selected = 0;
	} else {
		wpa_msg(wpa_s, MSG_INFO, "Found AP for WPS [%*s]", (*ssid)->ssid_len,(*ssid)->ssid);

		switch (wps->reg_mode) {
		case WPS_SUPPLICANT_REGMODE_NONE:
			if (wps->config) {
				free(wps->config);
				wps->config = 0;
				wps->config_len = 0;
			}
			break;
		case WPS_SUPPLICANT_REGMODE_CONFIGURE_AP:
			break;
		case WPS_SUPPLICANT_REGMODE_REGISTER_AP:
		case WPS_SUPPLICANT_REGMODE_REGISTER_STA:
			if (wps->config) {
				free(wps->config);
				wps->config = 0;
				wps->config_len = 0;
			}

			(void)wps_get_supplicant_ssid_configuration(wpa_s, (*ssid)->id, &wps->config, &wps->config_len);
			break;
		default:
			break;
		}

		if (wpa_s->current_ssid)
			wpa_supplicant_disassociate(wpa_s, REASON_DEAUTH_LEAVING);

		tmp = wpa_s->conf->ssid;
		while (tmp) {
                        #if 0   /* original from Sony */
			tmp->disabled = (*ssid)->id != tmp->id;
                        #else
                        /* Set bit 1 of disabled as "temporary WPS bit" */
			tmp->disabled = ((*ssid)->id != tmp->id) << 1;
                        #endif
			tmp = tmp->next;
		}

		wps->nwid_trying_wps = (*ssid)->id;

		wpa_s->reassociate = 1;
		wpa_supplicant_req_scan(wpa_s, 0, 0);
	}

	return selected;
}
コード例 #9
0
ファイル: wps_config.c プロジェクト: KHATEEBNSIT/AP
/*
 * This installs received WPS configuration into a new network configuration.
 * It is optional that the new network configuration be saved to the
 * original configuration file.
 */
int wps_set_supplicant_ssid_configuration(void *ctx, u8 *buf, size_t len)
{
	int ret = -1;
	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)ctx;
	struct wpa_ssid *ssid = 0;
	struct wps_data *wps = 0;
	u8 str_ssid[33];
	size_t ssid_length;
	u16 auth, encr;
	u8 nwKeyIdx;
	u8 *nwKey = 0;
	size_t nwKey_length;
	u8 macAddr[6];
	char *eapType = 0;
	char *eapIdentity = 0;
	Boolean keyProvideAuto;
	Boolean enabled8021X;
	Boolean passphrase = 0;
	size_t length;
	char *var, *value;

	do {
		if (!wpa_s)
			break;

                /* Optionally share new configuration with other software,
                 * e.g. with hostapd.
                 */
                wps_new_configuration_share(wpa_s, buf, len);

		ssid = wpa_config_add_network(wpa_s->conf);
		if (!ssid)
			break;
		wpa_config_set_network_defaults(ssid);

		if (wps_create_wps_data(&wps))
			break;

		if(wps_parse_wps_data(buf, len, wps))
			break;

		/* SSID */
		ssid_length = sizeof(str_ssid);
		if(wps_get_value(wps, WPS_TYPE_SSID, str_ssid, &ssid_length))
			break;
		str_ssid[ssid_length] = 0;

		/* Authentication Type */
		if (wps_get_value(wps, WPS_TYPE_AUTH_TYPE, &auth, NULL))
			break;

		/* Encryption Type */
		if (wps_get_value(wps, WPS_TYPE_ENCR_TYPE, &encr, NULL))
			break;

		/* Network Key Index (Option) */
		if(wps_get_value(wps, WPS_TYPE_NW_KEY_INDEX, &nwKeyIdx, NULL))
			nwKeyIdx = 1;
		if ((1 > nwKeyIdx) || (4 < nwKeyIdx)) { /* warning */
			wpa_printf(MSG_WARNING, "Network Key Index is fixed. %d -> 1\n", nwKeyIdx);
			nwKeyIdx = 1;
		}

		/* Network Key */
		nwKey_length = 0;
		(void)wps_get_value(wps, WPS_TYPE_NW_KEY, NULL, &nwKey_length);
		if (nwKey_length) {
			nwKey = (u8 *)calloc(1, nwKey_length + 1);
			if (!nwKey)
				break;
			if (wps_get_value(wps, WPS_TYPE_NW_KEY, nwKey, &nwKey_length)) {
				break;
			}
			nwKey[nwKey_length] = 0;
		}

		/* MAC Address */
		length = sizeof(macAddr);
		if(wps_get_value(wps, WPS_TYPE_MAC_ADDR, macAddr, &length))
			break;

		/* EAP Type (Option) */
		length = 0;
		(void)wps_get_value(wps, WPS_TYPE_EAP_TYPE, NULL, &length);
		if (length) {
			eapType = (char *)calloc(1, length + 1);
			if (!eapType)
				break;
			if (wps_get_value(wps, WPS_TYPE_EAP_TYPE, eapType, &length)) {
				break;
			}
			eapType[length] = 0;
		}

		/* EAP Identity (Option) */
		length = 0;
		(void)wps_get_value(wps, WPS_TYPE_EAP_IDENTITY, NULL, &length);
		if (length) {
			eapIdentity = (char *)calloc(1, length + 1);
			if (!eapIdentity)
				break;
			if (wps_get_value(wps, WPS_TYPE_EAP_IDENTITY, eapIdentity, &length)) {
				break;
			}
			eapIdentity[length] = 0;
		}

		/* Key Provided Automaticaly (Option) */
		if(wps_get_value(wps, WPS_TYPE_KEY_PROVIDED_AUTO, &keyProvideAuto, NULL))
			keyProvideAuto = 0;

		/* 802.1X Enabled (Option) */
		if(wps_get_value(wps, WPS_TYPE_8021X_ENABLED, &enabled8021X, NULL))
			enabled8021X = 0;

		/* Set Configuration */
                /* %%%%%% Sony set disabled to 1... why? */
		ssid->disabled = 0;
		/* ssid */
		var = "ssid";
		value = (char *)os_malloc(os_strlen((char *)str_ssid) + 3);
		if (!value)
			break;
		os_snprintf(value, os_strlen((char *)str_ssid) + 3, "\"%s\"", str_ssid);
		if (wpa_config_set(ssid, var, value, 0))
			break;
		free(value);

		/* auth_alg */
		var = "auth_alg";
		if (WPS_AUTHTYPE_SHARED == auth)
			value = "SHARED";
		else
			value = "OPEN";
		if (wpa_config_set(ssid, var, value, 0))
			break;

		/* key_mgmt */
		var = "key_mgmt";
		switch (auth) {
		case WPS_AUTHTYPE_OPEN:
		case WPS_AUTHTYPE_SHARED:
			if (enabled8021X)
				value = "IEEE8021X";
			else
				value = "NONE";
			break;
		case WPS_AUTHTYPE_WPAPSK:
		case WPS_AUTHTYPE_WPA2PSK:
			if (enabled8021X)
				value = "WPA-PSK IEEE8021X";
			else
				value = "WPA-PSK";
			break;
		case WPS_AUTHTYPE_WPA:
		case WPS_AUTHTYPE_WPA2:
			if (enabled8021X)
				value = "WPA-EAP IEEE8021X";
			else
				value = "WPA-EAP";
			break;
		default:
			value = 0;
			break;
		}
		if (!value | wpa_config_set(ssid, var, value, 0))
			break;

		/* proto */
		var = "proto";
		switch (auth) {
		case WPS_AUTHTYPE_WPA:
		case WPS_AUTHTYPE_WPAPSK:
			value = "WPA";
			break;
		case WPS_AUTHTYPE_WPA2:
		case WPS_AUTHTYPE_WPA2PSK:
			value = "RSN";
			break;
		default:
			ssid->proto = 0;
			value = 0;
			break;
		}
		if (value && wpa_config_set(ssid, var, value, 0))
			break;

		/* pariwise */
		var = "pairwise";
		switch (encr) {
		case WPS_ENCRTYPE_NONE:
			ssid->pairwise_cipher = WPA_CIPHER_NONE;
			value = 0;
			break;
		case WPS_ENCRTYPE_TKIP:
			value = "TKIP";
			break;
		case WPS_ENCRTYPE_AES:
			value = "CCMP";
			break;
		default:
			value = 0;
			break;
		}
		if (value && wpa_config_set(ssid, var, value, 0))
			break;

		/* group */
		var = "group";
		switch (encr) {
		case WPS_ENCRTYPE_NONE:
			ssid->group_cipher = WPA_CIPHER_NONE;
			value = 0;
			break;
		case WPS_ENCRTYPE_WEP:
			value = "WEP104 WEP40";
			break;
		case WPS_ENCRTYPE_TKIP:
			value = "TKIP";
			break;
		case WPS_ENCRTYPE_AES:
                        #if 0   /* original */
			value = "CCMP";
                        #else   /* HACK! */
                        /* It is not uncommon for group cipher to be
                         * TKIP whereas the pairwise is CCMP, but 
                         * WPS makes no distinction.
                         * Workaround by configuring both in this case.
                         */
			value = "TKIP CCMP";
                        #endif
			break;
		default:
			value = 0;
			break;
		}
		if (value && wpa_config_set(ssid, var, value, 0))
			break;

		/* wep_tx_keyidx */
		var = "wep_tx_keyidx";
		switch (encr) {
		case WPS_ENCRTYPE_WEP:
			value = (char *)os_malloc(2);
			if (!value)
				break;
			os_snprintf(value, 2, "%d", nwKeyIdx - 1);
			break;
		default:
			value = 0;
			break;
		}
		if (value && wpa_config_set(ssid, var, value, 0)) {
			free(value);
			break;
		} else if (value)
			free(value);
		if (!value && (WPS_ENCRTYPE_WEP == encr))
			break;

		/* wep_keyn */
		switch (encr) {
		case WPS_ENCRTYPE_WEP:
			var = (char *)os_malloc(9);
			if (!var)
				break;
			os_snprintf(var, 9, "wep_key%d", nwKeyIdx - 1);
			if (is_hex(nwKey, nwKey_length)) {
				value = (char *)os_malloc(nwKey_length * 2 + 1);
				if (!value)
					break;
				wpa_snprintf_hex_uppercase(value, nwKey_length * 2 + 1,
										   nwKey, nwKey_length);
				value[nwKey_length * 2] = 0;
			} else if ((5 == nwKey_length) || (13 == nwKey_length)) {
				value = (char *)os_malloc(nwKey_length + 3);
				if (!value)
					break;
				os_snprintf(value, nwKey_length + 3, "\"%s\"", nwKey);
			} else if ((nwKey_length) || (13 == nwKey_length)) {
				value = (char *)os_malloc(nwKey_length + 1);
				if (!value)
					break;
				os_memcpy(value, nwKey, nwKey_length);
				value[nwKey_length] = 0;
			}
			break;
		default:
			var = 0;
			value = 0;
			break;
		}
		if (var && value && wpa_config_set(ssid, var, value, 0))
			break;
		if (var)
			free(var);
		if (value)
			free(value);
		if ((!var || !value) && (WPS_ENCRTYPE_WEP == encr))
			break;

		/* psk */
		var = "psk";
		switch (auth) {
		case WPS_AUTHTYPE_WPA:
		case WPS_AUTHTYPE_WPA2:
		case WPS_AUTHTYPE_WPAPSK:
		case WPS_AUTHTYPE_WPA2PSK:
			if (nwKey_length) {
				value = (char *)os_malloc(nwKey_length + 3);
				if (!value)
					break;
				if (64 > nwKey_length) {
					os_snprintf(value, nwKey_length + 3, "\"%s\"", nwKey);
					passphrase = 1;
				} else if (64 == nwKey_length) {
					os_memcpy(value, nwKey, nwKey_length);
					value[nwKey_length] = 0;
				} else {
					free(value);
					value = 0;
					break;
				}
			} else
				value = 0;
			break;
		default:
			value = 0;
			break;
		}
		if (value && wpa_config_set(ssid, var, value, 0)) {
			free(value);
			break;
		} else if (value)
			free(value);
		if (nwKey_length && !value &&
			((WPS_AUTHTYPE_WPA == auth) ||
			 (WPS_AUTHTYPE_WPA2 == auth) ||
			 (WPS_AUTHTYPE_WPAPSK == auth) ||
			 (WPS_AUTHTYPE_WPA2PSK == auth)))
			break;
		
		/* eap */
		if (eapType && os_strlen(eapType)) {
			var = "eap";
			value = (char *)eapType;
			if (wpa_config_set(ssid, var, value, 0))
				break;
		}

		/* identity */
		if (eapIdentity && os_strlen(eapIdentity)) {
			var = "identity";
			value = (char *)eapIdentity;
			if (wpa_config_set(ssid, var, value, 0))
				break;
		}

		ret = 0;
	} while (0);

	(void)wps_destroy_wps_data(&wps);

	if (ret) {
		if (ssid)
			(void)wpa_config_remove_network(wpa_s->conf, ssid->id);
	} else {
		if (passphrase)
			wpa_config_update_psk(ssid);
	}

	if (nwKey)
		free(nwKey);
	if (eapType)
		free(eapType);
	if (eapIdentity)
		free(eapIdentity);

	return ret?ret:ssid->id;
}
コード例 #10
0
ファイル: wps_config.c プロジェクト: KHATEEBNSIT/AP
int wps_config_remove_network(struct wpa_supplicant *wpa_s, int network_id)
{
	if (0 > network_id)
		return -1;
	return wpa_config_remove_network(wpa_s->conf, network_id);
}
コード例 #11
0
status_t
WPASupplicantApp::_JoinNetwork(BMessage *message)
{
	const char *interfaceName = NULL;
	status_t status = message->FindString("device", &interfaceName);
	if (status != B_OK)
		return status;

	// Check if we already registered this interface.
	wpa_supplicant *interface = wpa_supplicant_get_iface(fWPAGlobal,
		interfaceName);
	if (interface == NULL) {
		wpa_interface interfaceOptions;
		memset(&interfaceOptions, 0, sizeof(wpa_interface));

		interfaceOptions.ifname = interfaceName;

		interface = wpa_supplicant_add_iface(fWPAGlobal, &interfaceOptions);
		if (interface == NULL)
			return B_NO_MEMORY;
	} else {
		// Disable everything
		wpa_supplicant_disable_network(interface, NULL);

		// Try to remove any existing network
		while (true) {
			wpa_ssid *network = wpa_config_get_network(interface->conf, 0);
			if (network == NULL)
				break;

			wpas_notify_network_removed(interface, network);
			wpa_config_remove_network(interface->conf, network->id);
		}
	}

	const char *networkName = NULL;
	status = message->FindString("name", &networkName);
	if (status != B_OK)
		return status;

	uint32 authMode = B_NETWORK_AUTHENTICATION_NONE;
	status = message->FindUInt32("authentication", &authMode);
	if (status != B_OK)
		return status;

	uint32 encapMode = B_NETWORK_EAP_ENCAPSULATION_NONE;
	if (authMode == B_NETWORK_AUTHENTICATION_EAP)
		message->FindUInt32("encapsulation", &encapMode);

	const char *username = NULL;
	if (encapMode > B_NETWORK_EAP_ENCAPSULATION_NONE) {
		status = message->FindString("username", &username);
		if (status != B_OK)
			return status;
	}

	const char *password = NULL;
	if (authMode > B_NETWORK_AUTHENTICATION_NONE) {
		status = message->FindString("password", &password);
		if (status != B_OK)
			return status;
	}

	wpa_ssid *network = wpa_config_add_network(interface->conf);
	if (network == NULL)
		return B_NO_MEMORY;

	wpas_notify_network_added(interface, network);

	network->disabled = 1;
	wpa_config_set_network_defaults(network);

	// Fill in the info from the join request

	// The format includes the quotes
	BString value;
	value = "\"";
	value += networkName;
	value += "\"";
	int result = wpa_config_set(network, "ssid", value.String(), 0);

	if (result == 0)
		result = wpa_config_set(network, "scan_ssid", "1", 1);

	if (authMode >= B_NETWORK_AUTHENTICATION_WPA) {
		if (result == 0)
			result = wpa_config_set(network, "proto", "WPA RSN", 2);
		if (result == 0) {
			switch (authMode) {
				case B_NETWORK_AUTHENTICATION_WPA:
				case B_NETWORK_AUTHENTICATION_WPA2:
				default:
					result = wpa_config_set(network, "key_mgmt", "WPA-PSK", 3);
					break;
				case B_NETWORK_AUTHENTICATION_EAP:
					result = wpa_config_set(network, "key_mgmt", "WPA-EAP", 3);
					break;
			}
		}
		if (result == 0)
			result = wpa_config_set(network, "pairwise", "CCMP TKIP NONE", 4);
		if (result == 0) {
			result = wpa_config_set(network, "group",
				"CCMP TKIP WEP104 WEP40", 5);
		}
		if (result == 0) {
			if (encapMode > B_NETWORK_EAP_ENCAPSULATION_NONE) {
				switch (encapMode) {
					case B_NETWORK_EAP_ENCAPSULATION_PEAP:
						result = wpa_config_set(network, "eap", "PEAP", 6);
						break;
					case B_NETWORK_EAP_ENCAPSULATION_TLS:
						result = wpa_config_set(network, "eap", "TLS", 6);
						break;
				}
			}
		}
	} else {
		// Open or WEP.
		if (result == 0)
			result = wpa_config_set(network, "key_mgmt", "NONE", 6);
	}

	if (result == 0) {
		if (authMode == B_NETWORK_AUTHENTICATION_WEP) {
			if (strncmp("0x", password, 2) == 0) {
				// interpret as hex key
				// TODO: make this non-ambiguous
				result = wpa_config_set(network, "wep_key0", password + 2, 7);
			} else {
				value = "\"";
				value += password;
				value += "\"";
				result = wpa_config_set(network, "wep_key0", value.String(), 8);
			}

			if (result == 0)
				result = wpa_config_set(network, "wep_tx_keyidx", "0", 9);
		} else if (authMode == B_NETWORK_AUTHENTICATION_EAP) {
			// EAP
			value = "\"";
			value += password;
			value += "\"";
			result = wpa_config_set(network, "password", value.String(), 10);
			if (encapMode > B_NETWORK_EAP_ENCAPSULATION_NONE) {
				value = "\"";
				value += username;
				value += "\"";
				result = wpa_config_set(network, "identity",
					value.String(), 11);
			}
			// TODO: Does EAP need the same thing?
			#if 0
			if (result == 0) {
				// We need to actually "apply" the PSK
				wpa_config_update_psk(network);
			}
			#endif
		} else if (authMode >= B_NETWORK_AUTHENTICATION_WPA) {
			// WPA/WPA2
			value = "\"";
			value += password;
			value += "\"";
			result = wpa_config_set(network, "psk", value.String(), 10);

			if (result == 0) {
				// We need to actually "apply" the PSK
				wpa_config_update_psk(network);
			}
		}

		if (result != 0) {
			// The key format is invalid, we need to ask for another password.
			BMessage newJoinRequest = *message;
			newJoinRequest.RemoveName("password");
			newJoinRequest.AddString("error", "Password format invalid");
			newJoinRequest.AddBool("forceDialog", true);
			PostMessage(&newJoinRequest);
		}
	}

	if (result != 0) {
		wpas_notify_network_removed(interface, network);
		wpa_config_remove_network(interface->conf, network->id);
		return B_ERROR;
	}

	// Set up watching for the completion event
	_StartWatchingInterfaceChanges(interface, _InterfaceStateChangeCallback,
		message);

	// Now attempt to connect
	wpa_supplicant_select_network(interface, network);

	// Use a message runner to return a timeout and stop watching after a while
	BMessage timeout(kMsgJoinTimeout);
	timeout.AddPointer("interface", interface);

	BMessageRunner::StartSending(be_app_messenger, &timeout,
		15 * 1000 * 1000, 1);
		// Note that we don't need to cancel this. If joining works before the
		// timeout happens, it will take the StateChangeWatchingEntry with it
		// and the timeout message won't match anything and be discarded.

	return B_OK;
}
コード例 #12
0
static struct wpa_ssid * wpas_wps_add_network(struct wpa_supplicant *wpa_s,
					      int registrar, const u8 *bssid)
{
	struct wpa_ssid *ssid;

	ssid = wpa_config_add_network(wpa_s->conf);
	if (ssid == NULL)
		return NULL;
	wpas_notify_network_added(wpa_s, ssid);
	wpa_config_set_network_defaults(ssid);
	ssid->temporary = 1;
	if (wpa_config_set(ssid, "key_mgmt", "WPS", 0) < 0 ||
	    wpa_config_set(ssid, "eap", "WSC", 0) < 0 ||
	    wpa_config_set(ssid, "identity", registrar ?
			   "\"" WSC_ID_REGISTRAR "\"" :
			   "\"" WSC_ID_ENROLLEE "\"", 0) < 0) {
		wpas_notify_network_removed(wpa_s, ssid);
		wpa_config_remove_network(wpa_s->conf, ssid->id);
		return NULL;
	}

	if (bssid) {
#ifndef CONFIG_P2P
		struct wpa_bss *bss;
		int count = 0;
#endif /* CONFIG_P2P */

		os_memcpy(ssid->bssid, bssid, ETH_ALEN);
		ssid->bssid_set = 1;

		/*
		 * Note: With P2P, the SSID may change at the time the WPS
		 * provisioning is started, so better not filter the AP based
		 * on the current SSID in the scan results.
		 */
#ifndef CONFIG_P2P
		dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
			if (os_memcmp(bssid, bss->bssid, ETH_ALEN) != 0)
				continue;

			os_free(ssid->ssid);
			ssid->ssid = os_malloc(bss->ssid_len);
			if (ssid->ssid == NULL)
				break;
			os_memcpy(ssid->ssid, bss->ssid, bss->ssid_len);
			ssid->ssid_len = bss->ssid_len;
			wpa_hexdump_ascii(MSG_DEBUG, "WPS: Picked SSID from "
					  "scan results",
					  ssid->ssid, ssid->ssid_len);
			count++;
		}

		if (count > 1) {
			wpa_printf(MSG_DEBUG, "WPS: More than one SSID found "
				   "for the AP; use wildcard");
			os_free(ssid->ssid);
			ssid->ssid = NULL;
			ssid->ssid_len = 0;
		}
#endif /* CONFIG_P2P */
	}

	return ssid;
}