1    	/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2    	
3    	/*
4    	 * Dan Williams <dcbw@redhat.com>
5    	 * Tambet Ingo <tambet@gmail.com>
6    	 *
7    	 * This library is free software; you can redistribute it and/or
8    	 * modify it under the terms of the GNU Lesser General Public
9    	 * License as published by the Free Software Foundation; either
10   	 * version 2 of the License, or (at your option) any later version.
11   	 *
12   	 * This library is distributed in the hope that it will be useful,
13   	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   	 * Lesser General Public License for more details.
16   	 *
17   	 * You should have received a copy of the GNU Lesser General Public
18   	 * License along with this library; if not, write to the
19   	 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20   	 * Boston, MA 02110-1301 USA.
21   	 *
22   	 * (C) Copyright 2007 - 2013 Red Hat, Inc.
23   	 * (C) Copyright 2007 - 2008 Novell, Inc.
24   	 */
25   	
26   	#include <string.h>
27   	#include <net/ethernet.h>
28   	#include <netinet/ether.h>
29   	#include <dbus/dbus-glib.h>
30   	#include <glib/gi18n.h>
31   	
32   	#include "NetworkManager.h"
33   	#include "nm-setting-wireless.h"
34   	#include "nm-param-spec-specialized.h"
35   	#include "nm-utils.h"
36   	#include "nm-dbus-glib-types.h"
37   	#include "nm-utils-private.h"
38   	#include "nm-setting-private.h"
39   	
40   	/**
41   	 * SECTION:nm-setting-wireless
42   	 * @short_description: Describes connection properties for 802.11 WiFi networks
43   	 * @include: nm-setting-wireless.h
44   	 *
45   	 * The #NMSettingWireless object is a #NMSetting subclass that describes properties
46   	 * necessary for connection to 802.11 WiFi networks.
47   	 **/
48   	
49   	/**
50   	 * nm_setting_wireless_error_quark:
51   	 *
52   	 * Registers an error quark for #NMSettingWireless if necessary.
53   	 *
54   	 * Returns: the error quark used for #NMSettingWireless errors.
55   	 **/
56   	GQuark
57   	nm_setting_wireless_error_quark (void)
58   	{
59   		static GQuark quark;
60   	
61   		if (G_UNLIKELY (!quark))
62   			quark = g_quark_from_static_string ("nm-setting-wireless-error-quark");
63   		return quark;
64   	}
65   	
66   	
67   	G_DEFINE_TYPE_WITH_CODE (NMSettingWireless, nm_setting_wireless, NM_TYPE_SETTING,
68   	                         _nm_register_setting (NM_SETTING_WIRELESS_SETTING_NAME,
69   	                                               g_define_type_id,
70   	                                               1,
71   	                                               NM_SETTING_WIRELESS_ERROR))
72   	NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIRELESS)
73   	
74   	#define NM_SETTING_WIRELESS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS, NMSettingWirelessPrivate))
75   	
76   	typedef struct {
77   		GByteArray *ssid;
78   		char *mode;
79   		char *band;
80   		guint32 channel;
81   		GByteArray *bssid;
82   		guint32 rate;
83   		guint32 tx_power;
84   		GByteArray *device_mac_address;
85   		GByteArray *cloned_mac_address;
86   		GSList *mac_address_blacklist;
87   		guint32 mtu;
88   		GSList *seen_bssids;
89   		char *security;
90   		gboolean hidden;
91   	} NMSettingWirelessPrivate;
92   	
93   	enum {
94   		PROP_0,
95   		PROP_SSID,
96   		PROP_MODE,
97   		PROP_BAND,
98   		PROP_CHANNEL,
99   		PROP_BSSID,
100  		PROP_RATE,
101  		PROP_TX_POWER,
102  		PROP_MAC_ADDRESS,
103  		PROP_CLONED_MAC_ADDRESS,
104  		PROP_MAC_ADDRESS_BLACKLIST,
105  		PROP_MTU,
106  		PROP_SEEN_BSSIDS,
107  		PROP_SEC,
108  		PROP_HIDDEN,
109  	
110  		LAST_PROP
111  	};
112  	
113  	static gboolean
114  	match_cipher (const char *cipher,
115  	              const char *expected,
116  	              guint32 wpa_flags,
117  	              guint32 rsn_flags,
118  	              guint32 flag)
119  	{
120  		if (strcmp (cipher, expected) != 0)
121  			return FALSE;
122  	
123  		if (!(wpa_flags & flag) && !(rsn_flags & flag))
124  			return FALSE;
125  	
126  		return TRUE;
127  	}
128  	
129  	/**
130  	 * nm_setting_wireless_ap_security_compatible:
131  	 * @s_wireless: a #NMSettingWireless
132  	 * @s_wireless_sec: a #NMSettingWirelessSecurity or %NULL
133  	 * @ap_flags: the %NM80211ApFlags of the given access point
134  	 * @ap_wpa: the %NM80211ApSecurityFlags of the given access point's WPA
135  	 * capabilities
136  	 * @ap_rsn: the %NM80211ApSecurityFlags of the given access point's WPA2/RSN
137  	 * capabilities
138  	 * @ap_mode: the 802.11 mode of the AP, either Ad-Hoc or Infrastructure
139  	 *
140  	 * Given a #NMSettingWireless and an optional #NMSettingWirelessSecurity,
141  	 * determine if the configuration given by the settings is compatible with
142  	 * the security of an access point using that access point's capability flags
143  	 * and mode.  Useful for clients that wish to filter a set of connections
144  	 * against a set of access points and determine which connections are
145  	 * compatible with which access points.
146  	 *
147  	 * Returns: %TRUE if the given settings are compatible with the access point's
148  	 * security flags and mode, %FALSE if they are not.
149  	 */ 
150  	gboolean
151  	nm_setting_wireless_ap_security_compatible (NMSettingWireless *s_wireless,
152  	                                            NMSettingWirelessSecurity *s_wireless_sec,
153  	                                            NM80211ApFlags ap_flags,
154  	                                            NM80211ApSecurityFlags ap_wpa,
155  	                                            NM80211ApSecurityFlags ap_rsn,
156  	                                            NM80211Mode ap_mode)
157  	{
158  		NMSettingWirelessPrivate *priv;
159  		const char *key_mgmt = NULL, *cipher;
160  		guint32 num, i;
161  		gboolean found = FALSE;
162  	
163  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (s_wireless), FALSE);
164  	
(1) Event returned_pointer: Pointer "priv" returned by "g_type_instance_get_private((GTypeInstance *)s_wireless, nm_setting_wireless_get_type())" is never used.
165  		priv = NM_SETTING_WIRELESS_GET_PRIVATE (s_wireless);
166  	
167  		if (!s_wireless_sec) {
168  			if (   (ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
169  			    || (ap_wpa != NM_802_11_AP_SEC_NONE)
170  			    || (ap_rsn != NM_802_11_AP_SEC_NONE))
171  				return FALSE;
172  			return TRUE;
173  		}
174  	
175  		key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec);
176  		if (!key_mgmt)
177  			return FALSE;
178  	
179  		/* Static WEP */
180  		if (!strcmp (key_mgmt, "none")) {
181  			if (   !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY)
182  			    || (ap_wpa != NM_802_11_AP_SEC_NONE)
183  			    || (ap_rsn != NM_802_11_AP_SEC_NONE))
184  				return FALSE;
185  			return TRUE;
186  		}
187  	
188  		/* Adhoc WPA */
189  		if (!strcmp (key_mgmt, "wpa-none")) {
190  			if (ap_mode != NM_802_11_MODE_ADHOC)
191  				return FALSE;
192  			/* FIXME: validate ciphers if they're in the beacon */
193  			return TRUE;
194  		}
195  	
196  		/* Adhoc WPA2 (ie, RSN IBSS) */
197  		if (ap_mode == NM_802_11_MODE_ADHOC) {
198  			if (strcmp (key_mgmt, "wpa-psk"))
199  				return FALSE;
200  	
201  			/* Ensure the AP has RSN PSK capability */
202  			if (!(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK))
203  				return FALSE;
204  	
205  			/* Fall through and check ciphers in generic WPA-PSK code */
206  		}
207  	
208  		/* Dynamic WEP or LEAP */
209  		if (!strcmp (key_mgmt, "ieee8021x")) {
210  			if (!(ap_flags & NM_802_11_AP_FLAGS_PRIVACY))
211  				return FALSE;
212  	
213  			/* If the AP is advertising a WPA IE, make sure it supports WEP ciphers */
214  			if (ap_wpa != NM_802_11_AP_SEC_NONE) {
215  				if (!(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
216  					return FALSE;
217  	
218  				/* quick check; can't use AP if it doesn't support at least one
219  				 * WEP cipher in both pairwise and group suites.
220  				 */
221  				if (   !(ap_wpa & (NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104))
222  				    || !(ap_wpa & (NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104)))
223  					return FALSE;
224  	
225  				/* Match at least one pairwise cipher with AP's capability if the
226  				 * wireless-security setting explicitly lists pairwise ciphers
227  				 */
228  				num = nm_setting_wireless_security_get_num_pairwise (s_wireless_sec);
229  				for (i = 0, found = FALSE; i < num; i++) {
230  					cipher = nm_setting_wireless_security_get_pairwise (s_wireless_sec, i);
231  					if ((found = match_cipher (cipher, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP40)))
232  						break;
233  					if ((found = match_cipher (cipher, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_PAIR_WEP104)))
234  						break;
235  				}
236  				if (!found && num)
237  					return FALSE;
238  	
239  				/* Match at least one group cipher with AP's capability if the
240  				 * wireless-security setting explicitly lists group ciphers
241  				 */
242  				num = nm_setting_wireless_security_get_num_groups (s_wireless_sec);
243  				for (i = 0, found = FALSE; i < num; i++) {
244  					cipher = nm_setting_wireless_security_get_group (s_wireless_sec, i);
245  					if ((found = match_cipher (cipher, "wep40", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP40)))
246  						break;
247  					if ((found = match_cipher (cipher, "wep104", ap_wpa, ap_wpa, NM_802_11_AP_SEC_GROUP_WEP104)))
248  						break;
249  				}
250  				if (!found && num)
251  					return FALSE;
252  			}
253  			return TRUE;
254  		}
255  	
256  		/* WPA[2]-PSK and WPA[2] Enterprise */
257  		if (   !strcmp (key_mgmt, "wpa-psk")
258  		    || !strcmp (key_mgmt, "wpa-eap")) {
259  	
260  			if (!strcmp (key_mgmt, "wpa-psk")) {
261  				if (   !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK)
262  				    && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK))
263  					return FALSE;
264  			} else if (!strcmp (key_mgmt, "wpa-eap")) {
265  				if (   !(ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
266  				    && !(ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_802_1X))
267  					return FALSE;
268  			}
269  	
270  			// FIXME: should handle WPA and RSN separately here to ensure that
271  			// if the Connection only uses WPA we don't match a cipher against
272  			// the AP's RSN IE instead
273  	
274  			/* Match at least one pairwise cipher with AP's capability if the
275  			 * wireless-security setting explicitly lists pairwise ciphers
276  			 */
277  			num = nm_setting_wireless_security_get_num_pairwise (s_wireless_sec);
278  			for (i = 0, found = FALSE; i < num; i++) {
279  				cipher = nm_setting_wireless_security_get_pairwise (s_wireless_sec, i);
280  				if ((found = match_cipher (cipher, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_TKIP)))
281  					break;
282  				if ((found = match_cipher (cipher, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_PAIR_CCMP)))
283  					break;
284  			}
285  			if (!found && num)
286  				return FALSE;
287  	
288  			/* Match at least one group cipher with AP's capability if the
289  			 * wireless-security setting explicitly lists group ciphers
290  			 */
291  			num = nm_setting_wireless_security_get_num_groups (s_wireless_sec);
292  			for (i = 0, found = FALSE; i < num; i++) {
293  				cipher = nm_setting_wireless_security_get_group (s_wireless_sec, i);
294  	
295  				if ((found = match_cipher (cipher, "wep40", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP40)))
296  					break;
297  				if ((found = match_cipher (cipher, "wep104", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_WEP104)))
298  					break;
299  				if ((found = match_cipher (cipher, "tkip", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_TKIP)))
300  					break;
301  				if ((found = match_cipher (cipher, "ccmp", ap_wpa, ap_rsn, NM_802_11_AP_SEC_GROUP_CCMP)))
302  					break;
303  			}
304  			if (!found && num)
305  				return FALSE;
306  	
307  			return TRUE;
308  		}
309  	
310  		return FALSE;
311  	}
312  	
313  	/**
314  	 * nm_setting_wireless_new:
315  	 *
316  	 * Creates a new #NMSettingWireless object with default values.
317  	 *
318  	 * Returns: (transfer full): the new empty #NMSettingWireless object
319  	 **/
320  	NMSetting *
321  	nm_setting_wireless_new (void)
322  	{
323  		return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS, NULL);
324  	}
325  	
326  	/**
327  	 * nm_setting_wireless_get_ssid:
328  	 * @setting: the #NMSettingWireless
329  	 *
330  	 * Returns: the #NMSettingWireless:ssid property of the setting
331  	 **/
332  	const GByteArray *
333  	nm_setting_wireless_get_ssid (NMSettingWireless *setting)
334  	{
335  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
336  	
337  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->ssid;
338  	}
339  	
340  	/**
341  	 * nm_setting_wireless_get_mode:
342  	 * @setting: the #NMSettingWireless
343  	 *
344  	 * Returns: the #NMSettingWireless:mode property of the setting
345  	 **/
346  	const char *
347  	nm_setting_wireless_get_mode (NMSettingWireless *setting)
348  	{
349  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
350  	
351  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mode;
352  	}
353  	
354  	/**
355  	 * nm_setting_wireless_get_band:
356  	 * @setting: the #NMSettingWireless
357  	 *
358  	 * Returns: the #NMSettingWireless:band property of the setting
359  	 **/
360  	const char *
361  	nm_setting_wireless_get_band (NMSettingWireless *setting)
362  	{
363  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
364  	
365  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->band;
366  	}
367  	
368  	/**
369  	 * nm_setting_wireless_get_channel:
370  	 * @setting: the #NMSettingWireless
371  	 *
372  	 * Returns: the #NMSettingWireless:channel property of the setting
373  	 **/
374  	guint32
375  	nm_setting_wireless_get_channel (NMSettingWireless *setting)
376  	{
377  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0);
378  	
379  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->channel;
380  	}
381  	
382  	/**
383  	 * nm_setting_wireless_get_bssid:
384  	 * @setting: the #NMSettingWireless
385  	 *
386  	 * Returns: the #NMSettingWireless:bssid property of the setting
387  	 **/
388  	const GByteArray *
389  	nm_setting_wireless_get_bssid (NMSettingWireless *setting)
390  	{
391  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
392  	
393  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->bssid;
394  	}
395  	
396  	/**
397  	 * nm_setting_wireless_get_rate:
398  	 * @setting: the #NMSettingWireless
399  	 *
400  	 * Returns: the #NMSettingWireless:rate property of the setting
401  	 **/
402  	guint32
403  	nm_setting_wireless_get_rate (NMSettingWireless *setting)
404  	{
405  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0);
406  	
407  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->rate;
408  	}
409  	
410  	/**
411  	 * nm_setting_wireless_get_tx_power:
412  	 * @setting: the #NMSettingWireless
413  	 *
414  	 * Returns: the #NMSettingWireless:tx-power property of the setting
415  	 **/
416  	guint32
417  	nm_setting_wireless_get_tx_power (NMSettingWireless *setting)
418  	{
419  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0);
420  	
421  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->tx_power;
422  	}
423  	
424  	/**
425  	 * nm_setting_wireless_get_mac_address:
426  	 * @setting: the #NMSettingWireless
427  	 *
428  	 * Returns: the #NMSettingWireless:mac-address property of the setting
429  	 **/
430  	const GByteArray *
431  	nm_setting_wireless_get_mac_address (NMSettingWireless *setting)
432  	{
433  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
434  	
435  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->device_mac_address;
436  	}
437  	
438  	/**
439  	 * nm_setting_wireless_get_cloned_mac_address:
440  	 * @setting: the #NMSettingWireless
441  	 *
442  	 * Returns: the #NMSettingWireless:cloned-mac-address property of the setting
443  	 **/
444  	const GByteArray *
445  	nm_setting_wireless_get_cloned_mac_address (NMSettingWireless *setting)
446  	{
447  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
448  	
449  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->cloned_mac_address;
450  	}
451  	
452  	/**
453  	 * nm_setting_wireless_get_mac_address_blacklist:
454  	 * @setting: the #NMSettingWireless
455  	 *
456  	 * Returns: (element-type GLib.ByteArray): the
457  	 * #NMSettingWireless:mac-address-blacklist property of the setting
458  	 **/
459  	const GSList *
460  	nm_setting_wireless_get_mac_address_blacklist (NMSettingWireless *setting)
461  	{
462  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
463  	
464  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist;
465  	}
466  	
467  	/**
468  	 * nm_setting_wireless_get_num_mac_blacklist_items:
469  	 * @setting: the #NMSettingWireless
470  	 *
471  	 * Returns: the number of blacklisted MAC addresses
472  	 *
473  	 * Since: 0.9.10
474  	 **/
475  	guint32
476  	nm_setting_wireless_get_num_mac_blacklist_items (NMSettingWireless *setting)
477  	{
478  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0);
479  	
480  		return g_slist_length (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mac_address_blacklist);
481  	}
482  	
483  	/**
484  	 * nm_setting_wireless_get_mac_blacklist_item:
485  	 * @setting: the #NMSettingWireless
486  	 * @idx: the zero-based index of the MAC address entry
487  	 *
488  	 * Returns: the blacklisted MAC address string (hex-digits-and-colons notation)
489  	 * at index @idx
490  	 *
491  	 * Since: 0.9.10
492  	 **/
493  	const char *
494  	nm_setting_wireless_get_mac_blacklist_item (NMSettingWireless *setting, guint32 idx)
495  	{
496  		NMSettingWirelessPrivate *priv;
497  	
498  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
499  	
500  		priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting);
501  		g_return_val_if_fail (idx <= g_slist_length (priv->mac_address_blacklist), NULL);
502  	
503  		return (const char *) g_slist_nth_data (priv->mac_address_blacklist, idx);
504  	}
505  	
506  	/**
507  	 * nm_setting_wireless_add_mac_blacklist_item:
508  	 * @setting: the #NMSettingWireless
509  	 * @mac: the MAC address string (hex-digits-and-colons notation) to blacklist
510  	 *
511  	 * Adds a new MAC address to the #NMSettingWireless:mac-address-blacklist property.
512  	 *
513  	 * Returns: %TRUE if the MAC address was added; %FALSE if the MAC address
514  	 * is invalid or was already present
515  	 *
516  	 * Since: 0.9.10
517  	 **/
518  	gboolean
519  	nm_setting_wireless_add_mac_blacklist_item (NMSettingWireless *setting, const char *mac)
520  	{
521  		NMSettingWirelessPrivate *priv;
522  		GSList *iter;
523  		guint8 buf[32];
524  	
525  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE);
526  		g_return_val_if_fail (mac != NULL, FALSE);
527  	
528  		if (!nm_utils_hwaddr_aton (mac, ARPHRD_ETHER, buf))
529  			return FALSE;
530  	
531  		priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting);
532  		for (iter = priv->mac_address_blacklist; iter; iter = g_slist_next (iter)) {
533  			if (!strcasecmp (mac, (char *) iter->data))
534  				return FALSE;
535  		}
536  	
537  		priv->mac_address_blacklist = g_slist_append (priv->mac_address_blacklist,
538  		                                              g_ascii_strup (mac, -1));
539  		return TRUE;
540  	}
541  	
542  	/**
543  	 * nm_setting_wireless_remove_mac_blacklist_item:
544  	 * @setting: the #NMSettingWireless
545  	 * @idx: index number of the MAC address
546  	 *
547  	 * Removes the MAC address at index @idx from the blacklist.
548  	 *
549  	 * Since: 0.9.10
550  	 **/
551  	void
552  	nm_setting_wireless_remove_mac_blacklist_item (NMSettingWireless *setting, guint32 idx)
553  	{
554  		NMSettingWirelessPrivate *priv;
555  		GSList *elt;
556  	
557  		g_return_if_fail (NM_IS_SETTING_WIRELESS (setting));
558  	
559  		priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting);
560  		elt = g_slist_nth (priv->mac_address_blacklist, idx);
561  		g_return_if_fail (elt != NULL);
562  	
563  		g_free (elt->data);
564  		priv->mac_address_blacklist = g_slist_delete_link (priv->mac_address_blacklist, elt);
565  	}
566  	
567  	/**
568  	 * nm_setting_wireless_get_mtu:
569  	 * @setting: the #NMSettingWireless
570  	 *
571  	 * Returns: the #NMSettingWireless:mtu property of the setting
572  	 **/
573  	guint32
574  	nm_setting_wireless_get_mtu (NMSettingWireless *setting)
575  	{
576  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0);
577  	
578  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->mtu;
579  	}
580  	
581  	/**
582  	 * nm_setting_wireless_get_security:
583  	 * @setting: the #NMSettingWireless
584  	 *
585  	 * Returns: the #NMSettingWireless:security property of the setting
586  	 *
587  	 * Deprecated: 0.9.10: No longer used. Security rescrictions are recognized by
588  	 * the presence of NM_SETTING_WIRELESS_SECURITY_SETTING_NAME in the connection.
589  	 **/
590  	const char *
591  	nm_setting_wireless_get_security (NMSettingWireless *setting)
592  	{
593  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
594  	
595  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->security;
596  	}
597  	
598  	/**
599  	 * nm_setting_wireless_get_hidden:
600  	 * @setting: the #NMSettingWireless
601  	 *
602  	 * Returns: the #NMSettingWireless:hidden property of the setting
603  	 **/
604  	gboolean
605  	nm_setting_wireless_get_hidden (NMSettingWireless *setting)
606  	{
607  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE);
608  	
609  		return NM_SETTING_WIRELESS_GET_PRIVATE (setting)->hidden;
610  	}
611  	
612  	/**
613  	 * nm_setting_wireless_add_seen_bssid:
614  	 * @setting: the #NMSettingWireless
615  	 * @bssid: the new BSSID to add to the list
616  	 *
617  	 * Adds a new Wi-Fi AP's BSSID to the previously seen BSSID list of the setting.
618  	 * NetworkManager now tracks previously seen BSSIDs internally so this function
619  	 * no longer has much use. Actually, changes you make using this function will
620  	 * not be preserved.
621  	 *
622  	 * Returns: %TRUE if @bssid was already known, %FALSE if not
623  	 **/
624  	gboolean
625  	nm_setting_wireless_add_seen_bssid (NMSettingWireless *setting,
626  	                                    const char *bssid)
627  	{
628  		NMSettingWirelessPrivate *priv;
629  		char *lower_bssid;
630  		GSList *iter;
631  		gboolean found = FALSE;
632  	
633  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), FALSE);
634  		g_return_val_if_fail (bssid != NULL, FALSE);
635  	
636  		lower_bssid = g_ascii_strdown (bssid, -1);
637  		if (!lower_bssid)
638  			return FALSE;
639  	
640  		priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting);
641  	
642  		for (iter = priv->seen_bssids; iter; iter = iter->next) {
643  			if (!strcmp ((char *) iter->data, lower_bssid)) {
644  				found = TRUE;
645  				break;
646  			}
647  		}
648  	
649  		if (!found) {
650  			priv->seen_bssids = g_slist_prepend (priv->seen_bssids, lower_bssid);
651  			g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SEEN_BSSIDS);
652  		} else
653  			g_free (lower_bssid);
654  	
655  		return !found;
656  	}
657  	
658  	/**
659  	 * nm_setting_wireless_get_num_seen_bssids:
660  	 * @setting: the #NMSettingWireless
661  	 *
662  	 * Returns: the number of BSSIDs in the previously seen BSSID list
663  	 **/
664  	guint32
665  	nm_setting_wireless_get_num_seen_bssids (NMSettingWireless *setting)
666  	{
667  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), 0);
668  	
669  		return g_slist_length (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids);
670  	}
671  	
672  	/**
673  	 * nm_setting_wireless_get_seen_bssid:
674  	 * @setting: the #NMSettingWireless
675  	 * @i: index of a BSSID in the previously seen BSSID list
676  	 *
677  	 * Returns: the BSSID at index @i
678  	 **/
679  	const char *
680  	nm_setting_wireless_get_seen_bssid (NMSettingWireless *setting,
681  										guint32 i)
682  	{
683  		g_return_val_if_fail (NM_IS_SETTING_WIRELESS (setting), NULL);
684  	
685  		return (const char *) g_slist_nth_data (NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids, i);
686  	}
687  	
688  	static gboolean
689  	verify (NMSetting *setting, GSList *all_settings, GError **error)
690  	{
691  		NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting);
692  		const char *valid_modes[] = { NM_SETTING_WIRELESS_MODE_INFRA, NM_SETTING_WIRELESS_MODE_ADHOC, NM_SETTING_WIRELESS_MODE_AP, NULL };
693  		const char *valid_bands[] = { "a", "bg", NULL };
694  		GSList *iter;
695  	
696  		if (!priv->ssid) {
697  			g_set_error_literal (error,
698  			                     NM_SETTING_WIRELESS_ERROR,
699  			                     NM_SETTING_WIRELESS_ERROR_MISSING_PROPERTY,
700  			                     _("property is missing"));
701  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID);
702  			return FALSE;
703  		}
704  	
705  		if (!priv->ssid->len || priv->ssid->len > 32) {
706  			g_set_error_literal (error,
707  			                     NM_SETTING_WIRELESS_ERROR,
708  			                     NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
709  			                     _("SSID length is out of range <1-32> bytes"));
710  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID);
711  			return FALSE;
712  		}
713  	
714  		if (priv->mode && !_nm_utils_string_in_list (priv->mode, valid_modes)) {
715  			g_set_error (error,
716  			             NM_SETTING_WIRELESS_ERROR,
717  			             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
718  			             _("'%s' is not a valid Wi-Fi mode"),
719  			             priv->mode);
720  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MODE);
721  			return FALSE;
722  		}
723  	
724  		if (priv->band && !_nm_utils_string_in_list (priv->band, valid_bands)) {
725  			g_set_error (error,
726  			             NM_SETTING_WIRELESS_ERROR,
727  			             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
728  			             _("'%s' is not a valid band"),
729  			             priv->band);
730  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BAND);
731  			return FALSE;
732  		}
733  	
734  		if (priv->channel && !priv->band) {
735  			g_set_error (error,
736  			             NM_SETTING_WIRELESS_ERROR,
737  			             NM_SETTING_WIRELESS_ERROR_CHANNEL_REQUIRES_BAND,
738  			             _("requires setting '%s' property"),
739  			             NM_SETTING_WIRELESS_BAND);
740  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CHANNEL);
741  			return FALSE;
742  		}
743  	
744  		if (priv->channel) {
745  			if (!nm_utils_wifi_is_channel_valid (priv->channel, priv->band)) {
746  				g_set_error (error,
747  				             NM_SETTING_WIRELESS_ERROR,
748  				             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
749  				             _("'%d' is not a valid channel"),
750  				             priv->channel);
751  				g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CHANNEL);
752  				return FALSE;
753  			}
754  		}
755  	
756  		if (priv->bssid && priv->bssid->len != ETH_ALEN) {
757  			g_set_error_literal (error,
758  			                     NM_SETTING_WIRELESS_ERROR,
759  			                     NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
760  			                     _("property is invalid"));
761  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BSSID);
762  			return FALSE;
763  		}
764  	
765  		if (priv->device_mac_address && priv->device_mac_address->len != ETH_ALEN) {
766  			g_set_error_literal (error,
767  			                     NM_SETTING_WIRELESS_ERROR,
768  			                     NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
769  			                     _("property is invalid"));
770  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS);
771  			return FALSE;
772  		}
773  	
774  		if (priv->cloned_mac_address && priv->cloned_mac_address->len != ETH_ALEN) {
775  			g_set_error_literal (error,
776  			                     NM_SETTING_WIRELESS_ERROR,
777  			                     NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
778  			                     _("property is invalid"));
779  			g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS);
780  			return FALSE;
781  		}
782  	
783  		for (iter = priv->mac_address_blacklist; iter; iter = iter->next) {
784  			struct ether_addr addr;
785  	
786  			if (!ether_aton_r (iter->data, &addr)) {
787  				g_set_error (error,
788  				             NM_SETTING_WIRELESS_ERROR,
789  				             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
790  				             _("'%s' is not a valid MAC address"),
791  				             (const char *) iter->data);
792  				g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST);
793  				return FALSE;
794  			}
795  		}
796  	
797  		for (iter = priv->seen_bssids; iter; iter = iter->next) {
798  			struct ether_addr addr;
799  	
800  			if (!ether_aton_r (iter->data, &addr)) {
801  				g_set_error (error,
802  				             NM_SETTING_WIRELESS_ERROR,
803  				             NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY,
804  				             _("'%s' is not a valid MAC address"),
805  				             (const char *) iter->data);
806  				g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SEEN_BSSIDS);
807  				return FALSE;
808  			}
809  		}
810  	
811  		return TRUE;
812  	}
813  	
814  	static void
815  	nm_setting_wireless_init (NMSettingWireless *setting)
816  	{
817  		g_object_set (setting, NM_SETTING_NAME, NM_SETTING_WIRELESS_SETTING_NAME, NULL);
818  	}
819  	
820  	static void
821  	finalize (GObject *object)
822  	{
823  		NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object);
824  	
825  		g_free (priv->mode);
826  		g_free (priv->band);
827  		g_free (priv->security);
828  	
829  		if (priv->ssid)
830  			g_byte_array_free (priv->ssid, TRUE);
831  		if (priv->bssid)
832  			g_byte_array_free (priv->bssid, TRUE);
833  		if (priv->device_mac_address)
834  			g_byte_array_free (priv->device_mac_address, TRUE);
835  		if (priv->cloned_mac_address)
836  			g_byte_array_free (priv->cloned_mac_address, TRUE);
837  		g_slist_free_full (priv->mac_address_blacklist, g_free);
838  		g_slist_free_full (priv->seen_bssids, g_free);
839  	
840  		G_OBJECT_CLASS (nm_setting_wireless_parent_class)->finalize (object);
841  	}
842  	
843  	static void
844  	set_property (GObject *object, guint prop_id,
845  			    const GValue *value, GParamSpec *pspec)
846  	{
847  		NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (object);
848  	
849  		switch (prop_id) {
850  		case PROP_SSID:
851  			if (priv->ssid)
852  				g_byte_array_free (priv->ssid, TRUE);
853  			priv->ssid = g_value_dup_boxed (value);
854  			break;
855  		case PROP_MODE:
856  			g_free (priv->mode);
857  			priv->mode = g_value_dup_string (value);
858  			break;
859  		case PROP_BAND:
860  			g_free (priv->band);
861  			priv->band = g_value_dup_string (value);
862  			break;
863  		case PROP_CHANNEL:
864  			priv->channel = g_value_get_uint (value);
865  			break;
866  		case PROP_BSSID:
867  			if (priv->bssid)
868  				g_byte_array_free (priv->bssid, TRUE);
869  			priv->bssid = g_value_dup_boxed (value);
870  			break;
871  		case PROP_RATE:
872  			priv->rate = g_value_get_uint (value);
873  			break;
874  		case PROP_TX_POWER:
875  			priv->tx_power = g_value_get_uint (value);
876  			break;
877  		case PROP_MAC_ADDRESS:
878  			if (priv->device_mac_address)
879  				g_byte_array_free (priv->device_mac_address, TRUE);
880  			priv->device_mac_address = g_value_dup_boxed (value);
881  			break;
882  		case PROP_CLONED_MAC_ADDRESS:
883  			if (priv->cloned_mac_address)
884  				g_byte_array_free (priv->cloned_mac_address, TRUE);
885  			priv->cloned_mac_address = g_value_dup_boxed (value);
886  			break;
887  		case PROP_MAC_ADDRESS_BLACKLIST:
888  			g_slist_free_full (priv->mac_address_blacklist, g_free);
889  			priv->mac_address_blacklist = g_value_dup_boxed (value);
890  			break;
891  		case PROP_MTU:
892  			priv->mtu = g_value_get_uint (value);
893  			break;
894  		case PROP_SEEN_BSSIDS:
895  			g_slist_free_full (priv->seen_bssids, g_free);
896  			priv->seen_bssids = g_value_dup_boxed (value);
897  			break;
898  		case PROP_SEC:
899  			g_free (priv->security);
900  			priv->security = g_value_dup_string (value);
901  			break;
902  		case PROP_HIDDEN:
903  			priv->hidden = g_value_get_boolean (value);
904  			break;
905  		default:
906  			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
907  			break;
908  		}
909  	}
910  	
911  	static void
912  	get_property (GObject *object, guint prop_id,
913  			    GValue *value, GParamSpec *pspec)
914  	{
915  		NMSettingWireless *setting = NM_SETTING_WIRELESS (object);
916  	
917  		switch (prop_id) {
918  		case PROP_SSID:
919  			g_value_set_boxed (value, nm_setting_wireless_get_ssid (setting));
920  			break;
921  		case PROP_MODE:
922  			g_value_set_string (value, nm_setting_wireless_get_mode (setting));
923  			break;
924  		case PROP_BAND:
925  			g_value_set_string (value, nm_setting_wireless_get_band (setting));
926  			break;
927  		case PROP_CHANNEL:
928  			g_value_set_uint (value, nm_setting_wireless_get_channel (setting));
929  			break;
930  		case PROP_BSSID:
931  			g_value_set_boxed (value, nm_setting_wireless_get_bssid (setting));
932  			break;
933  		case PROP_RATE:
934  			g_value_set_uint (value, nm_setting_wireless_get_rate (setting));
935  			break;
936  		case PROP_TX_POWER:
937  			g_value_set_uint (value, nm_setting_wireless_get_tx_power (setting));
938  			break;
939  		case PROP_MAC_ADDRESS:
940  			g_value_set_boxed (value, nm_setting_wireless_get_mac_address (setting));
941  			break;
942  		case PROP_CLONED_MAC_ADDRESS:
943  			g_value_set_boxed (value, nm_setting_wireless_get_cloned_mac_address (setting));
944  			break;
945  		case PROP_MAC_ADDRESS_BLACKLIST:
946  			g_value_set_boxed (value, nm_setting_wireless_get_mac_address_blacklist (setting));
947  			break;
948  		case PROP_MTU:
949  			g_value_set_uint (value, nm_setting_wireless_get_mtu (setting));
950  			break;
951  		case PROP_SEEN_BSSIDS:
952  			g_value_set_boxed (value, NM_SETTING_WIRELESS_GET_PRIVATE (setting)->seen_bssids);
953  			break;
954  		case PROP_SEC:
955  			g_value_set_string (value, NM_SETTING_WIRELESS_GET_PRIVATE (setting)->security);
956  			break;
957  		case PROP_HIDDEN:
958  			g_value_set_boolean (value, nm_setting_wireless_get_hidden (setting));
959  			break;
960  		default:
961  			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
962  			break;
963  		}
964  	}
965  	
966  	static void
967  	nm_setting_wireless_class_init (NMSettingWirelessClass *setting_class)
968  	{
969  		GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
970  		NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
971  	
972  		g_type_class_add_private (setting_class, sizeof (NMSettingWirelessPrivate));
973  	
974  		/* virtual methods */
975  		object_class->set_property = set_property;
976  		object_class->get_property = get_property;
977  		object_class->finalize     = finalize;
978  		parent_class->verify       = verify;
979  	
980  		/* Properties */
981  		/**
982  		 * NMSettingWireless:ssid:
983  		 *
984  		 * SSID of the WiFi network.
985  		 **/
986  		g_object_class_install_property
987  			(object_class, PROP_SSID,
988  			 _nm_param_spec_specialized (NM_SETTING_WIRELESS_SSID,
989  								   "SSID",
990  								   "SSID of the WiFi network.  Must be specified.",
991  								   DBUS_TYPE_G_UCHAR_ARRAY,
992  								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
993  	
994  		/**
995  		 * NMSettingWireless:mode:
996  		 *
997  		 * WiFi network mode; one of 'infrastructure', 'adhoc' or 'ap'.  If blank,
998  		 * infrastructure is assumed.
999  		 **/
1000 		g_object_class_install_property
1001 			(object_class, PROP_MODE,
1002 			 g_param_spec_string (NM_SETTING_WIRELESS_MODE,
1003 							  "Mode",
1004 							  "WiFi network mode; one of 'infrastructure', "
1005 							  "'adhoc' or 'ap'.  If blank, infrastructure is assumed.",
1006 							  NULL,
1007 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1008 	
1009 		/**
1010 		 * NMSettingWireless:band:
1011 		 *
1012 		 * 802.11 frequency band of the network.  One of 'a' for 5GHz 802.11a or
1013 		 * 'bg' for 2.4GHz 802.11.  This will lock associations to the WiFi network
1014 		 * to the specific band, i.e. if 'a' is specified, the device will not
1015 		 * associate with the same network in the 2.4GHz band even if the network's
1016 		 * settings are compatible.  This setting depends on specific driver
1017 		 * capability and may not work with all drivers.
1018 		 **/
1019 		g_object_class_install_property
1020 			(object_class, PROP_BAND,
1021 			 g_param_spec_string (NM_SETTING_WIRELESS_BAND,
1022 							  "Band",
1023 							  "802.11 frequency band of the network.  One of 'a' "
1024 							  "for 5GHz 802.11a or 'bg' for 2.4GHz 802.11.  This "
1025 							  "will lock associations to the WiFi network to the "
1026 							  "specific band, i.e. if 'a' is specified, the device "
1027 							  "will not associate with the same network in the "
1028 							  "2.4GHz band even if the network's settings are "
1029 							  "compatible.  This setting depends on specific driver "
1030 							  "capability and may not work with all drivers.",
1031 							  NULL,
1032 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1033 	
1034 		/**
1035 		 * NMSettingWireless:channel:
1036 		 *
1037 		 * Wireless channel to use for the WiFi connection.  The device will only
1038 		 * join (or create for Ad-Hoc networks) a WiFi network on the specified
1039 		 * channel.  Because channel numbers overlap between bands, this property
1040 		 * also requires the 'band' property to be set.
1041 		 **/
1042 		g_object_class_install_property
1043 			(object_class, PROP_CHANNEL,
1044 			 g_param_spec_uint (NM_SETTING_WIRELESS_CHANNEL,
1045 							"Channel",
1046 							"Wireless channel to use for the WiFi connection.  The "
1047 							"device will only join (or create for Ad-Hoc networks) "
1048 							"a WiFi network on the specified channel.  Because "
1049 							"channel numbers overlap between bands, this property "
1050 							"also requires the 'band' property to be set.",
1051 							0, G_MAXUINT32, 0,
1052 							G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
1053 	
1054 		/**
1055 		 * NMSettingWireless:bssid:
1056 		 *
1057 		 * If specified, directs the device to only associate with the given access
1058 		 * point.  This capability is highly driver dependent and not supported by
1059 		 * all devices.  Note: this property does not control the BSSID used when
1060 		 * creating an Ad-Hoc network and is unlikely to in the future.
1061 		 **/
1062 		g_object_class_install_property
1063 			(object_class, PROP_BSSID,
1064 			 _nm_param_spec_specialized (NM_SETTING_WIRELESS_BSSID,
1065 								   "BSSID",
1066 								   "If specified, directs the device to only associate "
1067 								   "with the given access point.  This capability is "
1068 								   "highly driver dependent and not supported by all "
1069 								   "devices.  Note: this property does not control "
1070 								   "the BSSID used when creating an Ad-Hoc network "
1071 								   "and is unlikely to in the future.",
1072 								   DBUS_TYPE_G_UCHAR_ARRAY,
1073 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1074 	
1075 		/**
1076 		 * NMSettingWireless:rate:
1077 		 *
1078 		 * If non-zero, directs the device to only use the specified bitrate for
1079 		 * communication with the access point.  Units are in Kb/s, ie 5500 = 5.5
1080 		 * Mbit/s.  This property is highly driver dependent and not all devices
1081 		 * support setting a static bitrate.
1082 		 **/
1083 		g_object_class_install_property
1084 			(object_class, PROP_RATE,
1085 			 g_param_spec_uint (NM_SETTING_WIRELESS_RATE,
1086 							"Rate",
1087 							"If non-zero, directs the device to only use the "
1088 							"specified bitrate for communication with the access "
1089 							"point.  Units are in Kb/s, ie 5500 = 5.5 Mbit/s.  This "
1090 							"property is highly driver dependent and not all devices "
1091 							"support setting a static bitrate.",
1092 							0, G_MAXUINT32, 0,
1093 							G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
1094 	
1095 		/**
1096 		 * NMSettingWireless:tx-power:
1097 		 *
1098 		 * If non-zero, directs the device to use the specified transmit power.
1099 		 * Units are dBm.  This property is highly driver dependent and not all
1100 		 * devices support setting a static transmit power.
1101 		 **/
1102 		g_object_class_install_property
1103 			(object_class, PROP_TX_POWER,
1104 			 g_param_spec_uint (NM_SETTING_WIRELESS_TX_POWER,
1105 							"TX Power",
1106 							"If non-zero, directs the device to use the specified "
1107 							"transmit power.  Units are dBm.  This property is highly "
1108 							"driver dependent and not all devices support setting a "
1109 							"static transmit power.",
1110 							0, G_MAXUINT32, 0,
1111 							G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
1112 	
1113 		/**
1114 		 * NMSettingWireless:mac-address:
1115 		 *
1116 		 * If specified, this connection will only apply to the WiFi device
1117 		 * whose permanent MAC address matches. This property does not change the MAC address
1118 		 * of the device (i.e. MAC spoofing).
1119 		 **/
1120 		g_object_class_install_property
1121 			(object_class, PROP_MAC_ADDRESS,
1122 			 _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS,
1123 								   "Device MAC Address",
1124 								   "If specified, this connection will only apply to "
1125 								   "the WiFi device whose permanent MAC address matches.  "
1126 								   "This property does not change the MAC address "
1127 								   "of the device (i.e. MAC spoofing).",
1128 								   DBUS_TYPE_G_UCHAR_ARRAY,
1129 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1130 	
1131 		/**
1132 		 * NMSettingWireless:cloned-mac-address:
1133 		 *
1134 		 * If specified, request that the Wifi device use this MAC address instead of its
1135 		 * permanent MAC address.  This is known as MAC cloning or spoofing.
1136 		 **/
1137 		g_object_class_install_property
1138 			(object_class, PROP_CLONED_MAC_ADDRESS,
1139 			 _nm_param_spec_specialized (NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
1140 		                                     "Spoof MAC Address",
1141 		                                     "If specified, request that the WiFi device use "
1142 		                                     "this MAC address instead of its permanent MAC address.  "
1143 		                                     "This is known as MAC cloning or spoofing.",
1144 		                                     DBUS_TYPE_G_UCHAR_ARRAY,
1145 		                                     G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1146 	
1147 		/**
1148 		 * NMSettingWireless:mac-address-blacklist:
1149 		 *
1150 		 * A list of permanent MAC addresses of Wi-Fi devices to which this
1151 		 * connection should never apply.  Each MAC address should be given in the
1152 		 * standard hex-digits-and-colons notation (eg '00:11:22:33:44:55').
1153 		 **/
1154 		g_object_class_install_property
1155 			(object_class, PROP_MAC_ADDRESS_BLACKLIST,
1156 			 _nm_param_spec_specialized (NM_SETTING_WIRELESS_MAC_ADDRESS_BLACKLIST,
1157 			                             "MAC Address Blacklist",
1158 			                             "A list of permanent MAC addresses of Wi-Fi "
1159 			                             "devices to which this connection should "
1160 			                             "never apply.  Each MAC address should be "
1161 			                             "given in the standard hex-digits-and-colons "
1162 			                             "notation (eg '00:11:22:33:44:55').",
1163 			                             DBUS_TYPE_G_LIST_OF_STRING,
1164 			                             G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
1165 	
1166 		/**
1167 		 * NMSettingWireless:seen-bssids:
1168 		 *
1169 		 * A list of BSSIDs (each BSSID formatted as a MAC address like
1170 		 * '00:11:22:33:44:55') that have been detected as part of the Wi-FI network.
1171 		 * NetworkManager internally tracks previously seen BSSIDs. The property is only
1172 		 * meant for reading and reflects the BBSID list of NetworkManager. The changes you
1173 		 * make to this property will not be preserved.
1174 		 **/
1175 		g_object_class_install_property
1176 			(object_class, PROP_SEEN_BSSIDS,
1177 			 _nm_param_spec_specialized (NM_SETTING_WIRELESS_SEEN_BSSIDS,
1178 			                             "Seen BSSIDS",
1179 			                             "A list of BSSIDs (each BSSID formatted as a MAC "
1180 			                             "address like 00:11:22:33:44:55') that have been "
1181 			                             "detected as part of the WiFI network. "
1182 			                             "NetworkManager internally tracks previously seen "
1183 			                             "BSSIDs. The property is only meant for reading "
1184 			                             "and reflects the BBSID list of NetworkManager. "
1185 			                             "The changes you make to this property will not be "
1186 			                             "preserved.",
1187 			                             DBUS_TYPE_G_LIST_OF_STRING,
1188 			                             G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
1189 	
1190 		/**
1191 		 * NMSettingWireless:mtu:
1192 		 *
1193 		 * If non-zero, only transmit packets of the specified size or smaller,
1194 		 * breaking larger packets up into multiple Ethernet frames.
1195 		 **/
1196 		g_object_class_install_property
1197 			(object_class, PROP_MTU,
1198 			 g_param_spec_uint (NM_SETTING_WIRELESS_MTU,
1199 							"MTU",
1200 							"If non-zero, only transmit packets of the specified "
1201 							"size or smaller, breaking larger packets up into "
1202 							"multiple Ethernet frames.",
1203 							0, G_MAXUINT32, 0,
1204 							G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE));
1205 	
1206 		/**
1207 		 * NMSettingWireless:security:
1208 		 *
1209 		 * If the wireless connection has any security restrictions, like 802.1x,
1210 		 * WEP, or WPA, set this property to '802-11-wireless-security' and ensure
1211 		 * the connection contains a valid 802-11-wireless-security setting.
1212 		 *
1213 		 * Deprecated: 0.9.10: No longer used. Security rescrictions are recognized by
1214 		 * the presence of NM_SETTING_WIRELESS_SECURITY_SETTING_NAME in the connection.
1215 		 **/
1216 		g_object_class_install_property
1217 			(object_class, PROP_SEC,
1218 			 g_param_spec_string (NM_SETTING_WIRELESS_SEC,
1219 							  "Security",
1220 							  "If the wireless connection has any security "
1221 							  "restrictions, like 802.1x, WEP, or WPA, set this "
1222 							  "property to '" NM_SETTING_WIRELESS_SECURITY_SETTING_NAME "' "
1223 							  "and ensure the connection contains a valid "
1224 							  NM_SETTING_WIRELESS_SECURITY_SETTING_NAME " setting.",
1225 							  NULL,
1226 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1227 	
1228 		/**
1229 		 * NMSettingWireless:hidden:
1230 		 *
1231 		 * If %TRUE, indicates this network is a non-broadcasting network that
1232 		 * hides its SSID.  In this case various workarounds may take place, such
1233 		 * as probe-scanning the SSID for more reliable network discovery.  However,
1234 		 * these workarounds expose inherent insecurities with hidden SSID networks,
1235 		 * and thus hidden SSID networks should be used with caution.
1236 		 **/
1237 		g_object_class_install_property
1238 			(object_class, PROP_HIDDEN,
1239 			 g_param_spec_boolean (NM_SETTING_WIRELESS_HIDDEN,
1240 			                       "Hidden",
1241 			                       "If TRUE, indicates this network is a non-broadcasting "
1242 			                       "network that hides its SSID.  In this case various "
1243 			                       "workarounds may take place, such as probe-scanning "
1244 			                       "the SSID for more reliable network discovery.  "
1245 			                       "However, these workarounds expose inherent "
1246 			                       "insecurities with hidden SSID networks, and thus "
1247 			                       "hidden SSID networks should be used with caution.",
1248 			                       FALSE,
1249 			                       G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
1250 	}
1251