~khurshid-alam/unity-control-center/use-usd-schemas

« back to all changes in this revision

Viewing changes to panels/network/connection-editor/ce-page-security.c

  • Committer: Sebastien Bacher
  • Author(s): Khurshid Alam
  • Date: 2019-05-17 07:34:33 UTC
  • mfrom: (12920.1.1 unity-control-center)
  • Revision ID: seb128@ubuntu.com-20190517073433-ch2kybdhhzpkmvq4
Network: Port to libnm 1.2 (lp: #1744619)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2012 Red Hat, Inc
 
4
 *
 
5
 * Licensed under the GNU General Public License Version 2
 
6
 *
 
7
 * This program is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 */
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <glib-object.h>
 
25
#include <glib/gi18n.h>
 
26
 
 
27
#include <NetworkManager.h>
 
28
 
 
29
#include "wireless-security.h"
 
30
#include "ce-page-security.h"
 
31
 
 
32
G_DEFINE_TYPE (CEPageSecurity, ce_page_security, CE_TYPE_PAGE)
 
33
 
 
34
enum {
 
35
        S_NAME_COLUMN,
 
36
        S_SEC_COLUMN,
 
37
        S_ADHOC_VALID_COLUMN
 
38
};
 
39
 
 
40
static gboolean
 
41
find_proto (NMSettingWirelessSecurity *sec, const char *item)
 
42
{
 
43
        guint32 i;
 
44
 
 
45
        for (i = 0; i < nm_setting_wireless_security_get_num_protos (sec); i++) {
 
46
                if (!strcmp (item, nm_setting_wireless_security_get_proto (sec, i)))
 
47
                        return TRUE;
 
48
        }
 
49
        return FALSE;
 
50
}
 
51
 
 
52
static NMUtilsSecurityType
 
53
get_default_type_for_security (NMSettingWirelessSecurity *sec)
 
54
{
 
55
        const char *key_mgmt, *auth_alg;
 
56
 
 
57
        g_return_val_if_fail (sec != NULL, NMU_SEC_NONE);
 
58
 
 
59
        key_mgmt = nm_setting_wireless_security_get_key_mgmt (sec);
 
60
        auth_alg = nm_setting_wireless_security_get_auth_alg (sec);
 
61
 
 
62
        /* No IEEE 802.1x */
 
63
        if (!strcmp (key_mgmt, "none"))
 
64
                return NMU_SEC_STATIC_WEP;
 
65
 
 
66
        if (!strcmp (key_mgmt, "ieee8021x")) {
 
67
                if (auth_alg && !strcmp (auth_alg, "leap"))
 
68
                        return NMU_SEC_LEAP;
 
69
                return NMU_SEC_DYNAMIC_WEP;
 
70
        }
 
71
 
 
72
        if (   !strcmp (key_mgmt, "wpa-none")
 
73
            || !strcmp (key_mgmt, "wpa-psk")) {
 
74
                if (find_proto (sec, "rsn"))
 
75
                        return NMU_SEC_WPA2_PSK;
 
76
                else if (find_proto (sec, "wpa"))
 
77
                        return NMU_SEC_WPA_PSK;
 
78
                else
 
79
                        return NMU_SEC_WPA_PSK;
 
80
        }
 
81
 
 
82
        if (!strcmp (key_mgmt, "wpa-eap")) {
 
83
                if (find_proto (sec, "rsn"))
 
84
                        return NMU_SEC_WPA2_ENTERPRISE;
 
85
                else if (find_proto (sec, "wpa"))
 
86
                        return NMU_SEC_WPA_ENTERPRISE;
 
87
                else
 
88
                        return NMU_SEC_WPA_ENTERPRISE;
 
89
        }
 
90
 
 
91
        return NMU_SEC_INVALID;
 
92
}
 
93
 
 
94
static WirelessSecurity *
 
95
security_combo_get_active (CEPageSecurity *page)
 
96
{
 
97
        GtkTreeIter iter;
 
98
        GtkTreeModel *model;
 
99
        WirelessSecurity *sec = NULL;
 
100
 
 
101
        model = gtk_combo_box_get_model (page->security_combo);
 
102
        gtk_combo_box_get_active_iter (page->security_combo, &iter);
 
103
        gtk_tree_model_get (model, &iter, S_SEC_COLUMN, &sec, -1);
 
104
 
 
105
        return sec;
 
106
}
 
107
 
 
108
static void
 
109
wsec_size_group_clear (GtkSizeGroup *group)
 
110
{
 
111
        GSList *children;
 
112
        GSList *iter;
 
113
 
 
114
        g_return_if_fail (group != NULL);
 
115
 
 
116
        children = gtk_size_group_get_widgets (group);
 
117
        for (iter = children; iter; iter = g_slist_next (iter))
 
118
                gtk_size_group_remove_widget (group, GTK_WIDGET (iter->data));
 
119
}
 
120
 
 
121
static void
 
122
security_combo_changed (GtkComboBox *combo,
 
123
                        gpointer     user_data)
 
124
{
 
125
        CEPageSecurity *page = CE_PAGE_SECURITY (user_data);
 
126
        GtkWidget *vbox;
 
127
        GList *l, *children;
 
128
        WirelessSecurity *sec;
 
129
 
 
130
        wsec_size_group_clear (page->group);
 
131
 
 
132
        vbox = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "vbox"));
 
