device: renew dhcp leases on awake for software devices
[NetworkManager.git] / libnm-util / nm-setting-wireless-security.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 - 2014 Red Hat, Inc.
20  * Copyright 2007 - 2008 Novell, Inc.
21  */
22
23 #include "nm-default.h"
24
25 #include <string.h>
26 #include <dbus/dbus-glib.h>
27
28 #include "nm-setting-wireless-security.h"
29 #include "nm-setting-8021x.h"
30 #include "nm-param-spec-specialized.h"
31 #include "nm-utils.h"
32 #include "nm-dbus-glib-types.h"
33 #include "nm-utils-private.h"
34 #include "nm-setting-private.h"
35
36 /**
37  * SECTION:nm-setting-wireless-security
38  * @short_description: Describes connection properties for Wi-Fi networks that
39  * use WEP, LEAP, WPA or WPA2/RSN security
40  * @include: nm-setting-wireless-security.h
41  *
42  * The #NMSettingWirelessSecurity object is a #NMSetting subclass that describes
43  * properties necessary for connection to encrypted Wi-Fi networks.
44  *
45  * It's a good idea to read up on wpa_supplicant configuration before using this
46  * setting extensively, since most of the options here correspond closely with
47  * the relevant wpa_supplicant configuration options.  To get a better overview
48  * of how Wi-Fi security works, you may want to get copies of the following books.
49  *
50  *  802.11 Wireless Networks: The Definitive Guide, Second Edition
51  *       Author: Matthew Gast
52  *       ISBN: 978-0596100520
53  *
54  *  Cisco Wireless LAN Security
55  *       Authors: Krishna Sankar, Sri Sundaralingam, Darrin Miller, and Andrew Balinsky
56  *       ISBN: 978-1587051548
57  **/
58
59 /**
60  * nm_setting_wireless_security_error_quark:
61  *
62  * Registers an error quark for #NMSettingWired if necessary.
63  *
64  * Returns: the error quark used for #NMSettingWired errors.
65  **/
66 GQuark
67 nm_setting_wireless_security_error_quark (void)
68 {
69         static GQuark quark;
70
71         if (G_UNLIKELY (!quark))
72                 quark = g_quark_from_static_string ("nm-setting-wireless-security-error-quark");
73         return quark;
74 }
75
76
77 G_DEFINE_TYPE_WITH_CODE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_SETTING,
78                          _nm_register_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
79                                                g_define_type_id,
80                                                2,
81                                                NM_SETTING_WIRELESS_SECURITY_ERROR))
82 NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_WIRELESS_SECURITY)
83
84 #define NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIRELESS_SECURITY, NMSettingWirelessSecurityPrivate))
85
86 typedef struct {
87         char *key_mgmt;
88         char *auth_alg;
89         GSList *proto; /* GSList of strings */
90         GSList *pairwise; /* GSList of strings */
91         GSList *group; /* GSList of strings */
92
93         /* LEAP */
94         char *leap_username;
95         char *leap_password;
96         NMSettingSecretFlags leap_password_flags;
97
98         /* WEP */
99         char *wep_key0;
100         char *wep_key1;
101         char *wep_key2;
102         char *wep_key3;
103         NMSettingSecretFlags wep_key_flags;
104         NMWepKeyType wep_key_type;
105         guint32 wep_tx_keyidx;
106
107         /* WPA-PSK */
108         char *psk;
109         NMSettingSecretFlags psk_flags;
110 } NMSettingWirelessSecurityPrivate;
111
112 enum {
113         PROP_0,
114         PROP_KEY_MGMT,
115         PROP_WEP_TX_KEYIDX,
116         PROP_AUTH_ALG,
117         PROP_PROTO,
118         PROP_PAIRWISE,
119         PROP_GROUP,
120         PROP_LEAP_USERNAME,
121         PROP_WEP_KEY0,
122         PROP_WEP_KEY1,
123         PROP_WEP_KEY2,
124         PROP_WEP_KEY3,
125         PROP_WEP_KEY_FLAGS,
126         PROP_WEP_KEY_TYPE,
127         PROP_PSK,
128         PROP_PSK_FLAGS,
129         PROP_LEAP_PASSWORD,
130         PROP_LEAP_PASSWORD_FLAGS,
131
132         LAST_PROP
133 };
134
135 /**
136  * nm_setting_wireless_security_new:
137  *
138  * Creates a new #NMSettingWirelessSecurity object with default values.
139  *
140  * Returns: (transfer full): the new empty #NMSettingWirelessSecurity object
141  **/
142 NMSetting *
143 nm_setting_wireless_security_new (void)
144 {
145         return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, NULL);
146 }
147
148 /**
149  * nm_setting_wireless_security_get_key_mgmt:
150  * @setting: the #NMSettingWirelessSecurity
151  *
152  * Returns: the #NMSettingWirelessSecurity:key-mgmt property of the setting
153  **/
154 const char *
155 nm_setting_wireless_security_get_key_mgmt (NMSettingWirelessSecurity *setting)
156 {
157         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
158
159         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->key_mgmt;
160 }
161
162 /**
163  * nm_setting_wireless_security_get_num_protos:
164  * @setting: the #NMSettingWirelessSecurity
165  *
166  * Returns: the number of security protocols this connection allows when
167  * connecting to secure Wi-Fi networks
168  **/
169 guint32
170 nm_setting_wireless_security_get_num_protos (NMSettingWirelessSecurity *setting)
171 {
172         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
173
174         return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->proto);
175 }
176
177 /**
178  * nm_setting_wireless_security_get_proto:
179  * @setting: the #NMSettingWirelessSecurity
180  * @i: an index into the protocol list
181  *
182  * Returns: the protocol at index @i
183  **/
184 const char *
185 nm_setting_wireless_security_get_proto (NMSettingWirelessSecurity *setting, guint32 i)
186 {
187         NMSettingWirelessSecurityPrivate *priv;
188
189         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
190
191         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
192         g_return_val_if_fail (i <= g_slist_length (priv->proto), NULL);
193
194         return (const char *) g_slist_nth_data (priv->proto, i);
195 }
196
197 /**
198  * nm_setting_wireless_security_add_proto:
199  * @setting: the #NMSettingWirelessSecurity
200  * @proto: the protocol to add, one of "wpa" or "rsn"
201  *
202  * Adds a Wi-Fi security protocol (one of "wpa" or "rsn") to the allowed list;
203  * only protocols in this list will be used when finding and connecting to
204  * the Wi-Fi network specified by this connection.  For example, if the
205  * protocol list contains only "wpa" but the access point for the SSID specified
206  * by this connection only supports WPA2/RSN, the connection cannot be used
207  * with the access point.
208  *
209  * Returns: %TRUE if the protocol was new and and was added to the allowed
210  * protocol list, or %FALSE if it was already in the list
211  **/
212 gboolean
213 nm_setting_wireless_security_add_proto (NMSettingWirelessSecurity *setting, const char *proto)
214 {
215         NMSettingWirelessSecurityPrivate *priv;
216         GSList *iter;
217
218         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
219         g_return_val_if_fail (proto != NULL, FALSE);
220
221         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
222         for (iter = priv->proto; iter; iter = g_slist_next (iter)) {
223                 if (strcasecmp (proto, (char *) iter->data) == 0)
224                         return FALSE;
225         }
226
227         priv->proto = g_slist_append (priv->proto, g_ascii_strdown (proto, -1));
228         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
229         return TRUE;
230 }
231
232 /**
233  * nm_setting_wireless_security_remove_proto:
234  * @setting: the #NMSettingWirelessSecurity
235  * @i: index of the protocol to remove
236  *
237  * Removes a protocol from the allowed protocol list.
238  **/
239 void
240 nm_setting_wireless_security_remove_proto (NMSettingWirelessSecurity *setting, guint32 i)
241 {
242         NMSettingWirelessSecurityPrivate *priv;
243         GSList *elt;
244
245         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
246
247         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
248         elt = g_slist_nth (priv->proto, i);
249         g_return_if_fail (elt != NULL);
250
251         g_free (elt->data);
252         priv->proto = g_slist_delete_link (priv->proto, elt);
253         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
254 }
255
256 /**
257  * nm_setting_wireless_security_remove_proto_by_value:
258  * @setting: the #NMSettingWirelessSecurity
259  * @proto: the protocol to remove, one of "wpa" or "rsn"
260  *
261  * Removes a protocol from the allowed protocol list.
262  *
263  * Returns: %TRUE if the protocol was found and removed; %FALSE it it was not.
264  *
265  * Since: 0.9.10
266  **/
267 gboolean
268 nm_setting_wireless_security_remove_proto_by_value (NMSettingWirelessSecurity *setting,
269                                                     const char *proto)
270 {
271         NMSettingWirelessSecurityPrivate *priv;
272         GSList *iter;
273
274         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
275         g_return_val_if_fail (proto != NULL, FALSE);
276
277         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
278         for (iter = priv->proto; iter; iter = g_slist_next (iter)) {
279                 if (strcasecmp (proto, (char *) iter->data) == 0) {
280                         priv->proto = g_slist_delete_link (priv->proto, iter);
281                         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
282                         return TRUE;
283                 }
284         }
285         return FALSE;
286 }
287
288 /**
289  * nm_setting_wireless_security_clear_protos:
290  * @setting: the #NMSettingWirelessSecurity
291  *
292  * Removes all protocols from the allowed list.  If there are no protocols
293  * specified then all protocols are allowed.
294  **/
295 void
296 nm_setting_wireless_security_clear_protos (NMSettingWirelessSecurity *setting)
297 {
298         NMSettingWirelessSecurityPrivate *priv;
299
300         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
301
302         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
303         g_slist_free_full (priv->proto, g_free);
304         priv->proto = NULL;
305         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PROTO);
306 }
307
308 /**
309  * nm_setting_wireless_security_get_num_pairwise:
310  * @setting: the #NMSettingWirelessSecurity
311  *
312  * Returns: the number of pairwise encryption algorithms in the allowed list
313  **/
314 guint32
315 nm_setting_wireless_security_get_num_pairwise (NMSettingWirelessSecurity *setting)
316 {
317         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
318
319         return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->pairwise);
320 }
321
322 /**
323  * nm_setting_wireless_security_get_pairwise:
324  * @setting: the #NMSettingWirelessSecurity
325  * @i: index of an item in the allowed pairwise encryption algorithm list
326  *
327  * Returns the allowed pairwise encryption algorithm from allowed algorithm
328  * list.
329  *
330  * Returns: the pairwise encryption algorithm at index @i
331  **/
332 const char *
333 nm_setting_wireless_security_get_pairwise (NMSettingWirelessSecurity *setting, guint32 i)
334 {
335         NMSettingWirelessSecurityPrivate *priv;
336
337         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
338
339         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
340         g_return_val_if_fail (i <= g_slist_length (priv->pairwise), NULL);
341
342         return (const char *) g_slist_nth_data (priv->pairwise, i);
343 }
344
345 /**
346  * nm_setting_wireless_security_add_pairwise:
347  * @setting: the #NMSettingWirelessSecurity
348  * @pairwise: the encryption algorithm to add, one of "tkip" or "ccmp"
349  *
350  * Adds an encryption algorithm to the list of allowed pairwise encryption
351  * algorithms.  If the list is not empty, then only access points that support
352  * one or more of the encryption algorithms in the list will be considered
353  * compatible with this connection.
354  *
355  * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was
356  * already in the list
357  **/
358 gboolean
359 nm_setting_wireless_security_add_pairwise (NMSettingWirelessSecurity *setting, const char *pairwise)
360 {
361         NMSettingWirelessSecurityPrivate *priv;
362         GSList *iter;
363
364         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
365         g_return_val_if_fail (pairwise != NULL, FALSE);
366
367         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
368         for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) {
369                 if (strcasecmp (pairwise, (char *) iter->data) == 0)
370                         return FALSE;
371         }
372
373         priv->pairwise = g_slist_append (priv->pairwise, g_ascii_strdown (pairwise, -1));
374         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
375         return TRUE;
376 }
377
378 /**
379  * nm_setting_wireless_security_remove_pairwise:
380  * @setting: the #NMSettingWirelessSecurity
381  * @i: the index of an item in the allowed pairwise encryption algorithm list
382  *
383  * Removes an encryption algorithm from the allowed pairwise encryption
384  * algorithm list.
385  **/
386 void
387 nm_setting_wireless_security_remove_pairwise (NMSettingWirelessSecurity *setting, guint32 i)
388 {
389         NMSettingWirelessSecurityPrivate *priv;
390         GSList *elt;
391
392         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
393
394         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
395         elt = g_slist_nth (priv->pairwise, i);
396         g_return_if_fail (elt != NULL);
397
398         g_free (elt->data);
399         priv->pairwise = g_slist_delete_link (priv->pairwise, elt);
400         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
401 }
402
403 /**
404  * nm_setting_wireless_security_remove_pairwise_by_value:
405  * @setting: the #NMSettingWirelessSecurity
406  * @pairwise: the encryption algorithm to remove, one of "tkip" or "ccmp"
407  *
408  * Removes an encryption algorithm from the allowed pairwise encryption
409  * algorithm list.
410  *
411  * Returns: %TRUE if the encryption algorith was found and removed; %FALSE it it was not.
412  *
413  * Since: 0.9.10
414  **/
415 gboolean
416 nm_setting_wireless_security_remove_pairwise_by_value (NMSettingWirelessSecurity *setting,
417                                                        const char *pairwise)
418 {
419         NMSettingWirelessSecurityPrivate *priv;
420         GSList *iter;
421
422         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
423         g_return_val_if_fail (pairwise != NULL, FALSE);
424
425         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
426         for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) {
427                 if (strcasecmp (pairwise, (char *) iter->data) == 0) {
428                         priv->pairwise = g_slist_delete_link (priv->pairwise, iter);
429                         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
430                         return TRUE;
431                 }
432         }
433         return FALSE;
434 }
435
436 /**
437  * nm_setting_wireless_security_clear_pairwise:
438  * @setting: the #NMSettingWirelessSecurity
439  *
440  * Removes all algorithms from the allowed list.  If there are no algorithms
441  * specified then all pairwise encryption algorithms are allowed.
442  **/
443 void
444 nm_setting_wireless_security_clear_pairwise (NMSettingWirelessSecurity *setting)
445 {
446         NMSettingWirelessSecurityPrivate *priv;
447
448         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
449
450         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
451         g_slist_free_full (priv->pairwise, g_free);
452         priv->pairwise = NULL;
453         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
454 }
455
456 /**
457  * nm_setting_wireless_security_get_num_groups:
458  * @setting: the #NMSettingWirelessSecurity
459  *
460  * Returns: the number of groupwise encryption algorithms in the allowed list
461  **/
462 guint32
463 nm_setting_wireless_security_get_num_groups (NMSettingWirelessSecurity *setting)
464 {
465         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
466
467         return g_slist_length (NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->group);
468 }
469
470 /**
471  * nm_setting_wireless_security_get_group:
472  * @setting: the #NMSettingWirelessSecurity
473  * @i: index of an item in the allowed groupwise encryption algorithm list
474  *
475  * Returns the allowed groupwise encryption algorithm from allowed algorithm
476  * list.
477  *
478  * Returns: the groupwise encryption algorithm at index @i
479  **/
480 const char *
481 nm_setting_wireless_security_get_group (NMSettingWirelessSecurity *setting, guint32 i)
482 {
483         NMSettingWirelessSecurityPrivate *priv;
484
485         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
486
487         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
488         g_return_val_if_fail (i <= g_slist_length (priv->group), NULL);
489
490         return (const char *) g_slist_nth_data (priv->group, i);
491 }
492
493 /**
494  * nm_setting_wireless_security_add_group:
495  * @setting: the #NMSettingWirelessSecurity
496  * @group: the encryption algorithm to add, one of "wep40", "wep104",
497  * "tkip", or "ccmp"
498  *
499  * Adds an encryption algorithm to the list of allowed groupwise encryption
500  * algorithms.  If the list is not empty, then only access points that support
501  * one or more of the encryption algorithms in the list will be considered
502  * compatible with this connection.
503  *
504  * Returns: %TRUE if the algorithm was added to the list, %FALSE if it was
505  * already in the list
506  **/
507 gboolean
508 nm_setting_wireless_security_add_group (NMSettingWirelessSecurity *setting, const char *group)
509 {
510         NMSettingWirelessSecurityPrivate *priv;
511         GSList *iter;
512
513         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
514         g_return_val_if_fail (group != NULL, FALSE);
515
516         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
517         for (iter = priv->group; iter; iter = g_slist_next (iter)) {
518                 if (strcasecmp (group, (char *) iter->data) == 0)
519                         return FALSE;
520         }
521
522         priv->group = g_slist_append (priv->group, g_ascii_strdown (group, -1));
523         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
524         return TRUE;
525 }
526
527 /**
528  * nm_setting_wireless_security_remove_group:
529  * @setting: the #NMSettingWirelessSecurity
530  * @i: the index of an item in the allowed groupwise encryption algorithm list
531  *
532  * Removes an encryption algorithm from the allowed groupwise encryption
533  * algorithm list.
534  **/
535 void
536 nm_setting_wireless_security_remove_group (NMSettingWirelessSecurity *setting, guint32 i)
537 {
538         NMSettingWirelessSecurityPrivate *priv;
539         GSList *elt;
540
541         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
542
543         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
544         elt = g_slist_nth (priv->group, i);
545         g_return_if_fail (elt != NULL);
546
547         g_free (elt->data);
548         priv->group = g_slist_delete_link (priv->group, elt);
549         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
550 }
551
552 /**
553  * nm_setting_wireless_security_remove_group_by_value:
554  * @setting: the #NMSettingWirelessSecurity
555  * @group: the encryption algorithm to remove, one of "wep40", "wep104",
556  * "tkip", or "ccmp"
557  *
558  * Removes an encryption algorithm from the allowed groupwise encryption
559  * algorithm list.
560  *
561  * Returns: %TRUE if the algorithm was found and removed; %FALSE it it was not.
562  *
563  * Since: 0.9.10
564  **/
565 gboolean
566 nm_setting_wireless_security_remove_group_by_value (NMSettingWirelessSecurity *setting,
567                                                     const char *group)
568 {
569         NMSettingWirelessSecurityPrivate *priv;
570         GSList *iter;
571
572         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), FALSE);
573         g_return_val_if_fail (group != NULL, FALSE);
574
575         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
576         for (iter = priv->group; iter; iter = g_slist_next (iter)) {
577                 if (strcasecmp (group, (char *) iter->data) == 0) {
578                         priv->group = g_slist_delete_link (priv->group, iter);
579                         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
580                         return TRUE;
581                 }
582         }
583         return FALSE;
584 }
585
586 /**
587  * nm_setting_wireless_security_clear_groups:
588  * @setting: the #NMSettingWirelessSecurity
589  *
590  * Removes all algorithms from the allowed list.  If there are no algorithms
591  * specified then all groupwise encryption algorithms are allowed.
592  **/
593 void
594 nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting)
595 {
596         NMSettingWirelessSecurityPrivate *priv;
597
598         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
599
600         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
601         g_slist_free_full (priv->group, g_free);
602         priv->group = NULL;
603         g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_GROUP);
604 }
605
606 /**
607  * nm_setting_wireless_security_get_psk:
608  * @setting: the #NMSettingWirelessSecurity
609  *
610  * Returns: the #NMSettingWirelessSecurity:psk property of the setting
611  **/
612 const char *
613 nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting)
614 {
615         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
616
617         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk;
618 }
619
620 /**
621  * nm_setting_wireless_security_get_psk_flags:
622  * @setting: the #NMSettingWirelessSecurity
623  *
624  * Returns: the #NMSettingSecretFlags pertaining to the
625  * #NMSettingWirelessSecurity:psk
626  **/
627 NMSettingSecretFlags
628 nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting)
629 {
630         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE);
631
632         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk_flags;
633 }
634
635 /**
636  * nm_setting_wireless_security_get_leap_username:
637  * @setting: the #NMSettingWirelessSecurity
638  *
639  * Returns: the #NMSettingWirelessSecurity:leap-username property of the setting
640  **/
641 const char *
642 nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting)
643 {
644         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
645
646         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_username;
647 }
648
649 /**
650  * nm_setting_wireless_security_get_leap_password:
651  * @setting: the #NMSettingWirelessSecurity
652  *
653  * Returns: the #NMSettingWirelessSecurity:leap-password property of the setting
654  **/
655 const char *
656 nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setting)
657 {
658         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
659
660         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password;
661 }
662
663 /**
664  * nm_setting_wireless_security_get_leap_password_flags:
665  * @setting: the #NMSettingWirelessSecurity
666  *
667  * Returns: the #NMSettingSecretFlags pertaining to the
668  * #NMSettingWirelessSecurity:leap-password
669  **/
670 NMSettingSecretFlags
671 nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting)
672 {
673         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE);
674
675         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password_flags;
676 }
677
678 /**
679  * nm_setting_wireless_security_get_wep_key:
680  * @setting: the #NMSettingWirelessSecurity
681  * @idx: the WEP key index (0..3 inclusive)
682  *
683  * Returns: the WEP key at the given index
684  **/
685 const char *
686 nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx)
687 {
688         NMSettingWirelessSecurityPrivate *priv;
689
690         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
691         g_return_val_if_fail (idx < 4, NULL);
692
693         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
694         if (idx == 0)
695                 return priv->wep_key0;
696         else if (idx == 1)
697                 return priv->wep_key1;
698         else if (idx == 2)
699                 return priv->wep_key2;
700         else if (idx == 3)
701                 return priv->wep_key3;
702
703         g_assert_not_reached ();
704         return NULL;
705 }
706
707 /**
708  * nm_setting_wireless_security_set_wep_key:
709  * @setting: the #NMSettingWirelessSecurity
710  * @idx: the index of the key (0..3 inclusive)
711  * @key: the WEP key as a string, in either hexadecimal, ASCII, or passphrase
712  * form as determiend by the value of the #NMSettingWirelessSecurity:wep-key-type
713  * property.
714  *
715  * Sets a WEP key in the given index.
716  **/
717 void
718 nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key)
719 {
720         NMSettingWirelessSecurityPrivate *priv;
721
722         g_return_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting));
723         g_return_if_fail (idx < 4);
724
725         priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
726         switch (idx) {
727         case 0:
728                 g_free (priv->wep_key0);
729                 priv->wep_key0 = g_strdup (key);
730                 g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
731                 break;
732         case 1:
733                 g_free (priv->wep_key1);
734                 priv->wep_key1 = g_strdup (key);
735                 g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
736                 break;
737         case 2:
738                 g_free (priv->wep_key2);
739                 priv->wep_key2 = g_strdup (key);
740                 g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
741                 break;
742         case 3:
743                 g_free (priv->wep_key3);
744                 priv->wep_key3 = g_strdup (key);
745                 g_object_notify (G_OBJECT (setting), NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
746                 break;
747         default:
748                 g_assert_not_reached ();
749         }
750 }
751
752 /**
753  * nm_setting_wireless_security_get_wep_tx_keyidx:
754  * @setting: the #NMSettingWirelessSecurity
755  *
756  * Returns: the #NMSettingWirelessSecurity:wep-tx-keyidx property of the setting
757  **/
758 guint32
759 nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting)
760 {
761         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
762
763         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_tx_keyidx;
764 }
765
766 /**
767  * nm_setting_wireless_security_get_auth_alg:
768  * @setting: the #NMSettingWirelessSecurity
769  *
770  * Returns: the #NMSettingWirelessSecurity:auth-alg property of the setting
771  **/
772 const char *
773 nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting)
774 {
775         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NULL);
776
777         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->auth_alg;
778 }
779
780 /**
781  * nm_setting_wireless_security_get_wep_key_flags:
782  * @setting: the #NMSettingWirelessSecurity
783  *
784  * Returns: the #NMSettingSecretFlags pertaining to the all WEP keys
785  **/
786 NMSettingSecretFlags
787 nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting)
788 {
789         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE);
790
791         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_flags;
792 }
793
794 /**
795  * nm_setting_wireless_security_get_wep_key_type:
796  * @setting: the #NMSettingWirelessSecurity
797  *
798  * Returns: the #NMSettingWirelessSecurity:wep-key-type property of the setting
799  **/
800 NMWepKeyType
801 nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting)
802 {
803         g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), 0);
804
805         return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_type;
806 }
807
808 static GPtrArray *
809 need_secrets (NMSetting *setting)
810 {
811         NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting);
812         NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
813         GPtrArray *secrets;
814
815         secrets = g_ptr_array_sized_new (4);
816
817         g_assert (priv->key_mgmt);
818
819         /* Static WEP */
820         if (strcmp (priv->key_mgmt, "none") == 0) {
821                 if ((priv->wep_tx_keyidx == 0) && !nm_utils_wep_key_valid (priv->wep_key0, priv->wep_key_type)) {
822                         g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0);
823                         return secrets;
824                 }
825                 if ((priv->wep_tx_keyidx == 1) && !nm_utils_wep_key_valid (priv->wep_key1, priv->wep_key_type)) {
826                         g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1);
827                         return secrets;
828                 }
829                 if ((priv->wep_tx_keyidx == 2) && !nm_utils_wep_key_valid (priv->wep_key2, priv->wep_key_type)) {
830                         g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2);
831                         return secrets;
832                 }
833                 if ((priv->wep_tx_keyidx == 3) && !nm_utils_wep_key_valid (priv->wep_key3, priv->wep_key_type)) {
834                         g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3);
835                         return secrets;
836                 }
837                 goto no_secrets;
838         }
839
840         /* WPA-PSK infrastructure and adhoc */
841         if (   (strcmp (priv->key_mgmt, "wpa-none") == 0)
842             || (strcmp (priv->key_mgmt, "wpa-psk") == 0)) {
843                 if (!nm_utils_wpa_psk_valid (priv->psk)) {
844                         g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_PSK);
845                         return secrets;
846                 }
847                 goto no_secrets;
848         }
849
850         /* LEAP */
851         if (   priv->auth_alg
852             && !strcmp (priv->auth_alg, "leap")
853             && !strcmp (priv->key_mgmt, "ieee8021x")) {
854                 if (!priv->leap_password || !*priv->leap_password) {
855                         g_ptr_array_add (secrets, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD);
856                         return secrets;
857                 }
858                 goto no_secrets;
859         }
860
861         if (   (strcmp (priv->key_mgmt, "ieee8021x") == 0)
862             || (strcmp (priv->key_mgmt, "wpa-eap") == 0)) {
863                 /* Let caller check the 802.1x setting for secrets */
864                 goto no_secrets;
865         }
866
867         g_assert_not_reached ();
868         return secrets;
869
870 no_secrets:
871         if (secrets)
872                 g_ptr_array_free (secrets, TRUE);
873         return NULL;
874 }
875
876 static gboolean
877 verify (NMSetting *setting, GSList *all_settings, GError **error)
878 {
879         NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (setting);
880         NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
881         const char *valid_key_mgmt[] = { "none", "ieee8021x", "wpa-none", "wpa-psk", "wpa-eap", NULL };
882         const char *valid_auth_algs[] = { "open", "shared", "leap", NULL };
883         const char *valid_protos[] = { "wpa", "rsn", NULL };
884         const char *valid_pairwise[] = { "tkip", "ccmp", NULL };
885         const char *valid_groups[] = { "wep40", "wep104", "tkip", "ccmp", NULL };
886
887         if (!priv->key_mgmt) {
888                 g_set_error_literal (error,
889                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
890                                      NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_PROPERTY,
891                                      _("property is missing"));
892                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
893                 return FALSE;
894         }
895
896         if (!_nm_utils_string_in_list (priv->key_mgmt, valid_key_mgmt)) {
897                 g_set_error (error,
898                              NM_SETTING_WIRELESS_SECURITY_ERROR,
899                              NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
900                              _("'%s' is not a valid value for the property"),
901                              priv->key_mgmt);
902                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
903                 return FALSE;
904         }
905
906         if (priv->auth_alg && !strcmp (priv->auth_alg, "leap")) {
907                 /* LEAP must use ieee8021x key management */
908                 if (strcmp (priv->key_mgmt, "ieee8021x")) {
909                         g_set_error (error,
910                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
911                                      NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X,
912                                      _("'%s' security requires '%s=%s'"),
913                                      "leap", NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x");
914                         g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
915                         return FALSE;
916                 }
917                 if (!priv->leap_username) {
918                         g_set_error_literal (error,
919                                              NM_SETTING_WIRELESS_SECURITY_ERROR,
920                                              NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME,
921                                              _("property is empty"));
922                         g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
923                         return FALSE;
924                 }
925         } else {
926                 if (   (strcmp (priv->key_mgmt, "ieee8021x") == 0)
927                     || (strcmp (priv->key_mgmt, "wpa-eap") == 0)) {
928                         /* Need an 802.1x setting too */
929                         if (!nm_setting_find_in_list (all_settings, NM_SETTING_802_1X_SETTING_NAME)) {
930                                 g_set_error (error,
931                                              NM_SETTING_WIRELESS_SECURITY_ERROR,
932                                              NM_SETTING_WIRELESS_SECURITY_ERROR_MISSING_802_1X_SETTING,
933                                              _("'%s' security requires '%s' setting presence"),
934                                              priv->key_mgmt, NM_SETTING_802_1X_SETTING_NAME);
935                                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT);
936                                 return FALSE;
937                         }
938                 }
939         }
940
941         if (priv->leap_username && !strlen (priv->leap_username)) {
942                 g_set_error_literal (error,
943                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
944                                      NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
945                                      _("property is empty"));
946                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME);
947                 return FALSE;
948         }
949
950         if (priv->wep_tx_keyidx > 3) {
951                 g_set_error (error,
952                              NM_SETTING_WIRELESS_SECURITY_ERROR,
953                              NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
954                              _("'%d' value is out of range <0-3>"),
955                              priv->wep_tx_keyidx);
956                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX);
957                 return FALSE;
958         }
959
960         if (priv->wep_key_type > NM_WEP_KEY_TYPE_LAST) {
961                 g_set_error_literal (error,
962                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
963                                      NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
964                                      _("property is invalid"));
965                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE);
966                 return FALSE;
967         }
968
969         if (priv->auth_alg && !_nm_utils_string_in_list (priv->auth_alg, valid_auth_algs)) {
970                 g_set_error_literal (error,
971                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
972                                      NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
973                                      _("property is invalid"));
974                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
975                 return FALSE;
976         }
977
978         if (priv->proto && !_nm_utils_string_slist_validate (priv->proto, valid_protos)) {
979                 g_set_error_literal (error,
980                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
981                                      NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
982                                      _("property is invalid"));
983                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PROTO);
984                 return FALSE;
985         }
986
987         if (priv->pairwise) {
988                 const char *wpa_none[] = { "wpa-none", NULL };
989
990                 /* For ad-hoc connections, pairwise must be "none" */
991                 if (_nm_utils_string_in_list (priv->key_mgmt, wpa_none)) {
992                         GSList *iter;
993                         gboolean found = FALSE;
994
995                         for (iter = priv->pairwise; iter; iter = g_slist_next (iter)) {
996                                 if (!strcmp ((char *) iter->data, "none")) {
997                                         found = TRUE;
998                                         break;
999                                 }
1000                         }
1001
1002                         /* pairwise cipher list didn't contain "none", which is invalid
1003                          * for WPA adhoc connections.
1004                          */
1005                         if (!found) {
1006                                 g_set_error (error,
1007                                              NM_SETTING_WIRELESS_SECURITY_ERROR,
1008                                              NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
1009                                              _("'%s' connections require '%s' in this property"),
1010                                              NM_SETTING_WIRELESS_MODE_ADHOC, "none");
1011                                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
1012                                 return FALSE;
1013                         }
1014                 } else if (!_nm_utils_string_slist_validate (priv->pairwise, valid_pairwise)) {
1015                         g_set_error_literal (error,
1016                                              NM_SETTING_WIRELESS_SECURITY_ERROR,
1017                                              NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
1018                                              _("property is invalid"));
1019                         g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_PAIRWISE);
1020                         return FALSE;
1021                 }
1022         }
1023
1024         if (priv->group && !_nm_utils_string_slist_validate (priv->group, valid_groups)) {
1025                 g_set_error_literal (error,
1026                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
1027                                      NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY,
1028                                      _("property is invalid"));
1029                 g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_GROUP);
1030                 return FALSE;
1031         }
1032
1033         /* Shared Key auth can only be used with WEP */
1034         if (priv->auth_alg && !strcmp (priv->auth_alg, "shared")) {
1035                 if (priv->key_mgmt && strcmp (priv->key_mgmt, "none")) {
1036                         g_set_error (error,
1037                                      NM_SETTING_WIRELESS_SECURITY_ERROR,
1038                                      NM_SETTING_WIRELESS_SECURITY_ERROR_SHARED_KEY_REQUIRES_WEP,
1039                                      _("'%s' can only be used with '%s=%s' (WEP)"),
1040                                      "shared", NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none");
1041                         g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG);
1042                         return FALSE;
1043                 }
1044         }
1045
1046         return TRUE;
1047 }
1048
1049 static gboolean
1050 get_secret_flags (NMSetting *setting,
1051                   const char *secret_name,
1052                   gboolean verify_secret,
1053                   NMSettingSecretFlags *out_flags,
1054                   GError **error)
1055 {
1056         NMSettingClass *setting_class;
1057         gboolean verify_override = verify_secret;
1058
1059         /* There's only one 'flags' property for WEP keys, so alias all the WEP key
1060          * property names to that flags property.
1061          */
1062         if (   !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)
1063             || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1)
1064             || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2)
1065             || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
1066                 secret_name = "wep-key";
1067                 verify_override = FALSE; /* Already know it's a secret */
1068         }
1069
1070         /* Chain up to superclass with modified key name */
1071         setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class);
1072         return setting_class->get_secret_flags (setting, secret_name, verify_override, out_flags, error);
1073 }
1074
1075 static gboolean
1076 set_secret_flags (NMSetting *setting,
1077                   const char *secret_name,
1078                   gboolean verify_secret,
1079                   NMSettingSecretFlags flags,
1080                   GError **error)
1081 {
1082         NMSettingClass *setting_class;
1083         gboolean verify_override = verify_secret;
1084
1085         /* There's only one 'flags' property for WEP keys, so alias all the WEP key
1086          * property names to that flags property.
1087          */
1088         if (   !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)
1089             || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1)
1090             || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2)
1091             || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
1092                 secret_name = "wep-key";
1093                 verify_override = FALSE; /* Already know it's a secret */
1094         }
1095
1096         /* Chain up to superclass with modified key name */
1097         setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class);
1098         return setting_class->set_secret_flags (setting, secret_name, verify_override, flags, error);
1099 }
1100
1101 static void
1102 nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting)
1103 {
1104 }
1105
1106 static void
1107 finalize (GObject *object)
1108 {
1109         NMSettingWirelessSecurity *self = NM_SETTING_WIRELESS_SECURITY (object);
1110         NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (self);
1111
1112         /* Strings first. g_free() already checks for NULLs so we don't have to */
1113
1114         g_free (priv->key_mgmt);
1115         g_free (priv->auth_alg);
1116         g_free (priv->leap_username);
1117         g_free (priv->wep_key0);
1118         g_free (priv->wep_key1);
1119         g_free (priv->wep_key2);
1120         g_free (priv->wep_key3);
1121         g_free (priv->psk);
1122         g_free (priv->leap_password);
1123
1124         g_slist_free_full (priv->proto, g_free);
1125         g_slist_free_full (priv->pairwise, g_free);
1126         g_slist_free_full (priv->group, g_free);
1127
1128         G_OBJECT_CLASS (nm_setting_wireless_security_parent_class)->finalize (object);
1129 }
1130
1131 static void
1132 set_property (GObject *object, guint prop_id,
1133               const GValue *value, GParamSpec *pspec)
1134 {
1135         NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object);
1136         NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
1137         const char *str;
1138
1139         switch (prop_id) {
1140         case PROP_KEY_MGMT:
1141                 g_free (priv->key_mgmt);
1142                 str = g_value_get_string (value);
1143                 priv->key_mgmt = str ? g_ascii_strdown (str, -1) : NULL;
1144                 break;
1145         case PROP_WEP_TX_KEYIDX:
1146                 priv->wep_tx_keyidx = g_value_get_uint (value);
1147                 break;
1148         case PROP_AUTH_ALG:
1149                 g_free (priv->auth_alg);
1150                 str = g_value_get_string (value);
1151                 priv->auth_alg = str ? g_ascii_strdown (str, -1) : NULL;
1152                 break;
1153         case PROP_PROTO:
1154                 g_slist_free_full (priv->proto, g_free);
1155                 priv->proto = g_value_dup_boxed (value);
1156                 break;
1157         case PROP_PAIRWISE:
1158                 g_slist_free_full (priv->pairwise, g_free);
1159                 priv->pairwise = g_value_dup_boxed (value);
1160                 break;
1161         case PROP_GROUP:
1162                 g_slist_free_full (priv->group, g_free);
1163                 priv->group = g_value_dup_boxed (value);
1164                 break;
1165         case PROP_LEAP_USERNAME:
1166                 g_free (priv->leap_username);
1167                 priv->leap_username = g_value_dup_string (value);
1168                 break;
1169         case PROP_WEP_KEY0:
1170                 g_free (priv->wep_key0);
1171                 priv->wep_key0 = g_value_dup_string (value);
1172                 break;
1173         case PROP_WEP_KEY1:
1174                 g_free (priv->wep_key1);
1175                 priv->wep_key1 = g_value_dup_string (value);
1176                 break;
1177         case PROP_WEP_KEY2:
1178                 g_free (priv->wep_key2);
1179                 priv->wep_key2 = g_value_dup_string (value);
1180                 break;
1181         case PROP_WEP_KEY3:
1182                 g_free (priv->wep_key3);
1183                 priv->wep_key3 = g_value_dup_string (value);
1184                 break;
1185         case PROP_WEP_KEY_FLAGS:
1186                 priv->wep_key_flags = g_value_get_uint (value);
1187                 break;
1188         case PROP_PSK:
1189                 g_free (priv->psk);
1190                 priv->psk = g_value_dup_string (value);
1191                 break;
1192         case PROP_PSK_FLAGS:
1193                 priv->psk_flags = g_value_get_uint (value);
1194                 break;
1195         case PROP_LEAP_PASSWORD:
1196                 g_free (priv->leap_password);
1197                 priv->leap_password = g_value_dup_string (value);
1198                 break;
1199         case PROP_LEAP_PASSWORD_FLAGS:
1200                 priv->leap_password_flags = g_value_get_uint (value);
1201                 break;
1202         case PROP_WEP_KEY_TYPE:
1203                 priv->wep_key_type = g_value_get_uint (value);
1204                 break;
1205         default:
1206                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1207                 break;
1208         }
1209 }
1210
1211 static void
1212 get_property (GObject *object, guint prop_id,
1213               GValue *value, GParamSpec *pspec)
1214 {
1215         NMSettingWirelessSecurity *setting = NM_SETTING_WIRELESS_SECURITY (object);
1216         NMSettingWirelessSecurityPrivate *priv = NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting);
1217
1218         switch (prop_id) {
1219         case PROP_KEY_MGMT:
1220                 g_value_set_string (value, priv->key_mgmt);
1221                 break;
1222         case PROP_WEP_TX_KEYIDX:
1223                 g_value_set_uint (value, priv->wep_tx_keyidx);
1224                 break;
1225         case PROP_AUTH_ALG:
1226                 g_value_set_string (value, priv->auth_alg);
1227                 break;
1228         case PROP_PROTO:
1229                 g_value_set_boxed (value, priv->proto);
1230                 break;
1231         case PROP_PAIRWISE:
1232                 g_value_set_boxed (value, priv->pairwise);
1233                 break;
1234         case PROP_GROUP:
1235                 g_value_set_boxed (value, priv->group);
1236                 break;
1237         case PROP_LEAP_USERNAME:
1238                 g_value_set_string (value, priv->leap_username);
1239                 break;
1240         case PROP_WEP_KEY0:
1241                 g_value_set_string (value, priv->wep_key0);
1242                 break;
1243         case PROP_WEP_KEY1:
1244                 g_value_set_string (value, priv->wep_key1);
1245                 break;
1246         case PROP_WEP_KEY2:
1247                 g_value_set_string (value, priv->wep_key2);
1248                 break;
1249         case PROP_WEP_KEY3:
1250                 g_value_set_string (value, priv->wep_key3);
1251                 break;
1252         case PROP_WEP_KEY_FLAGS:
1253                 g_value_set_uint (value, priv->wep_key_flags);
1254                 break;
1255         case PROP_PSK:
1256                 g_value_set_string (value, priv->psk);
1257                 break;
1258         case PROP_PSK_FLAGS:
1259                 g_value_set_uint (value, priv->psk_flags);
1260                 break;
1261         case PROP_LEAP_PASSWORD:
1262                 g_value_set_string (value, priv->leap_password);
1263                 break;
1264         case PROP_LEAP_PASSWORD_FLAGS:
1265                 g_value_set_uint (value, priv->leap_password_flags);
1266                 break;
1267         case PROP_WEP_KEY_TYPE:
1268                 g_value_set_uint (value, priv->wep_key_type);
1269                 break;
1270         default:
1271                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1272                 break;
1273         }
1274 }
1275
1276 static void
1277 nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting_class)
1278 {
1279         GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
1280         NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
1281
1282         g_type_class_add_private (setting_class, sizeof (NMSettingWirelessSecurityPrivate));
1283
1284         /* virtual methods */
1285         object_class->set_property = set_property;
1286         object_class->get_property = get_property;
1287         object_class->finalize     = finalize;
1288
1289         parent_class->verify           = verify;
1290         parent_class->need_secrets     = need_secrets;
1291         parent_class->get_secret_flags = get_secret_flags;
1292         parent_class->set_secret_flags = set_secret_flags;
1293
1294         /* Properties */
1295         /**
1296          * NMSettingWirelessSecurity:key-mgmt:
1297          *
1298          * Key management used for the connection.  One of "none" (WEP), "ieee8021x"
1299          * (Dynamic WEP), "wpa-none" (Ad-Hoc WPA-PSK), "wpa-psk" (infrastructure
1300          * WPA-PSK), or "wpa-eap" (WPA-Enterprise).  This property must be set for
1301          * any Wi-Fi connection that uses security.
1302          **/
1303         g_object_class_install_property
1304                 (object_class, PROP_KEY_MGMT,
1305                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "", "",
1306                                       NULL,
1307                                       G_PARAM_READWRITE |
1308                                       NM_SETTING_PARAM_REQUIRED |
1309                                       G_PARAM_STATIC_STRINGS));
1310
1311         /**
1312          * NMSettingWirelessSecurity:wep-tx-keyidx:
1313          *
1314          * When static WEP is used (ie, key-mgmt = "none") and a non-default WEP key
1315          * index is used by the AP, put that WEP key index here.  Valid values are 0
1316          * (default key) through 3.  Note that some consumer access points (like the
1317          * Linksys WRT54G) number the keys 1 - 4.
1318          **/
1319         g_object_class_install_property
1320                 (object_class, PROP_WEP_TX_KEYIDX,
1321                  g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, "", "",
1322                                     0, 3, 0,
1323                                     G_PARAM_READWRITE |
1324                                     G_PARAM_CONSTRUCT |
1325                                     G_PARAM_STATIC_STRINGS));
1326
1327         /**
1328          * NMSettingWirelessSecurity:auth-alg:
1329          *
1330          * When WEP is used (ie, key-mgmt = "none" or "ieee8021x") indicate the
1331          * 802.11 authentication algorithm required by the AP here.  One of "open"
1332          * for Open System, "shared" for Shared Key, or "leap" for Cisco LEAP.  When
1333          * using Cisco LEAP (ie, key-mgmt = "ieee8021x" and auth-alg = "leap") the
1334          * "leap-username" and "leap-password" properties must be specified.
1335          **/
1336         g_object_class_install_property
1337                 (object_class, PROP_AUTH_ALG,
1338                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "", "",
1339                                       NULL,
1340                                       G_PARAM_READWRITE |
1341                                       G_PARAM_STATIC_STRINGS));
1342
1343         /**
1344          * NMSettingWirelessSecurity:proto:
1345          *
1346          * List of strings specifying the allowed WPA protocol versions to use.
1347          * Each element may be one "wpa" (allow WPA) or "rsn" (allow WPA2/RSN).  If
1348          * not specified, both WPA and RSN connections are allowed.
1349          **/
1350         g_object_class_install_property
1351                 (object_class, PROP_PROTO,
1352                  _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PROTO, "", "",
1353                                              DBUS_TYPE_G_LIST_OF_STRING,
1354                                              G_PARAM_READWRITE |
1355                                              G_PARAM_STATIC_STRINGS));
1356
1357         /**
1358          * NMSettingWirelessSecurity:pairwise:
1359          *
1360          * A list of pairwise encryption algorithms which prevents connections to
1361          * Wi-Fi networks that do not utilize one of the algorithms in the list.
1362          * For maximum compatibility leave this property empty.  Each list element
1363          * may be one of "tkip" or "ccmp".
1364          **/
1365         g_object_class_install_property
1366                 (object_class, PROP_PAIRWISE,
1367                  _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "", "",
1368                                              DBUS_TYPE_G_LIST_OF_STRING,
1369                                              G_PARAM_READWRITE |
1370                                              G_PARAM_STATIC_STRINGS));
1371
1372         /**
1373          * NMSettingWirelessSecurity:group:
1374          *
1375          * A list of group/broadcast encryption algorithms which prevents
1376          * connections to Wi-Fi networks that do not utilize one of the algorithms
1377          * in the list.  For maximum compatibility leave this property empty.  Each
1378          * list element may be one of "wep40", "wep104", "tkip", or "ccmp".
1379          **/
1380         g_object_class_install_property
1381                 (object_class, PROP_GROUP,
1382                  _nm_param_spec_specialized (NM_SETTING_WIRELESS_SECURITY_GROUP, "", "",
1383                                              DBUS_TYPE_G_LIST_OF_STRING,
1384                                              G_PARAM_READWRITE |
1385                                              G_PARAM_STATIC_STRINGS));
1386
1387         /**
1388          * NMSettingWirelessSecurity:leap-username:
1389          *
1390          * The login username for legacy LEAP connections (ie, key-mgmt =
1391          * "ieee8021x" and auth-alg = "leap").
1392          **/
1393         g_object_class_install_property
1394                 (object_class, PROP_LEAP_USERNAME,
1395                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "", "",
1396                                       NULL,
1397                                       G_PARAM_READWRITE |
1398                                       G_PARAM_STATIC_STRINGS));
1399
1400         /**
1401          * NMSettingWirelessSecurity:wep-key0:
1402          *
1403          * Index 0 WEP key.  This is the WEP key used in most networks.  See the
1404          * "wep-key-type" property for a description of how this key is interpreted.
1405          **/
1406         g_object_class_install_property
1407                 (object_class, PROP_WEP_KEY0,
1408                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "", "",
1409                                       NULL,
1410                                       G_PARAM_READWRITE |
1411                                       NM_SETTING_PARAM_SECRET |
1412                                       G_PARAM_STATIC_STRINGS));
1413
1414         /**
1415          * NMSettingWirelessSecurity:wep-key1:
1416          *
1417          * Index 1 WEP key.  This WEP index is not used by most networks.  See the
1418          * "wep-key-type" property for a description of how this key is interpreted.
1419          **/
1420         g_object_class_install_property
1421                 (object_class, PROP_WEP_KEY1,
1422                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, "", "",
1423                                       NULL,
1424                                       G_PARAM_READWRITE |
1425                                       NM_SETTING_PARAM_SECRET |
1426                                       G_PARAM_STATIC_STRINGS));
1427
1428         /**
1429          * NMSettingWirelessSecurity:wep-key2:
1430          *
1431          * Index 2 WEP key.  This WEP index is not used by most networks.  See the
1432          * "wep-key-type" property for a description of how this key is interpreted.
1433          **/
1434         g_object_class_install_property
1435                 (object_class, PROP_WEP_KEY2,
1436                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, "", "",
1437                                       NULL,
1438                                       G_PARAM_READWRITE |
1439                                       NM_SETTING_PARAM_SECRET |
1440                                       G_PARAM_STATIC_STRINGS));
1441
1442         /**
1443          * NMSettingWirelessSecurity:wep-key3:
1444          *
1445          * Index 3 WEP key.  This WEP index is not used by most networks.  See the
1446          * "wep-key-type" property for a description of how this key is interpreted.
1447          **/
1448         g_object_class_install_property
1449                 (object_class, PROP_WEP_KEY3,
1450                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, "", "",
1451                                       NULL,
1452                                       G_PARAM_READWRITE |
1453                                       NM_SETTING_PARAM_SECRET |
1454                                       G_PARAM_STATIC_STRINGS));
1455
1456         /**
1457          * NMSettingWirelessSecurity:wep-key-flags:
1458          *
1459          * Flags indicating how to handle the #NMSettingWirelessSecurity:wep-key0,
1460          * #NMSettingWirelessSecurity:wep-key1, #NMSettingWirelessSecurity:wep-key2,
1461          * and #NMSettingWirelessSecurity:wep-key3 properties.
1462          **/
1463         g_object_class_install_property
1464                 (object_class, PROP_WEP_KEY_FLAGS,
1465                  g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, "", "",
1466                                     NM_SETTING_SECRET_FLAG_NONE,
1467                                     NM_SETTING_SECRET_FLAGS_ALL,
1468                                     NM_SETTING_SECRET_FLAG_NONE,
1469                                     G_PARAM_READWRITE |
1470                                     G_PARAM_STATIC_STRINGS));
1471
1472         /**
1473          * NMSettingWirelessSecurity:psk:
1474          *
1475          * Pre-Shared-Key for WPA networks.  If the key is 64-characters long, it
1476          * must contain only hexadecimal characters and is interpreted as a
1477          * hexadecimal WPA key.  Otherwise, the key must be between 8 and 63 ASCII
1478          * characters (as specified in the 802.11i standard) and is interpreted as a
1479          * WPA passphrase, and is hashed to derive the actual WPA-PSK used when
1480          * connecting to the Wi-Fi network.
1481          **/
1482         g_object_class_install_property
1483                 (object_class, PROP_PSK,
1484                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_PSK, "", "",
1485                                       NULL,
1486                                       G_PARAM_READWRITE |
1487                                       NM_SETTING_PARAM_SECRET |
1488                                       G_PARAM_STATIC_STRINGS));
1489
1490         /**
1491          * NMSettingWirelessSecurity:psk-flags:
1492          *
1493          * Flags indicating how to handle the #NMSettingWirelessSecurity:psk
1494          * property.
1495          **/
1496         g_object_class_install_property
1497                 (object_class, PROP_PSK_FLAGS,
1498                  g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, "", "",
1499                                     NM_SETTING_SECRET_FLAG_NONE,
1500                                     NM_SETTING_SECRET_FLAGS_ALL,
1501                                     NM_SETTING_SECRET_FLAG_NONE,
1502                                     G_PARAM_READWRITE |
1503                                     G_PARAM_STATIC_STRINGS));
1504
1505         /**
1506          * NMSettingWirelessSecurity:leap-password:
1507          *
1508          * The login password for legacy LEAP connections (ie, key-mgmt =
1509          * "ieee8021x" and auth-alg = "leap").
1510          **/
1511         g_object_class_install_property
1512                 (object_class, PROP_LEAP_PASSWORD,
1513                  g_param_spec_string (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD, "", "",
1514                                       NULL,
1515                                       G_PARAM_READWRITE |
1516                                       NM_SETTING_PARAM_SECRET |
1517                                       G_PARAM_STATIC_STRINGS));
1518
1519         /**
1520          * NMSettingWirelessSecurity:leap-password-flags:
1521          *
1522          * Flags indicating how to handle the
1523          * #NMSettingWirelessSecurity:leap-password property.
1524          **/
1525         g_object_class_install_property
1526                 (object_class, PROP_LEAP_PASSWORD_FLAGS,
1527                  g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, "", "",
1528                                     NM_SETTING_SECRET_FLAG_NONE,
1529                                     NM_SETTING_SECRET_FLAGS_ALL,
1530                                     NM_SETTING_SECRET_FLAG_NONE,
1531                                     G_PARAM_READWRITE |
1532                                     G_PARAM_STATIC_STRINGS));
1533
1534         /**
1535          * NMSettingWirelessSecurity:wep-key-type:
1536          *
1537          * Controls the interpretation of WEP keys.  Allowed values are
1538          * %NM_WEP_KEY_TYPE_KEY, in which case the key is either a 10- or
1539          * 26-character hexadecimal string, or a 5- or 13-character ASCII password;
1540          * or %NM_WEP_KEY_TYPE_PASSPHRASE, in which case the passphrase is provided
1541          * as a string and will be hashed using the de-facto MD5 method to derive
1542          * the actual WEP key.
1543          **/
1544         g_object_class_install_property
1545                 (object_class, PROP_WEP_KEY_TYPE,
1546                  g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE, "", "",
1547                                     NM_WEP_KEY_TYPE_UNKNOWN,
1548                                     NM_WEP_KEY_TYPE_LAST,
1549                                     NM_WEP_KEY_TYPE_UNKNOWN,
1550                                     G_PARAM_READWRITE |
1551                                     G_PARAM_CONSTRUCT |
1552                                     G_PARAM_STATIC_STRINGS));
1553 }