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