133
        children = gtk_container_get_children (GTK_CONTAINER (vbox));
 
134
        for (l = children; l; l = l->next) {
 
135
                gtk_container_remove (GTK_CONTAINER (vbox), GTK_WIDGET (l->data));
 
136
        }
 
137
 
 
138
        sec = security_combo_get_active (page);
 
139
        if (sec) {
 
140
                GtkWidget *sec_widget;
 
141
                GtkWidget *parent;
 
142
 
 
143
                sec_widget = wireless_security_get_widget (sec);
 
144
                g_assert (sec_widget);
 
145
                parent = gtk_widget_get_parent (sec_widget);
 
146
                if (parent)
 
147
                        gtk_container_remove (GTK_CONTAINER (parent), sec_widget);
 
148
 
 
149
                gtk_size_group_add_widget (page->group, page->security_heading);
 
150
                wireless_security_add_to_size_group (sec, page->group);
 
151
 
 
152
                gtk_container_add (GTK_CONTAINER (vbox), sec_widget);
 
153
                wireless_security_unref (sec);
 
154
        }
 
155
 
 
156
        ce_page_changed (CE_PAGE (page));
 
157
}
 
158
 
 
159
static void
 
160
stuff_changed_cb (WirelessSecurity *sec, gpointer user_data)
 
161
{
 
162
        ce_page_changed (CE_PAGE (user_data));
 
163
}
 
164
 
 
165
static void
 
166
add_security_item (CEPageSecurity   *page,
 
167
                   WirelessSecurity *sec,
 
168
                   GtkListStore     *model,
 
169
                   GtkTreeIter      *iter,
 
170
                   const char       *text,
 
171
                   gboolean          adhoc_valid)
 
172
{
 
173
        wireless_security_set_changed_notify (sec, stuff_changed_cb, page);
 
174
        gtk_list_store_append (model, iter);
 
175
        gtk_list_store_set (model, iter,
 
176
                            S_NAME_COLUMN, text,
 
177
                            S_SEC_COLUMN, sec,
 
178
                            S_ADHOC_VALID_COLUMN, adhoc_valid,
 
179
                            -1);
 
180
        wireless_security_unref (sec);
 
181
}
 
182
 
 
183
static void
 
184
set_sensitive (GtkCellLayout *cell_layout,
 
185
               GtkCellRenderer *cell,
 
186
               GtkTreeModel *tree_model,
 
187
               GtkTreeIter *iter,
 
188
               gpointer data)
 
189
{
 
190
        gboolean *adhoc = data;
 
191
        gboolean sensitive = TRUE, adhoc_valid = TRUE;
 
192
 
 
193
        gtk_tree_model_get (tree_model, iter, S_ADHOC_VALID_COLUMN, &adhoc_valid, -1);
 
194
        if (*adhoc && !adhoc_valid)
 
195
                sensitive = FALSE;
 
196
 
 
197
        g_object_set (cell, "sensitive", sensitive, NULL);
 
198
}
 
199
 
 
200
static void
 
201
finish_setup (CEPageSecurity *page)
 
