static void
add_group_ciphers (NMAccessPoint *ap, NMSettingWirelessSecurity *sec)
{
	guint32 num = nm_setting_wireless_security_get_num_groups (sec);
	guint32 flags = NM_802_11_AP_SEC_NONE;
	guint32 i;

	/* If no ciphers are specified, that means "all" WPA ciphers */
	if (num == 0) {
		flags |= NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP;
	} else {
		for (i = 0; i < num; i++) {
			const char *cipher = nm_setting_wireless_security_get_group (sec, i);

			if (!strcmp (cipher, "wep40"))
				flags |= NM_802_11_AP_SEC_GROUP_WEP40;
			else if (!strcmp (cipher, "wep104"))
				flags |= NM_802_11_AP_SEC_GROUP_WEP104;
			else if (!strcmp (cipher, "tkip"))
				flags |= NM_802_11_AP_SEC_GROUP_TKIP;
			else if (!strcmp (cipher, "ccmp"))
				flags |= NM_802_11_AP_SEC_GROUP_CCMP;
		}
	}

	if (has_proto (sec, PROTO_WPA))
		nm_ap_set_wpa_flags (ap, nm_ap_get_wpa_flags (ap) | flags);
	if (has_proto (sec, PROTO_RSN))
		nm_ap_set_rsn_flags (ap, nm_ap_get_rsn_flags (ap) | flags);
}
Пример #2
0
static void
add_pair_ciphers (NMAccessPoint *ap, NMSettingWirelessSecurity *sec)
{
	guint32 num = nm_setting_wireless_security_get_num_pairwise (sec);
	NM80211ApSecurityFlags flags = NM_802_11_AP_SEC_NONE;
	guint32 i;

	/* If no ciphers are specified, that means "all" WPA ciphers */
	if (num == 0) {
		flags |= NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP;
	} else {
		for (i = 0; i < num; i++) {
			const char *cipher = nm_setting_wireless_security_get_pairwise (sec, i);

			if (!strcmp (cipher, "tkip"))
				flags |= NM_802_11_AP_SEC_PAIR_TKIP;
			else if (!strcmp (cipher, "ccmp"))
				flags |= NM_802_11_AP_SEC_PAIR_CCMP;
		}
	}

	if (has_proto (sec, PROTO_WPA))
		nm_ap_set_wpa_flags (ap, nm_ap_get_wpa_flags (ap) | flags);
	if (has_proto (sec, PROTO_RSN))
		nm_ap_set_rsn_flags (ap, nm_ap_get_rsn_flags (ap) | flags);
}
NMAccessPoint *
nm_ap_new_fake_from_connection (NMConnection *connection)
{
	NMAccessPoint *ap;
	NMSettingWireless *s_wireless;
	NMSettingWirelessSecurity *s_wireless_sec;
	const GByteArray *ssid;
	const char *mode, *band, *key_mgmt;
	guint32 channel, flags;
	gboolean psk = FALSE, eap = FALSE;

	g_return_val_if_fail (connection != NULL, NULL);

	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
	g_return_val_if_fail (s_wireless != NULL, NULL);

	ssid = nm_setting_wireless_get_ssid (s_wireless);
	g_return_val_if_fail (ssid != NULL, NULL);
	g_return_val_if_fail (ssid->len > 0, NULL);

	ap = nm_ap_new ();
	nm_ap_set_fake (ap, TRUE);
	nm_ap_set_ssid (ap, ssid);

	// FIXME: bssid too?

	mode = nm_setting_wireless_get_mode (s_wireless);
	if (mode) {
		if (!strcmp (mode, "infrastructure"))
			nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
		else if (!strcmp (mode, "adhoc"))
			nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
		else
			goto error;
	} else {
		nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
	}

	band = nm_setting_wireless_get_band (s_wireless);
	channel = nm_setting_wireless_get_channel (s_wireless);

	if (band && channel) {
		guint32 freq = channel_to_freq (channel, band);

		if (freq == 0)
			goto error;

		nm_ap_set_freq (ap, freq);
	}

	s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
	/* Assume presence of a security setting means the AP is encrypted */
	if (!s_wireless_sec)
		goto done;

	key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec);

	/* Everything below here uses encryption */
	nm_ap_set_flags (ap, nm_ap_get_flags (ap) | NM_802_11_AP_FLAGS_PRIVACY);

	/* Static & Dynamic WEP */
	if (!strcmp (key_mgmt, "none") || !strcmp (key_mgmt, "ieee8021x"))
		goto done;

	psk = !strcmp (key_mgmt, "wpa-psk");
	eap = !strcmp (key_mgmt, "wpa-eap");
	if (psk || eap) {
		if (has_proto (s_wireless_sec, PROTO_WPA)) {
			flags = nm_ap_get_wpa_flags (ap);
			flags |= eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK;
			nm_ap_set_wpa_flags (ap, flags);
		}
		if (has_proto (s_wireless_sec, PROTO_RSN)) {
			flags = nm_ap_get_rsn_flags (ap);
			flags |= eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK;
			nm_ap_set_rsn_flags (ap, flags);
		}

		add_pair_ciphers (ap, s_wireless_sec);
		add_group_ciphers (ap, s_wireless_sec);
	} else if (!strcmp (key_mgmt, "wpa-none")) {
		guint32 i;

		/* Ad-Hoc has special requirements: proto=WPA, pairwise=(none), and
		 * group=TKIP/CCMP (but not both).
		 */

		flags = nm_ap_get_wpa_flags (ap);
		flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK;

		/* Clear ciphers; pairwise must be unset anyway, and group gets set below */
		flags &= ~(  NM_802_11_AP_SEC_PAIR_WEP40
		           | NM_802_11_AP_SEC_PAIR_WEP104
		           | NM_802_11_AP_SEC_PAIR_TKIP
		           | NM_802_11_AP_SEC_PAIR_CCMP
		           | NM_802_11_AP_SEC_GROUP_WEP40
		           | NM_802_11_AP_SEC_GROUP_WEP104
		           | NM_802_11_AP_SEC_GROUP_TKIP
		           | NM_802_11_AP_SEC_GROUP_CCMP);

		for (i = 0; i < nm_setting_wireless_security_get_num_groups (s_wireless_sec); i++) {
			if (!strcmp (nm_setting_wireless_security_get_group (s_wireless_sec, i), "ccmp")) {
				flags |= NM_802_11_AP_SEC_GROUP_CCMP;
				break;
			}
		}

		/* Default to TKIP since not all WPA-capable cards can do CCMP */
		if (!(flags & NM_802_11_AP_SEC_GROUP_CCMP))
			flags |= NM_802_11_AP_SEC_GROUP_TKIP;

		nm_ap_set_wpa_flags (ap, flags);

		/* Don't use Ad-Hoc RSN yet */
		nm_ap_set_rsn_flags (ap, NM_802_11_AP_SEC_NONE);
	}

