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 <string.h>
24   	
25   	#include "nm-test-helpers.h"
26   	#include <nm-utils.h>
27   	
28   	#include "nm-setting-connection.h"
29   	#include "nm-setting-wired.h"
30   	#include "nm-setting-8021x.h"
31   	#include "nm-setting-ip4-config.h"
32   	#include "nm-setting-wireless.h"
33   	#include "nm-setting-wireless-security.h"
34   	#include "nm-setting-cdma.h"
35   	#include "nm-setting-gsm.h"
36   	#include "nm-setting-ppp.h"
37   	#include "nm-setting-pppoe.h"
38   	#include "nm-setting-vpn.h"
39   	
40   	
41   	#define TEST_NEED_SECRETS_EAP_TLS_CA_CERT TEST_CERT_DIR "/test_ca_cert.pem"
42   	#define TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT TEST_CERT_DIR "/test_key_and_cert.pem"
43   	#define TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY TEST_CERT_DIR "/test_key_and_cert.pem"
44   	
45   	static gboolean
46   	find_hints_item (GPtrArray *hints, const char *item)
47   	{
48   		int i;
49   	
50   		for (i = 0; i < hints->len; i++) {
51   			if (!strcmp (item, (const char *) g_ptr_array_index (hints, i)))
52   				return TRUE;
53   		}
54   		return FALSE;
55   	}
56   	
57   	static NMConnection *
58   	make_tls_connection (const char *detail, NMSetting8021xCKScheme scheme)
59   	{
60   		NMConnection *connection;
61   		NMSettingConnection *s_con;
62   		NMSetting8021x *s_8021x;
63   		NMSettingWired *s_wired;
64   		NMSettingIP4Config *s_ip4;
65   		char *uuid;
66   		gboolean success;
67   		GError *error = NULL;
68   	
69   		connection = nm_connection_new ();
70   	
71   		/* Connection setting */
72   		s_con = (NMSettingConnection *) nm_setting_connection_new ();
73   		nm_connection_add_setting (connection, NM_SETTING (s_con));
74   	
75   		uuid = nm_utils_uuid_generate ();
76   		g_object_set (s_con,
77   		              NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets",
78   		              NM_SETTING_CONNECTION_UUID, uuid,
79   		              NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
80   		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
81   		              NULL);
82   		g_free (uuid);
83   	
84   		/* Wired setting */
85   		s_wired = (NMSettingWired *) nm_setting_wired_new ();
86   		nm_connection_add_setting (connection, NM_SETTING (s_wired));
87   	
88   		/* Wireless security setting */
89   		s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
90   		nm_connection_add_setting (connection, NM_SETTING (s_8021x));
91   	
92   		g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
93   	
94   		nm_setting_802_1x_add_eap_method (s_8021x, "tls");
95   	
96   		success = nm_setting_802_1x_set_ca_cert (s_8021x,
97   		                                         TEST_NEED_SECRETS_EAP_TLS_CA_CERT,
98   		                                         scheme,
99   		                                         NULL,
100  		                                         &error);
101  		ASSERT (success == TRUE,
102  		        detail, "failed to set CA certificate '%s': %s",
103  		        TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message);
104  	
105  		success = nm_setting_802_1x_set_client_cert (s_8021x,
106  		                                             TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT,
107  		                                             scheme,
108  		                                             NULL,
109  		                                             &error);
110  		ASSERT (success == TRUE,
111  		        detail, "failed to set client certificate '%s': %s",
112  		        TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message);
113  	
114  		success = nm_setting_802_1x_set_private_key (s_8021x,
115  		                                             TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY,
116  		                                             "test",
117  		                                             scheme,
118  		                                             NULL,
119  		                                             &error);
120  		ASSERT (success == TRUE,
121  		        detail, "failed to set private key '%s': %s",
122  		        TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message);
123  	
124  		/* IP4 setting */
125  		s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
126  		nm_connection_add_setting (connection, NM_SETTING (s_ip4));
127  	
128  		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
129  	
130  		ASSERT (nm_connection_verify (connection, &error) == TRUE,
131  		        detail, "failed to verify connection: %s",
132  		        (error && error->message) ? error->message : "(unknown)");
133  	
134  		return connection;
135  	}
136  	
137  	static void
138  	test_need_tls_secrets_path (void)
139  	{
140  		NMConnection *connection;
141  		const char *setting_name;
142  		GPtrArray *hints = NULL;
143  	
144  		connection = make_tls_connection ("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH);
145  		ASSERT (connection != NULL,
146  		        "need-tls-secrets-path-key",
147  		        "error creating test connection");
148  	
149  		/* Ensure we don't need any secrets since we just set up the connection */
150  		setting_name = nm_connection_need_secrets (connection, &hints);
151  		ASSERT (setting_name == NULL,
152  		        "need-tls-secrets-path-key",
153  		        "secrets are unexpectedly required");
154  		ASSERT (hints == NULL,
155  		        "need-tls-secrets-path-key",
156  		        "hints should be NULL since no secrets were required");
157  	
158  		/* Connection is good; clear secrets and ensure private key password is then required */
159  		nm_connection_clear_secrets (connection);
160  	
161  		hints = NULL;
162  		setting_name = nm_connection_need_secrets (connection, &hints);
163  		ASSERT (setting_name != NULL,
164  		        "need-tls-secrets-path-key-password",
165  		        "unexpected secrets success");
166  		ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
167  				"need-tls-secrets-path-key-password",
168  				"unexpected setting secrets required");
169  	
170  		ASSERT (hints != NULL,
171  		        "need-tls-secrets-path-key-password",
172  		        "expected returned secrets hints");
173  		ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD),
174  				"need-tls-secrets-path-key-password",
175  				"expected to require private key password, but it wasn't");
176  	
177  		g_object_unref (connection);
178  	}
179  	
180  	static void
181  	test_need_tls_secrets_blob (void)
182  	{
183  		NMConnection *connection;
184  		const char *setting_name;
185  		GPtrArray *hints = NULL;
186  	
187  		connection = make_tls_connection ("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB);
188  		ASSERT (connection != NULL,
189  		        "need-tls-secrets-blob-key",
190  		        "error creating test connection");
191  	
192  		/* Ensure we don't need any secrets since we just set up the connection */
193  		setting_name = nm_connection_need_secrets (connection, &hints);
194  		ASSERT (setting_name == NULL,
195  		        "need-tls-secrets-blob-key",
196  		        "secrets are unexpectedly required");
197  		ASSERT (hints == NULL,
198  		        "need-tls-secrets-blob-key",
199  		        "hints should be NULL since no secrets were required");
200  	
201  		/* Clear secrets and ensure password is again required */
202  		nm_connection_clear_secrets (connection);
203  	
204  		hints = NULL;
205  		setting_name = nm_connection_need_secrets (connection, &hints);
206  		ASSERT (setting_name != NULL,
207  		        "need-tls-secrets-blob-key-password",
208  		        "unexpected secrets success");
209  		ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
210  				"need-tls-secrets-blob-key-password",
211  				"unexpected setting secrets required");
212  	
213  		ASSERT (hints != NULL,
214  		        "need-tls-secrets-blob-key-password",
215  		        "expected returned secrets hints");
216  		ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD),
217  				"need-tls-secrets-blob-key-password",
218  				"expected to require private key password, but it wasn't");
219  	
220  		g_object_unref (connection);
221  	}
222  	
223  	static NMConnection *
224  	make_tls_phase2_connection (const char *detail, NMSetting8021xCKScheme scheme)
225  	{
226  		NMConnection *connection;
227  		NMSettingConnection *s_con;
228  		NMSetting8021x *s_8021x;
229  		NMSettingWired *s_wired;
230  		NMSettingIP4Config *s_ip4;
231  		char *uuid;
232  		gboolean success;
233  		GError *error = NULL;
234  	
235  		connection = nm_connection_new ();
236  	
237  		/* Connection setting */
238  		s_con = (NMSettingConnection *) nm_setting_connection_new ();
239  		nm_connection_add_setting (connection, NM_SETTING (s_con));
240  	
241  		uuid = nm_utils_uuid_generate ();
242  		g_object_set (s_con,
243  		              NM_SETTING_CONNECTION_ID, "Test Need TLS Secrets",
244  		              NM_SETTING_CONNECTION_UUID, uuid,
245  		              NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
246  		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
247  		              NULL);
248  		g_free (uuid);
249  	
250  		/* Wired setting */
251  		s_wired = (NMSettingWired *) nm_setting_wired_new ();
252  		nm_connection_add_setting (connection, NM_SETTING (s_wired));
253  	
254  		/* Wireless security setting */
255  		s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
256  		nm_connection_add_setting (connection, NM_SETTING (s_8021x));
257  	
258  		g_object_set (s_8021x, NM_SETTING_802_1X_ANONYMOUS_IDENTITY, "blahblah", NULL);
259  		g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
260  	
261  		nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
262  		g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "tls", NULL);
263  	
264  		success = nm_setting_802_1x_set_phase2_ca_cert (s_8021x,
265  		                                                TEST_NEED_SECRETS_EAP_TLS_CA_CERT,
266  		                                                scheme,
267  		                                                NULL,
268  		                                                &error);
269  		ASSERT (success == TRUE,
270  		        detail, "failed to set phase2 CA certificate '%s': %s",
271  		        TEST_NEED_SECRETS_EAP_TLS_CA_CERT, error->message);
272  	
273  		success = nm_setting_802_1x_set_phase2_client_cert (s_8021x,
274  		                                                    TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT,
275  		                                                    scheme,
276  		                                                    NULL,
277  		                                                    &error);
278  		ASSERT (success == TRUE,
279  		        detail, "failed to set phase2 client certificate '%s': %s",
280  		        TEST_NEED_SECRETS_EAP_TLS_CLIENT_CERT, error->message);
281  	
282  		success = nm_setting_802_1x_set_phase2_private_key (s_8021x,
283  		                                                    TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY,
284  		                                                    "test",
285  		                                                    scheme,
286  		                                                    NULL,
287  		                                                    &error);
288  		ASSERT (success == TRUE,
289  		        detail, "failed to set phase2 private key '%s': %s",
290  		        TEST_NEED_SECRETS_EAP_TLS_PRIVATE_KEY, error->message);
291  	
292  		/* IP4 setting */
293  		s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
294  		nm_connection_add_setting (connection, NM_SETTING (s_ip4));
295  	
296  		g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
297  	
298  		ASSERT (nm_connection_verify (connection, &error) == TRUE,
299  		        detail, "failed to verify connection: %s",
300  		        (error && error->message) ? error->message : "(unknown)");
301  	
302  		return connection;
303  	}
304  	
305  	static void
306  	test_need_tls_phase2_secrets_path (void)
307  	{
308  		NMConnection *connection;
309  		const char *setting_name;
310  		GPtrArray *hints = NULL;
311  	
312  		connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key",
313  		                                         NM_SETTING_802_1X_CK_SCHEME_PATH);
314  		ASSERT (connection != NULL,
315  		        "need-tls-phase2-secrets-path-key",
316  		        "error creating test connection");
317  	
318  		/* Ensure we don't need any secrets since we just set up the connection */
319  		setting_name = nm_connection_need_secrets (connection, &hints);
320  		ASSERT (setting_name == NULL,
321  		        "need-tls-phase2-secrets-path-key",
322  		        "secrets are unexpectedly required");
323  		ASSERT (hints == NULL,
324  		        "need-tls-phase2-secrets-path-key",
325  		        "hints should be NULL since no secrets were required");
326  	
327  		/* Connection is good; clear secrets and ensure private key password is then required */
328  		nm_connection_clear_secrets (connection);
329  	
330  		hints = NULL;
331  		setting_name = nm_connection_need_secrets (connection, &hints);
332  		ASSERT (setting_name != NULL,
333  		        "need-tls-phase2-secrets-path-key-password",
334  		        "unexpected secrets success");
335  		ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
336  				"need-tls-phase2-secrets-path-key-password",
337  				"unexpected setting secrets required");
338  	
339  		ASSERT (hints != NULL,
340  		        "need-tls-phase2-secrets-path-key-password",
341  		        "expected returned secrets hints");
342  		ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD),
343  				"need-tls-phase2-secrets-path-key-password",
344  				"expected to require private key password, but it wasn't");
345  	
346  		g_object_unref (connection);
347  	}
348  	
349  	static void
350  	test_need_tls_phase2_secrets_blob (void)
351  	{
352  		NMConnection *connection;
353  		const char *setting_name;
354  		GPtrArray *hints = NULL;
355  	
356  		connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key",
357  		                                         NM_SETTING_802_1X_CK_SCHEME_BLOB);
358  		ASSERT (connection != NULL,
359  		        "need-tls-phase2-secrets-blob-key",
360  		        "error creating test connection");
361  	
362  		/* Ensure we don't need any secrets since we just set up the connection */
363  		setting_name = nm_connection_need_secrets (connection, &hints);
364  		ASSERT (setting_name == NULL,
365  		        "need-tls-phase2-secrets-blob-key",
366  		        "secrets are unexpectedly required");
367  		ASSERT (hints == NULL,
368  		        "need-tls-phase2-secrets-blob-key",
369  		        "hints should be NULL since no secrets were required");
370  	
371  		/* Connection is good; clear secrets and ensure private key password is then required */
372  		nm_connection_clear_secrets (connection);
373  	
374  		hints = NULL;
375  		setting_name = nm_connection_need_secrets (connection, &hints);
376  		ASSERT (setting_name != NULL,
377  		        "need-tls-phase2-secrets-blob-key-password",
378  		        "unexpected secrets success");
379  		ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0,
380  				"need-tls-phase2-secrets-blob-key-password",
381  				"unexpected setting secrets required");
382  	
383  		ASSERT (hints != NULL,
384  		        "need-tls-phase2-secrets-blob-key-password",
385  		        "expected returned secrets hints");
386  		ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD),
387  				"need-tls-phase2-secrets-blob-key-password",
388  				"expected to require private key password, but it wasn't");
389  	
390  		g_object_unref (connection);
391  	}
392  	
393  	static NMConnection *
394  	wifi_connection_new (void)
395  	{
396  		NMConnection *connection;
397  		NMSettingConnection *s_con;
398  		NMSettingWireless *s_wifi;
399  		NMSettingWirelessSecurity *s_wsec;
400  		unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 };
401  		char *uuid;
402  		GByteArray *ssid;
403  	
404  		connection = nm_connection_new ();
405  		g_assert (connection);
406  	
407  		/* Connection setting */
408  		s_con = (NMSettingConnection *) nm_setting_connection_new ();
409  		g_assert (s_con);
410  	
411  		uuid = nm_utils_uuid_generate ();
412  		g_object_set (s_con,
413  		              NM_SETTING_CONNECTION_ID, "Test Wireless",
414  		              NM_SETTING_CONNECTION_UUID, uuid,
415  		              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
416  		              NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
417  		              NULL);
418  		g_free (uuid);
419  		nm_connection_add_setting (connection, NM_SETTING (s_con));
420  	
421  		/* Wireless setting */
422  		s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
423  		g_assert (s_wifi);
424  	
425  		ssid = g_byte_array_sized_new (sizeof (tmpssid));
426  		g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid));
427  		g_object_set (s_wifi,
428  		              NM_SETTING_WIRELESS_SSID, ssid,
429  		              NULL);
430  		g_byte_array_free (ssid, TRUE);
431  		nm_connection_add_setting (connection, NM_SETTING (s_wifi));
432  	
433  		/* Wifi security */
434  		s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
435  		g_assert (s_wsec);
436  	
437  		g_object_set (G_OBJECT (s_wsec),
438  		              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
439  		              NULL);
440  		nm_connection_add_setting (connection, NM_SETTING (s_wsec));
441  	
442  		return connection;
443  	}
444  	
445  	static void
446  	value_destroy (gpointer data)
447  	{
448  		GValue *value = (GValue *) data;
449  	
450  		g_value_unset (value);
451  		g_slice_free (GValue, value);
452  	}
453  	
454  	static GValue *
455  	string_to_gvalue (const char *str)
456  	{
457  		GValue *val = g_slice_new0 (GValue);
458  	
459  		g_value_init (val, G_TYPE_STRING);
460  		g_value_set_string (val, str);
461  		return val;
462  	}
463  	
464  	static GValue *
465  	uint_to_gvalue (guint32 i)
466  	{
467  		GValue *val;
468  	
469  		val = g_slice_new0 (GValue);
470  		g_value_init (val, G_TYPE_UINT);
471  		g_value_set_uint (val, i);
472  		return val;
473  	}
474  	
475  	static void
476  	test_update_secrets_wifi_single_setting (void)
477  	{
478  		NMConnection *connection;
479  		NMSettingWirelessSecurity *s_wsec;
480  		GHashTable *secrets;
481  		GError *error = NULL;
482  		gboolean success;
483  		const char *wepkey = "11111111111111111111111111";
484  		const char *tmp;
485  	
486  		/* Test update with a hashed setting of 802-11-wireless secrets */
487  	
488  		connection = wifi_connection_new ();
489  	
490  		/* Build up the secrets hash */
491  		secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy);
492  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
493  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY));
494  	
495  		success = nm_connection_update_secrets (connection,
496  		                                        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
497  		                                        secrets,
498  		                                        &error);
499  		g_assert_no_error (error);
500  		g_assert (success);
501  	
502  		/* Make sure the secret is now in the connection */
503  		s_wsec = nm_connection_get_setting_wireless_security (connection);
504  		g_assert (s_wsec);
505  		tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
506  		g_assert_cmpstr (tmp, ==, wepkey);
507  	
508  		g_object_unref (connection);
509  	}
510  	
511  	static void
512  	test_update_secrets_wifi_full_hash (void)
513  	{
514  		NMConnection *connection;
515  		NMSettingWirelessSecurity *s_wsec;
516  		GHashTable *secrets, *all;
517  		GError *error = NULL;
518  		gboolean success;
519  		const char *wepkey = "11111111111111111111111111";
520  		const char *tmp;
521  	
522  		/* Test update with a hashed connection containing only 802-11-wireless
523  		 * setting and secrets.
524  		 */
525  	
526  		connection = wifi_connection_new ();
527  	
528  		/* Build up the secrets hash */
529  		all = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy);
530  		secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy);
531  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
532  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY));
533  		g_hash_table_insert (all, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, secrets);
534  	
535  		success = nm_connection_update_secrets (connection,
536  		                                        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
537  		                                        all,
538  		                                        &error);
539  		g_assert_no_error (error);
540  		g_assert (success);
541  	
542  		/* Make sure the secret is now in the connection */
543  		s_wsec = nm_connection_get_setting_wireless_security (connection);
544  		g_assert (s_wsec);
545  		tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0);
546  		g_assert_cmpstr (tmp, ==, wepkey);
547  	
548  		g_object_unref (connection);
549  	}
550  	
551  	static void
552  	test_update_secrets_wifi_bad_setting_name (void)
553  	{
554  		NMConnection *connection;
555  		GHashTable *secrets;
556  		GError *error = NULL;
557  		gboolean success;
558  		const char *wepkey = "11111111111111111111111111";
559  	
560  		/* Test that passing an invalid setting name to
561  		 * nm_connection_update_secrets() fails with the correct error.
562  		 */
563  	
564  		connection = wifi_connection_new ();
565  	
566  		/* Build up the secrets hash */
567  		secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy);
568  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
569  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY));
570  	
571  		success = nm_connection_update_secrets (connection,
572  		                                        "asdfasdfasdfasf",
573  		                                        secrets,
574  		                                        &error);
575  		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
576  		g_assert (success == FALSE);
577  	
578  		g_object_unref (connection);
579  	}
580  	
581  	static void
582  	test_update_secrets_whole_connection (void)
583  	{
584  		NMConnection *connection;
585  		NMSettingWirelessSecurity *s_wsec;
586  		GHashTable *secrets, *wsec_hash;
587  		GError *error = NULL;
588  		gboolean success;
589  		const char *wepkey = "11111111111111111111111111";
590  	
591  		/* Test calling nm_connection_update_secrets() with an entire hashed
592  		 * connection including non-secrets.
593  		 */
594  	
595  		connection = wifi_connection_new ();
596  	
597  		/* Build up the secrets hash */
598  		secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
599  		wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
600  		g_assert (wsec_hash);
601  		g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
602  	
(8) Event example_assign: Example3: Assigning: "success" = return value from "nm_connection_update_secrets(connection, NULL, secrets, &error)".
Also see events: [check_return][example_assign][example_checked][example_assign][example_checked][example_checked][example_assign][example_checked][example_assign][example_checked][unchecked_value]
603  		success = nm_connection_update_secrets (connection, NULL, secrets, &error);
604  		g_assert_no_error (error);
(9) Event example_checked: Example3 (cont.): "success" has its value checked in "success == 1".
Also see events: [check_return][example_assign][example_checked][example_assign][example_checked][example_assign][example_assign][example_checked][example_assign][example_checked][unchecked_value]
605  		g_assert (success == TRUE);
606  	
607  		s_wsec = nm_connection_get_setting_wireless_security (connection);
608  		g_assert (s_wsec);
609  		g_assert_cmpstr (nm_setting_wireless_security_get_wep_key (s_wsec, 0), ==, wepkey);
610  	
611  		g_object_unref (connection);
612  	}
613  	
614  	static void
615  	test_update_secrets_whole_connection_empty_hash (void)
616  	{
617  		NMConnection *connection;
618  		GHashTable *secrets;
619  		GError *error = NULL;
620  		gboolean success;
621  	
622  		/* Test that updating secrets with an empty hash returns success */
623  	
624  		connection = wifi_connection_new ();
625  		secrets = g_hash_table_new (g_str_hash, g_str_equal);
626  		success = nm_connection_update_secrets (connection, NULL, secrets, &error);
627  		g_assert_no_error (error);
628  		g_assert (success == TRUE);
629  		g_object_unref (connection);
630  	}
631  	
632  	static void
633  	test_update_secrets_whole_connection_bad_setting (void)
634  	{
635  		NMConnection *connection;
636  		GHashTable *secrets, *wsec_hash;
637  		GError *error = NULL;
638  		gboolean success;
639  		const char *wepkey = "11111111111111111111111111";
640  	
641  		/* Test that sending a hashed connection containing an invalid setting
642  		 * name fails with the right error.
643  		 */
644  	
645  		connection = wifi_connection_new ();
646  	
647  		/* Build up the secrets hash */
648  		secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL);
649  		wsec_hash = g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
650  		g_assert (wsec_hash);
651  		g_hash_table_insert (wsec_hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
652  	
653  		/* Steal the wsec setting hash so it's not deallocated, and stuff it back
654  		 * in with a different name so we ensure libnm-util is returning the right
655  		 * error when it finds an entry in the connection hash that doesn't match
656  		 * any setting in the connection.
657  		 */
658  		g_hash_table_steal (secrets, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME);
659  		g_hash_table_insert (secrets, "asdfasdfasdfasdf", wsec_hash);
660  	
(10) Event example_assign: Example4: Assigning: "success" = return value from "nm_connection_update_secrets(connection, NULL, secrets, &error)".
Also see events: [check_return][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_checked][example_assign][example_checked][unchecked_value]
661  		success = nm_connection_update_secrets (connection, NULL, secrets, &error);
662  		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
(11) Event example_checked: Example4 (cont.): "success" has its value checked in "success == 0".
Also see events: [check_return][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_assign][example_checked][unchecked_value]
663  		g_assert (success == FALSE);
664  	
665  		g_object_unref (connection);
666  	}
667  	
668  	static void
669  	test_update_secrets_whole_connection_empty_base_setting (void)
670  	{
671  		NMConnection *connection;
672  		GHashTable *secrets;
673  		GError *error = NULL;
674  		gboolean success;
675  	
676  		/* Test that a hashed connection which does not have any hashed secrets
677  		 * for the requested setting returns success.
678  		 */
679  	
680  		connection = wifi_connection_new ();
681  		secrets = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
682  		g_assert_cmpint (g_hash_table_size (secrets), ==, 1);
683  		g_assert (g_hash_table_lookup (secrets, NM_SETTING_WIRELESS_SETTING_NAME));
684  	
(12) Event example_assign: Example5: Assigning: "success" = return value from "nm_connection_update_secrets(connection, "802-11-wireless-security", secrets, &error)".
Also see events: [check_return][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_checked][unchecked_value]
685  		success = nm_connection_update_secrets (connection,
686  		                                        NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
687  		                                        secrets,
688  		                                        &error);
689  		g_assert_no_error (error);
(13) Event example_checked: Example5 (cont.): "success" has its value checked in "success".
Also see events: [check_return][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][unchecked_value]
690  		g_assert (success);
691  	
692  		g_hash_table_destroy (secrets);
693  		g_object_unref (connection);
694  	}
695  	
696  	static void
697  	test_update_secrets_null_setting_name_with_setting_hash (void)
698  	{
699  		NMConnection *connection;
700  		GHashTable *secrets;
701  		GError *error = NULL;
702  		gboolean success;
703  		const char *wepkey = "11111111111111111111111111";
704  	
705  		/* Ensure that a NULL setting name and only a hashed setting fails */
706  	
707  		connection = wifi_connection_new ();
708  	
709  		secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy);
710  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, string_to_gvalue (wepkey));
711  		g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, uint_to_gvalue (NM_WEP_KEY_TYPE_KEY));
712  	
(6) Event example_assign: Example2: Assigning: "success" = return value from "nm_connection_update_secrets(connection, NULL, secrets, &error)".
Also see events: [check_return][example_assign][example_checked][example_checked][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][unchecked_value]
713  		success = nm_connection_update_secrets (connection, NULL, secrets, &error);
714  		g_assert_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND);
(7) Event example_checked: Example2 (cont.): "success" has its value checked in "success".
Also see events: [check_return][example_assign][example_checked][example_assign][example_assign][example_checked][example_assign][example_checked][example_assign][example_checked][unchecked_value]
715  		g_assert (!success);
716  	
717  		g_hash_table_destroy (secrets);
718  		g_object_unref (connection);
719  	}
720  	
721  	int main (int argc, char **argv)
722  	{
723  		GError *error = NULL;
724  		char *base;
725  	
726  		g_type_init ();
727  	
728  		if (!nm_utils_init (&error))
729  			FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message);
730  	
731  		/* The tests */
732  		test_need_tls_secrets_path ();
733  		test_need_tls_secrets_blob ();
734  		test_need_tls_phase2_secrets_path ();
735  		test_need_tls_phase2_secrets_blob ();
736  	
737  		test_update_secrets_wifi_single_setting ();
738  		test_update_secrets_wifi_full_hash ();
739  		test_update_secrets_wifi_bad_setting_name ();
740  	
741  		test_update_secrets_whole_connection ();
742  		test_update_secrets_whole_connection_empty_hash ();
743  		test_update_secrets_whole_connection_bad_setting ();
744  		test_update_secrets_whole_connection_empty_base_setting ();
745  		test_update_secrets_null_setting_name_with_setting_hash ();
746  	
747  		base = g_path_get_basename (argv[0]);
748  		fprintf (stdout, "%s: SUCCESS\n", base);
749  		g_free (base);
750  		return 0;
751  	}
752  	
753