202
{
 
203
        NMConnection *connection = CE_PAGE (page)->connection;
 
204
        NMSettingWireless *sw;
 
205
        NMSettingWirelessSecurity *sws;
 
206
        gboolean is_adhoc = FALSE;
 
207
        GtkListStore *sec_model;
 
208
        GtkTreeIter iter;
 
209
        const gchar *mode;
 
210
        guint32 dev_caps = 0;
 
211
        NMUtilsSecurityType default_type = NMU_SEC_NONE;
 
212
        int active = -1;
 
213
        int item = 0;
 
214
        GtkComboBox *combo;
 
215
        GtkCellRenderer *renderer;
 
216
 
 
217
        sw = nm_connection_get_setting_wireless (connection);
 
218
        g_assert (sw);
 
219
 
 
220
        page->group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
 
221
 
 
222
        page->security_heading = GTK_WIDGET (gtk_builder_get_object (CE_PAGE (page)->builder, "heading_sec"));
 
223
        page->security_combo = combo = GTK_COMBO_BOX (gtk_builder_get_object (CE_PAGE (page)->builder, "combo_sec"));
 
224
 
 
225
        dev_caps =   NM_WIFI_DEVICE_CAP_CIPHER_WEP40
 
226
                   | NM_WIFI_DEVICE_CAP_CIPHER_WEP104
 
227
                   | NM_WIFI_DEVICE_CAP_CIPHER_TKIP
 
228
                   | NM_WIFI_DEVICE_CAP_CIPHER_CCMP
 
229
                   | NM_WIFI_DEVICE_CAP_WPA
 
230
                   | NM_WIFI_DEVICE_CAP_RSN;
 
231
 
 
232
        mode = nm_setting_wireless_get_mode (sw);
 
233
        if (mode && !strcmp (mode, "adhoc"))
 
234
                is_adhoc = TRUE;
 
235
        page->adhoc = is_adhoc;
 
236
 
 
237
        sws = nm_connection_get_setting_wireless_security (connection);
 
238
        if (sws)
 
239
                default_type = get_default_type_for_security (sws);
 
240
 
 
241
        sec_model = gtk_list_store_new (3, G_TYPE_STRING, WIRELESS_TYPE_SECURITY, G_TYPE_BOOLEAN);
 
242
 
 
243
        if (nm_utils_security_valid (NMU_SEC_NONE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
 
244
                gtk_list_store_insert_with_values (sec_model, &iter, -1,
 
245
                                                   S_NAME_COLUMN, C_("Wi-Fi/Ethernet security", "None"),
 
246
                                                   S_ADHOC_VALID_COLUMN, TRUE,
 
247
                                                   -1);
 
248
                if (default_type == NMU_SEC_NONE)
 
249
                        active = item;
 
250
                item++;
 
251
        }
 
252
 
 
253
        if (nm_utils_security_valid (NMU_SEC_STATIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
 
254
                WirelessSecurityWEPKey *ws_wep;
 
255
                NMWepKeyType wep_type = NM_WEP_KEY_TYPE_KEY;
 
256
 
 
257
                if (default_type == NMU_SEC_STATIC_WEP) {
 
258
                        sws = nm_connection_get_setting_wireless_security (connection);
 
259
                        if (sws)
 
260
                                wep_type = nm_setting_wireless_security_get_wep_key_type (sws);
 
261
                        if (wep_type == NM_WEP_KEY_TYPE_UNKNOWN)
 
262
                                wep_type = NM_WEP_KEY_TYPE_KEY;
 
263
                }
 
264
 
 
265
                ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_KEY, FALSE, FALSE);
 
266
                if (ws_wep) {
 
267
                        add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model,
 
268
                                           &iter, _("WEP 40/128-bit Key (Hex or ASCII)"),
 
269
                                           TRUE);
 
270
                        if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_KEY))
 
271
                                active = item;
 
272
                        item++;
 
273
                }
 
274
 
 
275
                ws_wep = ws_wep_key_new (connection, NM_WEP_KEY_TYPE_PASSPHRASE, FALSE, FALSE);
 
276
                if (ws_wep) {
 
277
                        add_security_item (page, WIRELESS_SECURITY (ws_wep), sec_model,
 
278
                                           &iter, _("WEP 128-bit Passphrase"), TRUE);
 
279
                        if ((active < 0) && (default_type == NMU_SEC_STATIC_WEP) && (wep_type == NM_WEP_KEY_TYPE_PASSPHRASE))
 
280
                                active = item;
 
281
                        item++;
 
282
                }
 
283
        }
 
