1    	/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2    	
3    	/*
4    	 * Dan Williams <dcbw@redhat.com>
5    	 * Tambet Ingo <tambet@gmail.com>
6    	 *
7    	 * This library is free software; you can redistribute it and/or
8    	 * modify it under the terms of the GNU Lesser General Public
9    	 * License as published by the Free Software Foundation; either
10   	 * version 2 of the License, or (at your option) any later version.
11   	 *
12   	 * This library is distributed in the hope that it will be useful,
13   	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   	 * Lesser General Public License for more details.
16   	 *
17   	 * You should have received a copy of the GNU Lesser General Public
18   	 * License along with this library; if not, write to the
19   	 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20   	 * Boston, MA 02110-1301 USA.
21   	 *
22   	 * (C) Copyright 2007 - 2013 Red Hat, Inc.
23   	 * (C) Copyright 2007 - 2008 Novell, Inc.
24   	 */
25   	
26   	#include <string.h>
27   	#include <dbus/dbus-glib.h>
28   	#include <glib/gi18n.h>
29   	
30   	#include "nm-setting-8021x.h"
31   	#include "nm-param-spec-specialized.h"
32   	#include "nm-utils.h"
33   	#include "nm-dbus-glib-types.h"
34   	#include "crypto.h"
35   	#include "nm-utils-private.h"
36   	#include "nm-setting-private.h"
37   	
38   	/**
39   	 * SECTION:nm-setting-8021x
40   	 * @short_description: Describes 802.1x-authenticated connection properties
41   	 * @include: nm-setting-8021x.h
42   	 *
43   	 * The #NMSetting8021x object is a #NMSetting subclass that describes
44   	 * properties necessary for connection to 802.1x-authenticated networks, such as
45   	 * WPA and WPA2 Enterprise WiFi networks and wired 802.1x networks.  802.1x
46   	 * connections typically use certificates and/or EAP authentication methods to
47   	 * securely verify, identify, and authenticate the client to the network itself,
48   	 * instead of simply relying on a widely shared static key.
49   	 *
50   	 * It's a good idea to read up on wpa_supplicant configuration before using this
51   	 * setting extensively, since most of the options here correspond closely with
52   	 * the relevant wpa_supplicant configuration options.
53   	 *
54   	 * Furthermore, to get a good idea of 802.1x, EAP, TLS, TTLS, etc and their
55   	 * applications to WiFi and wired networks, you'll want to get copies of the
56   	 * following books.
57   	 *
58   	 *  802.11 Wireless Networks: The Definitive Guide, Second Edition
59   	 *       Author: Matthew Gast
60   	 *       ISBN: 978-0596100520
61   	 *
62   	 *  Cisco Wireless LAN Security
63   	 *       Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky
64   	 *       ISBN: 978-1587051548
65   	 **/
66   	
67   	#define SCHEME_PATH "file://"
68   	
69   	/**
70   	 * nm_setting_802_1x_error_quark:
71   	 *
72   	 * Registers an error quark for #NMSetting8021x if necessary.
73   	 *
74   	 * Returns: the error quark used for #NMSetting8021x errors.
75   	 **/
76   	GQuark
77   	nm_setting_802_1x_error_quark (void)
78   	{
79   		static GQuark quark;
80   	
81   		if (G_UNLIKELY (!quark))
82   			quark = g_quark_from_static_string ("nm-setting-802-1x-error-quark");
83   		return quark;
84   	}
85   	
86   	G_DEFINE_TYPE_WITH_CODE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING,
87   	                         _nm_register_setting (NM_SETTING_802_1X_SETTING_NAME,
88   	                                               g_define_type_id,
89   	                                               2,
90   	                                               NM_SETTING_802_1X_ERROR))
91   	NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_802_1X)
92   	
93   	#define NM_SETTING_802_1X_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_802_1X, NMSetting8021xPrivate))
94   	
95   	typedef struct {
96   		GSList *eap; /* GSList of strings */
97   		char *identity;
98   		char *anonymous_identity;
99   		char *pac_file;
100  		GByteArray *ca_cert;
101  		char *ca_path;
102  		char *subject_match;
103  		GSList *altsubject_matches;
104  		GByteArray *client_cert;
105  		char *phase1_peapver;
106  		char *phase1_peaplabel;
107  		char *phase1_fast_provisioning;
108  		char *phase2_auth;
109  		char *phase2_autheap;
110  		GByteArray *phase2_ca_cert;
111  		char *phase2_ca_path;
112  		char *phase2_subject_match;
113  		GSList *phase2_altsubject_matches;
114  		GByteArray *phase2_client_cert;
115  		char *password;
116  		NMSettingSecretFlags password_flags;
117  		GByteArray *password_raw;
118  		NMSettingSecretFlags password_raw_flags;
119  		char *pin;
120  		NMSettingSecretFlags pin_flags;
121  		GByteArray *private_key;
122  		char *private_key_password;
123  		NMSettingSecretFlags private_key_password_flags;
124  		GByteArray *phase2_private_key;
125  		char *phase2_private_key_password;
126  		NMSettingSecretFlags phase2_private_key_password_flags;
127  		gboolean system_ca_certs;
128  	} NMSetting8021xPrivate;
129  	
130  	enum {
131  		PROP_0,
132  		PROP_EAP,
133  		PROP_IDENTITY,
134  		PROP_ANONYMOUS_IDENTITY,
135  		PROP_PAC_FILE,
136  		PROP_CA_CERT,
137  		PROP_CA_PATH,
138  		PROP_SUBJECT_MATCH,
139  		PROP_ALTSUBJECT_MATCHES,
140  		PROP_CLIENT_CERT,
141  		PROP_PHASE1_PEAPVER,
142  		PROP_PHASE1_PEAPLABEL,
143  		PROP_PHASE1_FAST_PROVISIONING,
144  		PROP_PHASE2_AUTH,
145  		PROP_PHASE2_AUTHEAP,
146  		PROP_PHASE2_CA_CERT,
147  		PROP_PHASE2_CA_PATH,
148  		PROP_PHASE2_SUBJECT_MATCH,
149  		PROP_PHASE2_ALTSUBJECT_MATCHES,
150  		PROP_PHASE2_CLIENT_CERT,
151  		PROP_PASSWORD,
152  		PROP_PASSWORD_FLAGS,
153  		PROP_PASSWORD_RAW,
154  		PROP_PASSWORD_RAW_FLAGS,
155  		PROP_PRIVATE_KEY,
156  		PROP_PRIVATE_KEY_PASSWORD,
157  		PROP_PRIVATE_KEY_PASSWORD_FLAGS,
158  		PROP_PHASE2_PRIVATE_KEY,
159  		PROP_PHASE2_PRIVATE_KEY_PASSWORD,
160  		PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS,
161  		PROP_PIN,
162  		PROP_PIN_FLAGS,
163  		PROP_SYSTEM_CA_CERTS,
164  	
165  		LAST_PROP
166  	};
167  	
168  	/**
169  	 * nm_setting_802_1x_new:
170  	 *
171  	 * Creates a new #NMSetting8021x object with default values.
172  	 *
173  	 * Returns: the new empty #NMSetting8021x object
174  	 **/
175  	NMSetting *
176  	nm_setting_802_1x_new (void)
177  	{
178  		return (NMSetting *) g_object_new (NM_TYPE_SETTING_802_1X, NULL);
179  	}
180  	
181  	/**
182  	 * nm_setting_802_1x_get_num_eap_methods:
183  	 * @setting: the #NMSetting8021x
184  	 *
185  	 * Returns the number of eap methods allowed for use when connecting to the
186  	 * network.  Generally only one EAP method is used.  Use the functions
187  	 * nm_setting_802_1x_get_eap_method(), nm_setting_802_1x_add_eap_method(),
188  	 * and nm_setting_802_1x_remove_eap_method() for adding, removing, and retrieving
189  	 * allowed EAP methods.
190  	 *
191  	 * Returns: the number of allowed EAP methods
192  	 **/
193  	guint32
194  	nm_setting_802_1x_get_num_eap_methods (NMSetting8021x *setting)
195  	{
196  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
197  	
198  		return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->eap);
199  	}
200  	
201  	/**
202  	 * nm_setting_802_1x_get_eap_method:
203  	 * @setting: the #NMSetting8021x
204  	 * @i: the index of the EAP method name to return
205  	 *
206  	 * Returns the name of the allowed EAP method at index @i.
207  	 *
208  	 * Returns: the name of the allowed EAP method at index @i
209  	 **/
210  	const char *
211  	nm_setting_802_1x_get_eap_method (NMSetting8021x *setting, guint32 i)
212  	{
213  		NMSetting8021xPrivate *priv;
214  	
215  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
216  	
217  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
218  		g_return_val_if_fail (i <= g_slist_length (priv->eap), NULL);
219  	
220  		return (const char *) g_slist_nth_data (priv->eap, i);
221  	}
222  	
223  	/**
224  	 * nm_setting_802_1x_add_eap_method:
225  	 * @setting: the #NMSetting8021x
226  	 * @eap: the name of the EAP method to allow for this connection
227  	 *
228  	 * Adds an allowed EAP method.  The setting is not valid until at least one
229  	 * EAP method has been added.  See #NMSetting8021x:eap property for a list of
230  	 * allowed EAP methods.
231  	 *
232  	 * Returns: TRUE if the EAP method was successfully added, FALSE if it was
233  	 *  not a valid method or if it was already allowed.
234  	 **/
235  	gboolean
236  	nm_setting_802_1x_add_eap_method (NMSetting8021x *setting, const char *eap)
237  	{
238  		NMSetting8021xPrivate *priv;
239  		GSList *iter;
240  	
241  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
242  		g_return_val_if_fail (eap != NULL, FALSE);
243  	
244  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
245  		for (iter = priv->eap; iter; iter = g_slist_next (iter)) {
246  			if (!strcmp (eap, (char *) iter->data))
247  				return FALSE;
248  		}
249  	
250  		priv->eap = g_slist_append (priv->eap, g_ascii_strdown (eap, -1));
251  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP);
252  		return TRUE;
253  	}
254  	
255  	/**
256  	 * nm_setting_802_1x_remove_eap_method:
257  	 * @setting: the #NMSetting8021x
258  	 * @i: the index of the EAP method to remove
259  	 *
260  	 * Removes the allowed EAP method at the specified index.
261  	 **/
262  	void
263  	nm_setting_802_1x_remove_eap_method (NMSetting8021x *setting, guint32 i)
264  	{
265  		NMSetting8021xPrivate *priv;
266  		GSList *elt;
267  	
268  		g_return_if_fail (NM_IS_SETTING_802_1X (setting));
269  	
270  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
271  		elt = g_slist_nth (priv->eap, i);
272  		g_return_if_fail (elt != NULL);
273  	
274  		g_free (elt->data);
275  		priv->eap = g_slist_delete_link (priv->eap, elt);
276  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP);
277  	}
278  	
279  	/**
280  	 * nm_setting_802_1x_clear_eap_methods:
281  	 * @setting: the #NMSetting8021x
282  	 *
283  	 * Clears all allowed EAP methods.
284  	 **/
285  	void
286  	nm_setting_802_1x_clear_eap_methods (NMSetting8021x *setting)
287  	{
288  		NMSetting8021xPrivate *priv;
289  	
290  		g_return_if_fail (NM_IS_SETTING_802_1X (setting));
291  	
292  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
293  		g_slist_free_full (priv->eap, g_free);
294  		priv->eap = NULL;
295  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_EAP);
296  	}
297  	
298  	/**
299  	 * nm_setting_802_1x_get_identity:
300  	 * @setting: the #NMSetting8021x
301  	 *
302  	 * Returns the identifier used by some EAP methods (like TLS) to
303  	 * authenticate the user.  Often this is a username or login name.
304  	 *
305  	 * Returns: the user identifier
306  	 **/
307  	const char *
308  	nm_setting_802_1x_get_identity (NMSetting8021x *setting)
309  	{
310  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
311  	
312  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->identity;
313  	}
314  	
315  	/**
316  	 * nm_setting_802_1x_get_anonymous_identity:
317  	 * @setting: the #NMSetting8021x
318  	 *
319  	 * Returns the anonymous identifier used by some EAP methods (like TTLS) to
320  	 * authenticate the user in the outer unencrypted "phase 1" authentication.  The
321  	 * inner "phase 2" authentication will use the #NMSetting8021x:identity in
322  	 * a secure form, if applicable for that EAP method.
323  	 *
324  	 * Returns: the anonymous identifier
325  	 **/
326  	const char *
327  	nm_setting_802_1x_get_anonymous_identity (NMSetting8021x *setting)
328  	{
329  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
330  	
331  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->anonymous_identity;
332  	}
333  	
334  	/**
335  	 * nm_setting_802_1x_get_pac_file:
336  	 * @setting: the #NMSetting8021x
337  	 *
338  	 * Returns the file containing PAC credentials used by EAP-FAST method.
339  	 *
340  	 * Returns: the PAC file
341  	 **/
342  	const char *
343  	nm_setting_802_1x_get_pac_file (NMSetting8021x *setting)
344  	{
345  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
346  	
347  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->pac_file;
348  	}
349  	
350  	/**
351  	 * nm_setting_802_1x_get_ca_path:
352  	 * @setting: the #NMSetting8021x
353  	 *
354  	 * Returns the path of the CA certificate directory if previously set.  Systems
355  	 * will often have a directory that contains multiple individual CA certificates
356  	 * which the supplicant can then add to the verification chain.  This may be
357  	 * used in addition to the #NMSetting8021x:ca-cert property to add more CA
358  	 * certificates for verifying the network to client.
359  	 *
360  	 * Returns: the CA certificate directory path
361  	 **/
362  	const char *
363  	nm_setting_802_1x_get_ca_path (NMSetting8021x *setting)
364  	{
365  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
366  	
367  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_path;
368  	}
369  	
370  	/**
371  	 * nm_setting_802_1x_get_system_ca_certs:
372  	 * @setting: the #NMSetting8021x
373  	 *
374  	 * Sets the #NMSetting8021x:system-ca-certs property. The
375  	 * #NMSetting8021x:ca-path and #NMSetting8021x:phase2-ca-path
376  	 * properties are ignored if the #NMSetting8021x:system-ca-certs property is
377  	 * TRUE, in which case a system-wide CA certificate directory specified at
378  	 * compile time (using the --system-ca-path configure option) is used in place
379  	 * of these properties. 
380  	 *
381  	 * Returns: TRUE if a system CA certificate path should be used, FALSE if not
382  	 **/
383  	gboolean
384  	nm_setting_802_1x_get_system_ca_certs (NMSetting8021x *setting)
385  	{
386  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
387  	
388  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->system_ca_certs;
389  	}
390  	
391  	static NMSetting8021xCKScheme
392  	get_cert_scheme (GByteArray *array)
393  	{
394  		if (!array || !array->len)
395  			return NM_SETTING_802_1X_CK_SCHEME_UNKNOWN;
396  	
397  		if (   (array->len > strlen (SCHEME_PATH))
398  		    && !memcmp (array->data, SCHEME_PATH, strlen (SCHEME_PATH)))
399  			return NM_SETTING_802_1X_CK_SCHEME_PATH;
400  	
401  		return NM_SETTING_802_1X_CK_SCHEME_BLOB;
402  	}
403  	
404  	/**
405  	 * nm_setting_802_1x_get_ca_cert_scheme:
406  	 * @setting: the #NMSetting8021x
407  	 *
408  	 * Returns the scheme used to store the CA certificate.  If the returned scheme
409  	 * is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use nm_setting_802_1x_get_ca_cert_blob();
410  	 * if %NM_SETTING_802_1X_CK_SCHEME_PATH, use nm_setting_802_1x_get_ca_cert_path().
411  	 *
412  	 * Returns: scheme used to store the CA certificate (blob or path)
413  	 **/
414  	NMSetting8021xCKScheme
415  	nm_setting_802_1x_get_ca_cert_scheme (NMSetting8021x *setting)
416  	{
417  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN);
418  	
419  		return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert);
420  	}
421  	
422  	/**
423  	 * nm_setting_802_1x_get_ca_cert_blob:
424  	 * @setting: the #NMSetting8021x
425  	 *
426  	 * Returns the CA certificate blob if the CA certificate is stored using the
427  	 * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme.  Not all EAP methods use a
428  	 * CA certificate (LEAP for example), and those that can take advantage of the
429  	 * CA certificate allow it to be unset.  Note that lack of a CA certificate
430  	 * reduces security by allowing man-in-the-middle attacks, because the identity
431  	 * of the network cannot be confirmed by the client.
432  	 *
433  	 * Returns: the CA certificate data
434  	 **/
435  	const GByteArray *
436  	nm_setting_802_1x_get_ca_cert_blob (NMSetting8021x *setting)
437  	{
438  		NMSetting8021xCKScheme scheme;
439  	
440  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
441  	
442  		scheme = nm_setting_802_1x_get_ca_cert_scheme (setting);
443  		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL);
444  	
445  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert;
446  	}
447  	
448  	/**
449  	 * nm_setting_802_1x_get_ca_cert_path:
450  	 * @setting: the #NMSetting8021x
451  	 *
452  	 * Returns the CA certificate path if the CA certificate is stored using the
453  	 * %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.  Not all EAP methods use a
454  	 * CA certificate (LEAP for example), and those that can take advantage of the
455  	 * CA certificate allow it to be unset.  Note that lack of a CA certificate
456  	 * reduces security by allowing man-in-the-middle attacks, because the identity
457  	 * of the network cannot be confirmed by the client.
458  	 *
459  	 * Returns: path to the CA certificate file
460  	 **/
461  	const char *
462  	nm_setting_802_1x_get_ca_cert_path (NMSetting8021x *setting)
463  	{
464  		NMSetting8021xCKScheme scheme;
465  	
466  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
467  	
468  		scheme = nm_setting_802_1x_get_ca_cert_scheme (setting);
469  		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL);
470  	
471  		return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert->data + strlen (SCHEME_PATH));
472  	}
473  	
474  	static GByteArray *
475  	path_to_scheme_value (const char *path)
476  	{
477  		GByteArray *array;
478  	
479  		g_return_val_if_fail (path != NULL, NULL);
480  	
481  		/* Add the path scheme tag to the front, then the fielname */
482  		array = g_byte_array_sized_new (strlen (path) + strlen (SCHEME_PATH) + 1);
483  		g_assert (array);
484  		g_byte_array_append (array, (const guint8 *) SCHEME_PATH, strlen (SCHEME_PATH));
485  		g_byte_array_append (array, (const guint8 *) path, strlen (path));
486  		g_byte_array_append (array, (const guint8 *) "\0", 1);
487  		return array;
488  	}
489  	
490  	/**
491  	 * nm_setting_802_1x_set_ca_cert:
492  	 * @setting: the #NMSetting8021x
493  	 * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH
494  	 *   or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the CA certificate
495  	 *   file (PEM or DER format).  The path must be UTF-8 encoded; use
496  	 *   g_filename_to_utf8() to convert if needed.  Passing %NULL with any @scheme
497  	 *   clears the CA certificate.
498  	 * @scheme: desired storage scheme for the certificate
499  	 * @out_format: on successful return, the type of the certificate added
500  	 * @error: on unsuccessful return, an error
501  	 *
502  	 * Reads a certificate from disk and sets the #NMSetting8021x:ca-cert property
503  	 * with the raw certificate data if using the %NM_SETTING_802_1X_CK_SCHEME_BLOB
504  	 * scheme, or with the path to the certificate file if using the
505  	 * %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.
506  	 *
507  	 * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful
508  	 **/
509  	gboolean
510  	nm_setting_802_1x_set_ca_cert (NMSetting8021x *setting,
511  	                               const char *cert_path,
512  	                               NMSetting8021xCKScheme scheme,
513  	                               NMSetting8021xCKFormat *out_format,
514  	                               GError **error)
515  	{
516  		NMSetting8021xPrivate *priv;
517  		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
518  		GByteArray *data;
519  	
520  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
521  	
522  		if (cert_path) {
523  			g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE);
524  			g_return_val_if_fail (   scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB
525  			                      || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
526  			                      FALSE);
527  		}
528  	
529  		if (out_format)
530  			g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE);
531  	
532  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
533  	
534  		/* Clear out any previous ca_cert blob */
535  		if (priv->ca_cert) {
536  			g_byte_array_free (priv->ca_cert, TRUE);
537  			priv->ca_cert = NULL;
538  		}
539  	
540  		if (!cert_path) {
541  			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CA_CERT);
542  			return TRUE;
543  		}
544  	
545  		data = crypto_load_and_verify_certificate (cert_path, &format, error);
546  		if (data) {
547  			/* wpa_supplicant can only use raw x509 CA certs */
548  			if (format == NM_CRYPTO_FILE_FORMAT_X509) {
549  				if (out_format)
550  					*out_format = NM_SETTING_802_1X_CK_FORMAT_X509;
551  	
552  				if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
553  					priv->ca_cert = g_byte_array_ref (data);
554  				else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
555  					priv->ca_cert = path_to_scheme_value (cert_path);
556  				else
557  					g_assert_not_reached ();
558  			} else {
559  				g_set_error (error,
560  				             NM_SETTING_802_1X_ERROR,
561  				             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
562  				             NM_SETTING_802_1X_CA_CERT);
563  			}
564  			g_byte_array_unref (data);
565  		}
566  	
567  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CA_CERT);
568  		return priv->ca_cert != NULL;
569  	}
570  	
571  	/**
572  	 * nm_setting_802_1x_get_subject_match:
573  	 * @setting: the #NMSetting8021x
574  	 *
575  	 * Returns: the #NMSetting8021x:subject-match property. This is the
576  	 * substring to be matched against the subject of the authentication
577  	 * server certificate, or %NULL no subject verification is to be
578  	 * performed.
579  	 **/
580  	const char *
581  	nm_setting_802_1x_get_subject_match (NMSetting8021x *setting)
582  	{
583  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
584  	
585  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->subject_match;
586  	}
587  	
588  	/**
589  	 * nm_setting_802_1x_get_num_altsubject_matches:
590  	 * @setting: the #NMSetting8021x
591  	 *
592  	 * Returns the number of entries in the
593  	 * #NMSetting8021x:altsubject-matches property of this setting.
594  	 *
595  	 * Returns: the number of altsubject-matches entries.
596  	 **/
597  	guint32
598  	nm_setting_802_1x_get_num_altsubject_matches (NMSetting8021x *setting)
599  	{
600  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
601  	
602  		return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->altsubject_matches);
603  	}
604  	
605  	/**
606  	 * nm_setting_802_1x_get_altsubject_match:
607  	 * @setting: the #NMSettingConnection
608  	 * @i: the zero-based index of the array of altSubjectName matches
609  	 *
610  	 * Returns the altSubjectName match at index @i.
611  	 *
612  	 * Returns: the altSubjectName match at index @i
613  	 **/
614  	const char *
615  	nm_setting_802_1x_get_altsubject_match (NMSetting8021x *setting, guint32 i)
616  	{
617  		NMSetting8021xPrivate *priv;
618  	
619  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
620  	
621  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
622  		g_return_val_if_fail (i <= g_slist_length (priv->altsubject_matches), NULL);
623  	
624  		return (const char *) g_slist_nth_data (priv->altsubject_matches, i);
625  	}
626  	
627  	/**
628  	 * nm_setting_802_1x_add_altsubject_match:
629  	 * @setting: the #NMSetting8021x
630  	 * @altsubject_match: the altSubjectName to allow for this connection
631  	 *
632  	 * Adds an allowed alternate subject name match.  Until at least one
633  	 * match is added, the altSubjectName of the remote authentication
634  	 * server is not verified.
635  	 *
636  	 * Returns: TRUE if the alternative subject name match was
637  	 *  successfully added, FALSE if it was already allowed.
638  	 **/
639  	gboolean
640  	nm_setting_802_1x_add_altsubject_match (NMSetting8021x *setting,
641  											const char *altsubject_match)
642  	{
643  		NMSetting8021xPrivate *priv;
644  		GSList *iter;
645  	
646  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
647  		g_return_val_if_fail (altsubject_match != NULL, FALSE);
648  	
649  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
650  		for (iter = priv->altsubject_matches; iter; iter = g_slist_next (iter)) {
651  			if (!strcmp (altsubject_match, (char *) iter->data))
652  				return FALSE;
653  		}
654  	
655  		priv->altsubject_matches = g_slist_append (priv->altsubject_matches, g_strdup (altsubject_match));
656  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES);
657  		return TRUE;
658  	}
659  	
660  	/**
661  	 * nm_setting_802_1x_remove_altsubject_match:
662  	 * @setting: the #NMSetting8021x
663  	 * @i: the index of the altSubjectName match to remove
664  	 *
665  	 * Removes the allowed altSubjectName at the specified index.
666  	 **/
667  	void
668  	nm_setting_802_1x_remove_altsubject_match (NMSetting8021x *setting, guint32 i)
669  	{
670  		NMSetting8021xPrivate *priv;
671  		GSList *elt;
672  	
673  		g_return_if_fail (NM_IS_SETTING_802_1X (setting));
674  	
675  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
676  		elt = g_slist_nth (priv->altsubject_matches, i);
677  		g_return_if_fail (elt != NULL);
678  	
679  		g_free (elt->data);
680  		priv->altsubject_matches = g_slist_delete_link (priv->altsubject_matches, elt);
681  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES);
682  	}
683  	
684  	/**
685  	 * nm_setting_802_1x_clear_altsubject_matches:
686  	 * @setting: the #NMSetting8021x
687  	 *
688  	 * Clears all altSubjectName matches.
689  	 **/
690  	void
691  	nm_setting_802_1x_clear_altsubject_matches (NMSetting8021x *setting)
692  	{
693  		NMSetting8021xPrivate *priv;
694  	
695  		g_return_if_fail (NM_IS_SETTING_802_1X (setting));
696  	
697  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
698  		g_slist_free_full (priv->altsubject_matches, g_free);
699  		priv->altsubject_matches = NULL;
700  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_ALTSUBJECT_MATCHES);
701  	}
702  	
703  	/**
704  	 * nm_setting_802_1x_get_client_cert_scheme:
705  	 * @setting: the #NMSetting8021x
706  	 *
707  	 * Returns the scheme used to store the client certificate.  If the returned scheme
708  	 * is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use nm_setting_802_1x_get_client_cert_blob();
709  	 * if %NM_SETTING_802_1X_CK_SCHEME_PATH, use nm_setting_802_1x_get_client_cert_path().
710  	 *
711  	 * Returns: scheme used to store the client certificate (blob or path)
712  	 **/
713  	NMSetting8021xCKScheme
714  	nm_setting_802_1x_get_client_cert_scheme (NMSetting8021x *setting)
715  	{
716  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN);
717  	
718  		return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert);
719  	}
720  	
721  	/**
722  	 * nm_setting_802_1x_get_client_cert_blob:
723  	 * @setting: the #NMSetting8021x
724  	 *
725  	 * Client certificates are used to identify the connecting client to the network
726  	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
727  	 * authentication method.
728  	 *
729  	 * Returns: the client certificate data
730  	 **/
731  	const GByteArray *
732  	nm_setting_802_1x_get_client_cert_blob (NMSetting8021x *setting)
733  	{
734  		NMSetting8021xCKScheme scheme;
735  	
736  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
737  	
738  		scheme = nm_setting_802_1x_get_client_cert_scheme (setting);
739  		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL);
740  	
741  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert;
742  	}
743  	
744  	/**
745  	 * nm_setting_802_1x_get_client_cert_path:
746  	 * @setting: the #NMSetting8021x
747  	 *
748  	 * Client certificates are used to identify the connecting client to the network
749  	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
750  	 * authentication method.
751  	 *
752  	 * Returns: path to the client certificate file
753  	 **/
754  	const char *
755  	nm_setting_802_1x_get_client_cert_path (NMSetting8021x *setting)
756  	{
757  		NMSetting8021xCKScheme scheme;
758  	
759  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
760  	
761  		scheme = nm_setting_802_1x_get_client_cert_scheme (setting);
762  		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL);
763  	
764  		return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert->data + strlen (SCHEME_PATH));
765  	}
766  	
767  	/**
768  	 * nm_setting_802_1x_set_client_cert:
769  	 * @setting: the #NMSetting8021x
770  	 * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH
771  	 *   or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the client
772  	 *   certificate file (PEM, DER, or PKCS#12 format).  The path must be UTF-8
773  	 *   encoded; use g_filename_to_utf8() to convert if needed.  Passing %NULL with
774  	 *   any @scheme clears the client certificate.
775  	 * @scheme: desired storage scheme for the certificate
776  	 * @out_format: on successful return, the type of the certificate added
777  	 * @error: on unsuccessful return, an error
778  	 *
779  	 * Reads a certificate from disk and sets the #NMSetting8021x:client-cert
780  	 * property with the raw certificate data if using the
781  	 * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate
782  	 * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.
783  	 *
784  	 * Client certificates are used to identify the connecting client to the network
785  	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
786  	 * authentication method.
787  	 *
788  	 * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful
789  	 **/
790  	gboolean
791  	nm_setting_802_1x_set_client_cert (NMSetting8021x *setting,
792  	                                   const char *cert_path,
793  	                                   NMSetting8021xCKScheme scheme,
794  	                                   NMSetting8021xCKFormat *out_format,
795  	                                   GError **error)
796  	{
797  		NMSetting8021xPrivate *priv;
798  		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
799  		GByteArray *data;
800  	
801  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
802  	
803  		if (cert_path) {
804  			g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE);
805  			g_return_val_if_fail (   scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB
806  			                      || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
807  			                      FALSE);
808  		}
809  	
810  		if (out_format)
811  			g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE);
812  	
813  		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
814  	
815  		/* Clear out any previous ca_cert blob */
816  		if (priv->client_cert) {
817  			g_byte_array_free (priv->client_cert, TRUE);
818  			priv->client_cert = NULL;
819  		}
820  	
821  		if (!cert_path) {
822  			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT);
823  			return TRUE;
824  		}
825  	
826  		data = crypto_load_and_verify_certificate (cert_path, &format, error);
827  		if (data) {
828  			gboolean valid = FALSE;
829  	
830  			switch (format) {
831  			case NM_CRYPTO_FILE_FORMAT_X509:
832  				if (out_format)
833  					*out_format = NM_SETTING_802_1X_CK_FORMAT_X509;
834  				valid = TRUE;
835  				break;
836  			case NM_CRYPTO_FILE_FORMAT_PKCS12:
837  				if (out_format)
838  					*out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12;
839  				valid = TRUE;
840  				break;
841  			default:
842  				g_set_error (error,
843  				             NM_SETTING_802_1X_ERROR,
844  				             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
845  				             NM_SETTING_802_1X_CLIENT_CERT);
846  				break;
847  			}
848  	
849  			if (valid) {
850  				if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
851  					priv->client_cert = g_byte_array_ref (data);
852  				else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
853  					priv->client_cert = path_to_scheme_value (cert_path);
854  				else
855  					g_assert_not_reached ();
856  			}
857  			g_byte_array_unref (data);
858  		}
859  	
860  		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT);
861  		return priv->client_cert != NULL;
862  	}
863  	
864  	/**
865  	 * nm_setting_802_1x_get_phase1_peapver:
866  	 * @setting: the #NMSetting8021x
867  	 *
868  	 * Returns: the "phase 1" PEAP version to be used when authenticating with
869  	 *  EAP-PEAP as contained in the #NMSetting8021x:phase1-peapver property.  Valid
870  	 *  values are %NULL (unset), "0" (PEAP version 0), and "1" (PEAP version 1).
871  	 **/
872  	const char *
873  	nm_setting_802_1x_get_phase1_peapver (NMSetting8021x *setting)
874  	{
875  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
876  	
877  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_peapver;
878  	}
879  	
880  	/**
881  	 * nm_setting_802_1x_get_phase1_peaplabel:
882  	 * @setting: the #NMSetting8021x
883  	 *
884  	 * Returns: whether the "phase 1" PEAP label is new-style or old-style, to be
885  	 *  used when authenticating with EAP-PEAP, as contained in the
886  	 *  #NMSetting8021x:phase1-peaplabel property.  Valid values are %NULL (unset),
887  	 *  "0" (use old-style label), and "1" (use new-style label).  See the
888  	 *  wpa_supplicant documentation for more details.
889  	 **/
890  	const char *
891  	nm_setting_802_1x_get_phase1_peaplabel (NMSetting8021x *setting)
892  	{
893  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
894  	
895  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_peaplabel;
896  	}
897  	
898  	/**
899  	 * nm_setting_802_1x_get_phase1_fast_provisioning:
900  	 * @setting: the #NMSetting8021x
901  	 *
902  	 * Returns: whether "phase 1" PEAP fast provisioning should be used, as specified
903  	 *  by the #NMSetting8021x:phase1-fast-provisioning property.  See the
904  	 *  wpa_supplicant documentation for more details.
905  	 **/
906  	const char *
907  	nm_setting_802_1x_get_phase1_fast_provisioning (NMSetting8021x *setting)
908  	{
909  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
910  	
911  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_fast_provisioning;
912  	}
913  	
914  	/**
915  	 * nm_setting_802_1x_get_phase2_auth:
916  	 * @setting: the #NMSetting8021x
917  	 *
918  	 * Returns: the "phase 2" non-EAP (ex MD5) allowed authentication method as
919  	 *   specified by the #NMSetting8021x:phase2-auth property.
920  	 **/
921  	const char *
922  	nm_setting_802_1x_get_phase2_auth (NMSetting8021x *setting)
923  	{
924  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
925  	
926  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_auth;
927  	}
928  	
929  	/**
930  	 * nm_setting_802_1x_get_phase2_autheap:
931  	 * @setting: the #NMSetting8021x
932  	 *
933  	 * Returns: the "phase 2" EAP-based (ex TLS) allowed authentication method as
934  	 *   specified by the #NMSetting8021x:phase2-autheap property.
935  	 **/
936  	const char *
937  	nm_setting_802_1x_get_phase2_autheap (NMSetting8021x *setting)
938  	{
939  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
940  	
941  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_autheap;
942  	}
943  	
944  	/**
945  	 * nm_setting_802_1x_get_phase2_ca_path:
946  	 * @setting: the #NMSetting8021x
947  	 *
948  	 * Returns the path of the "phase 2" CA certificate directory if previously set.
949  	 * Systems will often have a directory that contains multiple individual CA
950  	 * certificates which the supplicant can then add to the verification chain.
951  	 * This may be used in addition to the #NMSetting8021x:phase2-ca-cert property
952  	 * to add more CA certificates for verifying the network to client.
953  	 *
954  	 * Returns: the "phase 2" CA certificate directory path
955  	 **/
956  	const char *
957  	nm_setting_802_1x_get_phase2_ca_path (NMSetting8021x *setting)
958  	{
959  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
960  	
961  		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_path;
962  	}
963  	
964  	/**
965  	 * nm_setting_802_1x_get_phase2_ca_cert_scheme:
966  	 * @setting: the #NMSetting8021x
967  	 *
968  	 * Returns the scheme used to store the "phase 2" CA certificate.  If the
969  	 * returned scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use
970  	 * nm_setting_802_1x_get_ca_cert_blob(); if %NM_SETTING_802_1X_CK_SCHEME_PATH,
971  	 * use nm_setting_802_1x_get_ca_cert_path().
972  	 *
973  	 * Returns: scheme used to store the "phase 2" CA certificate (blob or path)
974  	 **/
975  	NMSetting8021xCKScheme
976  	nm_setting_802_1x_get_phase2_ca_cert_scheme (NMSetting8021x *setting)
977  	{
978  		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN);
979  	
980  		return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert);
981  	}
982  	
983  	/**
984  	 * nm_setting_802_1x_get_phase2_ca_cert_blob:
985  	 * @setting: the #NMSetting8021x
986  	 *
987  	 * Returns the "phase 2" CA certificate blob if the CA certificate is stored
988  	 * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme.  Not all EAP methods use
989  	 * a CA certificate (LEAP for example), and those that can take advantage of the
990  	 * CA certificate allow it to be unset.  Note that lack of a CA certificate
991  	 * reduces security by allowing man-in-the-middle attacks, because the identity
992  	 * of the network cannot be confirmed by the client.
993  	 *
994  	 * Returns: the "phase 2" CA certificate data
995  	 **/
996  	const GByteArray *
997  	nm_setting_802_1x_get_phase2_ca_cert_blob (NMSetting8021x *setting)
998  	{
999  		NMSetting8021xCKScheme scheme;
1000 	
1001 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1002 	
1003 		scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (setting);
1004 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL);
1005 	
1006 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert;
1007 	}
1008 	
1009 	/**
1010 	 * nm_setting_802_1x_get_phase2_ca_cert_path:
1011 	 * @setting: the #NMSetting8021x
1012 	 *
1013 	 * Returns the "phase 2" CA certificate path if the CA certificate is stored
1014 	 * using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.  Not all EAP methods use
1015 	 * a CA certificate (LEAP for example), and those that can take advantage of the
1016 	 * CA certificate allow it to be unset.  Note that lack of a CA certificate
1017 	 * reduces security by allowing man-in-the-middle attacks, because the identity
1018 	 * of the network cannot be confirmed by the client.
1019 	 *
1020 	 * Returns: path to the "phase 2" CA certificate file
1021 	 **/
1022 	const char *
1023 	nm_setting_802_1x_get_phase2_ca_cert_path (NMSetting8021x *setting)
1024 	{
1025 		NMSetting8021xCKScheme scheme;
1026 	
1027 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1028 	
1029 		scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (setting);
1030 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL);
1031 	
1032 		return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert->data + strlen (SCHEME_PATH));
1033 	}
1034 	
1035 	/**
1036 	 * nm_setting_802_1x_set_phase2_ca_cert:
1037 	 * @setting: the #NMSetting8021x
1038 	 * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH
1039 	 *   or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" CA
1040 	 *   certificate file (PEM or DER format).  The path must be UTF-8 encoded; use
1041 	 *   g_filename_to_utf8() to convert if needed.  Passing %NULL with any @scheme
1042 	 *   clears the "phase2" CA certificate.
1043 	 * @scheme: desired storage scheme for the certificate
1044 	 * @out_format: on successful return, the type of the certificate added
1045 	 * @error: on unsuccessful return, an error
1046 	 *
1047 	 * Reads a certificate from disk and sets the #NMSetting8021x:phase2-ca-cert
1048 	 * property with the raw certificate data if using the
1049 	 * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate
1050 	 * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.
1051 	 *
1052 	 * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful
1053 	 **/
1054 	gboolean
1055 	nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting,
1056 	                                      const char *cert_path,
1057 	                                      NMSetting8021xCKScheme scheme,
1058 	                                      NMSetting8021xCKFormat *out_format,
1059 	                                      GError **error)
1060 	{
1061 		NMSetting8021xPrivate *priv;
1062 		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
1063 		GByteArray *data;
1064 	
1065 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
1066 	
1067 		if (cert_path) {
1068 			g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE);
1069 			g_return_val_if_fail (   scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB
1070 			                      || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
1071 			                      FALSE);
1072 		}
1073 	
1074 		if (out_format)
1075 			g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE);
1076 	
1077 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1078 	
1079 		/* Clear out any previous ca_cert blob */
1080 		if (priv->phase2_ca_cert) {
1081 			g_byte_array_free (priv->phase2_ca_cert, TRUE);
1082 			priv->phase2_ca_cert = NULL;
1083 		}
1084 	
1085 		if (!cert_path) {
1086 			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CA_CERT);
1087 			return TRUE;
1088 		}
1089 	
1090 		data = crypto_load_and_verify_certificate (cert_path, &format, error);
1091 		if (data) {
1092 			/* wpa_supplicant can only use raw x509 CA certs */
1093 			if (format == NM_CRYPTO_FILE_FORMAT_X509) {
1094 				if (out_format)
1095 					*out_format = NM_SETTING_802_1X_CK_FORMAT_X509;
1096 	
1097 				if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
1098 					priv->phase2_ca_cert = g_byte_array_ref (data);
1099 				else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
1100 					priv->phase2_ca_cert = path_to_scheme_value (cert_path);
1101 				else
1102 					g_assert_not_reached ();
1103 			} else {
1104 				g_set_error (error,
1105 				             NM_SETTING_802_1X_ERROR,
1106 				             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
1107 				             NM_SETTING_802_1X_PHASE2_CA_CERT);
1108 			}
1109 			g_byte_array_unref (data);
1110 		}
1111 	
1112 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CA_CERT);
1113 		return priv->phase2_ca_cert != NULL;
1114 	}
1115 	
1116 	/**
1117 	 * nm_setting_802_1x_get_phase2_subject_match:
1118 	 * @setting: the #NMSetting8021x
1119 	 *
1120 	 * Returns: the #NMSetting8021x:phase2-subject-match property. This is
1121 	 * the substring to be matched against the subject of the "phase 2"
1122 	 * authentication server certificate, or %NULL no subject verification
1123 	 * is to be performed.
1124 	 **/
1125 	const char *
1126 	nm_setting_802_1x_get_phase2_subject_match (NMSetting8021x *setting)
1127 	{
1128 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1129 	
1130 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_subject_match;
1131 	}
1132 	
1133 	/**
1134 	 * nm_setting_802_1x_get_num_phase2_altsubject_matches:
1135 	 * @setting: the #NMSetting8021x
1136 	 *
1137 	 * Returns the number of entries in the
1138 	 * #NMSetting8021x:phase2-altsubject-matches property of this setting.
1139 	 *
1140 	 * Returns: the number of phase2-altsubject-matches entries.
1141 	 **/
1142 	guint32
1143 	nm_setting_802_1x_get_num_phase2_altsubject_matches (NMSetting8021x *setting)
1144 	{
1145 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0);
1146 	
1147 		return g_slist_length (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_altsubject_matches);
1148 	}
1149 	
1150 	/**
1151 	 * nm_setting_802_1x_get_phase2_altsubject_match:
1152 	 * @setting: the #NMSettingConnection
1153 	 * @i: the zero-based index of the array of "phase 2" altSubjectName matches
1154 	 *
1155 	 * Returns the "phase 2" altSubjectName match at index @i.
1156 	 *
1157 	 * Returns: the "phase 2" altSubjectName match at index @i
1158 	 **/
1159 	const char *
1160 	nm_setting_802_1x_get_phase2_altsubject_match (NMSetting8021x *setting, guint32 i)
1161 	{
1162 		NMSetting8021xPrivate *priv;
1163 	
1164 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1165 	
1166 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1167 		g_return_val_if_fail (i <= g_slist_length (priv->phase2_altsubject_matches), NULL);
1168 	
1169 		return (const char *) g_slist_nth_data (priv->phase2_altsubject_matches, i);
1170 	}
1171 	
1172 	/**
1173 	 * nm_setting_802_1x_add_phase2_altsubject_match:
1174 	 * @setting: the #NMSetting8021x
1175 	 * @phase2_altsubject_match: the "phase 2" altSubjectName to allow for this
1176 	 * connection
1177 	 *
1178 	 * Adds an allowed alternate subject name match for "phase 2".  Until
1179 	 * at least one match is added, the altSubjectName of the "phase 2"
1180 	 * remote authentication server is not verified.
1181 	 *
1182 	 * Returns: TRUE if the "phase 2" alternative subject name match was
1183 	 *  successfully added, FALSE if it was already allowed.
1184 	 **/
1185 	gboolean
1186 	nm_setting_802_1x_add_phase2_altsubject_match (NMSetting8021x *setting,
1187 												   const char *phase2_altsubject_match)
1188 	{
1189 		NMSetting8021xPrivate *priv;
1190 		GSList *iter;
1191 	
1192 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
1193 		g_return_val_if_fail (phase2_altsubject_match != NULL, FALSE);
1194 	
1195 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1196 		for (iter = priv->phase2_altsubject_matches; iter; iter = g_slist_next (iter)) {
1197 			if (!strcmp (phase2_altsubject_match, (char *) iter->data))
1198 				return FALSE;
1199 		}
1200 	
1201 		priv->phase2_altsubject_matches = g_slist_append (priv->altsubject_matches,
1202 														  g_strdup (phase2_altsubject_match));
1203 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES);
1204 		return TRUE;
1205 	}
1206 	
1207 	/**
1208 	 * nm_setting_802_1x_remove_phase2_altsubject_match:
1209 	 * @setting: the #NMSetting8021x
1210 	 * @i: the index of the "phase 2" altSubjectName match to remove
1211 	 *
1212 	 * Removes the allowed "phase 2" altSubjectName at the specified index.
1213 	 **/
1214 	void
1215 	nm_setting_802_1x_remove_phase2_altsubject_match (NMSetting8021x *setting, guint32 i)
1216 	{
1217 		NMSetting8021xPrivate *priv;
1218 		GSList *elt;
1219 	
1220 		g_return_if_fail (NM_IS_SETTING_802_1X (setting));
1221 	
1222 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1223 		elt = g_slist_nth (priv->phase2_altsubject_matches, i);
1224 		g_return_if_fail (elt != NULL);
1225 	
1226 		g_free (elt->data);
1227 		priv->phase2_altsubject_matches = g_slist_delete_link (priv->phase2_altsubject_matches, elt);
1228 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES);
1229 	}
1230 	
1231 	/**
1232 	 * nm_setting_802_1x_clear_phase2_altsubject_matches:
1233 	 * @setting: the #NMSetting8021x
1234 	 *
1235 	 * Clears all "phase 2" altSubjectName matches.
1236 	 **/
1237 	void
1238 	nm_setting_802_1x_clear_phase2_altsubject_matches (NMSetting8021x *setting)
1239 	{
1240 		NMSetting8021xPrivate *priv;
1241 	
1242 		g_return_if_fail (NM_IS_SETTING_802_1X (setting));
1243 	
1244 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1245 		g_slist_free_full (priv->phase2_altsubject_matches, g_free);
1246 		priv->phase2_altsubject_matches = NULL;
1247 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES);
1248 	}
1249 	
1250 	/**
1251 	 * nm_setting_802_1x_get_phase2_client_cert_scheme:
1252 	 * @setting: the #NMSetting8021x
1253 	 *
1254 	 * Returns the scheme used to store the "phase 2" client certificate.  If the
1255 	 * returned scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use
1256 	 * nm_setting_802_1x_get_client_cert_blob(); if
1257 	 * %NM_SETTING_802_1X_CK_SCHEME_PATH, use
1258 	 * nm_setting_802_1x_get_client_cert_path().
1259 	 *
1260 	 * Returns: scheme used to store the "phase 2" client certificate (blob or path)
1261 	 **/
1262 	NMSetting8021xCKScheme
1263 	nm_setting_802_1x_get_phase2_client_cert_scheme (NMSetting8021x *setting)
1264 	{
1265 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN);
1266 	
1267 		return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert);
1268 	}
1269 	
1270 	/**
1271 	 * nm_setting_802_1x_get_phase2_client_cert_blob:
1272 	 * @setting: the #NMSetting8021x
1273 	 *
1274 	 * Client certificates are used to identify the connecting client to the network
1275 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1276 	 * authentication method.
1277 	 *
1278 	 * Returns: the "phase 2" client certificate data
1279 	 **/
1280 	const GByteArray *
1281 	nm_setting_802_1x_get_phase2_client_cert_blob (NMSetting8021x *setting)
1282 	{
1283 		NMSetting8021xCKScheme scheme;
1284 	
1285 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1286 	
1287 		scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (setting);
1288 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL);
1289 	
1290 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert;
1291 	}
1292 	
1293 	/**
1294 	 * nm_setting_802_1x_get_phase2_client_cert_path:
1295 	 * @setting: the #NMSetting8021x
1296 	 *
1297 	 * Client certificates are used to identify the connecting client to the network
1298 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1299 	 * authentication method.
1300 	 *
1301 	 * Returns: path to the "phase 2" client certificate file
1302 	 **/
1303 	const char *
1304 	nm_setting_802_1x_get_phase2_client_cert_path (NMSetting8021x *setting)
1305 	{
1306 		NMSetting8021xCKScheme scheme;
1307 	
1308 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1309 	
1310 		scheme = nm_setting_802_1x_get_phase2_client_cert_scheme (setting);
1311 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL);
1312 	
1313 		return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert->data + strlen (SCHEME_PATH));
1314 	}
1315 	
1316 	/**
1317 	 * nm_setting_802_1x_set_phase2_client_cert:
1318 	 * @setting: the #NMSetting8021x
1319 	 * @cert_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH
1320 	 *   or %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" client
1321 	 *   certificate file (PEM, DER, or PKCS#12 format).  The path must be UTF-8
1322 	 *   encoded; use g_filename_to_utf8() to convert if needed.  Passing %NULL with
1323 	 *   any @scheme clears the "phase2" client certificate.
1324 	 * @scheme: desired storage scheme for the certificate
1325 	 * @out_format: on successful return, the type of the certificate added
1326 	 * @error: on unsuccessful return, an error
1327 	 *
1328 	 * Reads a certificate from disk and sets the #NMSetting8021x:phase2-client-cert
1329 	 * property with the raw certificate data if using the
1330 	 * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the certificate
1331 	 * file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.
1332 	 *
1333 	 * Client certificates are used to identify the connecting client to the network
1334 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1335 	 * authentication method.
1336 	 *
1337 	 * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful
1338 	 **/
1339 	gboolean
1340 	nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting,
1341 	                                          const char *cert_path,
1342 	                                          NMSetting8021xCKScheme scheme,
1343 	                                          NMSetting8021xCKFormat *out_format,
1344 	                                          GError **error)
1345 	{
1346 		NMSetting8021xPrivate *priv;
1347 		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
1348 		GByteArray *data;
1349 	
1350 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
1351 	
1352 		if (cert_path) {
1353 			g_return_val_if_fail (g_utf8_validate (cert_path, -1, NULL), FALSE);
1354 			g_return_val_if_fail (   scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB
1355 			                      || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
1356 			                      FALSE);
1357 		}
1358 	
1359 		if (out_format)
1360 			g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE);
1361 	
1362 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1363 	
1364 		/* Clear out any previous ca_cert blob */
1365 		if (priv->phase2_client_cert) {
1366 			g_byte_array_free (priv->phase2_client_cert, TRUE);
1367 			priv->phase2_client_cert = NULL;
1368 		}
1369 	
1370 		if (!cert_path) {
1371 			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
1372 			return TRUE;
1373 		}
1374 	
1375 		data = crypto_load_and_verify_certificate (cert_path, &format, error);
1376 		if (data) {
1377 			gboolean valid = FALSE;
1378 	
1379 			/* wpa_supplicant can only use raw x509 CA certs */
1380 			switch (format) {
1381 			case NM_CRYPTO_FILE_FORMAT_X509:
1382 				if (out_format)
1383 					*out_format = NM_SETTING_802_1X_CK_FORMAT_X509;
1384 				valid = TRUE;
1385 				break;
1386 			case NM_CRYPTO_FILE_FORMAT_PKCS12:
1387 				if (out_format)
1388 					*out_format = NM_SETTING_802_1X_CK_FORMAT_PKCS12;
1389 				valid = TRUE;
1390 				break;
1391 			default:
1392 				g_set_error (error,
1393 				             NM_SETTING_802_1X_ERROR,
1394 				             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
1395 				             NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
1396 				break;
1397 			}
1398 	
1399 			if (valid) {
1400 				if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
1401 					priv->phase2_client_cert = g_byte_array_ref (data);
1402 				else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
1403 					priv->phase2_client_cert = path_to_scheme_value (cert_path);
1404 				else
1405 					g_assert_not_reached ();
1406 			}
1407 			g_byte_array_unref (data);
1408 		}
1409 	
1410 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
1411 		return priv->phase2_client_cert != NULL;
1412 	}
1413 	
1414 	/**
1415 	 * nm_setting_802_1x_get_password:
1416 	 * @setting: the #NMSetting8021x
1417 	 *
1418 	 * Returns: the password used by the authentication method, if any, as specified
1419 	 *   by the #NMSetting8021x:password property
1420 	 **/
1421 	const char *
1422 	nm_setting_802_1x_get_password (NMSetting8021x *setting)
1423 	{
1424 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1425 	
1426 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->password;
1427 	}
1428 	
1429 	/**
1430 	 * nm_setting_802_1x_get_password_flags:
1431 	 * @setting: the #NMSetting8021x
1432 	 *
1433 	 * Returns: the #NMSettingSecretFlags pertaining to the #NMSetting8021x:password
1434 	 **/
1435 	NMSettingSecretFlags
1436 	nm_setting_802_1x_get_password_flags (NMSetting8021x *setting)
1437 	{
1438 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE);
1439 	
1440 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_flags;
1441 	}
1442 	
1443 	/**
1444 	 * nm_setting_802_1x_get_password_raw:
1445 	 * @setting: the #NMSetting8021x
1446 	 *
1447 	 * Returns: the password used by the authentication method as a
1448 	 * UTF-8-encoded array of bytes, as specified by the
1449 	 * #NMSetting8021x:password-raw property
1450 	 **/
1451 	const GByteArray *
1452 	nm_setting_802_1x_get_password_raw (NMSetting8021x *setting)
1453 	{
1454 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1455 	
1456 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_raw;
1457 	}
1458 	
1459 	/**
1460 	 * nm_setting_802_1x_get_password_raw_flags:
1461 	 * @setting: the #NMSetting8021x
1462 	 *
1463 	 * Returns: the #NMSettingSecretFlags pertaining to the
1464 	 *   #NMSetting8021x:password-raw
1465 	 **/
1466 	NMSettingSecretFlags
1467 	nm_setting_802_1x_get_password_raw_flags (NMSetting8021x *setting)
1468 	{
1469 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE);
1470 	
1471 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_raw_flags;
1472 	}
1473 	
1474 	/**
1475 	 * nm_setting_802_1x_get_pin:
1476 	 * @setting: the #NMSetting8021x
1477 	 *
1478 	 * Returns: the PIN used by the authentication method, if any, as specified
1479 	 *   by the #NMSetting8021x:pin property
1480 	 **/
1481 	const char *
1482 	nm_setting_802_1x_get_pin (NMSetting8021x *setting)
1483 	{
1484 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1485 	
1486 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin;
1487 	}
1488 	
1489 	/**
1490 	 * nm_setting_802_1x_get_pin_flags:
1491 	 * @setting: the #NMSetting8021x
1492 	 *
1493 	 * Returns: the #NMSettingSecretFlags pertaining to the
1494 	 * #NMSetting8021x:pin
1495 	 **/
1496 	NMSettingSecretFlags
1497 	nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting)
1498 	{
1499 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE);
1500 	
1501 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin_flags;
1502 	}
1503 	
1504 	/**
1505 	 * nm_setting_802_1x_get_private_key_scheme:
1506 	 * @setting: the #NMSetting8021x
1507 	 *
1508 	 * Returns the scheme used to store the private key.  If the returned scheme is
1509 	 * %NM_SETTING_802_1X_CK_SCHEME_BLOB, use
1510 	 * nm_setting_802_1x_get_client_cert_blob(); if
1511 	 * %NM_SETTING_802_1X_CK_SCHEME_PATH, use
1512 	 * nm_setting_802_1x_get_client_cert_path().
1513 	 *
1514 	 * Returns: scheme used to store the private key (blob or path)
1515 	 **/
1516 	NMSetting8021xCKScheme
1517 	nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting)
1518 	{
1519 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN);
1520 	
1521 		return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key);
1522 	}
1523 	
1524 	/**
1525 	 * nm_setting_802_1x_get_private_key_blob:
1526 	 * @setting: the #NMSetting8021x
1527 	 *
1528 	 * Private keys are used to authenticate the connecting client to the network
1529 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1530 	 * authentication method.
1531 	 *
1532 	 * WARNING: the private key property is not a "secret" property, and thus
1533 	 * unencrypted private key data may be readable by unprivileged users.  Private
1534 	 * keys should always be encrypted with a private key password.
1535 	 *
1536 	 * Returns: the private key data
1537 	 **/
1538 	const GByteArray *
1539 	nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting)
1540 	{
1541 		NMSetting8021xCKScheme scheme;
1542 	
1543 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1544 	
1545 		scheme = nm_setting_802_1x_get_private_key_scheme (setting);
1546 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL);
1547 	
1548 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key;
1549 	}
1550 	
1551 	/**
1552 	 * nm_setting_802_1x_get_private_key_path:
1553 	 * @setting: the #NMSetting8021x
1554 	 *
1555 	 * Private keys are used to authenticate the connecting client to the network
1556 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1557 	 * authentication method.
1558 	 *
1559 	 * Returns: path to the private key file
1560 	 **/
1561 	const char *
1562 	nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting)
1563 	{
1564 		NMSetting8021xCKScheme scheme;
1565 	
1566 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1567 	
1568 		scheme = nm_setting_802_1x_get_private_key_scheme (setting);
1569 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL);
1570 	
1571 		return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key->data + strlen (SCHEME_PATH));
1572 	}
1573 	
1574 	static GByteArray *
1575 	file_to_byte_array (const char *filename)
1576 	{
1577 		char *contents;
1578 		GByteArray *array = NULL;
1579 		gsize length = 0;
1580 	
1581 		if (g_file_get_contents (filename, &contents, &length, NULL)) {
1582 			array = g_byte_array_sized_new (length);
1583 			g_byte_array_append (array, (guint8 *) contents, length);
1584 			g_assert (array->len == length);
1585 			g_free (contents);
1586 		}
1587 		return array;
1588 	}
1589 	
1590 	/**
1591 	 * nm_setting_802_1x_set_private_key:
1592 	 * @setting: the #NMSetting8021x
1593 	 * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or
1594 	 *   %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the private key file
1595 	 *   (PEM, DER, or PKCS#12 format).  The path must be UTF-8 encoded; use
1596 	 *   g_filename_to_utf8() to convert if needed.  Passing %NULL with any @scheme
1597 	 *   clears the private key.
1598 	 * @password: password used to decrypt the private key, or %NULL if the password
1599 	 *   is unknown.  If the password is given but fails to decrypt the private key,
1600 	 *   an error is returned.
1601 	 * @scheme: desired storage scheme for the private key
1602 	 * @out_format: on successful return, the type of the private key added
1603 	 * @error: on unsuccessful return, an error
1604 	 *
1605 	 * Private keys are used to authenticate the connecting client to the network
1606 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1607 	 * authentication method.
1608 	 *
1609 	 * This function reads a private key from disk and sets the
1610 	 * #NMSetting8021x:private-key property with the private key file data if using
1611 	 * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the private
1612 	 * key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.
1613 	 *
1614 	 * If @password is given, this function attempts to decrypt the private key to
1615 	 * verify that @password is correct, and if it is, updates the
1616 	 * #NMSetting8021x:private-key-password property with the given @password.  If
1617 	 * the decryption is unsuccessful, %FALSE is returned, @error is set, and no
1618 	 * internal data is changed.  If no @password is given, the private key is
1619 	 * assumed to be valid, no decryption is performed, and the password may be set
1620 	 * at a later time.
1621 	 *
1622 	 * WARNING: the private key property is not a "secret" property, and thus
1623 	 * unencrypted private key data using the BLOB scheme may be readable by
1624 	 * unprivileged users.  Private keys should always be encrypted with a private
1625 	 * key password to prevent unauthorized access to unencrypted private key data.
1626 	 *
1627 	 * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful
1628 	 **/
1629 	gboolean
1630 	nm_setting_802_1x_set_private_key (NMSetting8021x *setting,
1631 	                                   const char *key_path,
1632 	                                   const char *password,
1633 	                                   NMSetting8021xCKScheme scheme,
1634 	                                   NMSetting8021xCKFormat *out_format,
1635 	                                   GError **error)
1636 	{
1637 		NMSetting8021xPrivate *priv;
1638 		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
1639 		gboolean key_cleared = FALSE, password_cleared = FALSE;
1640 	
1641 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
1642 	
1643 		if (key_path) {
1644 			g_return_val_if_fail (g_utf8_validate (key_path, -1, NULL), FALSE);
1645 			g_return_val_if_fail (   scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB
1646 			                      || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
1647 			                      FALSE);
1648 		}
1649 	
1650 		if (out_format)
1651 			g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE);
1652 	
1653 		/* Ensure the private key is a recognized format and if the password was
1654 		 * given, that it decrypts the private key.
1655 		 */
1656 		if (key_path) {
1657 			format = crypto_verify_private_key (key_path, password, NULL);
1658 			if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) {
1659 				g_set_error (error,
1660 					         NM_SETTING_802_1X_ERROR,
1661 					         NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
1662 					         NM_SETTING_802_1X_PRIVATE_KEY);
1663 				return FALSE;
1664 			}
1665 		}
1666 	
1667 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1668 	
1669 		/* Clear out any previous private key data */
1670 		if (priv->private_key) {
1671 			/* Try not to leave the private key around in memory */
1672 			memset (priv->private_key->data, 0, priv->private_key->len);
1673 			g_byte_array_free (priv->private_key, TRUE);
1674 			priv->private_key = NULL;
1675 			key_cleared = TRUE;
1676 		}
1677 	
1678 		if (priv->private_key_password) {
1679 			g_free (priv->private_key_password);
1680 			priv->private_key_password = NULL;
1681 			password_cleared = TRUE;
1682 		}
1683 	
1684 		if (key_path == NULL) {
1685 			if (key_cleared)
1686 				g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY);
1687 			if (password_cleared)
1688 				g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
1689 			return TRUE;
1690 		}
1691 	
1692 		priv->private_key_password = g_strdup (password);
1693 		if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
1694 			/* Shouldn't fail this since we just verified the private key above */
1695 			priv->private_key = file_to_byte_array (key_path);
1696 			g_assert (priv->private_key);
1697 		} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
1698 			priv->private_key = path_to_scheme_value (key_path);
1699 		else
1700 			g_assert_not_reached ();
1701 	
1702 		/* As required by NM and wpa_supplicant, set the client-cert
1703 		 * property to the same PKCS#12 data.
1704 		 */
1705 		g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN);
1706 		if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) {
1707 			if (priv->client_cert)
1708 				g_byte_array_free (priv->client_cert, TRUE);
1709 	
1710 			priv->client_cert = g_byte_array_sized_new (priv->private_key->len);
1711 			g_byte_array_append (priv->client_cert, priv->private_key->data, priv->private_key->len);
1712 			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_CLIENT_CERT);
1713 		}
1714 	
1715 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY);
1716 		if (password_cleared || password)
1717 			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
1718 	
1719 		if (out_format)
1720 			*out_format = format;
1721 		return priv->private_key != NULL;
1722 	}
1723 	
1724 	/**
1725 	 * nm_setting_802_1x_get_private_key_password:
1726 	 * @setting: the #NMSetting8021x
1727 	 *
1728 	 * Returns: the private key password used to decrypt the private key if
1729 	 *  previously set with nm_setting_802_1x_set_private_key(), or the
1730 	 *  #NMSetting8021x:private-key-password property.
1731 	 **/
1732 	const char *
1733 	nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting)
1734 	{
1735 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1736 	
1737 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password;
1738 	}
1739 	
1740 	/**
1741 	 * nm_setting_802_1x_get_private_key_password_flags:
1742 	 * @setting: the #NMSetting8021x
1743 	 *
1744 	 * Returns: the #NMSettingSecretFlags pertaining to the
1745 	 * #NMSetting8021x:private-key-password
1746 	 **/
1747 	NMSettingSecretFlags
1748 	nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting)
1749 	{
1750 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE);
1751 	
1752 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password_flags;
1753 	}
1754 	
1755 	/**
1756 	 * nm_setting_802_1x_get_private_key_format:
1757 	 * @setting: the #NMSetting8021x
1758 	 *
1759 	 * Returns: the data format of the private key data stored in the
1760 	 *   #NMSetting8021x:private-key property
1761 	 **/
1762 	NMSetting8021xCKFormat
1763 	nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting)
1764 	{
1765 		NMSetting8021xPrivate *priv;
1766 		const char *path;
1767 		GError *error = NULL;
1768 	
1769 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_FORMAT_UNKNOWN);
1770 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1771 	
1772 		if (!priv->private_key)
1773 			return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
1774 	
1775 		switch (nm_setting_802_1x_get_private_key_scheme (setting)) {
1776 		case NM_SETTING_802_1X_CK_SCHEME_BLOB:
1777 			if (crypto_is_pkcs12_data (priv->private_key))
1778 				return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
1779 			return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
1780 		case NM_SETTING_802_1X_CK_SCHEME_PATH:
1781 			path = nm_setting_802_1x_get_private_key_path (setting);
1782 			if (crypto_is_pkcs12_file (path, &error))
1783 				return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
1784 			if (error) {
1785 				/* Couldn't read the file or something */
1786 				g_error_free (error);
1787 				return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
1788 			}
1789 			return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
1790 		default:
1791 			break;
1792 		}
1793 	
1794 		return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
1795 	}
1796 	
1797 	/**
1798 	 * nm_setting_802_1x_get_phase2_private_key_password:
1799 	 * @setting: the #NMSetting8021x
1800 	 *
1801 	 * Returns: the private key password used to decrypt the private key if
1802 	 *  previously set with nm_setting_802_1x_set_phase2_private_key() or the
1803 	 *  #NMSetting8021x:phase2-private-key-password property.
1804 	 **/
1805 	const char *
1806 	nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting)
1807 	{
1808 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1809 	
1810 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password;
1811 	}
1812 	
1813 	/**
1814 	 * nm_setting_802_1x_get_phase2_private_key_password_flags:
1815 	 * @setting: the #NMSetting8021x
1816 	 *
1817 	 * Returns: the #NMSettingSecretFlags pertaining to the
1818 	 * #NMSetting8021x:phase2-private-key-password
1819 	 **/
1820 	NMSettingSecretFlags
1821 	nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting)
1822 	{
1823 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE);
1824 	
1825 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password_flags;
1826 	}
1827 	
1828 	/**
1829 	 * nm_setting_802_1x_get_phase2_private_key_scheme:
1830 	 * @setting: the #NMSetting8021x
1831 	 *
1832 	 * Returns the scheme used to store the "phase 2" private key.  If the returned
1833 	 * scheme is %NM_SETTING_802_1X_CK_SCHEME_BLOB, use
1834 	 * nm_setting_802_1x_get_client_cert_blob(); if
1835 	 * %NM_SETTING_802_1X_CK_SCHEME_PATH, use
1836 	 * nm_setting_802_1x_get_client_cert_path().
1837 	 *
1838 	 * Returns: scheme used to store the "phase 2" private key (blob or path)
1839 	 **/
1840 	NMSetting8021xCKScheme
1841 	nm_setting_802_1x_get_phase2_private_key_scheme (NMSetting8021x *setting)
1842 	{
1843 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_SCHEME_UNKNOWN);
1844 	
1845 		return get_cert_scheme (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key);
1846 	}
1847 	
1848 	/**
1849 	 * nm_setting_802_1x_get_phase2_private_key_blob:
1850 	 * @setting: the #NMSetting8021x
1851 	 *
1852 	 * Private keys are used to authenticate the connecting client to the network
1853 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1854 	 * authentication method.
1855 	 *
1856 	 * WARNING: the phase2 private key property is not a "secret" property, and thus
1857 	 * unencrypted private key data may be readable by unprivileged users.  Private
1858 	 * keys should always be encrypted with a private key password.
1859 	 *
1860 	 * Returns: the "phase 2" private key data
1861 	 **/
1862 	const GByteArray *
1863 	nm_setting_802_1x_get_phase2_private_key_blob (NMSetting8021x *setting)
1864 	{
1865 		NMSetting8021xCKScheme scheme;
1866 	
1867 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1868 	
1869 		scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting);
1870 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB, NULL);
1871 	
1872 		return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key;
1873 	}
1874 	
1875 	/**
1876 	 * nm_setting_802_1x_get_phase2_private_key_path:
1877 	 * @setting: the #NMSetting8021x
1878 	 *
1879 	 * Private keys are used to authenticate the connecting client to the network
1880 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1881 	 * authentication method.
1882 	 *
1883 	 * Returns: path to the "phase 2" private key file
1884 	 **/
1885 	const char *
1886 	nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting)
1887 	{
1888 		NMSetting8021xCKScheme scheme;
1889 	
1890 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
1891 	
1892 		scheme = nm_setting_802_1x_get_phase2_private_key_scheme (setting);
1893 		g_return_val_if_fail (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH, NULL);
1894 	
1895 		return (const char *) (NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key->data + strlen (SCHEME_PATH));
1896 	}
1897 	
1898 	/**
1899 	 * nm_setting_802_1x_set_phase2_private_key:
1900 	 * @setting: the #NMSetting8021x
1901 	 * @key_path: when @scheme is set to either %NM_SETTING_802_1X_CK_SCHEME_PATH or
1902 	 *   %NM_SETTING_802_1X_CK_SCHEME_BLOB, pass the path of the "phase2" private
1903 	 *   key file (PEM, DER, or PKCS#12 format).  The path must be UTF-8 encoded;
1904 	 *   use g_filename_to_utf8() to convert if needed.  Passing %NULL with any
1905 	 *   @scheme clears the private key.
1906 	 * @password: password used to decrypt the private key, or %NULL if the password
1907 	 *   is unknown.  If the password is given but fails to decrypt the private key,
1908 	 *   an error is returned.
1909 	 * @scheme: desired storage scheme for the private key
1910 	 * @out_format: on successful return, the type of the private key added
1911 	 * @error: on unsuccessful return, an error
1912 	 *
1913 	 * Private keys are used to authenticate the connecting client to the network
1914 	 * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x
1915 	 * authentication method.
1916 	 *
1917 	 * This function reads a private key from disk and sets the
1918 	 * #NMSetting8021x:phase2-private-key property with the private key file data if
1919 	 * using the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme, or with the path to the
1920 	 * private key file if using the %NM_SETTING_802_1X_CK_SCHEME_PATH scheme.
1921 	 *
1922 	 * If @password is given, this function attempts to decrypt the private key to
1923 	 * verify that @password is correct, and if it is, updates the
1924 	 * #NMSetting8021x:phase2-private-key-password property with the given
1925 	 * @password.  If the decryption is unsuccessful, %FALSE is returned, @error is
1926 	 * set, and no internal data is changed.  If no @password is given, the private
1927 	 * key is assumed to be valid, no decryption is performed, and the password may
1928 	 * be set at a later time.
1929 	 *
1930 	 * WARNING: the "phase2" private key property is not a "secret" property, and
1931 	 * thus unencrypted private key data using the BLOB scheme may be readable by
1932 	 * unprivileged users.  Private keys should always be encrypted with a private
1933 	 * key password to prevent unauthorized access to unencrypted private key data.
1934 	 *
1935 	 * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful
1936 	 **/
1937 	gboolean
1938 	nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting,
1939 	                                          const char *key_path,
1940 	                                          const char *password,
1941 	                                          NMSetting8021xCKScheme scheme,
1942 	                                          NMSetting8021xCKFormat *out_format,
1943 	                                          GError **error)
1944 	{
1945 		NMSetting8021xPrivate *priv;
1946 		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
1947 		gboolean key_cleared = FALSE, password_cleared = FALSE;
1948 	
1949 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), FALSE);
1950 	
1951 		if (key_path) {
1952 			g_return_val_if_fail (g_utf8_validate (key_path, -1, NULL), FALSE);
1953 			g_return_val_if_fail (   scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB
1954 			                      || scheme == NM_SETTING_802_1X_CK_SCHEME_PATH,
1955 			                      FALSE);
1956 		}
1957 	
1958 		if (out_format)
1959 			g_return_val_if_fail (*out_format == NM_SETTING_802_1X_CK_FORMAT_UNKNOWN, FALSE);
1960 	
1961 		/* Ensure the private key is a recognized format and if the password was
1962 		 * given, that it decrypts the private key.
1963 		 */
1964 		if (key_path) {
1965 			format = crypto_verify_private_key (key_path, password, NULL);
1966 			if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) {
1967 				g_set_error (error,
1968 					         NM_SETTING_802_1X_ERROR,
1969 					         NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
1970 					         NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
1971 				return FALSE;
1972 			}
1973 		}
1974 	
1975 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
1976 	
1977 		/* Clear out any previous private key data */
1978 		if (priv->phase2_private_key) {
1979 			/* Try not to leave the private key around in memory */
1980 			memset (priv->phase2_private_key->data, 0, priv->phase2_private_key->len);
1981 			g_byte_array_free (priv->phase2_private_key, TRUE);
1982 			priv->phase2_private_key = NULL;
1983 			key_cleared = TRUE;
1984 		}
1985 	
1986 		if (priv->phase2_private_key_password) {
1987 			g_free (priv->phase2_private_key_password);
1988 			priv->phase2_private_key_password = NULL;
1989 			password_cleared = TRUE;
1990 		}
1991 	
1992 		if (key_path == NULL) {
1993 			if (key_cleared)
1994 				g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
1995 			if (password_cleared)
1996 				g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
1997 			return TRUE;
1998 		}
1999 	
2000 		priv->phase2_private_key_password = g_strdup (password);
2001 		if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
2002 			/* Shouldn't fail this since we just verified the private key above */
2003 			priv->phase2_private_key = file_to_byte_array (key_path);
2004 			g_assert (priv->phase2_private_key);
2005 		} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
2006 			priv->phase2_private_key = path_to_scheme_value (key_path);
2007 		else
2008 			g_assert_not_reached ();
2009 	
2010 		/* As required by NM and wpa_supplicant, set the client-cert
2011 		 * property to the same PKCS#12 data.
2012 		 */
2013 		g_assert (format != NM_CRYPTO_FILE_FORMAT_UNKNOWN);
2014 		if (format == NM_CRYPTO_FILE_FORMAT_PKCS12) {
2015 			if (priv->phase2_client_cert)
2016 				g_byte_array_free (priv->phase2_client_cert, TRUE);
2017 	
2018 			priv->phase2_client_cert = g_byte_array_sized_new (priv->phase2_private_key->len);
2019 			g_byte_array_append (priv->phase2_client_cert, priv->phase2_private_key->data, priv->phase2_private_key->len);
2020 			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
2021 		}
2022 	
2023 		g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
2024 		if (password_cleared || password)
2025 			g_object_notify (G_OBJECT (setting), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
2026 	
2027 		if (out_format)
2028 			*out_format = format;
2029 		return priv->phase2_private_key != NULL;
2030 	}
2031 	
2032 	/**
2033 	 * nm_setting_802_1x_get_phase2_private_key_format:
2034 	 * @setting: the #NMSetting8021x
2035 	 *
2036 	 * Returns: the data format of the "phase 2" private key data stored in the
2037 	 *   #NMSetting8021x:phase2-private-key property
2038 	 **/
2039 	NMSetting8021xCKFormat
2040 	nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting)
2041 	{
2042 		NMSetting8021xPrivate *priv;
2043 		const char *path;
2044 		GError *error = NULL;
2045 	
2046 		g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_802_1X_CK_FORMAT_UNKNOWN);
2047 		priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
2048 	
2049 		if (!priv->phase2_private_key)
2050 			return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
2051 	
2052 		switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) {
2053 		case NM_SETTING_802_1X_CK_SCHEME_BLOB:
2054 			if (crypto_is_pkcs12_data (priv->phase2_private_key))
2055 				return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
2056 			return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
2057 		case NM_SETTING_802_1X_CK_SCHEME_PATH:
2058 			path = nm_setting_802_1x_get_phase2_private_key_path (setting);
2059 			if (crypto_is_pkcs12_file (path, &error))
2060 				return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
2061 			if (error) {
2062 				/* Couldn't read the file or something */
2063 				g_error_free (error);
2064 				return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
2065 			}
2066 			return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
2067 		default:
2068 			break;
2069 		}
2070 	
2071 		return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
2072 	}
2073 	
2074 	static void
2075 	need_secrets_password (NMSetting8021x *self,
2076 	                       GPtrArray *secrets,
2077 	                       gboolean phase2)
2078 	{
2079 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2080 	
2081 		if (   (!priv->password || !strlen (priv->password))
2082 		    && (!priv->password_raw || !priv->password_raw->len)) {
2083 			g_ptr_array_add (secrets, NM_SETTING_802_1X_PASSWORD);
2084 			g_ptr_array_add (secrets, NM_SETTING_802_1X_PASSWORD_RAW);
2085 		}
2086 	}
2087 	
2088 	static void
2089 	need_secrets_sim (NMSetting8021x *self,
2090 	                  GPtrArray *secrets,
2091 	                  gboolean phase2)
2092 	{
2093 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2094 	
2095 		if (!priv->pin || !strlen (priv->pin))
2096 			g_ptr_array_add (secrets, NM_SETTING_802_1X_PIN);
2097 	}
2098 	
2099 	static gboolean
2100 	need_private_key_password (const GByteArray *blob,
2101 	                           const char *path,
2102 	                           const char *password)
2103 	{
2104 		NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
2105 	
2106 		/* Private key password is required */
2107 		if (password) {
2108 			if (path)
2109 				format = crypto_verify_private_key (path, password, NULL);
2110 			else if (blob)
2111 				format = crypto_verify_private_key_data (blob, password, NULL);
2112 			else
2113 				g_warning ("%s: unknown private key password scheme", __func__);
2114 		}
2115 	
2116 		return (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN);
2117 	}
2118 	
2119 	static void
2120 	need_secrets_tls (NMSetting8021x *self,
2121 	                  GPtrArray *secrets,
2122 	                  gboolean phase2)
2123 	{
2124 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2125 		NMSetting8021xCKScheme scheme;
2126 		const GByteArray *blob = NULL;
2127 		const char *path = NULL;
2128 	
2129 		if (phase2) {
2130 			scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self);
2131 			if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
2132 				path = nm_setting_802_1x_get_phase2_private_key_path (self);
2133 			else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
2134 				blob = nm_setting_802_1x_get_phase2_private_key_blob (self);
2135 			else {
2136 				g_warning ("%s: unknown phase2 private key scheme %d", __func__, scheme);
2137 				g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
2138 				return;
2139 			}
2140 	
2141 			if (need_private_key_password (blob, path, priv->phase2_private_key_password))
2142 				g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
2143 		} else {
2144 			scheme = nm_setting_802_1x_get_private_key_scheme (self);
2145 			if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
2146 				path = nm_setting_802_1x_get_private_key_path (self);
2147 			else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
2148 				blob = nm_setting_802_1x_get_private_key_blob (self);
2149 			else {
2150 				g_warning ("%s: unknown private key scheme %d", __func__, scheme);
2151 				g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY);
2152 				return;
2153 			}
2154 	
2155 			if (need_private_key_password (blob, path, priv->private_key_password))
2156 				g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
2157 		}
2158 	}
2159 	
2160 	static gboolean
2161 	verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
2162 	{
2163 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2164 	
2165 		if (phase2) {
2166 			if (!priv->phase2_client_cert) {
2167 				g_set_error_literal (error,
2168 				                     NM_SETTING_802_1X_ERROR,
2169 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2170 				                     _("property is missing"));
2171 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
2172 				return FALSE;
2173 			} else if (!priv->phase2_client_cert->len) {
2174 				g_set_error_literal (error,
2175 				                     NM_SETTING_802_1X_ERROR,
2176 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2177 				                     _("property is empty"));
2178 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
2179 				return FALSE;
2180 			}
2181 	
2182 			/* Private key is required for TLS */
2183 			if (!priv->phase2_private_key) {
2184 				g_set_error_literal (error,
2185 				                     NM_SETTING_802_1X_ERROR,
2186 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2187 				                     _("property is missing"));
2188 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
2189 				return FALSE;
2190 			} else if (!priv->phase2_private_key->len) {
2191 				g_set_error_literal (error,
2192 				                     NM_SETTING_802_1X_ERROR,
2193 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2194 				                     _("property is empty"));
2195 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
2196 				return FALSE;
2197 			}
2198 	
2199 			/* If the private key is PKCS#12, check that it matches the client cert */
2200 			if (crypto_is_pkcs12_data (priv->phase2_private_key)) {
2201 				if (priv->phase2_private_key->len != priv->phase2_client_cert->len) {
2202 					g_set_error (error,
2203 					             NM_SETTING_802_1X_ERROR,
2204 					             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2205 					             _("has to match '%s' property for PKCS#12"),
2206 					             NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
2207 					g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
2208 					return FALSE;
2209 				}
2210 	
2211 				if (memcmp (priv->phase2_private_key->data,
2212 				            priv->phase2_client_cert->data,
2213 				            priv->phase2_private_key->len)) {
2214 					g_set_error (error,
2215 					             NM_SETTING_802_1X_ERROR,
2216 					             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2217 					             _("has to match '%s' property for PKCS#12"),
2218 					             NM_SETTING_802_1X_PHASE2_PRIVATE_KEY);
2219 					g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_CLIENT_CERT);
2220 					return FALSE;
2221 				}
2222 			}
2223 		} else {
2224 			if (!priv->client_cert) {
2225 				g_set_error_literal (error,
2226 				                     NM_SETTING_802_1X_ERROR,
2227 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2228 				                     _("property is missing"));
2229 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT);
2230 				return FALSE;
2231 			} else if (!priv->client_cert->len) {
2232 				g_set_error_literal (error,
2233 				                     NM_SETTING_802_1X_ERROR,
2234 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2235 				                     _("property is empty"));
2236 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT);
2237 				return FALSE;
2238 			}
2239 	
2240 			/* Private key is required for TLS */
2241 			if (!priv->private_key) {
2242 				g_set_error_literal (error,
2243 				                     NM_SETTING_802_1X_ERROR,
2244 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2245 				                     _("property is missing"));
2246 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY);
2247 				return FALSE;
2248 			} else if (!priv->private_key->len) {
2249 				g_set_error_literal (error,
2250 				                     NM_SETTING_802_1X_ERROR,
2251 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2252 				                     _("property is empty"));
2253 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PRIVATE_KEY);
2254 				return FALSE;
2255 			}
2256 	
2257 			/* If the private key is PKCS#12, check that it matches the client cert */
2258 			if (crypto_is_pkcs12_data (priv->private_key)) {
2259 				if (priv->private_key->len != priv->client_cert->len) {
2260 					g_set_error (error,
2261 					             NM_SETTING_802_1X_ERROR,
2262 					             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2263 					             _("has to match '%s' property for PKCS#12"),
2264 					             NM_SETTING_802_1X_PRIVATE_KEY);
2265 					g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT);
2266 					return FALSE;
2267 				}
2268 	
2269 				if (memcmp (priv->private_key->data,
2270 				            priv->client_cert->data,
2271 				            priv->private_key->len)) {
2272 					g_set_error (error,
2273 					             NM_SETTING_802_1X_ERROR,
2274 					             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2275 					             _("has to match '%s' property for PKCS#12"),
2276 					             NM_SETTING_802_1X_PRIVATE_KEY);
2277 					g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_CLIENT_CERT);
2278 					return FALSE;
2279 				}
2280 			}
2281 		}
2282 	
2283 		return TRUE;
2284 	}
2285 	
2286 	static gboolean
2287 	verify_ttls (NMSetting8021x *self, gboolean phase2, GError **error)
2288 	{
2289 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2290 	
2291 		if (   (!priv->identity || !strlen (priv->identity))
2292 		    && (!priv->anonymous_identity || !strlen (priv->anonymous_identity))) {
2293 			if (!priv->identity) {
2294 				g_set_error_literal (error,
2295 				                     NM_SETTING_802_1X_ERROR,
2296 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2297 				                     _("property is missing"));
2298 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
2299 			} else if (!strlen (priv->identity)) {
2300 				g_set_error_literal (error,
2301 				                     NM_SETTING_802_1X_ERROR,
2302 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2303 				                     _("property is empty"));
2304 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
2305 			} else if (!priv->anonymous_identity) {
2306 				g_set_error_literal (error,
2307 				                     NM_SETTING_802_1X_ERROR,
2308 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2309 				                     _("property is missing"));
2310 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY);
2311 			} else {
2312 				g_set_error_literal (error,
2313 				                     NM_SETTING_802_1X_ERROR,
2314 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2315 				                     _("property is empty"));
2316 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY);
2317 			}
2318 			return FALSE;
2319 		}
2320 	
2321 		if (   (!priv->phase2_auth || !strlen (priv->phase2_auth))
2322 		    && (!priv->phase2_autheap || !strlen (priv->phase2_autheap))) {
2323 			if (!priv->phase2_auth) {
2324 				g_set_error_literal (error,
2325 				                     NM_SETTING_802_1X_ERROR,
2326 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2327 				                     _("property is missing"));
2328 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
2329 			} else if (!strlen (priv->phase2_auth)) {
2330 				g_set_error_literal (error,
2331 				                     NM_SETTING_802_1X_ERROR,
2332 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2333 				                     _("property is empty"));
2334 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
2335 			} else if (!priv->phase2_autheap) {
2336 				g_set_error_literal (error,
2337 				                     NM_SETTING_802_1X_ERROR,
2338 				                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2339 				                     _("property is missing"));
2340 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
2341 			} else {
2342 				g_set_error_literal (error,
2343 				                     NM_SETTING_802_1X_ERROR,
2344 				                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2345 				                     _("property is empty"));
2346 				g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
2347 			}
2348 			return FALSE;
2349 		}
2350 	
2351 		return TRUE;
2352 	}
2353 	
2354 	static gboolean
2355 	verify_identity (NMSetting8021x *self, gboolean phase2, GError **error)
2356 	{
2357 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2358 	
2359 		if (!priv->identity) {
2360 			g_set_error_literal (error,
2361 			                     NM_SETTING_802_1X_ERROR,
2362 			                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2363 			                     _("property is missing"));
2364 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
2365 		} else if (!strlen (priv->identity)) {
2366 			g_set_error_literal (error,
2367 			                     NM_SETTING_802_1X_ERROR,
2368 			                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2369 			                     _("property is empty"));
2370 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
2371 		}
2372 	
2373 		return TRUE;
2374 	}
2375 	
2376 	/* Implemented below... */
2377 	static void need_secrets_phase2 (NMSetting8021x *self,
2378 	                                 GPtrArray *secrets,
2379 	                                 gboolean phase2);
2380 	
2381 	
2382 	typedef void (*EAPMethodNeedSecretsFunc) (NMSetting8021x *self,
2383 	                                          GPtrArray *secrets,
2384 	                                          gboolean phase2);
2385 	
2386 	typedef gboolean (*EAPMethodValidateFunc)(NMSetting8021x *self,
2387 	                                          gboolean phase2,
2388 	                                          GError **error);
2389 	
2390 	typedef struct {
2391 		const char *method;
2392 		EAPMethodNeedSecretsFunc ns_func;
2393 		EAPMethodValidateFunc v_func;
2394 	} EAPMethodsTable;
2395 	
2396 	static EAPMethodsTable eap_methods_table[] = {
2397 		{ "leap", need_secrets_password, verify_identity },
2398 		{ "pwd", need_secrets_password, verify_identity },
2399 		{ "md5", need_secrets_password, verify_identity },
2400 		{ "pap", need_secrets_password, verify_identity },
2401 		{ "chap", need_secrets_password, verify_identity },
2402 		{ "mschap", need_secrets_password, verify_identity },
2403 		{ "mschapv2", need_secrets_password, verify_identity },
2404 		{ "fast", need_secrets_password, verify_identity },
2405 		{ "tls", need_secrets_tls, verify_tls },
2406 		{ "peap", need_secrets_phase2, verify_ttls },
2407 		{ "ttls", need_secrets_phase2, verify_ttls },
2408 		{ "sim", need_secrets_sim, NULL },
2409 		{ "gtc", need_secrets_password, verify_identity },
2410 		{ "otp", NULL, NULL },  // FIXME: implement
2411 		{ NULL, NULL, NULL }
2412 	};
2413 	
2414 	static void
2415 	need_secrets_phase2 (NMSetting8021x *self,
2416 	                     GPtrArray *secrets,
2417 	                     gboolean phase2)
2418 	{
2419 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2420 		char *method = NULL;
2421 		int i;
2422 	
2423 		g_return_if_fail (phase2 == FALSE);
2424 	
2425 		/* Check phase2_auth and phase2_autheap */
2426 		method = priv->phase2_auth;
2427 		if (!method && priv->phase2_autheap)
2428 			method = priv->phase2_autheap;
2429 	
2430 		if (!method) {
2431 			g_warning ("Couldn't find EAP method.");
2432 			g_assert_not_reached();
2433 			return;
2434 		}
2435 	
2436 		/* Ask the configured phase2 method if it needs secrets */
2437 		for (i = 0; eap_methods_table[i].method; i++) {
2438 			if (eap_methods_table[i].ns_func == NULL)
2439 				continue;
2440 			if (!strcmp (eap_methods_table[i].method, method)) {
2441 				(*eap_methods_table[i].ns_func) (self, secrets, TRUE);
2442 				break;
2443 			}
2444 		}
2445 	}
2446 	
2447 	
2448 	static GPtrArray *
2449 	need_secrets (NMSetting *setting)
2450 	{
2451 		NMSetting8021x *self = NM_SETTING_802_1X (setting);
2452 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2453 		GSList *iter;
2454 		GPtrArray *secrets;
2455 		gboolean eap_method_found = FALSE;
2456 	
2457 		secrets = g_ptr_array_sized_new (4);
2458 	
2459 		/* Ask each configured EAP method if it needs secrets */
2460 		for (iter = priv->eap; iter && !eap_method_found; iter = g_slist_next (iter)) {
2461 			const char *method = (const char *) iter->data;
2462 			int i;
2463 	
2464 			for (i = 0; eap_methods_table[i].method; i++) {
2465 				if (eap_methods_table[i].ns_func == NULL)
2466 					continue;
2467 				if (!strcmp (eap_methods_table[i].method, method)) {
2468 					(*eap_methods_table[i].ns_func) (self, secrets, FALSE);
2469 	
2470 					/* Only break out of the outer loop if this EAP method
2471 					 * needed secrets.
2472 					 */
2473 					if (secrets->len > 0)
2474 						eap_method_found = TRUE;
2475 					break;
2476 				}
2477 			}
2478 		}
2479 	
2480 		if (secrets->len == 0) {
2481 			g_ptr_array_free (secrets, TRUE);
2482 			secrets = NULL;
2483 		}
2484 	
2485 		return secrets;
2486 	}
2487 	
2488 	static gboolean
2489 	verify_cert (GByteArray *array, const char *prop_name, GError **error)
2490 	{
2491 		if (!array)
2492 			return TRUE;
2493 	
2494 		switch (get_cert_scheme (array)) {
2495 		case NM_SETTING_802_1X_CK_SCHEME_BLOB:
2496 			return TRUE;
2497 		case NM_SETTING_802_1X_CK_SCHEME_PATH:
2498 			/* For path-based schemes, verify that the path is zero-terminated */
2499 			if (array->data[array->len - 1] == '\0') {
2500 				/* And ensure it's UTF-8 valid too so we can pass it through
2501 				 * D-Bus and stuff like that.
2502 				 */
2503 				if (g_utf8_validate ((const char *) (array->data + strlen (SCHEME_PATH)), -1, NULL))
2504 					return TRUE;
2505 			}
2506 			break;
2507 		default:
2508 			break;
2509 		}
2510 	
2511 		g_set_error_literal (error,
2512 		                     NM_SETTING_802_1X_ERROR,
2513 		                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2514 		                     _("property is invalid"));
2515 		g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, prop_name);
2516 		return FALSE;
2517 	}
2518 	
2519 	static gboolean
2520 	verify (NMSetting *setting, GSList *all_settings, GError **error)
2521 	{
2522 		NMSetting8021x *self = NM_SETTING_802_1X (setting);
2523 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2524 		const char *valid_eap[] = { "leap", "md5", "tls", "peap", "ttls", "sim", "fast", "pwd", NULL };
2525 		const char *valid_phase1_peapver[] = { "0", "1", NULL };
2526 		const char *valid_phase1_peaplabel[] = { "0", "1", NULL };
2527 		const char *valid_phase1_fast_pac[] = { "0", "1", "2", "3", NULL };
2528 		const char *valid_phase2_auth[] = { "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", "tls", NULL };
2529 		const char *valid_phase2_autheap[] = { "md5", "mschapv2", "otp", "gtc", "tls", NULL };
2530 		GSList *iter;
2531 	
2532 		if (error)
2533 			g_return_val_if_fail (*error == NULL, FALSE);
2534 	
2535 		if (!priv->eap) {
2536 			g_set_error_literal (error,
2537 			                     NM_SETTING_802_1X_ERROR,
2538 			                     NM_SETTING_802_1X_ERROR_MISSING_PROPERTY,
2539 			                     _("property is missing"));
2540 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_EAP);
2541 			return FALSE;
2542 		}
2543 	
2544 		if (!_nm_utils_string_slist_validate (priv->eap, valid_eap)) {
2545 			g_set_error_literal (error,
2546 			                     NM_SETTING_802_1X_ERROR,
2547 			                     NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2548 			                     _("property is invalid"));
2549 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_EAP);
2550 			return FALSE;
2551 		}
2552 	
2553 		/* Ask each configured EAP method if its valid */
2554 		for (iter = priv->eap; iter; iter = g_slist_next (iter)) {
2555 			const char *method = (const char *) iter->data;
2556 			int i;
2557 	
2558 			for (i = 0; eap_methods_table[i].method; i++) {
2559 				if (eap_methods_table[i].v_func == NULL)
2560 					continue;
2561 				if (!strcmp (eap_methods_table[i].method, method)) {
2562 					if (!(*eap_methods_table[i].v_func) (self, FALSE, error))
2563 						return FALSE;
2564 					break;
2565 				}
2566 			}
2567 		}
2568 	
2569 		if (priv->phase1_peapver && !_nm_utils_string_in_list (priv->phase1_peapver, valid_phase1_peapver)) {
2570 			g_set_error (error,
2571 			             NM_SETTING_802_1X_ERROR,
2572 			             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2573 			             _("'%s' is not a valid value for the property"),
2574 			             priv->phase1_peapver);
2575 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_PEAPVER);
2576 			return FALSE;
2577 		}
2578 	
2579 		if (priv->phase1_peaplabel && !_nm_utils_string_in_list (priv->phase1_peaplabel, valid_phase1_peaplabel)) {
2580 			g_set_error (error,
2581 			             NM_SETTING_802_1X_ERROR,
2582 			             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2583 			             _("'%s' is not a valid value for the property"),
2584 			             priv->phase1_peaplabel);
2585 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_PEAPLABEL);
2586 			return FALSE;
2587 		}
2588 	
2589 		if (priv->phase1_fast_provisioning && !_nm_utils_string_in_list (priv->phase1_fast_provisioning, valid_phase1_fast_pac)) {
2590 			g_set_error (error,
2591 			             NM_SETTING_802_1X_ERROR,
2592 			             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2593 			             _("'%s' is not a valid value for the property"),
2594 			             priv->phase1_fast_provisioning);
2595 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING);
2596 			return FALSE;
2597 		}
2598 	
2599 		if (priv->phase2_auth && !_nm_utils_string_in_list (priv->phase2_auth, valid_phase2_auth)) {
2600 			g_set_error (error,
2601 			             NM_SETTING_802_1X_ERROR,
2602 			             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2603 			             _("'%s' is not a valid value for the property"),
2604 			             priv->phase2_auth);
2605 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
2606 			return FALSE;
2607 		}
2608 	
2609 		if (priv->phase2_autheap && !_nm_utils_string_in_list (priv->phase2_autheap, valid_phase2_autheap)) {
2610 			g_set_error (error,
2611 			             NM_SETTING_802_1X_ERROR,
2612 			             NM_SETTING_802_1X_ERROR_INVALID_PROPERTY,
2613 			             _("'%s' is not a valid value for the property"),
2614 			             priv->phase2_autheap);
2615 			g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
2616 			return FALSE;
2617 		}
2618 	
2619 		if (!verify_cert (priv->ca_cert, NM_SETTING_802_1X_CA_CERT, error))
2620 			return FALSE;
2621 		if (!verify_cert (priv->phase2_ca_cert, NM_SETTING_802_1X_PHASE2_CA_CERT, error))
2622 			return FALSE;
2623 	
2624 		if (!verify_cert (priv->client_cert, NM_SETTING_802_1X_CLIENT_CERT, error))
2625 			return FALSE;
2626 		if (!verify_cert (priv->phase2_client_cert, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, error))
2627 			return FALSE;
2628 	
2629 		if (!verify_cert (priv->private_key, NM_SETTING_802_1X_PRIVATE_KEY, error))
2630 			return FALSE;
2631 		if (!verify_cert (priv->phase2_private_key, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, error))
2632 			return FALSE;
2633 	
2634 		/* FIXME: finish */
2635 	
2636 		return TRUE;
2637 	}
2638 	
2639 	static void
2640 	nm_setting_802_1x_init (NMSetting8021x *setting)
2641 	{
2642 		g_object_set (setting, NM_SETTING_NAME, NM_SETTING_802_1X_SETTING_NAME, NULL);
2643 	}
2644 	
2645 	static void
2646 	finalize (GObject *object)
2647 	{
2648 		NMSetting8021x *self = NM_SETTING_802_1X (object);
2649 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
2650 	
2651 		/* Strings first. g_free() already checks for NULLs so we don't have to */
2652 	
2653 		g_free (priv->identity);
2654 		g_free (priv->anonymous_identity);
2655 		g_free (priv->ca_path);
2656 		g_free (priv->subject_match);
2657 		g_free (priv->phase1_peapver);
2658 		g_free (priv->phase1_peaplabel);
2659 		g_free (priv->phase1_fast_provisioning);
2660 		g_free (priv->phase2_auth);
2661 		g_free (priv->phase2_autheap);
2662 		g_free (priv->phase2_ca_path);
2663 		g_free (priv->phase2_subject_match);
2664 		g_free (priv->password);
2665 		if (priv->password_raw)
2666 			g_byte_array_free (priv->password_raw, TRUE);
2667 		g_free (priv->pin);
2668 	
2669 		g_slist_free_full (priv->eap, g_free);
2670 		g_slist_free_full (priv->altsubject_matches, g_free);
2671 		g_slist_free_full (priv->phase2_altsubject_matches, g_free);
2672 	
2673 		if (priv->ca_cert)
2674 			g_byte_array_free (priv->ca_cert, TRUE);
2675 		if (priv->client_cert)
2676 			g_byte_array_free (priv->client_cert, TRUE);
2677 		if (priv->private_key)
2678 			g_byte_array_free (priv->private_key, TRUE);
2679 		g_free (priv->private_key_password);
2680 		if (priv->phase2_ca_cert)
2681 			g_byte_array_free (priv->phase2_ca_cert, TRUE);
2682 		if (priv->phase2_client_cert)
2683 			g_byte_array_free (priv->phase2_client_cert, TRUE);
2684 		if (priv->phase2_private_key)
2685 			g_byte_array_free (priv->phase2_private_key, TRUE);
2686 		g_free (priv->phase2_private_key_password);
2687 	
2688 		G_OBJECT_CLASS (nm_setting_802_1x_parent_class)->finalize (object);
2689 	}
2690 	
2691 	static GByteArray *
2692 	set_cert_prop_helper (const GValue *value, const char *prop_name, GError **error)
2693 	{
2694 		gboolean valid;
2695 		GByteArray *data = NULL;
2696 	
2697 		data = g_value_dup_boxed (value);
2698 		/* Verify the new data */
2699 		if (data) {
2700 			valid = verify_cert (data, prop_name, error);
2701 			if (!valid) {
2702 				g_byte_array_free (data, TRUE);
2703 				data = NULL;
2704 			}
2705 		}
2706 		return data;
2707 	}
2708 	
2709 	static void
2710 	set_property (GObject *object, guint prop_id,
2711 			    const GValue *value, GParamSpec *pspec)
2712 	{
2713 		NMSetting8021x *setting = NM_SETTING_802_1X (object);
2714 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
2715 		GError *error = NULL;
2716 	
2717 		switch (prop_id) {
2718 		case PROP_EAP:
2719 			g_slist_free_full (priv->eap, g_free);
2720 			priv->eap = g_value_dup_boxed (value);
2721 			break;
2722 		case PROP_IDENTITY:
2723 			g_free (priv->identity);
2724 			priv->identity = g_value_dup_string (value);
2725 			break;
2726 		case PROP_ANONYMOUS_IDENTITY:
2727 			g_free (priv->anonymous_identity);
2728 			priv->anonymous_identity = g_value_dup_string (value);
2729 			break;
2730 		case PROP_PAC_FILE:
2731 			g_free (priv->pac_file);
2732 			priv->pac_file = g_value_dup_string (value);
2733 			break;
2734 		case PROP_CA_CERT:
2735 			if (priv->ca_cert) {
2736 				g_byte_array_free (priv->ca_cert, TRUE);
2737 				priv->ca_cert = NULL;
2738 			}
2739 			priv->ca_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_CA_CERT, &error);
2740 			if (error) {
2741 				g_warning ("Error setting certificate (invalid data): (%d) %s",
2742 				           error->code, error->message);
2743 				g_error_free (error);
2744 			}
2745 			break;
2746 		case PROP_CA_PATH:
2747 			g_free (priv->ca_path);
2748 			priv->ca_path = g_value_dup_string (value);
2749 			break;
2750 		case PROP_SUBJECT_MATCH:
2751 			g_free (priv->subject_match);
2752 			priv->subject_match = g_value_dup_string (value);
2753 			break;
2754 		case PROP_ALTSUBJECT_MATCHES:
2755 			g_slist_free_full (priv->altsubject_matches, g_free);
2756 			priv->altsubject_matches = g_value_dup_boxed (value);
2757 			break;
2758 		case PROP_CLIENT_CERT:
2759 			if (priv->client_cert) {
2760 				g_byte_array_free (priv->client_cert, TRUE);
2761 				priv->client_cert = NULL;
2762 			}
2763 			priv->client_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_CLIENT_CERT, &error);
2764 			if (error) {
2765 				g_warning ("Error setting certificate (invalid data): (%d) %s",
2766 				           error->code, error->message);
2767 				g_error_free (error);
2768 			}
2769 			break;
2770 		case PROP_PHASE1_PEAPVER:
2771 			g_free (priv->phase1_peapver);
2772 			priv->phase1_peapver = g_value_dup_string (value);
2773 			break;
2774 		case PROP_PHASE1_PEAPLABEL:
2775 			g_free (priv->phase1_peaplabel);
2776 			priv->phase1_peaplabel = g_value_dup_string (value);
2777 			break;
2778 		case PROP_PHASE1_FAST_PROVISIONING:
2779 			g_free (priv->phase1_fast_provisioning);
2780 			priv->phase1_fast_provisioning = g_value_dup_string (value);
2781 			break;
2782 		case PROP_PHASE2_AUTH:
2783 			g_free (priv->phase2_auth);
2784 			priv->phase2_auth = g_value_dup_string (value);
2785 			break;
2786 		case PROP_PHASE2_AUTHEAP:
2787 			g_free (priv->phase2_autheap);
2788 			priv->phase2_autheap = g_value_dup_string (value);
2789 			break;
2790 		case PROP_PHASE2_CA_CERT:
2791 			if (priv->phase2_ca_cert) {
2792 				g_byte_array_free (priv->phase2_ca_cert, TRUE);
2793 				priv->phase2_ca_cert = NULL;
2794 			}
2795 			priv->phase2_ca_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_PHASE2_CA_CERT, &error);
2796 			if (error) {
2797 				g_warning ("Error setting certificate (invalid data): (%d) %s",
2798 				           error->code, error->message);
2799 				g_error_free (error);
2800 			}
2801 			break;
2802 		case PROP_PHASE2_CA_PATH:
2803 			g_free (priv->phase2_ca_path);
2804 			priv->phase2_ca_path = g_value_dup_string (value);
2805 			break;
2806 		case PROP_PHASE2_SUBJECT_MATCH:
2807 			g_free (priv->phase2_subject_match);
2808 			priv->phase2_subject_match = g_value_dup_string (value);
2809 			break;
2810 		case PROP_PHASE2_ALTSUBJECT_MATCHES:
2811 			g_slist_free_full (priv->phase2_altsubject_matches, g_free);
2812 			priv->phase2_altsubject_matches = g_value_dup_boxed (value);
2813 			break;
2814 		case PROP_PHASE2_CLIENT_CERT:
2815 			if (priv->phase2_client_cert) {
2816 				g_byte_array_free (priv->phase2_client_cert, TRUE);
2817 				priv->phase2_client_cert = NULL;
2818 			}
2819 			priv->phase2_client_cert = set_cert_prop_helper (value, NM_SETTING_802_1X_PHASE2_CLIENT_CERT, &error);
2820 			if (error) {
2821 				g_warning ("Error setting certificate (invalid data): (%d) %s",
2822 				           error->code, error->message);
2823 				g_error_free (error);
2824 			}
2825 			break;
2826 		case PROP_PASSWORD:
2827 			g_free (priv->password);
2828 			priv->password = g_value_dup_string (value);
2829 			break;
2830 		case PROP_PASSWORD_FLAGS:
2831 			priv->password_flags = g_value_get_uint (value);
2832 			break;
2833 		case PROP_PASSWORD_RAW:
2834 			if (priv->password_raw)
2835 				g_byte_array_free (priv->password_raw, TRUE);
2836 			priv->password_raw = g_value_dup_boxed (value);
2837 			break;
2838 		case PROP_PASSWORD_RAW_FLAGS:
2839 			priv->password_raw_flags = g_value_get_uint (value);
2840 			break;
2841 		case PROP_PRIVATE_KEY:
2842 			if (priv->private_key) {
2843 				g_byte_array_free (priv->private_key, TRUE);
2844 				priv->private_key = NULL;
2845 			}
2846 			priv->private_key = set_cert_prop_helper (value, NM_SETTING_802_1X_PRIVATE_KEY, &error);
2847 			if (error) {
2848 				g_warning ("Error setting private key (invalid data): (%d) %s",
2849 				           error->code, error->message);
2850 				g_error_free (error);
2851 			}
2852 			break;
2853 		case PROP_PRIVATE_KEY_PASSWORD:
2854 			g_free (priv->private_key_password);
2855 			priv->private_key_password = g_value_dup_string (value);
2856 			break;
2857 		case PROP_PRIVATE_KEY_PASSWORD_FLAGS:
2858 			priv->private_key_password_flags = g_value_get_uint (value);
2859 			break;
2860 		case PROP_PHASE2_PRIVATE_KEY:
2861 			if (priv->phase2_private_key) {
2862 				g_byte_array_free (priv->phase2_private_key, TRUE);
2863 				priv->phase2_private_key = NULL;
2864 			}
2865 			priv->phase2_private_key = set_cert_prop_helper (value, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, &error);
2866 			if (error) {
2867 				g_warning ("Error setting private key (invalid data): (%d) %s",
2868 				           error->code, error->message);
2869 				g_error_free (error);
2870 			}
2871 			break;
2872 		case PROP_PHASE2_PRIVATE_KEY_PASSWORD:
2873 			g_free (priv->phase2_private_key_password);
2874 			priv->phase2_private_key_password = g_value_dup_string (value);
2875 			break;
2876 		case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS:
2877 			priv->phase2_private_key_password_flags = g_value_get_uint (value);
2878 			break;
2879 		case PROP_PIN:
2880 			g_free (priv->pin);
2881 			priv->pin = g_value_dup_string (value);
2882 			break;
2883 		case PROP_PIN_FLAGS:
2884 			priv->pin_flags = g_value_get_uint (value);
2885 			break;
2886 		case PROP_SYSTEM_CA_CERTS:
2887 			priv->system_ca_certs = g_value_get_boolean (value);
2888 			break;
2889 		default:
2890 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2891 			break;
2892 		}
2893 	}
2894 	
2895 	static void
2896 	get_property (GObject *object, guint prop_id,
2897 			    GValue *value, GParamSpec *pspec)
2898 	{
2899 		NMSetting8021x *setting = NM_SETTING_802_1X (object);
2900 		NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (setting);
2901 	
2902 		switch (prop_id) {
2903 		case PROP_EAP:
2904 			g_value_set_boxed (value, priv->eap);
2905 			break;
2906 		case PROP_IDENTITY:
2907 			g_value_set_string (value, priv->identity);
2908 			break;
2909 		case PROP_ANONYMOUS_IDENTITY:
2910 			g_value_set_string (value, priv->anonymous_identity);
2911 			break;
2912 		case PROP_PAC_FILE:
2913 			g_value_set_string (value, priv->pac_file);
2914 			break;
2915 		case PROP_CA_CERT:
2916 			g_value_set_boxed (value, priv->ca_cert);
2917 			break;
2918 		case PROP_CA_PATH:
2919 			g_value_set_string (value, priv->ca_path);
2920 			break;
2921 		case PROP_SUBJECT_MATCH:
2922 			g_value_set_string (value, priv->subject_match);
2923 			break;
2924 		case PROP_ALTSUBJECT_MATCHES:
2925 			g_value_set_boxed (value, priv->altsubject_matches);
2926 			break;
2927 		case PROP_CLIENT_CERT:
2928 			g_value_set_boxed (value, priv->client_cert);
2929 			break;
2930 		case PROP_PHASE1_PEAPVER:
2931 			g_value_set_string (value, priv->phase1_peapver);
2932 			break;
2933 		case PROP_PHASE1_PEAPLABEL:
2934 			g_value_set_string (value, priv->phase1_peaplabel);
2935 			break;
2936 		case PROP_PHASE1_FAST_PROVISIONING:
2937 			g_value_set_string (value, priv->phase1_fast_provisioning);
2938 			break;
2939 		case PROP_PHASE2_AUTH:
2940 			g_value_set_string (value, priv->phase2_auth);
2941 			break;
2942 		case PROP_PHASE2_AUTHEAP:
2943 			g_value_set_string (value, priv->phase2_autheap);
2944 			break;
2945 		case PROP_PHASE2_CA_CERT:
2946 			g_value_set_boxed (value, priv->phase2_ca_cert);
2947 			break;
2948 		case PROP_PHASE2_CA_PATH:
2949 			g_value_set_string (value, priv->phase2_ca_path);
2950 			break;
2951 		case PROP_PHASE2_SUBJECT_MATCH:
2952 			g_value_set_string (value, priv->phase2_subject_match);
2953 			break;
2954 		case PROP_PHASE2_ALTSUBJECT_MATCHES:
2955 			g_value_set_boxed (value, priv->phase2_altsubject_matches);
2956 			break;
2957 		case PROP_PHASE2_CLIENT_CERT:
2958 			g_value_set_boxed (value, priv->phase2_client_cert);
2959 			break;
2960 		case PROP_PASSWORD:
2961 			g_value_set_string (value, priv->password);
2962 			break;
2963 		case PROP_PASSWORD_FLAGS:
2964 			g_value_set_uint (value, priv->password_flags);
2965 			break;
2966 		case PROP_PASSWORD_RAW:
2967 			g_value_set_boxed (value, priv->password_raw);
2968 			break;
2969 		case PROP_PASSWORD_RAW_FLAGS:
2970 			g_value_set_uint (value, priv->password_raw_flags);
2971 			break;
2972 		case PROP_PRIVATE_KEY:
2973 			g_value_set_boxed (value, priv->private_key);
2974 			break;
2975 		case PROP_PRIVATE_KEY_PASSWORD:
2976 			g_value_set_string (value, priv->private_key_password);
2977 			break;
2978 		case PROP_PRIVATE_KEY_PASSWORD_FLAGS:
2979 			g_value_set_uint (value, priv->private_key_password_flags);
2980 			break;
2981 		case PROP_PHASE2_PRIVATE_KEY:
2982 			g_value_set_boxed (value, priv->phase2_private_key);
2983 			break;
2984 		case PROP_PHASE2_PRIVATE_KEY_PASSWORD:
2985 			g_value_set_string (value, priv->phase2_private_key_password);
2986 			break;
2987 		case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS:
2988 			g_value_set_uint (value, priv->phase2_private_key_password_flags);
2989 			break;
2990 		case PROP_PIN:
2991 			g_value_set_string (value, priv->pin);
2992 			break;
2993 		case PROP_PIN_FLAGS:
2994 			g_value_set_uint (value, priv->pin_flags);
2995 			break;
2996 		case PROP_SYSTEM_CA_CERTS:
2997 			g_value_set_boolean (value, priv->system_ca_certs);
2998 			break;
2999 		default:
3000 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3001 			break;
3002 		}
3003 	}
3004 	
3005 	static void
3006 	nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
3007 	{
3008 		GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
3009 		NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
3010 		GError *error = NULL;
3011 	
3012 		g_type_class_add_private (setting_class, sizeof (NMSetting8021xPrivate));
3013 	
3014 		/* virtual methods */
3015 		object_class->set_property = set_property;
3016 		object_class->get_property = get_property;
3017 		object_class->finalize     = finalize;
3018 	
3019 		parent_class->verify         = verify;
3020 		parent_class->need_secrets   = need_secrets;
3021 	
3022 		/* Properties */
3023 	
3024 		/**
3025 		 * NMSetting8021x:eap:
3026 		 *
3027 		 * The allowed EAP method to be used when authenticating to the network with
3028 		 * 802.1x.  Valid methods are: "leap", "md5", "tls", "peap", "ttls", "pwd" and
3029 		 * "fast".  Each method requires different configuration using the
3030 		 * properties of this object; refer to wpa_supplicant documentation for the
3031 		 * allowed combinations.
3032 		 **/
3033 		g_object_class_install_property
3034 			(object_class, PROP_EAP,
3035 			 _nm_param_spec_specialized (NM_SETTING_802_1X_EAP,
3036 								   "EAP",
3037 								   "The allowed EAP method to be used when "
3038 								   "authenticating to the network with 802.1x. "
3039 								   "Valid methods are: 'leap', 'md5', 'tls', 'peap', "
3040 								   "'ttls', 'pwd', and 'fast'. Each method requires "
3041 								   "different configuration using the properties of "
3042 								   "this setting; refer to wpa_supplicant "
3043 								   "documentation for the allowed combinations.",
3044 								   DBUS_TYPE_G_LIST_OF_STRING,
3045 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3046 	
3047 		/**
3048 		 * NMSetting8021x:identity:
3049 		 *
3050 		 * Identity string for EAP authentication methods.  Often the user's
3051 		 * user or login name.
3052 		 **/
3053 		g_object_class_install_property
3054 			(object_class, PROP_IDENTITY,
3055 			 g_param_spec_string (NM_SETTING_802_1X_IDENTITY,
3056 							  "Identity",
3057 							  "Identity string for EAP authentication methods.  "
3058 							  "Often the user's user or login name.",
3059 							  NULL,
3060 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3061 	
3062 		/**
3063 		 * NMSetting8021x:anonymous-identity:
3064 		 *
3065 		 * Anonymous identity string for EAP authentication methods.  Used as the
3066 		 * unencrypted identity with EAP types that support different tunneled
3067 		 * identity like EAP-TTLS.
3068 		 **/
3069 		g_object_class_install_property
3070 			(object_class, PROP_ANONYMOUS_IDENTITY,
3071 			 g_param_spec_string (NM_SETTING_802_1X_ANONYMOUS_IDENTITY,
3072 							  "Anonymous identity",
3073 							  "Anonymous identity string for EAP authentication "
3074 							  "methods.  Used as the unencrypted identity with EAP "
3075 							  "types that support different tunneled identity like "
3076 							  "EAP-TTLS.",
3077 							  NULL,
3078 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3079 	
3080 		/**
3081 		 * NMSetting8021x:pac-file:
3082 		 *
3083 		 * UTF-8 encoded file path containing PAC for EAP-FAST.
3084 		 **/
3085 		g_object_class_install_property
3086 			(object_class, PROP_PAC_FILE,
3087 			 g_param_spec_string (NM_SETTING_802_1X_PAC_FILE,
3088 							  "PAC file",
3089 							  "UTF-8 encoded file path containing PAC for EAP-FAST.",
3090 							  NULL,
3091 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3092 	
3093 		/**
3094 		 * NMSetting8021x:ca-cert:
3095 		 *
3096 		 * Contains the CA certificate if used by the EAP method specified in the
3097 		 * #NMSetting8021x:eap property.  Setting this property directly is
3098 		 * discouraged; use the nm_setting_802_1x_set_ca_cert() function instead.
3099 		 **/
3100 		g_object_class_install_property
3101 			(object_class, PROP_CA_CERT,
3102 			 _nm_param_spec_specialized (NM_SETTING_802_1X_CA_CERT,
3103 								   "CA certificate",
3104 								   "Contains the CA certificate if used by the EAP "
3105 								   "method specified in the 'eap' property.  "
3106 								   "Certificate data is specified using a 'scheme'; "
3107 								   "two are currently supported: blob and path.  "
3108 								   "When using the blob scheme (which is backwards "
3109 								   "compatible with NM 0.7.x) this property should "
3110 								   "be set to the certificate's DER encoded data.  "
3111 								   "When using the path scheme, this property should "
3112 								   "be set to the full UTF-8 encoded path of the "
3113 								   "certificate, prefixed with the string 'file://' "
3114 								   "and ending with a terminating NULL byte.  This "
3115 								   "property can be unset even if the EAP method "
3116 								   "supports CA certificates, but this allows "
3117 								   "man-in-the-middle attacks and is NOT recommended.",
3118 								   DBUS_TYPE_G_UCHAR_ARRAY,
3119 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3120 	
3121 		/**
3122 		 * NMSetting8021x:ca-path:
3123 		 *
3124 		 * UTF-8 encoded path to a directory containing PEM or DER formatted
3125 		 * certificates to be added to the verification chain in addition to the
3126 		 * certificate specified in the #NMSetting8021x:ca-cert property.
3127 		 **/
3128 		g_object_class_install_property
3129 			(object_class, PROP_CA_PATH,
3130 			 g_param_spec_string (NM_SETTING_802_1X_CA_PATH,
3131 							  "CA path",
3132 							  "UTF-8 encoded path to a directory containing PEM or "
3133 							  "DER formatted certificates to be added to the "
3134 							  "verification chain in addition to the certificate "
3135 							  "specified in the 'ca-cert' property.",
3136 							  NULL,
3137 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3138 	
3139 		/**
3140 		 * NMSetting8021x:subject-match:
3141 		 *
3142 		 * Substring to be matched against the subject of the certificate
3143 		 * presented by the authentication server. When unset, no
3144 		 * verification of the authentication server certificate's subject
3145 		 * is performed.
3146 		 **/
3147 		g_object_class_install_property
3148 			(object_class, PROP_SUBJECT_MATCH,
3149 			 g_param_spec_string (NM_SETTING_802_1X_SUBJECT_MATCH,
3150 								  "Subject match",
3151 								  "Substring to be matched against the subject of "
3152 								  "the certificate presented by the authentication "
3153 								  "server. When unset, no verification of the "
3154 								  "authentication server certificate's subject is "
3155 								  "performed.",
3156 								  NULL,
3157 								  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3158 	
3159 		/**
3160 		 * NMSetting8021x:altsubject-matches:
3161 		 *
3162 		 * List of strings to be matched against the altSubjectName of the
3163 		 * certificate presented by the authentication server. If the list
3164 		 * is empty, no verification of the server certificate's
3165 		 * altSubjectName is performed.
3166 		 **/
3167 		 g_object_class_install_property
3168 			 (object_class, PROP_ALTSUBJECT_MATCHES,
3169 			  _nm_param_spec_specialized (NM_SETTING_802_1X_ALTSUBJECT_MATCHES,
3170 										  "altSubjectName matches",
3171 										  "List of strings to be matched against "
3172 										  "the altSubjectName of the certificate "
3173 										  "presented by the authentication server. "
3174 										  "If the list is empty, no verification "
3175 										  "of the server certificate's "
3176 										  "altSubjectName is performed.",
3177 										  DBUS_TYPE_G_LIST_OF_STRING,
3178 										  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3179 	
3180 		/**
3181 		 * NMSetting8021x:client-cert:
3182 		 *
3183 		 * Contains the client certificate if used by the EAP method specified in
3184 		 * the #NMSetting8021x:eap property.  Setting this property directly is
3185 		 * discouraged; use the nm_setting_802_1x_set_client_cert() function instead.
3186 		 **/
3187 		g_object_class_install_property
3188 			(object_class, PROP_CLIENT_CERT,
3189 			 _nm_param_spec_specialized (NM_SETTING_802_1X_CLIENT_CERT,
3190 								   "Client certificate",
3191 								   "Contains the client certificate if used by the "
3192 								   "EAP method specified in the 'eap' property.  "
3193 								   "Certificate data is specified using a 'scheme'; "
3194 								   "two are currently supported: blob and path.  "
3195 								   "When using the blob scheme (which is backwards "
3196 								   "compatible with NM 0.7.x) this property should "
3197 								   "be set to the certificate's DER encoded data.  "
3198 								   "When using the path scheme, this property should "
3199 								   "be set to the full UTF-8 encoded path of the "
3200 								   "certificate, prefixed with the string 'file://' "
3201 								   "and ending with a terminating NULL byte.",
3202 								   DBUS_TYPE_G_UCHAR_ARRAY,
3203 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3204 	
3205 		/**
3206 		 * NMSetting8021x:phase1-peapver:
3207 		 *
3208 		 * Forces which PEAP version is used when PEAP is set as the EAP method in
3209 		 * the #NMSetting8021x:eap property.  When unset, the version reported by
3210 		 * the server will be used.  Sometimes when using older RADIUS servers, it
3211 		 * is necessary to force the client to use a particular PEAP version.  To do
3212 		 * so, this property may be set to "0" or "1" to force that specific PEAP
3213 		 * version.
3214 		 **/
3215 		g_object_class_install_property
3216 			(object_class, PROP_PHASE1_PEAPVER,
3217 			 g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPVER,
3218 							  "Phase1 PEAPVER",
3219 							  "Forces which PEAP version is used when PEAP is set "
3220 							  "as the EAP method in 'eap' property.  When unset, "
3221 							  "the version reported by the server will be used.  "
3222 							  "Sometimes when using older RADIUS servers, it is "
3223 							  "necessary to force the client to use a particular "
3224 							  "PEAP version.  To do so, this property may be set to "
3225 							  "'0' or '1' to force that specific PEAP version.",
3226 							  NULL,
3227 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3228 	
3229 		/**
3230 		 * NMSetting8021x:phase1-peaplabel:
3231 		 *
3232 		 * Forces use of the new PEAP label during key derivation.  Some RADIUS
3233 		 * servers may require forcing the new PEAP label to interoperate with
3234 		 * PEAPv1.  Set to "1" to force use of the new PEAP label.  See the
3235 		 * wpa_supplicant documentation for more details.
3236 		 **/
3237 		g_object_class_install_property
3238 			(object_class, PROP_PHASE1_PEAPLABEL,
3239 			 g_param_spec_string (NM_SETTING_802_1X_PHASE1_PEAPLABEL,
3240 							  "Phase1 PEAP label",
3241 							  "Forces use of the new PEAP label during key "
3242 							  "derivation.  Some RADIUS servers may require forcing "
3243 							  "the new PEAP label to interoperate with PEAPv1.  "
3244 							  "Set to '1' to force use of the new PEAP label.  See "
3245 							  "the wpa_supplicant documentation for more details.",
3246 							  NULL,
3247 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3248 	
3249 		/**
3250 		 * NMSetting8021x:phase1-fast-provisioning:
3251 		 *
3252 		 * Enables or disables in-line provisioning of EAP-FAST credentials when
3253 		 * FAST is specified as the EAP method in the #NMSetting8021x:eap property.
3254 		 * Recognized values are "0" (disabled), "1" (allow unauthenticated
3255 		 * provisioning), "2" (allow authenticated provisioning), and "3" (allow
3256 		 * both authenticated and unauthenticated provisioning).  See the
3257 		 * wpa_supplicant documentation for more details.
3258 		 **/
3259 		g_object_class_install_property
3260 			(object_class, PROP_PHASE1_FAST_PROVISIONING,
3261 			 g_param_spec_string (NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING,
3262 							  "Phase1 fast provisioning",
3263 							  "Enables or disables in-line provisioning of EAP-FAST "
3264 							  "credentials when FAST is specified as the EAP method "
3265 							  "in the #NMSetting8021x:eap property. Allowed values "
3266 							  "are '0' (disabled), '1' (allow unauthenticated "
3267 							  "provisioning), '2' (allow authenticated provisioning), "
3268 							  "and '3' (allow both authenticated and unauthenticated "
3269 							  "provisioning).  See the wpa_supplicant documentation "
3270 							  "for more details.",
3271 							  NULL,
3272 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3273 	
3274 		/**
3275 		 * NMSetting8021x:phase2-auth:
3276 		 *
3277 		 * Specifies the allowed "phase 2" inner non-EAP authentication methods when
3278 		 * an EAP method that uses an inner TLS tunnel is specified in the
3279 		 * #NMSetting8021x:eap property.  Recognized non-EAP phase2 methods are
3280 		 * "pap", "chap", "mschap", "mschapv2", "gtc", "otp", "md5", and "tls".
3281 		 * Each 'phase 2' inner method requires specific parameters for successful
3282 		 * authentication; see the wpa_supplicant documentation for more details.
3283 		 **/
3284 		g_object_class_install_property
3285 			(object_class, PROP_PHASE2_AUTH,
3286 			 g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTH,
3287 							  "Phase2 auth",
3288 							  "Specifies the allowed 'phase 2' inner non-EAP "
3289 							  "authentication methods when an EAP method that uses "
3290 							  "an inner TLS tunnel is specified in the 'eap' "
3291 							  "property. Recognized non-EAP phase2 methods are 'pap', "
3292 							  "'chap', 'mschap', 'mschapv2', 'gtc', 'otp', 'md5', "
3293 							  "and 'tls'.  Each 'phase 2' inner method requires "
3294 							  "specific parameters for successful authentication; "
3295 							  "see the wpa_supplicant documentation for more details.",
3296 							  NULL,
3297 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3298 	
3299 		/**
3300 		 * NMSetting8021x:phase2-autheap:
3301 		 *
3302 		 * Specifies the allowed "phase 2" inner EAP-based authentication methods
3303 		 * when an EAP method that uses an inner TLS tunnel is specified in the
3304 		 * #NMSetting8021x:eap property.  Recognized EAP-based phase2 methods are
3305 		 * "md5", "mschapv2", "otp", "gtc", and "tls". Each 'phase 2' inner method
3306 		 * requires specific parameters for successful authentication; see the
3307 		 * wpa_supplicant documentation for more details.
3308 		 **/
3309 		g_object_class_install_property
3310 			(object_class, PROP_PHASE2_AUTHEAP,
3311 			 g_param_spec_string (NM_SETTING_802_1X_PHASE2_AUTHEAP,
3312 							  "Phase2 autheap",
3313 							  "Specifies the allowed 'phase 2' inner EAP-based "
3314 							  "authentication methods when an EAP method that uses "
3315 							  "an inner TLS tunnel is specified in the 'eap' "
3316 							  "property. Recognized EAP-based 'phase 2' methods are "
3317 							  "'md5', 'mschapv2', 'otp', 'gtc', and 'tls'. Each "
3318 							  "'phase 2' inner method requires specific parameters "
3319 							  "for successful authentication; see the wpa_supplicant "
3320 							  "documentation for more details.",
3321 							  NULL,
3322 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3323 	
3324 		/**
3325 		 * NMSetting8021x:phase2-ca-cert:
3326 		 *
3327 		 * Contains the CA certificate if used by the EAP method specified in the
3328 		 * #NMSetting8021x:phase2-auth or #NMSetting8021x:phase2-autheap properties.
3329 		 * Setting this property directly is discouraged; use the
3330 		 * nm_setting_802_1x_set_phase2_ca_cert() function instead.
3331 		 **/
3332 		g_object_class_install_property
3333 			(object_class, PROP_PHASE2_CA_CERT,
3334 			 _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CA_CERT,
3335 								   "Phase2 CA certificate",
3336 								   "Contains the 'phase 2' CA certificate if used by "
3337 								   "the EAP method specified in the 'phase2-auth' or "
3338 								   "'phase2-autheap' properties.  Certificate data "
3339 								   "is specified using a 'scheme'; two are currently"
3340 								   "supported: blob and path. When using the blob "
3341 								   "scheme (which is backwards compatible with NM "
3342 								   "0.7.x) this property should be set to the "
3343 								   "certificate's DER encoded data. When using the "
3344 								   "path scheme, this property should be set to the "
3345 								   "full UTF-8 encoded path of the certificate, "
3346 								   "prefixed with the string 'file://' and ending "
3347 								   "with a terminating NULL byte.  This property can "
3348 								   "be unset even if the EAP method supports CA "
3349 								   "certificates, but this allows man-in-the-middle "
3350 								   "attacks and is NOT recommended.",
3351 								   DBUS_TYPE_G_UCHAR_ARRAY,
3352 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3353 	
3354 		/**
3355 		 * NMSetting8021x:phase2-ca-path:
3356 		 *
3357 		 * UTF-8 encoded path to a directory containing PEM or DER formatted
3358 		 * certificates to be added to the verification chain in addition to the
3359 		 * certificate specified in the #NMSetting8021x:phase2-ca-cert property.
3360 		 **/
3361 		g_object_class_install_property
3362 			(object_class, PROP_PHASE2_CA_PATH,
3363 			 g_param_spec_string (NM_SETTING_802_1X_PHASE2_CA_PATH,
3364 							  "Phase2 auth CA path",
3365 							  "UTF-8 encoded path to a directory containing PEM or "
3366 							  "DER formatted certificates to be added to the "
3367 							  "verification chain in addition to the certificate "
3368 							  "specified in the 'phase2-ca-cert' property.",
3369 							  NULL,
3370 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3371 	
3372 		/**
3373 		 * NMSetting8021x:phase2-subject-match:
3374 		 *
3375 		 * Substring to be matched against the subject of the certificate
3376 		 * presented by the authentication server during the inner "phase
3377 		 * 2" authentication. When unset, no verification of the
3378 		 * authentication server certificate's subject is performed.
3379 		 **/
3380 		g_object_class_install_property
3381 			(object_class, PROP_PHASE2_SUBJECT_MATCH,
3382 			 g_param_spec_string (NM_SETTING_802_1X_PHASE2_SUBJECT_MATCH,
3383 								  "Phase2 subject match",
3384 								  "Substring to be matched against the subject of "
3385 								  "the certificate presented by the authentication "
3386 								  "server during the inner 'phase2' "
3387 								  "authentication. When unset, no verification of "
3388 								  "the authentication server certificate's subject "
3389 								  "is performed.",
3390 								  NULL,
3391 								  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3392 	
3393 		/**
3394 		 * NMSetting8021x:phase2-altsubject-matches:
3395 		 *
3396 		 * List of strings to be matched against the altSubjectName of the
3397 		 * certificate presented by the authentication server during the
3398 		 * inner "phase 2" authentication. If the list is empty, no
3399 		 * verification of the server certificate's altSubjectName is
3400 		 * performed.
3401 		 **/
3402 		 g_object_class_install_property
3403 			 (object_class, PROP_PHASE2_ALTSUBJECT_MATCHES,
3404 			  _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES,
3405 										  "altSubjectName matches",
3406 										  "List of strings to be matched against "
3407 										  "List of strings to be matched against "
3408 										  "the altSubjectName of the certificate "
3409 										  "presented by the authentication server "
3410 										  "during the inner 'phase 2' "
3411 										  "authentication. If the list is empty, no "
3412 										  "verification of the server certificate's "
3413 										  "altSubjectName is performed.",
3414 										  DBUS_TYPE_G_LIST_OF_STRING,
3415 										  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3416 	
3417 		/**
3418 		 * NMSetting8021x:phase2-client-cert:
3419 		 *
3420 		 * Contains the client certificate if used by the EAP method specified in
3421 		 * the #NMSetting8021x:phase2-auth or #NMSetting8021x:phase2-autheap
3422 		 * properties.  Setting this property directly is discouraged; use the
3423 		 * nm_setting_802_1x_set_phase2_client_cert() function instead.
3424 		 **/
3425 		g_object_class_install_property
3426 			(object_class, PROP_PHASE2_CLIENT_CERT,
3427 			 _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
3428 								   "Phase2 client certificate",
3429 								   "Contains the 'phase 2' client certificate if "
3430 								   "used by the EAP method specified in the "
3431 								   "'phase2-auth' or 'phase2-autheap' properties. "
3432 								   "Certificate data is specified using a 'scheme'; "
3433 								   "two are currently supported: blob and path.  "
3434 								   "When using the blob scheme (which is backwards "
3435 								   "compatible with NM 0.7.x) this property should "
3436 								   "be set to the certificate's DER encoded data.  "
3437 								   "When using the path scheme, this property should "
3438 								   "be set to the full UTF-8 encoded path of the "
3439 								   "certificate, prefixed with the string 'file://' "
3440 								   "and ending with a terminating NULL byte.",
3441 								   DBUS_TYPE_G_UCHAR_ARRAY,
3442 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3443 	
3444 		/**
3445 		 * NMSetting8021x:password:
3446 		 *
3447 		 * Password used for EAP authentication methods. If both
3448 		 * #NMSetting8021x:password and #NMSetting8021x:password-raw are
3449 		 * specified, #NMSetting8021x:password is preferred.
3450 		 **/
3451 		g_object_class_install_property
3452 			(object_class, PROP_PASSWORD,
3453 			 g_param_spec_string (NM_SETTING_802_1X_PASSWORD,
3454 							  "Password",
3455 							  "UTF-8 encoded password used for EAP authentication methods.",
3456 							  NULL,
3457 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
3458 	
3459 		/**
3460 		 * NMSetting8021x:password-flags:
3461 		 *
3462 		 * Flags indicating how to handle #NMSetting8021x:password:.
3463 		 **/
3464 		g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS,
3465 			 g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_FLAGS,
3466 			                    "Password Flags",
3467 			                    "Flags indicating how to handle the 802.1x password.",
3468 			                    NM_SETTING_SECRET_FLAG_NONE,
3469 			                    NM_SETTING_SECRET_FLAGS_ALL,
3470 			                    NM_SETTING_SECRET_FLAG_NONE,
3471 			                    G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3472 	
3473 		/**
3474 		 * NMSetting8021x:password-raw:
3475 		 *
3476 		 * Password used for EAP authentication methods delivered as a
3477 		 * UTF-8-encoded array of bytes. If both #NMSetting8021x:password
3478 		 * and #NMSetting8021x:password-raw are specified,
3479 		 * #NMSetting8021x:password is preferred.
3480 		 **/
3481 		g_object_class_install_property
3482 			(object_class, PROP_PASSWORD_RAW,
3483 			 _nm_param_spec_specialized (NM_SETTING_802_1X_PASSWORD_RAW,
3484 			                             "Password byte array",
3485 			                             "Password used for EAP authentication "
3486 			                             "methods, given as a byte array to allow "
3487 			                             "passwords in other encodings than UTF-8 "
3488 			                             "to be used.  If both 'password' and "
3489 			                             "'password-raw' are given, 'password' is "
3490 			                             "preferred.",
3491 			                             DBUS_TYPE_G_UCHAR_ARRAY,
3492 			                             G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
3493 	
3494 		/**
3495 		 * NMSetting8021x:password-raw-flags:
3496 		 *
3497 		 * Flags indicating how to handle #NMSetting8021x:password-raw:.
3498 		 **/
3499 		g_object_class_install_property (object_class, PROP_PASSWORD_RAW_FLAGS,
3500 			 g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_RAW_FLAGS,
3501 			                    "Password byte array Flags",
3502 			                    "Flags indicating how to handle the 802.1x password byte array.",
3503 			                    NM_SETTING_SECRET_FLAG_NONE,
3504 			                    NM_SETTING_SECRET_FLAGS_ALL,
3505 			                    NM_SETTING_SECRET_FLAG_NONE,
3506 			                    G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3507 	
3508 		/**
3509 		 * NMSetting8021x:private-key:
3510 		 *
3511 		 * Contains the private key if the #NMSetting8021x:eap property is set to
3512 		 * 'tls'.  Setting this property directly is discouraged; use the
3513 		 * nm_setting_802_1x_set_private_key() function instead.
3514 		 *
3515 		 * WARNING: #NMSetting8021x:private-key is not a "secret" property, and thus
3516 		 * unencrypted private key data using the BLOB scheme may be readable by
3517 		 * unprivileged users.  Private keys should always be encrypted with a
3518 		 * private key password to prevent unauthorized access to unencrypted
3519 		 * private key data.
3520 		 **/
3521 		g_object_class_install_property
3522 			(object_class, PROP_PRIVATE_KEY,
3523 			 _nm_param_spec_specialized (NM_SETTING_802_1X_PRIVATE_KEY,
3524 								   "Private key",
3525 								   "Contains the private key when the 'eap' property "
3526 								   "is set to 'tls'.  Key data is specified using a "
3527 								   "'scheme'; two are currently supported: blob and "
3528 								   "path. When using the blob scheme and private "
3529 								   "keys, this property should be set to the key's "
3530 								   "encrypted PEM encoded data. When using private "
3531 								   "keys with the path scheme, this property should "
3532 								   "be set to the full UTF-8 encoded path of the key, "
3533 								   "prefixed with the string 'file://' and ending "
3534 								   "with a terminating NULL byte.  When using "
3535 								   "PKCS#12 format private keys and the blob "
3536 								   "scheme, this property should be set to the "
3537 								   "PKCS#12 data and the 'private-key-password' "
3538 								   "property must be set to password used to "
3539 								   "decrypt the PKCS#12 certificate and key.  When "
3540 								   "using PKCS#12 files and the path scheme, this "
3541 								   "property should be set to the full UTF-8 encoded "
3542 								   "path of the key, prefixed with the string "
3543 								   "'file://' and and ending with a terminating NULL "
3544 								   "byte, and as with the blob scheme the "
3545 								   "'private-key-password' property must be set to "
3546 								   "the password used to decode the PKCS#12 private "
3547 								   "key and certificate.",
3548 								   DBUS_TYPE_G_UCHAR_ARRAY,
3549 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3550 	
3551 		/**
3552 		 * NMSetting8021x:private-key-password:
3553 		 *
3554 		 * The password used to decrypt the private key specified in
3555 		 * #NMSetting8021x:private-key when the private key either uses the path
3556 		 * scheme, or if the private key is a PKCS#12 format key.  Setting this
3557 		 * property directly is not generally necessary except when returning
3558 		 * secrets to NetworkManager; it is generally set automatically when setting
3559 		 * the private key by the nm_setting_802_1x_set_private_key() function.
3560 		 **/
3561 		g_object_class_install_property
3562 			(object_class, PROP_PRIVATE_KEY_PASSWORD,
3563 			 g_param_spec_string (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD,
3564 							  "Private key password",
3565 							  "The password used to decrypt the private key "
3566 							  "specified in the 'private-key' property when the "
3567 							  "private key either uses the path scheme, or if the "
3568 							  "private key is a PKCS#12 format key.",
3569 							  NULL,
3570 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
3571 	
3572 		/**
3573 		 * NMSetting8021x:private-key-password-flags:
3574 		 *
3575 		 * Flags indicating how to handle #NMSetting8021x:private-key-password:.
3576 		 **/
3577 		g_object_class_install_property (object_class, PROP_PRIVATE_KEY_PASSWORD_FLAGS,
3578 			 g_param_spec_uint (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS,
3579 			                    "Private Key Password Flags",
3580 			                    "Flags indicating how to handle the 802.1x private "
3581 			                    "key password.",
3582 			                    NM_SETTING_SECRET_FLAG_NONE,
3583 			                    NM_SETTING_SECRET_FLAGS_ALL,
3584 			                    NM_SETTING_SECRET_FLAG_NONE,
3585 			                    G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3586 	
3587 		/**
3588 		 * NMSetting8021x:phase2-private-key:
3589 		 *
3590 		 * Private key data used by "phase 2" inner authentication methods.
3591 		 *
3592 		 * Contains the "phase 2" inner private key if the #NMSetting8021x:phase2-auth
3593 		 * or #NMSetting8021x:phase2-autheap property is set to 'tls'.  Setting this
3594 		 * property directly is discouraged; use the
3595 		 * nm_setting_802_1x_set_phase2_private_key() function instead.
3596 		 **/
3597 		g_object_class_install_property
3598 			(object_class, PROP_PHASE2_PRIVATE_KEY,
3599 			 _nm_param_spec_specialized (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
3600 								   "Phase2 private key",
3601 								   "Contains the 'phase 2' inner private key when "
3602 								   "the 'phase2-auth' or 'phase2-autheap' property "
3603 								   "is set to 'tls'.  Key data is specified using a "
3604 								   "'scheme'; two are currently supported: blob and "
3605 								   "path. When using the blob scheme and private "
3606 								   "keys, this property should be set to the key's "
3607 								   "encrypted PEM encoded data. When using private "
3608 								   "keys with the path scheme, this property should "
3609 								   "be set to the full UTF-8 encoded path of the key, "
3610 								   "prefixed with the string 'file://' and ending "
3611 								   "with a terminating NULL byte.  When using "
3612 								   "PKCS#12 format private keys and the blob "
3613 								   "scheme, this property should be set to the "
3614 								   "PKCS#12 data and the 'phase2-private-key-password' "
3615 								   "property must be set to password used to "
3616 								   "decrypt the PKCS#12 certificate and key.  When "
3617 								   "using PKCS#12 files and the path scheme, this "
3618 								   "property should be set to the full UTF-8 encoded "
3619 								   "path of the key, prefixed with the string "
3620 								   "'file://' and and ending with a terminating NULL "
3621 								   "byte, and as with the blob scheme the "
3622 								   "'phase2-private-key-password' property must be "
3623 								   "set to the password used to decode the PKCS#12 "
3624 								   "private key and certificate.",
3625 								   DBUS_TYPE_G_UCHAR_ARRAY,
3626 								   G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3627 	
3628 		/**
3629 		 * NMSetting8021x:phase2-private-key-password:
3630 		 *
3631 		 * The password used to decrypt the private key specified in
3632 		 * #NMSetting8021x:phase2-private-key when the private key either uses the
3633 		 * path scheme, or if the private key is a PKCS#12 format key.  Setting this
3634 		 * property directly is not generally necessary except when returning
3635 		 * secrets to NetworkManager; it is generally set automatically when setting
3636 		 * the private key by the nm_setting_802_1x_set_phase2_private_key() function.
3637 		 **/
3638 		g_object_class_install_property
3639 			(object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD,
3640 			 g_param_spec_string (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD,
3641 							  "Phase2 private key password",
3642 							  "The password used to decrypt the 'phase 2' private "
3643 							  "key specified in the 'private-key' property when the "
3644 							  "phase2 private key either uses the path scheme, or "
3645 							  "if the phase2 private key is a PKCS#12 format key.",
3646 							  NULL,
3647 							  G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
3648 	
3649 		/**
3650 		 * NMSetting8021x:phase2-private-key-password-flags:
3651 		 *
3652 		 * Flags indicating how to handle #NMSetting8021x:phase2-private-key-password:.
3653 		 **/
3654 		g_object_class_install_property (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS,
3655 			 g_param_spec_uint (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS,
3656 			                    "Phase2 Private Key Password Flags",
3657 			                    "Flags indicating how to handle the 802.1x phase2 "
3658 			                    "private key password.",
3659 			                    NM_SETTING_SECRET_FLAG_NONE,
3660 			                    NM_SETTING_SECRET_FLAGS_ALL,
3661 			                    NM_SETTING_SECRET_FLAG_NONE,
3662 			                    G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3663 	
3664 		/**
3665 		 * NMSetting8021x:pin:
3666 		 *
3667 		 * PIN used for EAP authentication methods.
3668 		 **/
3669 		g_object_class_install_property
3670 			(object_class, PROP_PIN,
3671 			 g_param_spec_string (NM_SETTING_802_1X_PIN,
3672 			                      "PIN",
3673 			                      "PIN used for EAP authentication methods.",
3674 			                      NULL,
3675 			                      G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET));
3676 	
3677 		/**
3678 		 * NMSetting8021x:pin-flags:
3679 		 *
3680 		 * Flags indicating how to handle #NMSetting8021x:pin:.
3681 		 **/
3682 		g_object_class_install_property (object_class, PROP_PIN_FLAGS,
3683 			 g_param_spec_uint (NM_SETTING_802_1X_PIN_FLAGS,
3684 			                    "PIN Flags",
3685 			                    "Flags indicating how to handle the 802.1x PIN.",
3686 			                    NM_SETTING_SECRET_FLAG_NONE,
3687 			                    NM_SETTING_SECRET_FLAGS_ALL,
3688 			                    NM_SETTING_SECRET_FLAG_NONE,
3689 			                    G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
3690 	
3691 		/**
3692 		 * NMSetting8021x:system-ca-certs:
3693 		 *
3694 		 * When TRUE, overrides #NMSetting8021x:ca-path and
3695 		 * #NMSetting8021x:phase2-ca-path properties using the system CA directory
3696 		 * specified at configure time with the --system-ca-path switch.  The
3697 		 * certificates in this directory are added to the verification chain in
3698 		 * addition to any certificates specified by the #NMSetting8021x:ca-cert
3699 		 * and #NMSetting8021x:phase2-ca-cert properties.
3700 		 **/
3701 		g_object_class_install_property
3702 			(object_class, PROP_SYSTEM_CA_CERTS,
3703 			 g_param_spec_boolean (NM_SETTING_802_1X_SYSTEM_CA_CERTS,
3704 								   "Use system CA certificates",
3705 								   "When TRUE, overrides 'ca-path' and 'phase2-ca-path' "
3706 								   "properties using the system CA directory "
3707 								   "specified at configure time with the "
3708 								   "--system-ca-path switch.  The certificates in "
3709 								   "this directory are added to the verification "
3710 								   "chain in addition to any certificates specified "
3711 								   "by the 'ca-cert' and 'phase2-ca-cert' properties.",
3712 								   FALSE,
3713 								   G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE));
3714 	
3715 		/* Initialize crypto lbrary. */
(2) Event example_checked: Example1: "nm_utils_init(&error)" has its value checked in "nm_utils_init(&error)".
Also see events: [check_return][example_checked][example_checked][example_checked][example_checked][unchecked_value]
3716 		if (!nm_utils_init (&error)) {
3717 			g_warning ("Couldn't initilize nm-utils/crypto system: %d %s",
3718 			           error->code, error->message);
3719 			g_error_free (error);
3720 		}
3721 	
3722 	}
3723