1    	/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2    	/*
3    	 *
4    	 * This program is free software; you can redistribute it and/or modify
5    	 * it under the terms of the GNU General Public License as published by
6    	 * the Free Software Foundation; either version 2, or (at your option)
7    	 * any later version.
8    	 *
9    	 * This program is distributed in the hope that it will be useful,
10   	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   	 * GNU General Public License for more details.
13   	 *
14   	 * You should have received a copy of the GNU General Public License along
15   	 * with this program; if not, write to the Free Software Foundation, Inc.,
16   	 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17   	 *
18   	 * Copyright (C) 2008 - 2011 Red Hat, Inc.
19   	 *
20   	 */
21   	
22   	#include <glib.h>
23   	#include <dbus/dbus-glib.h>
24   	#include <string.h>
25   	#include <netinet/ether.h>
26   	#include <linux/if_infiniband.h>
27   	
28   	#include "nm-test-helpers.h"
29   	#include <nm-utils.h>
30   	
31   	#include "nm-setting-connection.h"
32   	#include "nm-setting-vpn.h"
33   	#include "nm-setting-gsm.h"
34   	#include "nm-setting-cdma.h"
35   	#include "nm-setting-wired.h"
36   	#include "nm-setting-wireless-security.h"
37   	#include "nm-setting-ip6-config.h"
38   	#include "nm-setting-ip4-config.h"
39   	#include "nm-setting-pppoe.h"
40   	#include "nm-setting-serial.h"
41   	#include "nm-setting-vlan.h"
42   	#include "nm-setting-bond.h"
43   	#include "nm-utils.h"
44   	#include "nm-dbus-glib-types.h"
45   	#include "nm-glib-compat.h"
46   	
47   	static void
48   	vpn_check_func (const char *key, const char *value, gpointer user_data)
49   	{
50   		const char *test = user_data;
51   	
52   		if (!strcmp (key, "foobar1")) {
53   			ASSERT (strcmp (value, "blahblah1") == 0,
54   					test, "unexpected vpn item '%s' / '%s'", key, value);
55   			return;
56   		}
57   	
58   		if (!strcmp (key, "foobar2")) {
59   			ASSERT (strcmp (value, "blahblah2") == 0,
60   					test, "unexpected vpn item '%s' / '%s'", key, value);
61   			return;
62   		}
63   	
64   		if (!strcmp (key, "foobar3")) {
65   			ASSERT (strcmp (value, "blahblah3") == 0,
66   					test, "unexpected vpn item '%s' / '%s'", key, value);
67   			return;
68   		}
69   	
70   		if (!strcmp (key, "foobar4")) {
71   			ASSERT (strcmp (value, "blahblah4") == 0,
72   					test, "unexpected vpn item '%s' / '%s'", key, value);
73   			return;
74   		}
75   	
76   		ASSERT (FALSE, test, "unexpected vpn item '%s'", key);
77   	}
78   	
79   	static void
80   	vpn_check_empty_func (const char *key, const char *value, gpointer user_data)
81   	{
82   		const char *test = user_data;
83   	
84   		/* We don't expect any values */
85   		ASSERT (FALSE, test, "unexpected vpn item '%s'", key);
86   	}
87   	
88   	static void
89   	test_setting_vpn_items (void)
90   	{
91   		NMSettingVPN *s_vpn;
92   	
93   		s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
94   		ASSERT (s_vpn != NULL,
95   		        "vpn-items",
96   		        "error creating vpn setting");
97   	
98   		nm_setting_vpn_add_data_item (s_vpn, "foobar1", "blahblah1");
99   		nm_setting_vpn_add_data_item (s_vpn, "foobar2", "blahblah2");
100  		nm_setting_vpn_add_data_item (s_vpn, "foobar3", "blahblah3");
101  		nm_setting_vpn_add_data_item (s_vpn, "foobar4", "blahblah4");
102  	
103  		/* Ensure that added values are all present */
104  		nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_func, "vpn-data");
105  		nm_setting_vpn_remove_data_item (s_vpn, "foobar1");
106  		nm_setting_vpn_remove_data_item (s_vpn, "foobar2");
107  		nm_setting_vpn_remove_data_item (s_vpn, "foobar3");
108  		nm_setting_vpn_remove_data_item (s_vpn, "foobar4");
109  	
110  		nm_setting_vpn_add_secret (s_vpn, "foobar1", "blahblah1");
111  		nm_setting_vpn_add_secret (s_vpn, "foobar2", "blahblah2");
112  		nm_setting_vpn_add_secret (s_vpn, "foobar3", "blahblah3");
113  		nm_setting_vpn_add_secret (s_vpn, "foobar4", "blahblah4");
114  	
115  		/* Ensure that added values are all present */
116  		nm_setting_vpn_foreach_secret (s_vpn, vpn_check_func, "vpn-secrets");
117  		nm_setting_vpn_remove_secret (s_vpn, "foobar1");
118  		nm_setting_vpn_remove_secret (s_vpn, "foobar2");
119  		nm_setting_vpn_remove_secret (s_vpn, "foobar3");
120  		nm_setting_vpn_remove_secret (s_vpn, "foobar4");
121  	
122  		/* Try to add some blank values and make sure they are rejected */
123  		nm_setting_vpn_add_data_item (s_vpn, NULL, NULL);
124  		nm_setting_vpn_add_data_item (s_vpn, "", "");
125  		nm_setting_vpn_add_data_item (s_vpn, "foobar1", NULL);
126  		nm_setting_vpn_add_data_item (s_vpn, "foobar1", "");
127  		nm_setting_vpn_add_data_item (s_vpn, NULL, "blahblah1");
128  		nm_setting_vpn_add_data_item (s_vpn, "", "blahblah1");
129  	
130  		nm_setting_vpn_foreach_data_item (s_vpn, vpn_check_empty_func, "vpn-data-empty");
131  	
132  		/* Try to add some blank secrets and make sure they are rejected */
133  		nm_setting_vpn_add_secret (s_vpn, NULL, NULL);
134  		nm_setting_vpn_add_secret (s_vpn, "", "");
135  		nm_setting_vpn_add_secret (s_vpn, "foobar1", NULL);
136  		nm_setting_vpn_add_secret (s_vpn, "foobar1", "");
137  		nm_setting_vpn_add_secret (s_vpn, NULL, "blahblah1");
138  		nm_setting_vpn_add_secret (s_vpn, "", "blahblah1");
139  	
140  		nm_setting_vpn_foreach_secret (s_vpn, vpn_check_empty_func, "vpn-secrets-empty");
141  	
142  		g_object_unref (s_vpn);
143  	}
144  	
145  	static void
146  	test_setting_vpn_update_secrets (void)
147  	{
148  		NMConnection *connection;
149  		NMSettingVPN *s_vpn;
150  		GHashTable *settings, *vpn, *secrets;
151  		GValue val = G_VALUE_INIT;
152  		gboolean success;
153  		GError *error = NULL;
154  		const char *tmp;
155  		const char *key1 = "foobar";
156  		const char *key2 = "blahblah";
157  		const char *val1 = "value1";
158  		const char *val2 = "value2";
159  	
160  		connection = nm_connection_new ();
161  		ASSERT (connection != NULL,
162  		        "vpn-update-secrets",
163  		        "error creating connection");
164  	
165  		s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
166  		ASSERT (s_vpn != NULL,
167  		        "vpn-update-secrets",
168  		        "error creating vpn setting");
169  		nm_connection_add_setting (connection, NM_SETTING (s_vpn));
170  	
171  		settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy);
172  		vpn = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_value_unset);
173  		g_hash_table_insert (settings, NM_SETTING_VPN_SETTING_NAME, vpn);
174  	
175  		secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
176  		g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING);
177  		g_value_take_boxed (&val, secrets);
178  		g_hash_table_insert (vpn, NM_SETTING_VPN_SECRETS, &val);
179  	
180  		/* Add some secrets */
181  		g_hash_table_insert (secrets, (char *) key1, (char *) val1);
182  		g_hash_table_insert (secrets, (char *) key2, (char *) val2);
183  	
(4) Event example_assign: Example1: Assigning: "success" = return value from "nm_connection_update_secrets(connection, "vpn", settings, &error)".
Also see events: [check_return][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][unchecked_value]
184  		success = nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, settings, &error);
(5) Event example_checked: Example1 (cont.): "success" has its value checked in "success == 1".
Also see events: [check_return][example_assign][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][unchecked_value]
185  		ASSERT (success == TRUE,
186  		        "vpn-update-secrets", "failed to update VPN secrets: %s", error->message);
187  	
188  		/* Read the secrets back out */
189  		tmp = nm_setting_vpn_get_secret (s_vpn, key1);
190  		ASSERT (tmp != NULL,
191  		        "vpn-update-secrets", "unexpected failure getting key #1");
192  		ASSERT (strcmp (tmp, val1) == 0,
193  		        "vpn-update-secrets", "unexpected key #1 value");
194  	
195  		tmp = nm_setting_vpn_get_secret (s_vpn, key2);
196  		ASSERT (tmp != NULL,
197  		        "vpn-update-secrets", "unexpected failure getting key #2");
198  		ASSERT (strcmp (tmp, val2) == 0,
199  		        "vpn-update-secrets", "unexpected key #2 value");
200  	
201  		g_hash_table_destroy (settings);
202  		g_object_unref (connection);
203  	}
204  	
205  	#define TO_DEL_NUM 50
206  	typedef struct {
207  		NMSettingVPN *s_vpn;
208  		char *to_del[TO_DEL_NUM];
209  		guint called;
210  	} IterInfo;
211  	
212  	static void
213  	del_iter_func (const char *key, const char *value, gpointer user_data)
214  	{
215  		IterInfo *info = user_data;
216  		int i;
217  	
218  		/* Record how many times this function gets called; it should get called
219  		 * exactly as many times as there are keys in the hash table, regardless
220  		 * of what keys we delete from the table.
221  		 */
222  		info->called++;
223  	
224  		/* During the iteration, remove a bunch of stuff from the table */
225  		if (info->called == 1) {
226  			for (i = 0; i < TO_DEL_NUM; i++)
227  				nm_setting_vpn_remove_data_item (info->s_vpn, info->to_del[i]);
228  		}
229  	}
230  	
231  	static void
232  	test_setting_vpn_modify_during_foreach (void)
233  	{
234  		NMSettingVPN *s_vpn;
235  		IterInfo info;
236  		char *key, *val;
237  		int i, u = 0;
238  	
239  		s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
240  		g_assert (s_vpn);
241  	
242  		for (i = 0; i < TO_DEL_NUM * 2; i++) {
243  			key = g_strdup_printf ("adsfasdfadf%d", i);
244  			val = g_strdup_printf ("42263236236awt%d", i);
245  			nm_setting_vpn_add_data_item (s_vpn, key, val);
246  	
247  			/* Cache some keys to delete */
248  			if (i % 2)
249  				info.to_del[u++] = g_strdup (key);
250  	
251  			g_free (key);
252  			g_free (val);
253  		}
254  	
255  		/* Iterate over current table keys */
256  		info.s_vpn = s_vpn;
257  		info.called = 0;
258  		nm_setting_vpn_foreach_data_item (s_vpn, del_iter_func, &info);
259  	
260  		/* Make sure all the things we removed during iteration are really gone */
261  		for (i = 0; i < TO_DEL_NUM; i++) {
262  			g_assert_cmpstr (nm_setting_vpn_get_data_item (s_vpn, info.to_del[i]), ==, NULL);
263  			g_free (info.to_del[i]);
264  		}
265  	
266  		/* And make sure the foreach callback was called the same number of times
267  		 * as there were keys in the table at the beginning of the foreach.
268  		 */
269  		g_assert_cmpint (info.called, ==, TO_DEL_NUM * 2);
270  	
271  		g_object_unref (s_vpn);
272  	}
273  	
274  	#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
275  	#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
276  	
277  	/* Test that setting the IPv6 setting's 'addresses' property using the old
278  	 * IPv6 address format still works, i.e. that the GValue transformation function
279  	 * from old->new is working correctly.
280  	 */
281  	static void
282  	test_setting_ip6_config_old_address_array (void)
283  	{
284  		NMSettingIP6Config *s_ip6;
285  		GPtrArray *addresses, *read_addresses;
286  		GValueArray *array, *read_array;
287  		GValue element = G_VALUE_INIT, written_value = G_VALUE_INIT, read_value = G_VALUE_INIT;
288  		GByteArray *ba;
289  		const guint8 addr[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
290  		                          0x11, 0x22, 0x33, 0x44, 0x66, 0x77, 0x88, 0x99 };
291  		const guint8 gw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292  		                          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
293  		guint32 prefix = 56;
294  		GValue *read_addr, *read_prefix, *read_gw;
295  	
296  		s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
297  		ASSERT (s_ip6 != NULL,
298  		        "ip6-old-addr", "error creating IP6 setting");
299  	
300  		g_value_init (&written_value, OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS);
301  	
302  		addresses = g_ptr_array_new ();
303  		array = g_value_array_new (3);
304  	
305  		/* IP address */
306  		g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
307  		ba = g_byte_array_new ();
308  		g_byte_array_append (ba, &addr[0], sizeof (addr));
309  		g_value_take_boxed (&element, ba);
310  		g_value_array_append (array, &element);
311  		g_value_unset (&element);
312  	
313  		/* Prefix */
314  		g_value_init (&element, G_TYPE_UINT);
315  		g_value_set_uint (&element, prefix);
316  		g_value_array_append (array, &element);
317  		g_value_unset (&element);
318  	
319  		g_ptr_array_add (addresses, array);
320  		g_value_set_boxed (&written_value, addresses);
321  	
322  		/* Set the address array on the object */
323  		g_object_set_property (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_ADDRESSES, &written_value);
324  	
325  		/* Get it back so we can compare it */
326  		g_value_init (&read_value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS);
327  		g_object_get_property (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_ADDRESSES, &read_value);
328  	
329  		ASSERT (G_VALUE_HOLDS (&read_value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS),
330  		        "ip6-old-addr", "wrong addresses property value type '%s'",
331  		        G_VALUE_TYPE_NAME (&read_value));
332  	
333  		read_addresses = (GPtrArray *) g_value_get_boxed (&read_value);
334  		ASSERT (read_addresses != NULL,
335  		        "ip6-old-addr", "missing addresses on readback");
336  		ASSERT (read_addresses->len == 1,
337  		        "ip6-old-addr", "expected one address on readback");
338  	
339  		read_array = (GValueArray *) g_ptr_array_index (read_addresses, 0);
340  	
341  		read_addr = g_value_array_get_nth (read_array, 0);
342  		ba = g_value_get_boxed (read_addr);
343  		ASSERT (ba->len == sizeof (addr),
344  		        "ip6-old-addr", "unexpected address item length %d", ba->len);
345  		ASSERT (memcmp (ba->data, &addr[0], sizeof (addr)) == 0,
346  		        "ip6-old-addr", "unexpected failure comparing addresses");
347  	
348  		read_prefix = g_value_array_get_nth (read_array, 1);
349  		ASSERT (g_value_get_uint (read_prefix) == prefix,
350  		        "ip6-old-addr", "unexpected failure comparing prefix");
351  	
352  		/* Ensure the gateway is all zeros, which is how the 2-item to 3-item
353  		 * conversion happens.
354  		 */
355  		read_gw = g_value_array_get_nth (read_array, 2);
356  		ba = g_value_get_boxed (read_gw);
357  		ASSERT (ba->len == sizeof (gw),
358  		        "ip6-old-addr", "unexpected gateway item length %d", ba->len);
359  		ASSERT (memcmp (ba->data, &gw[0], sizeof (gw)) == 0,
360  		        "ip6-old-addr", "unexpected failure comparing gateways");
361  	
362  		g_value_unset (&written_value);
363  		g_value_unset (&read_value);
364  		g_object_unref (s_ip6);
365  	}
366  	
367  	static void
368  	test_setting_gsm_apn_spaces (void)
369  	{
370  		NMSettingGsm *s_gsm;
371  		const char *tmp;
372  	
373  		s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
374  		ASSERT (s_gsm != NULL,
375  		        "gsm-apn-spaces",
376  		        "error creating GSM setting");
377  	
378  		/* Trailing space */
379  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar ", NULL);
380  		tmp = nm_setting_gsm_get_apn (s_gsm);
381  		ASSERT (tmp != NULL,
382  		        "gsm-apn-spaces", "empty APN");
383  		ASSERT (strcmp (tmp, "foobar") == 0,
384  		        "gsm-apn-spaces", "unexpected APN");
385  	
386  		/* Leading space */
387  		g_object_set (s_gsm, NM_SETTING_GSM_APN, " foobar", NULL);
388  		tmp = nm_setting_gsm_get_apn (s_gsm);
389  		ASSERT (tmp != NULL,
390  		        "gsm-apn-spaces", "empty APN");
391  		ASSERT (strcmp (tmp, "foobar") == 0,
392  		        "gsm-apn-spaces", "unexpected APN");
393  	}
394  	
395  	static void
396  	test_setting_gsm_apn_bad_chars (void)
397  	{
398  		NMSettingGsm *s_gsm;
399  	
400  		s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
401  		ASSERT (s_gsm != NULL,
402  		        "gsm-apn-bad-chars",
403  		        "error creating GSM setting");
404  	
405  		g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL);
406  	
407  		/* Make sure a valid APN works */
408  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar123.-baz", NULL);
409  		ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == TRUE,
410  		        "gsm-apn-bad-chars", "unexpectedly invalid GSM setting");
411  	
412  		/* Random invalid chars */
413  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "@#%$@#%@#%", NULL);
414  		ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE,
415  		        "gsm-apn-bad-chars", "unexpectedly valid GSM setting");
416  	
417  		/* Spaces */
418  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar baz", NULL);
419  		ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE,
420  		        "gsm-apn-bad-chars", "unexpectedly valid GSM setting");
421  	
422  		/* 0 characters long */
423  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "", NULL);
424  		ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE,
425  		        "gsm-apn-bad-chars", "unexpectedly valid GSM setting");
426  	
427  		/* 65-character long */
428  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl1", NULL);
429  		ASSERT (nm_setting_verify (NM_SETTING (s_gsm), NULL, NULL) == FALSE,
430  		        "gsm-apn-bad-chars", "unexpectedly valid GSM setting");
431  	}
432  	
433  	static void
434  	test_setting_gsm_apn_underscore (void)
435  	{
436  		NMSettingGsm *s_gsm;
437  		GError *error = NULL;
438  		gboolean success;
439  	
440  		s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
441  		g_assert (s_gsm);
442  	
443  		g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "*99#", NULL);
444  	
445  		/* 65-character long */
446  		g_object_set (s_gsm, NM_SETTING_GSM_APN, "foobar_baz", NULL);
447  		success = nm_setting_verify (NM_SETTING (s_gsm), NULL, &error);
448  		g_assert_no_error (error);
449  		g_assert (success == TRUE);
450  	}
451  	
452  	static void
453  	test_setting_gsm_without_number (void)
454  	{
455  		NMSettingGsm *s_gsm;
456  		GError *error = NULL;
457  		gboolean success;
458  	
459  		s_gsm = (NMSettingGsm *) nm_setting_gsm_new ();
460  		g_assert (s_gsm);
461  	
462  		g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, NULL, NULL);
463  		success = nm_setting_verify (NM_SETTING (s_gsm), NULL, &error);
464  		g_assert_no_error (error);
465  		g_assert (success == TRUE);
466  	
467  		g_object_set (s_gsm, NM_SETTING_GSM_NUMBER, "", NULL);
468  		success = nm_setting_verify (NM_SETTING (s_gsm), NULL, &error);
469  		g_assert_error (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY);
470  		g_error_free (error);
471  	}
472  	
473  	static NMSettingWirelessSecurity *
474  	make_test_wsec_setting (const char *detail)
475  	{
476  		NMSettingWirelessSecurity *s_wsec;
477  	
478  		s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
479  		ASSERT (s_wsec != NULL, detail, "error creating setting");
480  	
481  		g_object_set (s_wsec,
482  		              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
483  		              NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "foobarbaz",
484  		              NM_SETTING_WIRELESS_SECURITY_PSK, "random psk",
485  		              NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "aaaaaaaaaa",
486  		              NULL);
487  	
488  		return s_wsec;
489  	}
490  	
491  	static void
492  	test_setting_to_hash_all (void)
493  	{
494  		NMSettingWirelessSecurity *s_wsec;
495  		GHashTable *hash;
496  	
497  		s_wsec = make_test_wsec_setting ("setting-to-hash-all");
498  	
499  		hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ALL);
500  	
501  		/* Make sure all keys are there */
502  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT),
503  		        "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
504  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME),
505  		        "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
506  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK),
507  		        "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK);
508  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0),
509  		        "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
510  	
511  		g_hash_table_destroy (hash);
512  		g_object_unref (s_wsec);
513  	}
514  	
515  	static void
516  	test_setting_to_hash_no_secrets (void)
517  	{
518  		NMSettingWirelessSecurity *s_wsec;
519  		GHashTable *hash;
520  	
521  		s_wsec = make_test_wsec_setting ("setting-to-hash-no-secrets");
522  	
523  		hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_NO_SECRETS);
524  	
525  		/* Make sure non-secret keys are there */
526  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT),
527  		        "setting-to-hash-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
528  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME),
529  		        "setting-to-hash-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
530  	
531  		/* Make sure secrets are not there */
532  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK) == NULL,
533  		        "setting-to-hash-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK);
534  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) == NULL,
535  		        "setting-to-hash-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
536  	
537  		g_hash_table_destroy (hash);
538  		g_object_unref (s_wsec);
539  	}
540  	
541  	static void
542  	test_setting_to_hash_only_secrets (void)
543  	{
544  		NMSettingWirelessSecurity *s_wsec;
545  		GHashTable *hash;
546  	
547  		s_wsec = make_test_wsec_setting ("setting-to-hash-only-secrets");
548  	
549  		hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ONLY_SECRETS);
550  	
551  		/* Make sure non-secret keys are there */
552  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT) == NULL,
553  		        "setting-to-hash-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
554  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME) == NULL,
555  		        "setting-to-hash-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
556  	
557  		/* Make sure secrets are not there */
558  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK),
559  		        "setting-to-hash-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK);
560  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0),
561  		        "setting-to-hash-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
562  	
563  		g_hash_table_destroy (hash);
564  		g_object_unref (s_wsec);
565  	}
566  	
567  	static void
568  	test_connection_to_hash_setting_name (void)
569  	{
570  		NMConnection *connection;
571  		NMSettingWirelessSecurity *s_wsec;
572  		GHashTable *hash;
573  	
574  		connection = nm_connection_new ();
575  		s_wsec = make_test_wsec_setting ("connection-to-hash-setting-name");
576  		nm_connection_add_setting (connection, NM_SETTING (s_wsec));
577  	
578  		hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
579  	
580  		/* Make sure the keys of the first level hash are setting names, not
581  		 * the GType name of the setting objects.
582  		 */
583  		ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != NULL,
584  		        "connection-to-hash-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
585  	
586  		g_hash_table_destroy (hash);
587  		g_object_unref (connection);
588  	}
589  	
590  	static void
591  	test_setting_new_from_hash (void)
592  	{
593  		NMSettingWirelessSecurity *s_wsec;
594  		GHashTable *hash;
595  	
596  		s_wsec = make_test_wsec_setting ("setting-to-hash-all");
597  		hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ALL);
598  		g_object_unref (s_wsec);
599  	
600  		s_wsec = (NMSettingWirelessSecurity *) nm_setting_new_from_hash (NM_TYPE_SETTING_WIRELESS_SECURITY, hash);
601  		g_hash_table_destroy (hash);
602  	
603  		g_assert (s_wsec);
604  		g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk");
605  		g_assert_cmpstr (nm_setting_wireless_security_get_leap_username (s_wsec), ==, "foobarbaz");
606  		g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "random psk");
607  		g_object_unref (s_wsec);
608  	}
609  	
610  	static NMConnection *
611  	new_test_connection (void)
612  	{
613  		NMConnection *connection;
614  		NMSetting *setting;
615  		char *uuid;
616  		guint64 timestamp = time (NULL);
617  	
618  		connection = nm_connection_new ();
619  	
620  		setting = nm_setting_connection_new ();
621  		uuid = nm_utils_uuid_generate ();
622  		g_object_set (G_OBJECT (setting),
623  		              NM_SETTING_CONNECTION_ID, "foobar",
624  		              NM_SETTING_CONNECTION_UUID, uuid,
625  		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
626  		              NM_SETTING_CONNECTION_TIMESTAMP, timestamp,
627  		              NULL);
628  		g_free (uuid);
629  		nm_connection_add_setting (connection, setting);
630  	
631  		setting = nm_setting_wired_new ();
632  		g_object_set (G_OBJECT (setting),
633  		              NM_SETTING_WIRED_MTU, 1592,
634  		              NULL);
635  		nm_connection_add_setting (connection, setting);
636  	
637  		setting = nm_setting_ip4_config_new ();
638  		g_object_set (G_OBJECT (setting),
639  		              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO,
640  		              NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, "eyeofthetiger",
641  		              NULL);
642  		nm_connection_add_setting (connection, setting);
643  	
644  		return connection;
645  	}
646  	
647  	static GValue *
648  	string_to_gvalue (const char *str)
649  	{
650  		GValue *val;
651  	
652  		val = g_slice_new0 (GValue);
653  		g_value_init (val, G_TYPE_STRING);
654  		g_value_set_string (val, str);
655  		return val;
656  	}
657  	
658  	static void
659  	destroy_gvalue (gpointer data)
660  	{
661  		g_value_unset ((GValue *) data);
662  		g_slice_free (GValue, data);
663  	}
664  	
665  	static GHashTable *
666  	new_connection_hash (char **out_uuid,
667  	                     const char **out_expected_id,
668  	                     const char **out_expected_ip6_method)
669  	{
670  		GHashTable *hash;
671  		GHashTable *setting;
672  	
673  		hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_hash_table_destroy);
674  	
675  		*out_uuid = nm_utils_uuid_generate ();
676  		*out_expected_id = "My happy connection";
677  		*out_expected_ip6_method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
678  	
679  		/* Connection setting */
680  		setting = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
681  		g_hash_table_insert (setting,
682  		                     g_strdup (NM_SETTING_NAME),
683  		                     string_to_gvalue (NM_SETTING_CONNECTION_SETTING_NAME));
684  		g_hash_table_insert (setting,
685  		                     g_strdup (NM_SETTING_CONNECTION_ID),
686  		                     string_to_gvalue (*out_expected_id));
687  		g_hash_table_insert (setting,
688  		                     g_strdup (NM_SETTING_CONNECTION_UUID),
689  		                     string_to_gvalue (*out_uuid));
690  		g_hash_table_insert (setting,
691  		                     g_strdup (NM_SETTING_CONNECTION_TYPE),
692  		                     string_to_gvalue (NM_SETTING_WIRED_SETTING_NAME));
693  		g_hash_table_insert (hash, g_strdup (NM_SETTING_CONNECTION_SETTING_NAME), setting);
694  	
695  		/* Wired setting */
696  		setting = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
697  		g_hash_table_insert (hash, g_strdup (NM_SETTING_WIRED_SETTING_NAME), setting);
698  	
699  		/* IP6 */
700  		setting = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue);
701  		g_hash_table_insert (setting,
702  		                     g_strdup (NM_SETTING_IP6_CONFIG_METHOD),
703  		                     string_to_gvalue (*out_expected_ip6_method));
704  		g_hash_table_insert (hash, g_strdup (NM_SETTING_IP6_CONFIG_SETTING_NAME), setting);
705  	
706  		return hash;
707  	}
708  	
709  	static void
710  	test_connection_replace_settings ()
711  	{
712  		NMConnection *connection;
713  		GHashTable *new_settings;
714  		GError *error = NULL;
715  		gboolean success;
716  		NMSettingConnection *s_con;
717  		NMSettingIP6Config *s_ip6;
718  		char *uuid = NULL;
719  		const char *expected_id = NULL, *expected_method = NULL;
720  	
721  		connection = new_test_connection ();
722  	
723  		new_settings = new_connection_hash (&uuid, &expected_id, &expected_method);
724  		g_assert (new_settings);
725  	
726  		/* Replace settings and test */
727  		success = nm_connection_replace_settings (connection, new_settings, &error);
728  		g_assert_no_error (error);
729  		g_assert (success);
730  	
731  		s_con = nm_connection_get_setting_connection (connection);
732  		g_assert (s_con);
733  		g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
734  		g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid);
735  	
736  		g_assert (nm_connection_get_setting_wired (connection));
737  		g_assert (!nm_connection_get_setting_ip4_config (connection));
738  	
739  		s_ip6 = nm_connection_get_setting_ip6_config (connection);
740  		g_assert (s_ip6);
741  		g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, expected_method);
742  	
743  		g_free (uuid);
744  		g_hash_table_destroy (new_settings);
745  		g_object_unref (connection);
746  	}
747  	
748  	static void
749  	test_connection_replace_settings_from_connection ()
750  	{
751  		NMConnection *connection, *replacement;
752  		GError *error = NULL;
753  		gboolean success;
754  		NMSettingConnection *s_con;
755  		NMSetting *setting;
756  		GByteArray *ssid;
757  		char *uuid = NULL;
758  		const char *expected_id = "Awesome connection";
759  	
760  		connection = new_test_connection ();
761  		g_assert (connection);
762  	
763  		replacement = nm_connection_new ();
764  		g_assert (replacement);
765  	
766  		/* New connection setting */
767  		setting = nm_setting_connection_new ();
768  		g_assert (setting);
769  	
770  		uuid = nm_utils_uuid_generate ();
771  		g_object_set (setting,
772  		              NM_SETTING_CONNECTION_ID, expected_id,
773  		              NM_SETTING_CONNECTION_UUID, uuid,
774  		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
775  		              NULL);
776  		nm_connection_add_setting (replacement, setting);
777  	
778  		/* New wifi setting */
779  		setting = nm_setting_wireless_new ();
780  		g_assert (setting);
781  	
782  		ssid = g_byte_array_new ();
783  		g_byte_array_append (ssid, (const guint8 *) "1234567", 7);
784  		g_object_set (setting,
785  		              NM_SETTING_WIRELESS_SSID, ssid,
786  		              NM_SETTING_WIRELESS_MODE, "infrastructure",
787  		              NULL);
788  		g_byte_array_free (ssid, TRUE);
789  		nm_connection_add_setting (replacement, setting);
790  	
791  		/* Replace settings and test */
792  		success = nm_connection_replace_settings_from_connection (connection, replacement, &error);
793  		g_assert_no_error (error);
794  		g_assert (success);
795  	
796  		s_con = nm_connection_get_setting_connection (connection);
797  		g_assert (s_con);
798  		g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
799  		g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid);
800  	
801  		g_assert (!nm_connection_get_setting_wired (connection));
802  		g_assert (!nm_connection_get_setting_ip6_config (connection));
803  		g_assert (nm_connection_get_setting_wireless (connection));
804  	
805  		g_free (uuid);
806  		g_object_unref (replacement);
807  		g_object_unref (connection);
808  	}
809  	
810  	static void
811  	test_connection_new_from_hash ()
812  	{
813  		NMConnection *connection;
814  		GHashTable *new_settings;
815  		GError *error = NULL;
816  		NMSettingConnection *s_con;
817  		NMSettingIP6Config *s_ip6;
818  		char *uuid = NULL;
819  		const char *expected_id = NULL, *expected_method = NULL;
820  	
821  		new_settings = new_connection_hash (&uuid, &expected_id, &expected_method);
822  		g_assert (new_settings);
823  	
824  		/* Replace settings and test */
825  		connection = nm_connection_new_from_hash (new_settings, &error);
826  		g_assert_no_error (error);
827  		g_assert (connection);
828  	
829  		s_con = nm_connection_get_setting_connection (connection);
830  		g_assert (s_con);
831  		g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
832  		g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, uuid);
833  	
834  		g_assert (nm_connection_get_setting_wired (connection));
835  		g_assert (!nm_connection_get_setting_ip4_config (connection));
836  	
837  		s_ip6 = nm_connection_get_setting_ip6_config (connection);
838  		g_assert (s_ip6);
839  		g_assert_cmpstr (nm_setting_ip6_config_get_method (s_ip6), ==, expected_method);
840  	
841  		g_free (uuid);
842  		g_hash_table_destroy (new_settings);
843  		g_object_unref (connection);
844  	}
845  	
846  	static void
847  	check_permission (NMSettingConnection *s_con,
848  	                  guint32 idx,
849  	                  const char *expected_uname,
850  	                  const char *tag)
851  	{
852  		gboolean success;
853  		const char *ptype = NULL, *pitem = NULL, *detail = NULL;
854  	
855  		success = nm_setting_connection_get_permission (s_con, 0, &ptype, &pitem, &detail);
856  		ASSERT (success == TRUE, tag, "unexpected failure getting added permission");
857  	
858  		/* Permission type */
859  		ASSERT (ptype != NULL, tag, "unexpected failure getting permission type");
860  		ASSERT (strcmp (ptype, "user") == 0, tag, "retrieved unexpected permission type");
861  	
862  		/* Permission item */
863  		ASSERT (pitem != NULL, tag, "unexpected failure getting permission item");
864  		ASSERT (strcmp (pitem, expected_uname) == 0, tag, "retrieved unexpected permission item");
865  	
866  		ASSERT (detail == NULL, tag, "unexpected success getting permission detail");
867  	}
868  	
869  	#define TEST_UNAME "asdfasfasdf"
870  	
871  	static void
872  	test_setting_connection_permissions_helpers (void)
873  	{
874  		NMSettingConnection *s_con;
875  		gboolean success;
876  		char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 };
877  		GSList *list = NULL;
878  		const char *expected_perm = "user:" TEST_UNAME ":";
879  	
880  		s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
881  	
882  		/* Ensure a bad [type] is rejected */
883  		success = nm_setting_connection_add_permission (s_con, "foobar", "blah", NULL);
884  		ASSERT (success == FALSE,
885  		        "setting-connection-permissions-helpers", "unexpected success adding bad permission type #1");
886  	
887  		/* Ensure a bad [type] is rejected */
888  		success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL);
889  		ASSERT (success == FALSE,
890  		        "setting-connection-permissions-helpers", "unexpected success adding bad permission type #2");
891  	
892  		/* Ensure a bad [item] is rejected */
893  		success = nm_setting_connection_add_permission (s_con, "user", NULL, NULL);
894  		ASSERT (success == FALSE,
895  		        "setting-connection-permissions-helpers", "unexpected success adding bad permission item #1");
896  	
897  		/* Ensure a bad [item] is rejected */
898  		success = nm_setting_connection_add_permission (s_con, "user", "", NULL);
899  		ASSERT (success == FALSE,
900  		        "setting-connection-permissions-helpers", "unexpected success adding bad permission item #2");
901  	
902  		/* Ensure an [item] with ':' is rejected */
903  		success = nm_setting_connection_add_permission (s_con, "user", "ad:asdf", NULL);
904  		ASSERT (success == FALSE,
905  		        "setting-connection-permissions-helpers", "unexpected success adding bad permission item #3");
906  	
907  		/* Ensure a non-UTF-8 [item] is rejected */
908  		success = nm_setting_connection_add_permission (s_con, "user", buf, NULL);
909  		ASSERT (success == FALSE,
910  		        "setting-connection-permissions-helpers", "unexpected success adding bad permission item #4");
911  	
912  		/* Ensure a non-NULL [detail] is rejected */
913  		success = nm_setting_connection_add_permission (s_con, "user", "dafasdf", "asdf");
914  		ASSERT (success == FALSE,
915  		        "setting-connection-permissions-helpers", "unexpected success adding bad detail");
916  	
917  		/* Ensure a valid call results in success */
918  		success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL);
919  		ASSERT (success == TRUE,
920  		        "setting-connection-permissions-helpers", "unexpected failure adding valid user permisson");
921  	
922  		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1,
923  		        "setting-connection-permissions-helpers", "unexpected failure getting number of permissions");
924  	
925  		check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-helpers");
926  	
927  		/* Check the actual GObject property just to be paranoid */
928  		g_object_get (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, &list, NULL);
929  		ASSERT (list != NULL,
930  		        "setting-connection-permissions-helpers", "unexpected failure getting permissions list");
931  		ASSERT (g_slist_length (list) == 1,
932  		        "setting-connection-permissions-helpers", "unexpected failure getting number of permissions in list");
933  		ASSERT (strcmp (list->data, expected_perm) == 0,
934  		        "setting-connection-permissions-helpers", "unexpected permission property data");
935  		g_slist_free_full (list, g_free);
936  	
937  		/* Now remove that permission and ensure we have 0 permissions */
938  		nm_setting_connection_remove_permission (s_con, 0);
939  		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
940  		        "setting-connection-permissions-helpers", "unexpected failure removing permission");
941  	
942  		g_object_unref (s_con);
943  	}
944  	
945  	static void
946  	add_permission_property (NMSettingConnection *s_con,
947  	                         const char *ptype,
948  	                         const char *pitem,
949  	                         int pitem_len,
950  	                         const char *detail)
951  	{
952  		GString *str;
953  		GSList *list = NULL;
954  	
955  		str = g_string_sized_new (50);
956  		if (ptype)
957  			g_string_append (str, ptype);
958  		g_string_append_c (str, ':');
959  	
960  		if (pitem) {
961  			if (pitem_len >= 0)
962  				g_string_append_len (str, pitem, pitem_len);
963  			else
964  				g_string_append (str, pitem);
965  		}
966  	
967  		g_string_append_c (str, ':');
968  	
969  		if (detail)
970  			g_string_append (str, detail);
971  	
972  		list = g_slist_append (list, str->str);
973  		g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, list, NULL);
974  	
975  		g_string_free (str, TRUE);
976  		g_slist_free (list);
977  	}
978  	
979  	static void
980  	test_setting_connection_permissions_property (void)
981  	{
982  		NMSettingConnection *s_con;
983  		gboolean success;
984  		char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 };
985  	
986  		s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
987  	
988  		/* Ensure a bad [type] is rejected */
989  		add_permission_property (s_con, "foobar", "blah", -1, NULL);
990  		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
991  		        "setting-connection-permissions-property", "unexpected success adding bad permission type #1");
992  	
993  		/* Ensure a bad [type] is rejected */
994  		add_permission_property (s_con, NULL, "blah", -1, NULL);
995  		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
996  		        "setting-connection-permissions-property", "unexpected success adding bad permission type #2");
997  	
998  		/* Ensure a bad [item] is rejected */
999  		add_permission_property (s_con, "user", NULL, -1, NULL);
1000 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1001 		        "setting-connection-permissions-property", "unexpected success adding bad permission item #1");
1002 	
1003 		/* Ensure a bad [item] is rejected */
1004 		add_permission_property (s_con, "user", "", -1, NULL);
1005 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1006 		        "setting-connection-permissions-property", "unexpected success adding bad permission item #2");
1007 	
1008 		/* Ensure an [item] with ':' in the middle is rejected */
1009 		add_permission_property (s_con, "user", "ad:asdf", -1, NULL);
1010 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1011 		        "setting-connection-permissions-property", "unexpected success adding bad permission item #3");
1012 	
1013 		/* Ensure an [item] with ':' at the end is rejected */
1014 		add_permission_property (s_con, "user", "adasdfaf:", -1, NULL);
1015 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1016 		        "setting-connection-permissions-property", "unexpected success adding bad permission item #4");
1017 	
1018 		/* Ensure a non-UTF-8 [item] is rejected */
1019 		add_permission_property (s_con, "user", buf, (int) sizeof (buf), NULL);
1020 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1021 		        "setting-connection-permissions-property", "unexpected success adding bad permission item #5");
1022 	
1023 		/* Ensure a non-NULL [detail] is rejected */
1024 		add_permission_property (s_con, "user", "dafasdf", -1, "asdf");
1025 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1026 		        "setting-connection-permissions-property", "unexpected success adding bad detail");
1027 	
1028 		/* Ensure a valid call results in success */
1029 		success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL);
1030 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1,
1031 		        "setting-connection-permissions-property", "unexpected failure adding valid user permisson");
1032 	
1033 		check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-property");
1034 	
1035 		/* Now remove that permission and ensure we have 0 permissions */
1036 		nm_setting_connection_remove_permission (s_con, 0);
1037 		ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0,
1038 		        "setting-connection-permissions-property", "unexpected failure removing permission");
1039 	
1040 		g_object_unref (s_con);
1041 	}
1042 	
1043 	static void
1044 	test_connection_compare_same (void)
1045 	{
1046 		NMConnection *a, *b;
1047 	
1048 		a = new_test_connection ();
1049 		b = nm_connection_duplicate (a);
1050 		g_assert (nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT));
1051 		g_object_unref (a);
1052 		g_object_unref (b);
1053 	}
1054 	
1055 	static void
1056 	test_connection_compare_key_only_in_a (void)
1057 	{
1058 		NMConnection *a, *b;
1059 		NMSettingConnection *s_con;
1060 	
1061 		a = new_test_connection ();
1062 		b = nm_connection_duplicate (a);
1063 		s_con = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION);
1064 		g_assert (s_con);
1065 		g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (gulong) 0, NULL);
1066 	
1067 		g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT));
1068 		g_object_unref (a);
1069 		g_object_unref (b);
1070 	}
1071 	
1072 	static void
1073 	test_connection_compare_setting_only_in_a (void)
1074 	{
1075 		NMConnection *a, *b;
1076 	
1077 		a = new_test_connection ();
1078 		b = nm_connection_duplicate (a);
1079 		nm_connection_remove_setting (b, NM_TYPE_SETTING_IP4_CONFIG);
1080 		g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT));
1081 		g_object_unref (a);
1082 		g_object_unref (b);
1083 	}
1084 	
1085 	static void
1086 	test_connection_compare_key_only_in_b (void)
1087 	{
1088 		NMConnection *a, *b;
1089 		NMSettingConnection *s_con;
1090 	
1091 		a = new_test_connection ();
1092 		b = nm_connection_duplicate (a);
1093 		s_con = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION);
1094 		g_assert (s_con);
1095 		g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (gulong) 0, NULL);
1096 	
1097 		g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT));
1098 		g_object_unref (a);
1099 		g_object_unref (b);
1100 	}
1101 	
1102 	static void
1103 	test_connection_compare_setting_only_in_b (void)
1104 	{
1105 		NMConnection *a, *b;
1106 	
1107 		a = new_test_connection ();
1108 		b = nm_connection_duplicate (a);
1109 		nm_connection_remove_setting (a, NM_TYPE_SETTING_IP4_CONFIG);
1110 		g_assert (!nm_connection_compare (a, b, NM_SETTING_COMPARE_FLAG_EXACT));
1111 		g_object_unref (a);
1112 		g_object_unref (b);
1113 	}
1114 	
1115 	typedef struct {
1116 		const char *key_name;
1117 		guint32 result;
1118 	} DiffKey;
1119 	
1120 	typedef struct {
1121 		const char *name;
1122 		DiffKey keys[30];
1123 	} DiffSetting;
1124 	
1125 	#define ARRAY_LEN(a)  (sizeof (a) / sizeof (a[0]))
1126 	
1127 	static void
1128 	ensure_diffs (GHashTable *diffs, const DiffSetting *check, gsize n_check)
1129 	{
1130 		guint i;
1131 	
1132 		g_assert (g_hash_table_size (diffs) == n_check);
1133 	
1134 		/* Loop through the settings */
1135 		for (i = 0; i < n_check; i++) {
1136 			GHashTable *setting_hash;
1137 			guint z = 0;
1138 	
1139 			setting_hash = g_hash_table_lookup (diffs, check[i].name);
1140 			g_assert (setting_hash);
1141 	
1142 			/* Get the number of keys to check */
1143 			while (check[i].keys[z].key_name)
1144 				z++;
1145 			g_assert (g_hash_table_size (setting_hash) == z);
1146 	
1147 			/* Now compare the actual keys */
1148 			for (z = 0; check[i].keys[z].key_name; z++) {
1149 				NMSettingDiffResult result;
1150 	
1151 				result = GPOINTER_TO_UINT (g_hash_table_lookup (setting_hash, check[i].keys[z].key_name));
1152 				g_assert (result == check[i].keys[z].result);
1153 			}
1154 		}
1155 	}
1156 	
1157 	static void
1158 	test_connection_diff_a_only (void)
1159 	{
1160 		NMConnection *connection;
1161 		GHashTable *out_diffs = NULL;
1162 		gboolean same;
1163 		const DiffSetting settings[] = {
1164 			{ NM_SETTING_CONNECTION_SETTING_NAME, {
1165 				{ NM_SETTING_CONNECTION_ID,                   NM_SETTING_DIFF_RESULT_IN_A },
1166 				{ NM_SETTING_CONNECTION_UUID,                 NM_SETTING_DIFF_RESULT_IN_A },
1167 				{ NM_SETTING_CONNECTION_INTERFACE_NAME,       NM_SETTING_DIFF_RESULT_IN_A },
1168 				{ NM_SETTING_CONNECTION_TYPE,                 NM_SETTING_DIFF_RESULT_IN_A },
1169 				{ NM_SETTING_CONNECTION_TIMESTAMP,            NM_SETTING_DIFF_RESULT_IN_A },
1170 				{ NM_SETTING_CONNECTION_AUTOCONNECT,          NM_SETTING_DIFF_RESULT_IN_A },
1171 				{ NM_SETTING_CONNECTION_READ_ONLY,            NM_SETTING_DIFF_RESULT_IN_A },
1172 				{ NM_SETTING_CONNECTION_PERMISSIONS,          NM_SETTING_DIFF_RESULT_IN_A },
1173 				{ NM_SETTING_CONNECTION_ZONE,                 NM_SETTING_DIFF_RESULT_IN_A },
1174 				{ NM_SETTING_CONNECTION_MASTER,               NM_SETTING_DIFF_RESULT_IN_A },
1175 				{ NM_SETTING_CONNECTION_SLAVE_TYPE,           NM_SETTING_DIFF_RESULT_IN_A },
1176 				{ NM_SETTING_CONNECTION_SECONDARIES,          NM_SETTING_DIFF_RESULT_IN_A },
1177 				{ NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A },
1178 				{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN }
1179 			} },
1180 			{ NM_SETTING_WIRED_SETTING_NAME, {
1181 				{ NM_SETTING_WIRED_PORT,                  NM_SETTING_DIFF_RESULT_IN_A },
1182 				{ NM_SETTING_WIRED_SPEED,                 NM_SETTING_DIFF_RESULT_IN_A },
1183 				{ NM_SETTING_WIRED_DUPLEX,                NM_SETTING_DIFF_RESULT_IN_A },
1184 				{ NM_SETTING_WIRED_AUTO_NEGOTIATE,        NM_SETTING_DIFF_RESULT_IN_A },
1185 				{ NM_SETTING_WIRED_MAC_ADDRESS,           NM_SETTING_DIFF_RESULT_IN_A },
1186 				{ NM_SETTING_WIRED_CLONED_MAC_ADDRESS,    NM_SETTING_DIFF_RESULT_IN_A },
1187 				{ NM_SETTING_WIRED_MAC_ADDRESS_BLACKLIST, NM_SETTING_DIFF_RESULT_IN_A },
1188 				{ NM_SETTING_WIRED_MTU,                   NM_SETTING_DIFF_RESULT_IN_A },
1189 				{ NM_SETTING_WIRED_S390_SUBCHANNELS,      NM_SETTING_DIFF_RESULT_IN_A },
1190 				{ NM_SETTING_WIRED_S390_NETTYPE,          NM_SETTING_DIFF_RESULT_IN_A },
1191 				{ NM_SETTING_WIRED_S390_OPTIONS,          NM_SETTING_DIFF_RESULT_IN_A },
1192 				{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
1193 			} },
1194 			{ NM_SETTING_IP4_CONFIG_SETTING_NAME, {
1195 				{ NM_SETTING_IP4_CONFIG_METHOD,             NM_SETTING_DIFF_RESULT_IN_A },
1196 				{ NM_SETTING_IP4_CONFIG_DNS,                NM_SETTING_DIFF_RESULT_IN_A },
1197 				{ NM_SETTING_IP4_CONFIG_DNS_SEARCH,         NM_SETTING_DIFF_RESULT_IN_A },
1198 				{ NM_SETTING_IP4_CONFIG_ADDRESSES,          NM_SETTING_DIFF_RESULT_IN_A },
1199 				{ NM_SETTING_IP4_CONFIG_ROUTES,             NM_SETTING_DIFF_RESULT_IN_A },
1200 				{ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_ROUTES, NM_SETTING_DIFF_RESULT_IN_A },
1201 				{ NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS,    NM_SETTING_DIFF_RESULT_IN_A },
1202 				{ NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID,     NM_SETTING_DIFF_RESULT_IN_A },
1203 				{ NM_SETTING_IP4_CONFIG_DHCP_SEND_HOSTNAME, NM_SETTING_DIFF_RESULT_IN_A },
1204 				{ NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,      NM_SETTING_DIFF_RESULT_IN_A },
1205 				{ NM_SETTING_IP4_CONFIG_NEVER_DEFAULT,      NM_SETTING_DIFF_RESULT_IN_A },
1206 				{ NM_SETTING_IP4_CONFIG_MAY_FAIL,           NM_SETTING_DIFF_RESULT_IN_A },
1207 				{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
1208 			} },
1209 		};
1210 	
1211 		connection = new_test_connection ();
1212 	
1213 		same = nm_connection_diff (connection, NULL, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs);
1214 		g_assert (same == FALSE);
1215 		g_assert (out_diffs != NULL);
1216 		g_assert (g_hash_table_size (out_diffs) > 0);
1217 	
1218 		ensure_diffs (out_diffs, settings, ARRAY_LEN (settings));
1219 	
1220 		g_hash_table_destroy (out_diffs);
1221 		g_object_unref (connection);
1222 	}
1223 	
1224 	static void
1225 	test_connection_diff_same (void)
1226 	{
1227 		NMConnection *a, *b;
1228 		GHashTable *out_diffs = NULL;
1229 		gboolean same;
1230 	
1231 		a = new_test_connection ();
1232 		b = nm_connection_duplicate (a);
1233 	
1234 		same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs);
1235 		g_assert (same == TRUE);
1236 		g_assert (out_diffs == NULL);
1237 		g_object_unref (a);
1238 		g_object_unref (b);
1239 	}
1240 	
1241 	static void
1242 	test_connection_diff_different (void)
1243 	{
1244 		NMConnection *a, *b;
1245 		GHashTable *out_diffs = NULL;
1246 		NMSettingIP4Config *s_ip4;
1247 		gboolean same;
1248 		const DiffSetting settings[] = {
1249 			{ NM_SETTING_IP4_CONFIG_SETTING_NAME, {
1250 				{ NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_DIFF_RESULT_IN_A | NM_SETTING_DIFF_RESULT_IN_B },
1251 				{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
1252 			} },
1253 		};
1254 	
1255 		a = new_test_connection ();
1256 		b = nm_connection_duplicate (a);
1257 		s_ip4 = nm_connection_get_setting_ip4_config (a);
1258 		g_assert (s_ip4);
1259 		g_object_set (G_OBJECT (s_ip4),
1260 		              NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
1261 		              NULL);
1262 	
1263 		same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs);
1264 		g_assert (same == FALSE);
1265 		g_assert (out_diffs != NULL);
1266 		g_assert (g_hash_table_size (out_diffs) > 0);
1267 	
1268 		ensure_diffs (out_diffs, settings, ARRAY_LEN (settings));
1269 	
1270 		g_hash_table_destroy (out_diffs);
1271 		g_object_unref (a);
1272 		g_object_unref (b);
1273 	}
1274 	
1275 	static void
1276 	test_connection_diff_no_secrets (void)
1277 	{
1278 		NMConnection *a, *b;
1279 		GHashTable *out_diffs = NULL;
1280 		NMSetting *s_pppoe;
1281 		gboolean same;
1282 		const DiffSetting settings[] = {
1283 			{ NM_SETTING_PPPOE_SETTING_NAME, {
1284 				{ NM_SETTING_PPPOE_PASSWORD, NM_SETTING_DIFF_RESULT_IN_B },
1285 				{ NULL, NM_SETTING_DIFF_RESULT_UNKNOWN },
1286 			} },
1287 		};
1288 	
1289 		a = new_test_connection ();
1290 		s_pppoe = nm_setting_pppoe_new ();
1291 		g_object_set (G_OBJECT (s_pppoe),
1292 		              NM_SETTING_PPPOE_USERNAME, "thomas",
1293 		              NULL);
1294 		nm_connection_add_setting (a, s_pppoe);
1295 	
1296 		b = nm_connection_duplicate (a);
1297 	
1298 		/* Add a secret to B */
1299 		s_pppoe = NM_SETTING (nm_connection_get_setting_pppoe (b));
1300 		g_assert (s_pppoe);
1301 		g_object_set (G_OBJECT (s_pppoe),
1302 		              NM_SETTING_PPPOE_PASSWORD, "secretpassword",
1303 		              NULL);
1304 	
1305 		/* Make sure the diff returns no results as secrets are ignored */
1306 		same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, &out_diffs);
1307 		g_assert (same == TRUE);
1308 		g_assert (out_diffs == NULL);
1309 	
1310 		/* Now make sure the diff returns results if secrets are not ignored */
1311 		same = nm_connection_diff (a, b, NM_SETTING_COMPARE_FLAG_EXACT, &out_diffs);
1312 		g_assert (same == FALSE);
1313 		g_assert (out_diffs != NULL);
1314 		g_assert (g_hash_table_size (out_diffs) > 0);
1315 	
1316 		ensure_diffs (out_diffs, settings, ARRAY_LEN (settings));
1317 	
1318 		g_hash_table_destroy (out_diffs);
1319 		g_object_unref (a);
1320 		g_object_unref (b);
1321 	}
1322 	
1323 	static void
1324 	add_generic_settings (NMConnection *connection, const char *ctype)
1325 	{
1326 		NMSetting *setting;
1327 		char *uuid;
1328 	
1329 		uuid = nm_utils_uuid_generate ();
1330 	
1331 		setting = nm_setting_connection_new ();
1332 		g_object_set (setting,
1333 		              NM_SETTING_CONNECTION_ID, "asdfasdfadf",
1334 		              NM_SETTING_CONNECTION_TYPE, ctype,
1335 		              NM_SETTING_CONNECTION_UUID, uuid,
1336 		              NULL);
1337 		nm_connection_add_setting (connection, setting);
1338 	
1339 		g_free (uuid);
1340 	
1341 		setting = nm_setting_ip4_config_new ();
1342 		g_object_set (setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
1343 		nm_connection_add_setting (connection, setting);
1344 	
1345 		setting = nm_setting_ip6_config_new ();
1346 		g_object_set (setting, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
1347 		nm_connection_add_setting (connection, setting);
1348 	}
1349 	
1350 	static void
1351 	test_connection_good_base_types (void)
1352 	{
1353 		NMConnection *connection;
1354 		NMSetting *setting;
1355 		gboolean success;
1356 		GError *error = NULL;
1357 		GByteArray *array;
1358 		const guint8 bdaddr[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
1359 	
1360 		/* Try a basic wired connection */
1361 		connection = nm_connection_new ();
1362 		add_generic_settings (connection, NM_SETTING_WIRED_SETTING_NAME);
1363 		setting = nm_setting_wired_new ();
1364 		nm_connection_add_setting (connection, setting);
1365 	
1366 		success = nm_connection_verify (connection, &error);
1367 		g_assert_no_error (error);
1368 		g_assert (success);
1369 		g_object_unref (connection);
1370 	
1371 		/* Try a wired PPPoE connection */
1372 		connection = nm_connection_new ();
1373 		add_generic_settings (connection, NM_SETTING_PPPOE_SETTING_NAME);
1374 		setting = nm_setting_pppoe_new ();
1375 		g_object_set (setting, NM_SETTING_PPPOE_USERNAME, "bob smith", NULL);
1376 		nm_connection_add_setting (connection, setting);
1377 	
1378 		success = nm_connection_verify (connection, &error);
1379 		g_assert_no_error (error);
1380 		g_assert (success);
1381 		g_object_unref (connection);
1382 	
1383 		/* Wifi connection */
1384 		connection = nm_connection_new ();
1385 		add_generic_settings (connection, NM_SETTING_WIRELESS_SETTING_NAME);
1386 	
1387 		setting = nm_setting_wireless_new ();
1388 		array = g_byte_array_new ();
1389 		g_byte_array_append (array, (const guint8 *) "1234567", 7);
1390 		g_object_set (setting,
1391 		              NM_SETTING_WIRELESS_SSID, array,
1392 		              NM_SETTING_WIRELESS_MODE, "infrastructure",
1393 		              NULL);
1394 		g_byte_array_free (array, TRUE);
1395 		nm_connection_add_setting (connection, setting);
1396 	
1397 		success = nm_connection_verify (connection, &error);
1398 		g_assert_no_error (error);
1399 		g_assert (success);
1400 		g_object_unref (connection);
1401 	
1402 		/* Bluetooth connection */
1403 		connection = nm_connection_new ();
1404 		add_generic_settings (connection, NM_SETTING_BLUETOOTH_SETTING_NAME);
1405 	
1406 		setting = nm_setting_bluetooth_new ();
1407 		array = g_byte_array_new ();
1408 		g_byte_array_append (array, bdaddr, sizeof (bdaddr));
1409 		g_object_set (setting,
1410 		              NM_SETTING_BLUETOOTH_BDADDR, array,
1411 		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU,
1412 		              NULL);
1413 		g_byte_array_free (array, TRUE);
1414 		nm_connection_add_setting (connection, setting);
1415 	
1416 		success = nm_connection_verify (connection, &error);
1417 		g_assert_no_error (error);
1418 		g_assert (success);
1419 		g_object_unref (connection);
1420 	
1421 		/* WiMAX connection */
1422 		connection = nm_connection_new ();
1423 		add_generic_settings (connection, NM_SETTING_WIMAX_SETTING_NAME);
1424 		setting = nm_setting_wimax_new ();
1425 		g_object_set (setting, NM_SETTING_WIMAX_NETWORK_NAME, "CLEAR", NULL);
1426 		nm_connection_add_setting (connection, setting);
1427 	
1428 		success = nm_connection_verify (connection, &error);
1429 		g_assert_no_error (error);
1430 		g_assert (success);
1431 		g_object_unref (connection);
1432 	
1433 		/* GSM connection */
1434 		connection = nm_connection_new ();
1435 		add_generic_settings (connection, NM_SETTING_GSM_SETTING_NAME);
1436 	
1437 		setting = nm_setting_gsm_new ();
1438 		g_object_set (setting,
1439 		              NM_SETTING_GSM_NUMBER, "*99#",
1440 		              NM_SETTING_GSM_APN, "metered.billing.sucks",
1441 		              NULL);
1442 		nm_connection_add_setting (connection, setting);
1443 	
1444 		/* CDMA connection */
1445 		connection = nm_connection_new ();
1446 		add_generic_settings (connection, NM_SETTING_CDMA_SETTING_NAME);
1447 	
1448 		setting = nm_setting_cdma_new ();
1449 		g_object_set (setting,
1450 		              NM_SETTING_CDMA_NUMBER, "#777",
1451 		              NM_SETTING_CDMA_USERNAME, "foobar@vzw.com",
1452 		              NULL);
1453 		nm_connection_add_setting (connection, setting);
1454 	
1455 		success = nm_connection_verify (connection, &error);
1456 		g_assert_no_error (error);
1457 		g_assert (success);
1458 		g_object_unref (connection);
1459 	}
1460 	
1461 	static void
1462 	test_connection_bad_base_types (void)
1463 	{
1464 		NMConnection *connection;
1465 		NMSetting *setting;
1466 		gboolean success;
1467 		GError *error = NULL;
1468 	
1469 		/* Test various non-base connection types to make sure they are rejected;
1470 		 * using a fake 'wired' connection so the rest of it verifies
1471 		 */
1472 	
1473 		/* Connection setting */
1474 		connection = nm_connection_new ();
1475 		add_generic_settings (connection, NM_SETTING_CONNECTION_SETTING_NAME);
1476 		setting = nm_setting_wired_new ();
1477 		nm_connection_add_setting (connection, setting);
1478 	
1479 		success = nm_connection_verify (connection, &error);
1480 		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
1481 		g_assert (success == FALSE);
1482 		g_object_unref (connection);
1483 		g_clear_error (&error);
1484 	
1485 		/* PPP setting */
1486 		connection = nm_connection_new ();
1487 		add_generic_settings (connection, NM_SETTING_PPP_SETTING_NAME);
1488 		setting = nm_setting_wired_new ();
1489 		nm_connection_add_setting (connection, setting);
1490 		setting = nm_setting_ppp_new ();
1491 		nm_connection_add_setting (connection, setting);
1492 	
1493 		success = nm_connection_verify (connection, &error);
1494 		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
1495 		g_assert (success == FALSE);
1496 		g_object_unref (connection);
1497 		g_clear_error (&error);
1498 	
1499 		/* Serial setting */
1500 		connection = nm_connection_new ();
1501 		add_generic_settings (connection, NM_SETTING_SERIAL_SETTING_NAME);
1502 		setting = nm_setting_wired_new ();
1503 		nm_connection_add_setting (connection, setting);
1504 		setting = nm_setting_serial_new ();
1505 		nm_connection_add_setting (connection, setting);
1506 	
1507 		success = nm_connection_verify (connection, &error);
1508 		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
1509 		g_assert (success == FALSE);
1510 		g_object_unref (connection);
1511 		g_clear_error (&error);
1512 	
1513 		/* IP4 setting */
1514 		connection = nm_connection_new ();
1515 		add_generic_settings (connection, NM_SETTING_IP4_CONFIG_SETTING_NAME);
1516 		setting = nm_setting_wired_new ();
1517 		nm_connection_add_setting (connection, setting);
1518 	
1519 		success = nm_connection_verify (connection, &error);
1520 		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
1521 		g_assert (success == FALSE);
1522 		g_object_unref (connection);
1523 		g_clear_error (&error);
1524 	
1525 		/* IP6 setting */
1526 		connection = nm_connection_new ();
1527 		add_generic_settings (connection, NM_SETTING_IP6_CONFIG_SETTING_NAME);
1528 		setting = nm_setting_wired_new ();
1529 		nm_connection_add_setting (connection, setting);
1530 	
1531 		success = nm_connection_verify (connection, &error);
1532 		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_CONNECTION_TYPE_INVALID);
1533 		g_assert (success == FALSE);
1534 		g_object_unref (connection);
1535 		g_clear_error (&error);
1536 	}
1537 	
1538 	static void
1539 	test_setting_compare_id (void)
1540 	{
1541 		NMSetting *old, *new;
1542 		gboolean success;
1543 	
1544 		old = nm_setting_connection_new ();
1545 		g_object_set (old,
1546 		              NM_SETTING_CONNECTION_ID, "really awesome cool connection",
1547 		              NM_SETTING_CONNECTION_UUID, "fbbd59d5-acab-4e30-8f86-258d272617e7",
1548 		              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
1549 		              NULL);
1550 	
1551 		new = nm_setting_duplicate (old);
1552 		g_object_set (new, NM_SETTING_CONNECTION_ID, "some different connection id", NULL);
1553 	
1554 		/* First make sure they are different */
1555 		success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
1556 		g_assert (success == FALSE);
1557 	
1558 		success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_IGNORE_ID);
1559 		g_assert (success);
1560 	}
1561 	
1562 	static void
1563 	test_setting_compare_secrets (NMSettingSecretFlags secret_flags,
1564 	                              NMSettingCompareFlags comp_flags,
1565 	                              gboolean remove_secret)
1566 	{
1567 		NMSetting *old, *new;
1568 		gboolean success;
1569 	
1570 		/* Make sure that a connection with transient/unsaved secrets compares
1571 		 * successfully to the same connection without those secrets.
1572 		 */
1573 	
1574 		old = nm_setting_wireless_security_new ();
1575 		g_object_set (old,
1576 		              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk",
1577 		              NM_SETTING_WIRELESS_SECURITY_PSK, "really cool psk",
1578 		              NULL);
1579 		nm_setting_set_secret_flags (old, NM_SETTING_WIRELESS_SECURITY_PSK, secret_flags, NULL);
1580 	
1581 		/* Clear the PSK from the duplicated setting */
1582 		new = nm_setting_duplicate (old);
1583 		if (remove_secret) {
1584 			g_object_set (new, NM_SETTING_WIRELESS_SECURITY_PSK, NULL, NULL);
1585 	
1586 			success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
1587 			g_assert (success == FALSE);
1588 		}
1589 	
1590 		success = nm_setting_compare (old, new, comp_flags);
1591 		g_assert (success);
1592 	}
1593 	
1594 	static void
1595 	test_setting_compare_vpn_secrets (NMSettingSecretFlags secret_flags,
1596 	                                  NMSettingCompareFlags comp_flags,
1597 	                                  gboolean remove_secret)
1598 	{
1599 		NMSetting *old, *new;
1600 		gboolean success;
1601 	
1602 		/* Make sure that a connection with transient/unsaved secrets compares
1603 		 * successfully to the same connection without those secrets.
1604 		 */
1605 	
1606 		old = nm_setting_vpn_new ();
1607 		nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "foobarbaz", "really secret password");
1608 		nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "asdfasdfasdf", "really adfasdfasdfasdf");
1609 		nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "0123456778", "abcdefghijklmnpqrstuvqxyz");
1610 		nm_setting_vpn_add_secret (NM_SETTING_VPN (old), "borkbork", "yet another really secret password");
1611 		nm_setting_set_secret_flags (old, "borkbork", secret_flags, NULL);
1612 	
1613 		/* Clear "borkbork" from the duplicated setting */
1614 		new = nm_setting_duplicate (old);
1615 		if (remove_secret) {
1616 			nm_setting_vpn_remove_secret (NM_SETTING_VPN (new), "borkbork");
1617 	
1618 			/* First make sure they are different */
1619 			success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT);
1620 			g_assert (success == FALSE);
1621 		}
1622 	
1623 		success = nm_setting_compare (old, new, comp_flags);
1624 		g_assert (success);
1625 	}
1626 	
1627 	static void
1628 	test_hwaddr_aton_ether_normal (void)
1629 	{
1630 		guint8 buf[100];
1631 		guint8 expected[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
1632 	
1633 		g_assert (nm_utils_hwaddr_aton ("00:11:22:33:44:55", ARPHRD_ETHER, buf) != NULL);
1634 		g_assert (memcmp (buf, expected, sizeof (expected)) == 0);
1635 	}
1636 	
1637 	static void
1638 	test_hwaddr_aton_ib_normal (void)
1639 	{
1640 		guint8 buf[100];
1641 		const char *source = "00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90";
1642 		guint8 expected[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
1643 			0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89,
1644 			0x90 };
1645 	
1646 		g_assert (nm_utils_hwaddr_aton (source, ARPHRD_INFINIBAND, buf) != NULL);
1647 		g_assert (memcmp (buf, expected, sizeof (expected)) == 0);
1648 	}
1649 	
1650 	static void
1651 	test_hwaddr_aton_no_leading_zeros (void)
1652 	{
1653 		guint8 buf[100];
1654 		guint8 expected[ETH_ALEN] = { 0x00, 0x1A, 0x2B, 0x03, 0x44, 0x05 };
1655 	
1656 		g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:44:5", ARPHRD_ETHER, buf) != NULL);
1657 		g_assert (memcmp (buf, expected, sizeof (expected)) == 0);
1658 	}
1659 	
1660 	static void
1661 	test_hwaddr_aton_malformed (void)
1662 	{
1663 		guint8 buf[100];
1664 	
1665 		g_assert (nm_utils_hwaddr_aton ("0:1a:2B:3:a@%%", ARPHRD_ETHER, buf) == NULL);
1666 	}
1667 	
1668 	static void
1669 	test_connection_changed_cb (NMConnection *connection, gboolean *data)
1670 	{
1671 		*data = TRUE;
1672 	}
1673 	
1674 	#define ASSERT_CHANGED(statement) \
1675 	{ \
1676 		changed = FALSE; \
1677 		statement; \
1678 		g_assert (changed); \
1679 	}
1680 	
1681 	#define ASSERT_UNCHANGED(statement) \
1682 	{ \
1683 		changed = FALSE; \
1684 		statement; \
1685 		g_assert (!changed); \
1686 	}
1687 	
1688 	static void
1689 	test_connection_changed_signal (void)
1690 	{
1691 		NMConnection *connection;
1692 		gboolean changed = FALSE;
1693 	
1694 		connection = new_test_connection ();
1695 		g_signal_connect (connection,
1696 		                  NM_CONNECTION_CHANGED,
1697 		                  (GCallback) test_connection_changed_cb,
1698 		                  &changed);
1699 	
1700 		/* Add new setting */
1701 		ASSERT_CHANGED (nm_connection_add_setting (connection, nm_setting_vlan_new ()));
1702 	
1703 		/* Remove existing setting */
1704 		ASSERT_CHANGED (nm_connection_remove_setting (connection, NM_TYPE_SETTING_VLAN));
1705 	
1706 		/* Remove non-existing setting */
1707 		ASSERT_UNCHANGED (nm_connection_remove_setting (connection, NM_TYPE_SETTING_VLAN));
1708 	
1709 		g_object_unref (connection);
1710 	}
1711 	
1712 	static void
1713 	test_setting_connection_changed_signal (void)
1714 	{
1715 		NMConnection *connection;
1716 		gboolean changed = FALSE;
1717 		NMSettingConnection *s_con;
1718 		char *uuid;
1719 	
1720 		connection = nm_connection_new ();
1721 		g_signal_connect (connection,
1722 		                  NM_CONNECTION_CHANGED,
1723 		                  (GCallback) test_connection_changed_cb,
1724 		                  &changed);
1725 	
1726 		s_con = (NMSettingConnection *) nm_setting_connection_new ();
1727 		nm_connection_add_setting (connection, NM_SETTING (s_con));
1728 	
1729 		ASSERT_CHANGED (g_object_set (s_con, NM_SETTING_CONNECTION_ID, "adfadfasdfaf", NULL));
1730 	
1731 		ASSERT_CHANGED (nm_setting_connection_add_permission (s_con, "user", "billsmith", NULL));
1732 		ASSERT_CHANGED (nm_setting_connection_remove_permission (s_con, 0));
1733 		ASSERT_UNCHANGED (nm_setting_connection_remove_permission (s_con, 1));
1734 	
1735 		uuid = nm_utils_uuid_generate ();
1736 		ASSERT_CHANGED (nm_setting_connection_add_secondary (s_con, uuid));
1737 		ASSERT_CHANGED (nm_setting_connection_remove_secondary (s_con, 0));
1738 		ASSERT_UNCHANGED (nm_setting_connection_remove_secondary (s_con, 1));
1739 	
1740 		g_object_unref (connection);
1741 	}
1742 	
1743 	static void
1744 	test_setting_bond_changed_signal (void)
1745 	{
1746 		NMConnection *connection;
1747 		gboolean changed = FALSE;
1748 		NMSettingBond *s_bond;
1749 	
1750 		connection = nm_connection_new ();
1751 		g_signal_connect (connection,
1752 		                  NM_CONNECTION_CHANGED,
1753 		                  (GCallback) test_connection_changed_cb,
1754 		                  &changed);
1755 	
1756 		s_bond = (NMSettingBond *) nm_setting_bond_new ();
1757 		nm_connection_add_setting (connection, NM_SETTING (s_bond));
1758 	
1759 		ASSERT_CHANGED (nm_setting_bond_add_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY, "10"));
1760 		ASSERT_CHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_DOWNDELAY));
1761 		ASSERT_UNCHANGED (nm_setting_bond_remove_option (s_bond, NM_SETTING_BOND_OPTION_UPDELAY));
1762 	
1763 		g_object_unref (connection);
1764 	}
1765 	
1766 	static void
1767 	test_setting_ip4_changed_signal (void)
1768 	{
1769 		NMConnection *connection;
1770 		gboolean changed = FALSE;
1771 		NMSettingIP4Config *s_ip4;
1772 		NMIP4Address *addr;
1773 		NMIP4Route *route;
1774 	
1775 		connection = nm_connection_new ();
1776 		g_signal_connect (connection,
1777 		                  NM_CONNECTION_CHANGED,
1778 		                  (GCallback) test_connection_changed_cb,
1779 		                  &changed);
1780 	
1781 		s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
1782 		nm_connection_add_setting (connection, NM_SETTING (s_ip4));
1783 	
1784 		ASSERT_CHANGED (nm_setting_ip4_config_add_dns (s_ip4, 0x1122));
1785 		ASSERT_CHANGED (nm_setting_ip4_config_remove_dns (s_ip4, 0));
1786 		ASSERT_UNCHANGED (nm_setting_ip4_config_remove_dns (s_ip4, 1));
1787 	
1788 		nm_setting_ip4_config_add_dns (s_ip4, 0x3344);
1789 		ASSERT_CHANGED (nm_setting_ip4_config_clear_dns (s_ip4));
1790 	
1791 		ASSERT_CHANGED (nm_setting_ip4_config_add_dns_search (s_ip4, "foobar.com"));
1792 		ASSERT_CHANGED (nm_setting_ip4_config_remove_dns_search (s_ip4, 0));
1793 		ASSERT_UNCHANGED (nm_setting_ip4_config_remove_dns_search (s_ip4, 1));
1794 	
1795 		ASSERT_CHANGED (nm_setting_ip4_config_add_dns_search (s_ip4, "foobar.com"));
1796 		ASSERT_CHANGED (nm_setting_ip4_config_clear_dns_searches (s_ip4));
1797 	
1798 		addr = nm_ip4_address_new ();
1799 		nm_ip4_address_set_address (addr, 0x2233);
1800 		nm_ip4_address_set_prefix (addr, 24);
1801 		ASSERT_CHANGED (nm_setting_ip4_config_add_address (s_ip4, addr));
1802 		ASSERT_CHANGED (nm_setting_ip4_config_remove_address (s_ip4, 0));
1803 		ASSERT_UNCHANGED (nm_setting_ip4_config_remove_address (s_ip4, 1));
1804 	
1805 		nm_setting_ip4_config_add_address (s_ip4, addr);
1806 		ASSERT_CHANGED (nm_setting_ip4_config_clear_addresses (s_ip4));
1807 	
1808 		route = nm_ip4_route_new ();
1809 		nm_ip4_route_set_dest (route, 0x2233);
1810 		nm_ip4_route_set_prefix (route, 24);
1811 	
1812 		ASSERT_CHANGED (nm_setting_ip4_config_add_route (s_ip4, route));
1813 		ASSERT_CHANGED (nm_setting_ip4_config_remove_route (s_ip4, 0));
1814 		ASSERT_UNCHANGED (nm_setting_ip4_config_remove_route (s_ip4, 1));
1815 	
1816 		nm_setting_ip4_config_add_route (s_ip4, route);
1817 		ASSERT_CHANGED (nm_setting_ip4_config_clear_routes (s_ip4));
1818 	
1819 		nm_ip4_address_unref (addr);
1820 		nm_ip4_route_unref (route);
1821 		g_object_unref (connection);
1822 	}
1823 	
1824 	static void
1825 	test_setting_ip6_changed_signal (void)
1826 	{
1827 		NMConnection *connection;
1828 		gboolean changed = FALSE;
1829 		NMSettingIP6Config *s_ip6;
1830 		NMIP6Address *addr;
1831 		NMIP6Route *route;
1832 		const struct in6_addr t = { { { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 } } };
1833 	
1834 		connection = nm_connection_new ();
1835 		g_signal_connect (connection,
1836 		                  NM_CONNECTION_CHANGED,
1837 		                  (GCallback) test_connection_changed_cb,
1838 		                  &changed);
1839 	
1840 		s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
1841 		nm_connection_add_setting (connection, NM_SETTING (s_ip6));
1842 	
1843 		ASSERT_CHANGED (nm_setting_ip6_config_add_dns (s_ip6, &t));
1844 		ASSERT_CHANGED (nm_setting_ip6_config_remove_dns (s_ip6, 0));
1845 		ASSERT_UNCHANGED (nm_setting_ip6_config_remove_dns (s_ip6, 1));
1846 	
1847 		nm_setting_ip6_config_add_dns (s_ip6, &t);
1848 		ASSERT_CHANGED (nm_setting_ip6_config_clear_dns (s_ip6));
1849 	
1850 		ASSERT_CHANGED (nm_setting_ip6_config_add_dns_search (s_ip6, "foobar.com"));
1851 		ASSERT_CHANGED (nm_setting_ip6_config_remove_dns_search (s_ip6, 0));
1852 		ASSERT_UNCHANGED (nm_setting_ip6_config_remove_dns_search (s_ip6, 1));
1853 	
1854 		nm_setting_ip6_config_add_dns_search (s_ip6, "foobar.com");
1855 		ASSERT_CHANGED (nm_setting_ip6_config_clear_dns_searches (s_ip6));
1856 	
1857 		addr = nm_ip6_address_new ();
1858 		nm_ip6_address_set_address (addr, &t);
1859 		nm_ip6_address_set_prefix (addr, 64);
1860 	
1861 		ASSERT_CHANGED (nm_setting_ip6_config_add_address (s_ip6, addr));
1862 		ASSERT_CHANGED (nm_setting_ip6_config_remove_address (s_ip6, 0));
1863 		ASSERT_UNCHANGED (nm_setting_ip6_config_remove_address (s_ip6, 1));
1864 	
1865 		nm_setting_ip6_config_add_address (s_ip6, addr);
1866 		ASSERT_CHANGED (nm_setting_ip6_config_clear_addresses (s_ip6));
1867 	
1868 		route = nm_ip6_route_new ();
1869 		nm_ip6_route_set_dest (route, &t);
1870 		nm_ip6_route_set_prefix (route, 128);
1871 	
1872 		ASSERT_CHANGED (nm_setting_ip6_config_add_route (s_ip6, route));
1873 		ASSERT_CHANGED (nm_setting_ip6_config_remove_route (s_ip6, 0));
1874 		ASSERT_UNCHANGED (nm_setting_ip6_config_remove_route (s_ip6, 1));
1875 	
1876 		nm_setting_ip6_config_add_route (s_ip6, route);
1877 		ASSERT_CHANGED (nm_setting_ip6_config_clear_routes (s_ip6));
1878 	
1879 		nm_ip6_address_unref (addr);
1880 		nm_ip6_route_unref (route);
1881 		g_object_unref (connection);
1882 	}
1883 	
1884 	static void
1885 	test_setting_vlan_changed_signal (void)
1886 	{
1887 		NMConnection *connection;
1888 		gboolean changed = FALSE;
1889 		NMSettingVlan *s_vlan;
1890 	
1891 		connection = nm_connection_new ();
1892 		g_signal_connect (connection,
1893 		                  NM_CONNECTION_CHANGED,
1894 		                  (GCallback) test_connection_changed_cb,
1895 		                  &changed);
1896 	
1897 		s_vlan = (NMSettingVlan *) nm_setting_vlan_new ();
1898 		nm_connection_add_setting (connection, NM_SETTING (s_vlan));
1899 	
1900 		ASSERT_CHANGED (nm_setting_vlan_add_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1, 3));
1901 		ASSERT_CHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_INGRESS_MAP, 0));
1902 		ASSERT_UNCHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_INGRESS_MAP, 1));
1903 		ASSERT_CHANGED (nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_INGRESS_MAP, "1:3"));
1904 		ASSERT_CHANGED (nm_setting_vlan_clear_priorities (s_vlan, NM_VLAN_INGRESS_MAP));
1905 	
1906 		ASSERT_CHANGED (nm_setting_vlan_add_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, 3));
1907 		ASSERT_CHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0));
1908 		ASSERT_UNCHANGED (nm_setting_vlan_remove_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1));
1909 		ASSERT_CHANGED (nm_setting_vlan_add_priority_str (s_vlan, NM_VLAN_EGRESS_MAP, "1:3"));
1910 		ASSERT_CHANGED (nm_setting_vlan_clear_priorities (s_vlan, NM_VLAN_EGRESS_MAP));
1911 	
1912 		g_object_unref (connection);
1913 	}
1914 	
1915 	static void
1916 	test_setting_vpn_changed_signal (void)
1917 	{
1918 		NMConnection *connection;
1919 		gboolean changed = FALSE;
1920 		NMSettingVPN *s_vpn;
1921 	
1922 		connection = nm_connection_new ();
1923 		g_signal_connect (connection,
1924 		                  NM_CONNECTION_CHANGED,
1925 		                  (GCallback) test_connection_changed_cb,
1926 		                  &changed);
1927 	
1928 		s_vpn = (NMSettingVPN *) nm_setting_vpn_new ();
1929 		nm_connection_add_setting (connection, NM_SETTING (s_vpn));
1930 	
1931 		ASSERT_CHANGED (nm_setting_vpn_add_data_item (s_vpn, "foobar", "baz"));
1932 		ASSERT_CHANGED (nm_setting_vpn_remove_data_item (s_vpn, "foobar"));
1933 		ASSERT_UNCHANGED (nm_setting_vpn_remove_data_item (s_vpn, "not added"));
1934 	
1935 		ASSERT_CHANGED (nm_setting_vpn_add_secret (s_vpn, "foobar", "baz"));
1936 		ASSERT_CHANGED (nm_setting_vpn_remove_secret (s_vpn, "foobar"));
1937 		ASSERT_UNCHANGED (nm_setting_vpn_remove_secret (s_vpn, "not added"));
1938 	
1939 		g_object_unref (connection);
1940 	}
1941 	
1942 	static void
1943 	test_setting_wired_changed_signal (void)
1944 	{
1945 		NMConnection *connection;
1946 		gboolean changed = FALSE;
1947 		NMSettingWired *s_wired;
1948 	
1949 		connection = nm_connection_new ();
1950 		g_signal_connect (connection,
1951 		                  NM_CONNECTION_CHANGED,
1952 		                  (GCallback) test_connection_changed_cb,
1953 		                  &changed);
1954 	
1955 		s_wired = (NMSettingWired *) nm_setting_wired_new ();
1956 		nm_connection_add_setting (connection, NM_SETTING (s_wired));
1957 	
1958 		ASSERT_CHANGED (nm_setting_wired_add_s390_option (s_wired, "portno", "1"));
1959 		ASSERT_CHANGED (nm_setting_wired_remove_s390_option (s_wired, "portno"));
1960 		ASSERT_UNCHANGED (nm_setting_wired_remove_s390_option (s_wired, "layer2"));
1961 	
1962 		g_object_unref (connection);
1963 	}
1964 	
1965 	static void
1966 	test_setting_wireless_changed_signal (void)
1967 	{
1968 		NMConnection *connection;
1969 		gboolean changed = FALSE;
1970 		NMSettingWireless *s_wifi;
1971 	
1972 		connection = nm_connection_new ();
1973 		g_signal_connect (connection,
1974 		                  NM_CONNECTION_CHANGED,
1975 		                  (GCallback) test_connection_changed_cb,
1976 		                  &changed);
1977 	
1978 		s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
1979 		nm_connection_add_setting (connection, NM_SETTING (s_wifi));
1980 	
1981 		ASSERT_CHANGED (nm_setting_wireless_add_seen_bssid (s_wifi, "00:11:22:33:44:55"));
1982 	
1983 		g_object_unref (connection);
1984 	}
1985 	
1986 	static void
1987 	test_setting_wireless_security_changed_signal (void)
1988 	{
1989 		NMConnection *connection;
1990 		gboolean changed = FALSE;
1991 		NMSettingWirelessSecurity *s_wsec;
1992 	
1993 		connection = nm_connection_new ();
1994 		g_signal_connect (connection,
1995 		                  NM_CONNECTION_CHANGED,
1996 		                  (GCallback) test_connection_changed_cb,
1997 		                  &changed);
1998 	
1999 		s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
2000 		nm_connection_add_setting (connection, NM_SETTING (s_wsec));
2001 	
2002 		/* Protos */
2003 		ASSERT_CHANGED (nm_setting_wireless_security_add_proto (s_wsec, "wpa"));
2004 		ASSERT_CHANGED (nm_setting_wireless_security_remove_proto (s_wsec, 0));
2005 		ASSERT_UNCHANGED (nm_setting_wireless_security_remove_proto (s_wsec, 1));
2006 	
2007 		nm_setting_wireless_security_add_proto (s_wsec, "wep");
2008 		ASSERT_CHANGED (nm_setting_wireless_security_clear_protos (s_wsec));
2009 	
2010 		/* Pairwise ciphers */
2011 		ASSERT_CHANGED (nm_setting_wireless_security_add_pairwise (s_wsec, "tkip"));
2012 		ASSERT_CHANGED (nm_setting_wireless_security_remove_pairwise (s_wsec, 0));
2013 		ASSERT_UNCHANGED (nm_setting_wireless_security_remove_pairwise (s_wsec, 1));
2014 	
2015 		nm_setting_wireless_security_add_pairwise (s_wsec, "tkip");
2016 		ASSERT_CHANGED (nm_setting_wireless_security_clear_pairwise (s_wsec));
2017 	
2018 		/* Group ciphers */
2019 		ASSERT_CHANGED (nm_setting_wireless_security_add_group (s_wsec, "ccmp"));
2020 		ASSERT_CHANGED (nm_setting_wireless_security_remove_group (s_wsec, 0));
2021 		ASSERT_UNCHANGED (nm_setting_wireless_security_remove_group (s_wsec, 1));
2022 	
2023 		nm_setting_wireless_security_add_group (s_wsec, "tkip");
2024 		ASSERT_CHANGED (nm_setting_wireless_security_clear_groups (s_wsec));
2025 	
2026 		/* WEP key secret flags */
2027 		ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key0", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL)));
2028 		ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key1", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL)));
2029 		ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key2", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL)));
2030 		ASSERT_CHANGED (g_assert (nm_setting_set_secret_flags (NM_SETTING (s_wsec), "wep-key3", NM_SETTING_SECRET_FLAG_AGENT_OWNED, NULL)));
2031 	
2032 		g_object_unref (connection);
2033 	}
2034 	
2035 	static void
2036 	test_setting_802_1x_changed_signal (void)
2037 	{
2038 		NMConnection *connection;
2039 		gboolean changed = FALSE;
2040 		NMSetting8021x *s_8021x;
2041 	
2042 		connection = nm_connection_new ();
2043 		g_signal_connect (connection,
2044 		                  NM_CONNECTION_CHANGED,
2045 		                  (GCallback) test_connection_changed_cb,
2046 		                  &changed);
2047 	
2048 		s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
2049 		nm_connection_add_setting (connection, NM_SETTING (s_8021x));
2050 	
2051 		/* EAP methods */
2052 		ASSERT_CHANGED (nm_setting_802_1x_add_eap_method (s_8021x, "tls"));
2053 		ASSERT_CHANGED (nm_setting_802_1x_remove_eap_method (s_8021x, 0));
2054 		ASSERT_UNCHANGED (nm_setting_802_1x_remove_eap_method (s_8021x, 1));
2055 	
2056 		nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
2057 		ASSERT_CHANGED (nm_setting_802_1x_clear_eap_methods (s_8021x));
2058 	
2059 		/* alternate subject matches */
2060 		ASSERT_CHANGED (nm_setting_802_1x_add_altsubject_match (s_8021x, "EMAIL:server@example.com"));
2061 		ASSERT_CHANGED (nm_setting_802_1x_remove_altsubject_match (s_8021x, 0));
2062 		ASSERT_UNCHANGED (nm_setting_802_1x_remove_altsubject_match (s_8021x, 1));
2063 	
2064 		nm_setting_802_1x_add_altsubject_match (s_8021x, "EMAIL:server@example.com");
2065 		ASSERT_CHANGED (nm_setting_802_1x_clear_altsubject_matches (s_8021x));
2066 	
2067 		/* phase2 alternate subject matches */
2068 		ASSERT_CHANGED (nm_setting_802_1x_add_phase2_altsubject_match (s_8021x, "EMAIL:server@example.com"));
2069 		ASSERT_CHANGED (nm_setting_802_1x_remove_phase2_altsubject_match (s_8021x, 0));
2070 		ASSERT_UNCHANGED (nm_setting_802_1x_remove_phase2_altsubject_match (s_8021x, 1));
2071 	
2072 		nm_setting_802_1x_add_phase2_altsubject_match (s_8021x, "EMAIL:server@example.com");
2073 		ASSERT_CHANGED (nm_setting_802_1x_clear_phase2_altsubject_matches (s_8021x));
2074 	
2075 		g_object_unref (connection);
2076 	}
2077 	
2078 	static void
2079 	test_setting_old_uuid (void)
2080 	{
2081 		GError *error = NULL;
2082 		NMSetting *setting;
2083 		gboolean success;
2084 	
2085 		/* NetworkManager-0.9.4.0 generated 40-character UUIDs with no dashes,
2086 		 * like this one. Test that we maintain compatibility. */
2087 		const char *uuid = "f43bec2cdd60e5da381ebb1eb1fa39f3cc52660c";
2088 	
2089 		setting = nm_setting_connection_new ();
2090 		g_object_set (G_OBJECT (setting),
2091 		              NM_SETTING_CONNECTION_ID, "uuidtest",
2092 		              NM_SETTING_CONNECTION_UUID, uuid,
2093 		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
2094 		              NULL);
2095 	
2096 		success = nm_setting_verify (NM_SETTING (setting), NULL, &error);
2097 		g_assert_no_error (error);
2098 		g_assert (success == TRUE);
2099 	}
2100 	
2101 	int main (int argc, char **argv)
2102 	{
2103 		GError *error = NULL;
2104 		char *base;
2105 	
2106 		g_type_init ();
2107 	
2108 		if (!nm_utils_init (&error))
2109 			FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
2110 	
2111 		/* The tests */
2112 		test_setting_vpn_items ();
2113 		test_setting_vpn_update_secrets ();
2114 		test_setting_vpn_modify_during_foreach ();
2115 		test_setting_ip6_config_old_address_array ();
2116 		test_setting_gsm_apn_spaces ();
2117 		test_setting_gsm_apn_bad_chars ();
2118 		test_setting_gsm_apn_underscore ();
2119 		test_setting_gsm_without_number ();
2120 		test_setting_to_hash_all ();
2121 		test_setting_to_hash_no_secrets ();
2122 		test_setting_to_hash_only_secrets ();
2123 		test_setting_compare_id ();
2124 		test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
2125 		test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
2126 		test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
2127 		test_setting_compare_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
2128 		test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_AGENT_OWNED, NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS, TRUE);
2129 		test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NOT_SAVED, NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS, TRUE);
2130 		test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS, TRUE);
2131 		test_setting_compare_vpn_secrets (NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_COMPARE_FLAG_EXACT, FALSE);
2132 		test_setting_old_uuid ();
2133 	
2134 		test_connection_to_hash_setting_name ();
2135 		test_setting_new_from_hash ();
2136 		test_connection_replace_settings ();
2137 		test_connection_replace_settings_from_connection ();
2138 		test_connection_new_from_hash ();
2139 	
2140 		test_setting_connection_permissions_helpers ();
2141 		test_setting_connection_permissions_property ();
2142 	
2143 		test_connection_compare_same ();
2144 		test_connection_compare_key_only_in_a ();
2145 		test_connection_compare_setting_only_in_a ();
2146 		test_connection_compare_key_only_in_b ();
2147 		test_connection_compare_setting_only_in_b ();
2148 	
2149 		test_connection_diff_a_only ();
2150 		test_connection_diff_same ();
2151 		test_connection_diff_different ();
2152 		test_connection_diff_no_secrets ();
2153 		test_connection_good_base_types ();
2154 		test_connection_bad_base_types ();
2155 	
2156 		test_hwaddr_aton_ether_normal ();
2157 		test_hwaddr_aton_ib_normal ();
2158 		test_hwaddr_aton_no_leading_zeros ();
2159 		test_hwaddr_aton_malformed ();
2160 	
2161 		test_connection_changed_signal ();
2162 		test_setting_connection_changed_signal ();
2163 		test_setting_bond_changed_signal ();
2164 		test_setting_ip4_changed_signal ();
2165 		test_setting_ip6_changed_signal ();
2166 		test_setting_vlan_changed_signal ();
2167 		test_setting_vpn_changed_signal ();
2168 		test_setting_wired_changed_signal ();
2169 		test_setting_wireless_changed_signal ();
2170 		test_setting_wireless_security_changed_signal ();
2171 		test_setting_802_1x_changed_signal ();
2172 	
2173 		base = g_path_get_basename (argv[0]);
2174 		fprintf (stdout, "%s: SUCCESS\n", base);
2175 		g_free (base);
2176 		return 0;
2177 	}
2178 	
2179