284
 
 
285
        if (nm_utils_security_valid (NMU_SEC_LEAP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
 
286
                WirelessSecurityLEAP *ws_leap;
 
287
 
 
288
                ws_leap = ws_leap_new (connection, FALSE);
 
289
                if (ws_leap) {
 
290
                        add_security_item (page, WIRELESS_SECURITY (ws_leap), sec_model,
 
291
                                           &iter, _("LEAP"), FALSE);
 
292
                        if ((active < 0) && (default_type == NMU_SEC_LEAP))
 
293
                                active = item;
 
294
                        item++;
 
295
                }
 
296
        }
 
297
 
 
298
        if (nm_utils_security_valid (NMU_SEC_DYNAMIC_WEP, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
 
299
                WirelessSecurityDynamicWEP *ws_dynamic_wep;
 
300
 
 
301
                ws_dynamic_wep = ws_dynamic_wep_new (connection, TRUE, FALSE);
 
302
                if (ws_dynamic_wep) {
 
303
                        add_security_item (page, WIRELESS_SECURITY (ws_dynamic_wep), sec_model,
 
304
                                           &iter, _("Dynamic WEP (802.1x)"), FALSE);
 
305
                        if ((active < 0) && (default_type == NMU_SEC_DYNAMIC_WEP))
 
306
                                active = item;
 
307
                        item++;
 
308
                }
 
309
        }
 
310
 
 
311
        if (nm_utils_security_valid (NMU_SEC_WPA_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0) ||
 
312
            nm_utils_security_valid (NMU_SEC_WPA2_PSK, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
 
313
                WirelessSecurityWPAPSK *ws_wpa_psk;
 
314
 
 
315
                ws_wpa_psk = ws_wpa_psk_new (connection, FALSE);
 
316
                if (ws_wpa_psk) {
 
317
                        add_security_item (page, WIRELESS_SECURITY (ws_wpa_psk), sec_model,
 
318
                                           &iter, _("WPA & WPA2 Personal"), FALSE);
 
319
                        if ((active < 0) && ((default_type == NMU_SEC_WPA_PSK) || (default_type == NMU_SEC_WPA2_PSK)))
 
320
                                active = item;
 
321
                        item++;
 
322
                }
 
323
        }
 
324
 
 
325
        if (nm_utils_security_valid (NMU_SEC_WPA_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0) ||
 
326
            nm_utils_security_valid (NMU_SEC_WPA2_ENTERPRISE, dev_caps, FALSE, is_adhoc, 0, 0, 0)) {
 
327
                WirelessSecurityWPAEAP *ws_wpa_eap;
 
328
 
 
329
                ws_wpa_eap = ws_wpa_eap_new (connection, TRUE, FALSE);
 
330
                if (ws_wpa_eap) {
 
331
                        add_security_item (page, WIRELESS_SECURITY (ws_wpa_eap), sec_model,
 
332
                                           &iter, _("WPA & WPA2 Enterprise"), FALSE);
 
333
                        if ((active < 0) && ((default_type == NMU_SEC_WPA_ENTERPRISE) || (default_type == NMU_SEC_WPA2_ENTERPRISE)))
 
334
                                active = item;
 
335
                        item++;
 
336
                }
 
337
        }
 
338
 
 
339
        gtk_combo_box_set_model (combo, GTK_TREE_MODEL (sec_model));
 
340
        gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
 
341
 
 
342
        renderer = gtk_cell_renderer_text_new ();
 
343
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
 
344
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, "text", S_NAME_COLUMN, NULL);
 
345
        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer, set_sensitive, &page->adhoc, NULL);
 
346
 
 
347
        gtk_combo_box_set_active (combo, active < 0 ? 0 : (guint32) active);
 
348
        g_object_unref (G_OBJECT (sec_model));
 
349
 
 
350
        page->security_combo = combo;
 
351
 
 
352
        security_combo_changed (combo, page);
 
353
        g_signal_connect (combo, "changed",
 
354
                          G_CALLBACK (security_combo_changed), page);
 
355
}
 
356
 
 
357
static gboolean
 
358
validate (CEPage        *page,
 
359
          NMConnection  *connection,
 
360
          GError       **error)
 
361
{
 
362
        NMSettingWireless *sw;
 
363
        WirelessSecurity *sec;
 
364
        gboolean valid = FALSE;
 
365
        const char *mode;
 
366
 
 
367
        sw = nm_connection_get_setting_wireless (connection);
 
368
 
 
369
        mode = nm_setting_wireless_get_mode (sw);
 
370
        if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0)
 