done:
	return ap;

error:
	g_object_unref (ap);
	return NULL;
}
static void
foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
{
	GValue *variant = (GValue *) value;
	NMAccessPoint *ap = (NMAccessPoint *) user_data;

	if (G_VALUE_HOLDS_BOXED (variant)) {
		GArray *array = g_value_get_boxed (variant);

		if (!strcmp (key, "ssid")) {
			guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len);
			GByteArray * ssid;

			/* Stupid ieee80211 layer uses <hidden> */
			if (((len == 8) || (len == 9))
				&& (memcmp (array->data, "<hidden>", 8) == 0))
				return;

			if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len))
				return;

			ssid = g_byte_array_sized_new (len);
			g_byte_array_append (ssid, (const guint8 *) array->data, len);
			nm_ap_set_ssid (ap, ssid);
			g_byte_array_free (ssid, TRUE);
		} else if (!strcmp (key, "bssid")) {
			struct ether_addr addr;

			if (array->len != ETH_ALEN)
				return;
			memset (&addr, 0, sizeof (struct ether_addr));
			memcpy (&addr, array->data, ETH_ALEN);
			nm_ap_set_address (ap, &addr);
		} else if (!strcmp (key, "wpaie")) {
			guint8 * ie = (guint8 *) array->data;
			guint32 flags = nm_ap_get_wpa_flags (ap);

			if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
				return;
			flags = nm_ap_add_security_from_ie (flags, ie, array->len);
			nm_ap_set_wpa_flags (ap, flags);
		} else if (!strcmp (key, "rsnie")) {
			guint8 * ie = (guint8 *) array->data;
			guint32 flags = nm_ap_get_rsn_flags (ap);

			if (array->len <= 0 || array->len > WPA_MAX_IE_LEN)
				return;
			flags = nm_ap_add_security_from_ie (flags, ie, array->len);
			nm_ap_set_rsn_flags (ap, flags);
		}
	} else if (G_VALUE_HOLDS_INT (variant)) {
		gint32 int_val = g_value_get_int (variant);

		if (!strcmp (key, "frequency")) {
			nm_ap_set_freq (ap, (guint32) int_val);
		} else if (!strcmp (key, "maxrate")) {
			/* Supplicant reports as b/s, we use Kb/s internally */
			nm_ap_set_max_bitrate (ap, int_val / 1000);
		}
	} else if (G_VALUE_HOLDS_UINT (variant)) {
		guint32 val = g_value_get_uint (variant);

		if (!strcmp (key, "capabilities")) {
			if (val & IEEE80211_CAP_ESS) {
				nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
			} else if (val & IEEE80211_CAP_IBSS) {
				nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
			}

			if (val & IEEE80211_CAP_PRIVACY) {
				guint32 flags = nm_ap_get_flags (ap);
				nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY);
			}
		}
	}
}
Пример #5
0
static void
foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
{
	GValue *variant = (GValue *) value;
	NMAccessPoint *ap = (NMAccessPoint *) user_data;

	if (G_VALUE_HOLDS_BOXED (variant)) {
		GArray *array = g_value_get_boxed (variant);

		if (!strcmp (key, "SSID")) {
			guint32 len = MIN (32, array->len);
			GByteArray *ssid;

			/* Stupid ieee80211 layer uses <hidden> */
			if (((len == 8) || (len == 9))
				&& (memcmp (array->data, "<hidden>", 8) == 0))
				return;

			if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len))
				return;

			ssid = g_byte_array_sized_new (len);
			g_byte_array_append (ssid, (const guint8 *) array->data, len);
			nm_ap_set_ssid (ap, ssid);
			g_byte_array_free (ssid, TRUE);
		} else if (!strcmp (key, "BSSID")) {
			struct ether_addr addr;

			if (array->len != ETH_ALEN)
				return;
			memset (&addr, 0, sizeof (struct ether_addr));
			memcpy (&addr, array->data, ETH_ALEN);
			nm_ap_set_address (ap, &addr);
		} else if (!strcmp (key, "Rates")) {
			guint32 maxrate = 0;
			int i;

			/* Find the max AP rate */
			for (i = 0; i < array->len; i++) {
				guint32 r = g_array_index (array, guint32, i);

				if (r > maxrate) {
					maxrate = r;
					nm_ap_set_max_bitrate (ap, r / 1000);
				}
			}
		} else if (!strcmp (key, "WPA")) {
			NM80211ApSecurityFlags flags = nm_ap_get_wpa_flags (ap);

			flags |= security_from_dict (g_value_get_boxed (variant));
			nm_ap_set_wpa_flags (ap, flags);
		} else if (!strcmp (key, "RSN")) {
			NM80211ApSecurityFlags flags = nm_ap_get_rsn_flags (ap);

			flags |= security_from_dict (g_value_get_boxed (variant));
			nm_ap_set_rsn_flags (ap, flags);
		}
	} else if (G_VALUE_HOLDS_UINT (variant)) {
		guint32 val = g_value_get_uint (variant);

		if (!strcmp (key, "Frequency"))
			nm_ap_set_freq (ap, val);
	} else if (G_VALUE_HOLDS_INT (variant)) {
		gint val = g_value_get_int (variant);

		if (!strcmp (key, "Signal"))
			nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (val));
	} else if (G_VALUE_HOLDS_STRING (variant)) {
		const char *val = g_value_get_string (variant);

		if (val && !strcmp (key, "Mode")) {
			if (strcmp (val, "infrastructure") == 0)
				nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
			else if (strcmp (val, "ad-hoc") == 0)
				nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC);
		}
	} else if (G_VALUE_HOLDS_BOOLEAN (variant)) {
		gboolean val = g_value_get_boolean (variant);

		if (strcmp (key, "Privacy") == 0) {
			if (val) {
				NM80211ApFlags flags = nm_ap_get_flags (ap);
				nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY);
			}
		}
	}
}
Пример #6
0
NMAccessPoint *
nm_ap_match_in_list (NMAccessPoint *find_ap,
                     GSList *ap_list,
                     gboolean strict_match)
{
	GSList *iter;

	g_return_val_if_fail (find_ap != NULL, NULL);

	for (iter = ap_list; iter; iter = g_slist_next (iter)) {
		NMAccessPoint * list_ap = NM_AP (iter->data);
		const GByteArray * list_ssid = nm_ap_get_ssid (list_ap);
		const struct ether_addr * list_addr = nm_ap_get_address (list_ap);

		const GByteArray * find_ssid = nm_ap_get_ssid (find_ap);
		const struct ether_addr * find_addr = nm_ap_get_address (find_ap);

		/* SSID match; if both APs are hiding their SSIDs,
		 * let matching continue on BSSID and other properties
		 */
		if (   (!list_ssid && find_ssid)
		    || (list_ssid && !find_ssid)
		    || !nm_utils_same_ssid (list_ssid, find_ssid, TRUE))
			continue;

		/* BSSID match */
		if (   (strict_match || nm_ethernet_address_is_valid (find_addr))
		    && nm_ethernet_address_is_valid (list_addr)
		    && memcmp (list_addr->ether_addr_octet, 
		               find_addr->ether_addr_octet,
		               ETH_ALEN) != 0) {
			continue;
		}

		/* mode match */
		if (nm_ap_get_mode (list_ap) != nm_ap_get_mode (find_ap))
			continue;

		/* Frequency match */
		if (nm_ap_get_freq (list_ap) != nm_ap_get_freq (find_ap))
			continue;

		/* AP flags */
		if (nm_ap_get_flags (list_ap) != nm_ap_get_flags (find_ap))
			continue;

		if (strict_match) {
			if (nm_ap_get_wpa_flags (list_ap) != nm_ap_get_wpa_flags (find_ap))
				continue;

			if (nm_ap_get_rsn_flags (list_ap) != nm_ap_get_rsn_flags (find_ap))
				continue;
		} else {
			NM80211ApSecurityFlags list_wpa_flags = nm_ap_get_wpa_flags (list_ap);
			NM80211ApSecurityFlags find_wpa_flags = nm_ap_get_wpa_flags (find_ap);
			NM80211ApSecurityFlags list_rsn_flags = nm_ap_get_rsn_flags (list_ap);
			NM80211ApSecurityFlags find_rsn_flags = nm_ap_get_rsn_flags (find_ap);

			/* Just ensure that there is overlap in the capabilities */
			if (   !capabilities_compatible (list_wpa_flags, find_wpa_flags)
			    && !capabilities_compatible (list_rsn_flags, find_rsn_flags))
				continue;
		}

		return list_ap;
	}

	return NULL;
}
Пример #7
0
gboolean
nm_ap_check_compatible (NMAccessPoint *self,
                        NMConnection *connection)
{
	NMAccessPointPrivate *priv;
	NMSettingWireless *s_wireless;
	NMSettingWirelessSecurity *s_wireless_sec;
	const char *mode;
	const char *band;
	const GByteArray *bssid;
	guint32 channel;

	g_return_val_if_fail (NM_IS_AP (self), FALSE);
	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);

	priv = NM_AP_GET_PRIVATE (self);

	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
	if (s_wireless == NULL)
		return FALSE;
	
	if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), priv->ssid, TRUE))
		return FALSE;

	bssid = nm_setting_wireless_get_bssid (s_wireless);
	if (bssid && memcmp (bssid->data, &priv->address, ETH_ALEN))
		return FALSE;

	mode = nm_setting_wireless_get_mode (s_wireless);
	if (mode) {
		if (!strcmp (mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA))
			return FALSE;
		if (!strcmp (mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC))
			return FALSE;
	}

	band = nm_setting_wireless_get_band (s_wireless);
	if (band) {
		if (!strcmp (band, "a")) {
			if (priv->freq < 4915 || priv->freq > 5825)
				return FALSE;
		} else if (!strcmp (band, "bg")) {
			if (priv->freq < 2412 || priv->freq > 2484)
				return FALSE;
		}
	}

	channel = nm_setting_wireless_get_channel (s_wireless);
	if (channel) {
		guint32 ap_chan = nm_utils_wifi_freq_to_channel (priv->freq);

		if (channel != ap_chan)
			return FALSE;
	}

	s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
	                                                                          NM_TYPE_SETTING_WIRELESS_SECURITY);

	return nm_setting_wireless_ap_security_compatible (s_wireless,
	                                                   s_wireless_sec,
	                                                   nm_ap_get_flags (self),
	                                                   nm_ap_get_wpa_flags (self),
	                                                   nm_ap_get_rsn_flags (self),
	                                                   nm_ap_get_mode (self));
}