371
                CE_PAGE_SECURITY (page)->adhoc = TRUE;
 
372
        else
 
373
                CE_PAGE_SECURITY (page)->adhoc = FALSE;
 
374
 
 
375
        sec = security_combo_get_active (CE_PAGE_SECURITY (page));
 
376
        if (sec) {
 
377
                GBytes *ssid = nm_setting_wireless_get_ssid (sw);
 
378
 
 
379
                if (ssid) {
 
380
                        /* FIXME: get failed property and error out of wifi security objects */
 
381
                        valid = wireless_security_validate (sec, error);
 
382
                        if (valid)
 
383
                                wireless_security_fill_connection (sec, connection);
 
384
                } else {
 
385
                        g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, "Missing SSID");
 
386
                        valid = FALSE;
 
387
                }
 
388
 
 
389
                if (CE_PAGE_SECURITY (page)->adhoc) {
 
390
                        if (!wireless_security_adhoc_compatible (sec)) {
 
391
                                if (valid)
 
392
                                        g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_SETTING, "Security not compatible with Ad-Hoc mode");
 
393
                                valid = FALSE;
 
394
                        }
 
395
                }
 
396
 
 
397
                wireless_security_unref (sec);
 
398
        } else {
 
399
                /* No security, unencrypted */
 
400
                nm_connection_remove_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
 
401
                nm_connection_remove_setting (connection, NM_TYPE_SETTING_802_1X);
 
402
                valid = TRUE;
 
403
        }
 
404
 
 
405
        return valid;
 
406
}
 
407
 
 
408
static void
 
409
ce_page_security_init (CEPageSecurity *page)
 
410
{
 
411
}
 
412
 
 
413
static void
 
414
dispose (GObject *object)
 
415
{
 
416
        CEPageSecurity *page = CE_PAGE_SECURITY (object);
 
417
 
 
418
        g_clear_object (&page->group);
 
419
 
 
420
        G_OBJECT_CLASS (ce_page_security_parent_class)->dispose (object);
 
421
}
 
422
 
 
423
static void
 
424
ce_page_security_class_init (CEPageSecurityClass *class)
 
425
{
 
426
        GObjectClass *object_class = G_OBJECT_CLASS (class);
 
427
        CEPageClass *page_class = CE_PAGE_CLASS (class);
 
428
 
 
429
        object_class->dispose = dispose;
 
430
        page_class->validate = validate;
 
431
}
 
432
 
 
433
CEPage *
 
434
ce_page_security_new (NMConnection      *connection,
 
435
                      NMClient          *client)
 
436
{
 
437
        CEPageSecurity *page;
 
438
        NMUtilsSecurityType default_type = NMU_SEC_NONE;
 
439
        NMSettingWirelessSecurity *sws;
 
440
 
 
441
        page = CE_PAGE_SECURITY (ce_page_new (CE_TYPE_PAGE_SECURITY,
 
442
                                              connection,
 
443
                                              client,
 
444
                                              "/org/gnome/control-center/network/security-page.ui",
 
445
                                              _("Security")));
 
446
 
 
447
        sws = nm_connection_get_setting_wireless_security (connection);
 
448
        if (sws)
 
449
                default_type = get_default_type_for_security (sws);
 
450
 
 
451
        if (default_type == NMU_SEC_STATIC_WEP ||
 
452
            default_type == NMU_SEC_LEAP ||
 
453
            default_type == NMU_SEC_WPA_PSK ||
 
454
            default_type == NMU_SEC_WPA2_PSK) {
 
455
                CE_PAGE (page)->security_setting = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
 
456
        }
 
457
 
 
458
        if (default_type == NMU_SEC_DYNAMIC_WEP ||
 
459
            default_type == NMU_SEC_WPA_ENTERPRISE ||
 
460
            default_type == NMU_SEC_WPA2_ENTERPRISE) {
 
461
                CE_PAGE (page)->security_setting = NM_SETTING_802_1X_SETTING_NAME;
 
462
        }
 
463
 
 
464
        g_signal_connect (page, "initialized", G_CALLBACK (finish_setup), NULL);
 
465
 
 
466
        return CE_PAGE (page);
 
467
}