~afeder/network-manager-applet/bug-704123

« back to all changes in this revision

Viewing changes to src/applet-device-wifi.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Trudel-Lapierre
  • Date: 2011-05-30 13:25:18 UTC
  • mfrom: (1.2.20 upstream)
  • Revision ID: james.westby@ubuntu.com-20110530132518-ef2bkiy1s7v0na6r
Tags: 0.8.9997+git.20110529t170033.9ec4c5d-0ubuntu1
* upstream snapshot 2011-05-29 17:00:33 (GMT)
  + 9ec4c5de855de5d9ee6c17752c3b0de6c68e9384
  - applet: fix leak in import/upgrade code (LP: #784756)
* debian/rules: switch back to git "master" branch.
* debian/patches/0001-applet-fix-possibly-uninitialized-variable.patch: drop,
  this is fixed upstream.
* debian/patches/04-autostart.patch: refreshed.
* debian/patches/20_use_full_vpn_dialog_service_name_path.patch: refreshed.
* debian/patches/lp328572-dxteam-connect-text.patch: refreshed.
* debian/patches/lp337960_dxteam_notification_icon_names.diff: refreshed.
* debian/patches/lp341684_device_sensitive_disconnect_notify.patch: refresh.
* debian/patches/lp460144_correctly_update_notification.patch: refreshed.
* debian/patches/lp341684_device_sensitive_disconnect_notify.patch: refresh.
* debian/patches/lp358526_generic_disconnected_notification_icon.patch:
  refreshed.
* debian/patches/nm-applet-use-indicator.patch: refreshed and modified to
  build with GTK3 appindicator.
  - properly free icon_name for indicators (LP: #724554), thanks JKL.
  - fix leak in applet_menu_item_add_complex_separator_helper due to new'ing
    a GtkSeparatorMenuItem on top of a GtkImageMenuItem (LP: #784711).
* debian/control:
  - Bump Build-Depends to libappindicator3-dev.
  - Update Build-Depends for GTK to libgtk-3-dev.
  - Bump network-manager and libnm Depends and Build-Depends to 0.8.998.
* debian/rules, debian/patches/series: pass --libexecdir to configure, which
  now renders the patch 20_use_full_vpn_dialog_service_name_path.patch
  unnecessary, so we're dropping it.
* debian/patches/20_use_full_vpn_dialog_service_name_path.patch: dropped,
  see above.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 * with this program; if not, write to the Free Software Foundation, Inc.,
18
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
19
 *
20
 
 * (C) Copyright 2008 - 2010 Red Hat, Inc.
 
20
 * (C) Copyright 2008 - 2011 Red Hat, Inc.
21
21
 */
22
22
 
23
23
#ifdef HAVE_CONFIG_H
39
39
#include <nm-device-wifi.h>
40
40
#include <nm-setting-8021x.h>
41
41
#include <nm-utils.h>
 
42
#include <nm-secret-agent.h>
42
43
 
43
44
#include "applet.h"
44
45
#include "applet-device-wifi.h"
50
51
 
51
52
static void wireless_dialog_response_cb (GtkDialog *dialog, gint response, gpointer user_data);
52
53
 
 
54
static void nag_dialog_response_cb (GtkDialog *nag_dialog, gint response, gpointer user_data);
 
55
 
53
56
static NMAccessPoint *update_active_ap (NMDevice *device, NMDeviceState state, NMApplet *applet);
54
57
 
 
58
static void _do_new_auto_connection (NMApplet *applet,
 
59
                                     NMDevice *device,
 
60
                                     NMAccessPoint *ap,
 
61
                                     AppletNewAutoConnectionCallback callback,
 
62
                                     gpointer callback_data);
 
63
 
55
64
static void
56
65
show_ignore_focus_stealing_prevention (GtkWidget *widget)
57
66
{
 
67
        GdkWindow *window;
 
68
 
58
69
        gtk_widget_realize (widget);
59
70
        gtk_widget_show (widget);
60
 
        gtk_window_present_with_time (GTK_WINDOW (widget),
61
 
                gdk_x11_get_server_time (gtk_widget_get_window (widget)));
 
71
        window = gtk_widget_get_window (widget);
 
72
        gtk_window_present_with_time (GTK_WINDOW (widget), gdk_x11_get_server_time (window));
62
73
}
63
74
 
64
 
static void
65
 
other_wireless_activate_cb (GtkWidget *menu_item,
66
 
                            NMApplet *applet)
 
75
gboolean
 
76
applet_wifi_connect_to_hidden_network (NMApplet *applet)
67
77
{
68
78
        GtkWidget *dialog;
69
79
 
70
80
        dialog = nma_wireless_dialog_new_for_other (applet);
71
 
        if (!dialog)
72
 
                return;
73
 
 
74
 
        g_signal_connect (dialog, "response",
75
 
                          G_CALLBACK (wireless_dialog_response_cb),
76
 
                          applet);
77
 
 
78
 
        show_ignore_focus_stealing_prevention (dialog);
 
81
        if (dialog) {
 
82
                g_signal_connect (dialog, "response",
 
83
                                  G_CALLBACK (wireless_dialog_response_cb),
 
84
                                  applet);
 
85
                show_ignore_focus_stealing_prevention (dialog);
 
86
        }
 
87
        return !!dialog;
79
88
}
80
89
 
81
90
void
90
99
        gtk_container_add (GTK_CONTAINER (menu_item), label);
91
100
        gtk_widget_show_all (menu_item);
92
101
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
93
 
        g_signal_connect (menu_item, "activate", G_CALLBACK (other_wireless_activate_cb), applet);
94
 
}
95
 
 
96
 
static void
97
 
new_network_activate_cb (GtkWidget *menu_item, NMApplet *applet)
 
102
        g_signal_connect_swapped (menu_item, "activate",
 
103
                                  G_CALLBACK (applet_wifi_connect_to_hidden_network),
 
104
                                  applet);
 
105
}
 
106
 
 
107
gboolean
 
108
applet_wifi_can_create_wifi_network (NMApplet *applet)
 
109
{
 
110
        gboolean disabled, allowed = FALSE;
 
111
        NMClientPermissionResult perm;
 
112
        GError *error = NULL;
 
113
 
 
114
        /* FIXME: check WIFI_SHARE_PROTECTED too, and make the wireless dialog
 
115
         * handle the permissions as well so that admins can restrict open network
 
116
         * creation separately from protected network creation.
 
117
         */
 
118
        perm = nm_client_get_permission_result (applet->nm_client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN);
 
119
        if (perm == NM_CLIENT_PERMISSION_RESULT_YES || perm == NM_CLIENT_PERMISSION_RESULT_AUTH) {
 
120
                disabled = gconf_client_get_bool (applet->gconf_client, PREF_DISABLE_WIFI_CREATE, &error);
 
121
                if (!disabled && !error)
 
122
                        allowed = TRUE;
 
123
                g_clear_error (&error);
 
124
        }
 
125
        return allowed;
 
126
}
 
127
 
 
128
gboolean
 
129
applet_wifi_create_wifi_network (NMApplet *applet)
98
130
{
99
131
        GtkWidget *dialog;
100
132
 
101
133
        dialog = nma_wireless_dialog_new_for_create (applet);
102
 
        if (!dialog)
103
 
                return;
104
 
 
105
 
        g_signal_connect (dialog, "response",
106
 
                          G_CALLBACK (wireless_dialog_response_cb),
107
 
                          applet);
108
 
 
109
 
        show_ignore_focus_stealing_prevention (dialog);
 
134
        if (dialog) {
 
135
                g_signal_connect (dialog, "response",
 
136
                                  G_CALLBACK (wireless_dialog_response_cb),
 
137
                                  applet);
 
138
                show_ignore_focus_stealing_prevention (dialog);
 
139
        }
 
140
        return !!dialog;
110
141
}
111
142
 
112
143
void
114
145
{
115
146
        GtkWidget *menu_item;
116
147
        GtkWidget *label;
117
 
        GError *error = NULL;
118
 
        gboolean disabled;
119
148
 
120
149
        menu_item = gtk_menu_item_new ();
121
150
        label = gtk_label_new_with_mnemonic (_("Create _New Wireless Network..."));
123
152
        gtk_container_add (GTK_CONTAINER (menu_item), label);
124
153
        gtk_widget_show_all (menu_item);
125
154
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
126
 
        g_signal_connect (menu_item, "activate", G_CALLBACK (new_network_activate_cb), applet);
 
155
        g_signal_connect_swapped (menu_item, "activate",
 
156
                                  G_CALLBACK (applet_wifi_create_wifi_network),
 
157
                                  applet);
127
158
 
128
 
        /* FIXME: should really use PolicyKit and NM permissions here instead
129
 
         * using using GConf mandatory settings.  But this works for now.
130
 
         */
131
 
        disabled = gconf_client_get_bool (applet->gconf_client, PREF_DISABLE_WIFI_CREATE, &error);
132
 
        if (error || disabled)
 
159
        if (!applet_wifi_can_create_wifi_network (applet))
133
160
                gtk_widget_set_sensitive (GTK_WIDGET (menu_item), FALSE);
134
 
        g_clear_error (&error);
135
 
}
136
 
 
 
161
}
 
162
 
 
163
static void
 
164
dbus_8021x_add_and_activate_cb (NMClient *client,
 
165
                                NMActiveConnection *active,
 
166
                                const char *connection_path,
 
167
                                GError *error,
 
168
                                gpointer user_data)
 
169
{
 
170
        if (error)
 
171
                g_warning ("Failed to add/activate connection: (%d) %s", error->code, error->message);
 
172
}
 
173
 
 
174
typedef struct {
 
175
        NMApplet *applet;
 
176
        NMDevice *device;
 
177
        NMAccessPoint *ap;
 
178
} Dbus8021xInfo;
 
179
 
 
180
static void
 
181
dbus_connect_8021x_cb (NMConnection *connection,
 
182
                       gboolean auto_created,
 
183
                       gboolean canceled,
 
184
                       gpointer user_data)
 
185
{
 
186
        Dbus8021xInfo *info = user_data;
 
187
 
 
188
        if (canceled == FALSE) {
 
189
                g_return_if_fail (connection != NULL);
 
190
 
 
191
                /* Ask NM to add the new connection and activate it; NM will fill in the
 
192
                 * missing details based on the specific object and the device.
 
193
                 */
 
194
                nm_client_add_and_activate_connection (info->applet->nm_client,
 
195
                                                           connection,
 
196
                                                           info->device,
 
197
                                                           nm_object_get_path (NM_OBJECT (info->ap)),
 
198
                                                           dbus_8021x_add_and_activate_cb,
 
199
                                                           info->applet);
 
200
        }
 
201
 
 
202
        g_object_unref (info->device);
 
203
        g_object_unref (info->ap);
 
204
        memset (info, 0, sizeof (*info));
 
205
        g_free (info);
 
206
}
 
207
 
 
208
gboolean
 
209
applet_wifi_connect_to_8021x_network (NMApplet *applet,
 
210
                                      NMDevice *device,
 
211
                                      NMAccessPoint *ap)
 
212
{
 
213
        Dbus8021xInfo *info;
 
214
 
 
215
        info = g_malloc0 (sizeof (*info));
 
216
        info->applet = applet;
 
217
        info->device = g_object_ref (device);
 
218
        info->ap = g_object_ref (ap);
 
219
 
 
220
        _do_new_auto_connection (applet, device, ap, dbus_connect_8021x_cb, info);
 
221
        return TRUE;
 
222
}
137
223
 
138
224
 
139
225
typedef struct {
193
279
        return is_ssid_in_list (ssid, manf_default_ssids);
194
280
}
195
281
 
 
282
static char *
 
283
get_ssid_utf8 (NMAccessPoint *ap)
 
284
{
 
285
        char *ssid_utf8 = NULL;
 
286
        const GByteArray *ssid;
 
287
 
 
288
        if (ap) {
 
289
                ssid = nm_access_point_get_ssid (ap);
 
290
                if (ssid)
 
291
                        ssid_utf8 = nm_utils_ssid_to_utf8 (ssid);
 
292
        }
 
293
        if (!ssid_utf8)
 
294
                ssid_utf8 = g_strdup (_("(none)"));
 
295
 
 
296
        return ssid_utf8;
 
297
}
 
298
 
196
299
/* List known trojan networks that should never be shown to the user */
197
300
static const char *blacklisted_ssids[] = {
198
301
        /* http://www.npr.org/templates/story/story.php?storyId=130451369 */
206
309
        return is_ssid_in_list (ssid, blacklisted_ssids);
207
310
}
208
311
 
209
 
static void
210
 
add_ciphers_from_flags (NMSettingWirelessSecurity *sec,
211
 
                        guint32 flags,
212
 
                        gboolean pairwise)
213
 
{
214
 
        if (pairwise) {
215
 
                if (flags & NM_802_11_AP_SEC_PAIR_TKIP)
216
 
                        nm_setting_wireless_security_add_pairwise (sec, "tkip");
217
 
                if (flags & NM_802_11_AP_SEC_PAIR_CCMP)
218
 
                        nm_setting_wireless_security_add_pairwise (sec, "ccmp");
219
 
        } else {
220
 
                if (flags & NM_802_11_AP_SEC_GROUP_WEP40)
221
 
                        nm_setting_wireless_security_add_group (sec, "wep40");
222
 
                if (flags & NM_802_11_AP_SEC_GROUP_WEP104)
223
 
                        nm_setting_wireless_security_add_group (sec, "wep104");
224
 
                if (flags & NM_802_11_AP_SEC_GROUP_TKIP)
225
 
                        nm_setting_wireless_security_add_group (sec, "tkip");
226
 
                if (flags & NM_802_11_AP_SEC_GROUP_CCMP)
227
 
                        nm_setting_wireless_security_add_group (sec, "ccmp");
228
 
        }
229
 
}
230
 
 
231
 
static NMSettingWirelessSecurity *
232
 
get_security_for_ap (NMAccessPoint *ap,
233
 
                     guint32 dev_caps,
234
 
                     gboolean *supported,
235
 
                     NMSetting8021x **s_8021x)
236
 
{
237
 
        NMSettingWirelessSecurity *sec;
238
 
        NM80211Mode mode;
239
 
        guint32 flags;
240
 
        guint32 wpa_flags;
241
 
        guint32 rsn_flags;
242
 
 
243
 
        g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL);
244
 
        g_return_val_if_fail (supported != NULL, NULL);
245
 
        g_return_val_if_fail (*supported == TRUE, NULL);
246
 
        g_return_val_if_fail (s_8021x != NULL, NULL);
247
 
        g_return_val_if_fail (*s_8021x == NULL, NULL);
248
 
 
249
 
        sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
250
 
 
251
 
        mode = nm_access_point_get_mode (ap);
252
 
        flags = nm_access_point_get_flags (ap);
253
 
        wpa_flags = nm_access_point_get_wpa_flags (ap);
254
 
        rsn_flags = nm_access_point_get_rsn_flags (ap);
255
 
 
256
 
        /* No security */
257
 
        if (   !(flags & NM_802_11_AP_FLAGS_PRIVACY)
258
 
            && (wpa_flags == NM_802_11_AP_SEC_NONE)
259
 
            && (rsn_flags == NM_802_11_AP_SEC_NONE))
260
 
                goto none;
261
 
 
262
 
        /* Static WEP, Dynamic WEP, or LEAP */
263
 
        if (flags & NM_802_11_AP_FLAGS_PRIVACY) {
264
 
                if ((dev_caps & NM_WIFI_DEVICE_CAP_RSN) || (dev_caps & NM_WIFI_DEVICE_CAP_WPA)) {
265
 
                        /* If the device can do WPA/RSN but the AP has no WPA/RSN informatoin
266
 
                         * elements, it must be LEAP or static/dynamic WEP.
267
 
                         */
268
 
                        if ((wpa_flags == NM_802_11_AP_SEC_NONE) && (rsn_flags == NM_802_11_AP_SEC_NONE)) {
269
 
                                g_object_set (sec,
270
 
                                              NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
271
 
                                              NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
272
 
                                              NULL);
273
 
                                return sec;
274
 
                        }
275
 
                        /* Otherwise, the AP supports WPA or RSN, which is preferred */
276
 
                } else {
277
 
                        /* Device can't do WPA/RSN, but can at least pass through the
278
 
                         * WPA/RSN information elements from a scan.  Since Privacy was
279
 
                         * advertised, LEAP or static/dynamic WEP must be in use.
280
 
                         */
281
 
                        g_object_set (sec,
282
 
                                      NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
283
 
                                      NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
284
 
                                      NULL);
285
 
                        return sec;
286
 
                }
287
 
        }
288
 
 
289
 
        /* Stuff after this point requires infrastructure */
290
 
        if (mode != NM_802_11_MODE_INFRA) {
291
 
                *supported = FALSE;
292
 
                goto none;
293
 
        }
294
 
 
295
 
        /* WPA2 PSK first */
296
 
        if (   (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
297
 
            && (dev_caps & NM_WIFI_DEVICE_CAP_RSN)) {
298
 
                g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
299
 
                nm_setting_wireless_security_add_proto (sec, "rsn");
300
 
                add_ciphers_from_flags (sec, rsn_flags, TRUE);
301
 
                add_ciphers_from_flags (sec, rsn_flags, FALSE);
302
 
                return sec;
303
 
        }
304
 
 
305
 
        /* WPA PSK */
306
 
        if (   (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
307
 
            && (dev_caps & NM_WIFI_DEVICE_CAP_WPA)) {
308
 
                g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
309
 
                nm_setting_wireless_security_add_proto (sec, "wpa");
310
 
                add_ciphers_from_flags (sec, wpa_flags, TRUE);
311
 
                add_ciphers_from_flags (sec, wpa_flags, FALSE);
312
 
                return sec;
313
 
        }
314
 
 
315
 
        /* WPA2 Enterprise */
316
 
        if (   (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
317
 
            && (dev_caps & NM_WIFI_DEVICE_CAP_RSN)) {
318
 
                g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
319
 
                nm_setting_wireless_security_add_proto (sec, "rsn");
320
 
                add_ciphers_from_flags (sec, rsn_flags, TRUE);
321
 
                add_ciphers_from_flags (sec, rsn_flags, FALSE);
322
 
 
323
 
                *s_8021x = NM_SETTING_802_1X (nm_setting_802_1x_new ());
324
 
                nm_setting_802_1x_add_eap_method (*s_8021x, "ttls");
325
 
                g_object_set (*s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
326
 
                return sec;
327
 
        }
328
 
 
329
 
        /* WPA Enterprise */
330
 
        if (   (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
331
 
            && (dev_caps & NM_WIFI_DEVICE_CAP_WPA)) {
332
 
                g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
333
 
                nm_setting_wireless_security_add_proto (sec, "wpa");
334
 
                add_ciphers_from_flags (sec, wpa_flags, TRUE);
335
 
                add_ciphers_from_flags (sec, wpa_flags, FALSE);
336
 
 
337
 
                *s_8021x = NM_SETTING_802_1X (nm_setting_802_1x_new ());
338
 
                nm_setting_802_1x_add_eap_method (*s_8021x, "ttls");
339
 
                g_object_set (*s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
340
 
                return sec;
341
 
        }
342
 
 
343
 
        *supported = FALSE;
344
 
 
345
 
none:
346
 
        g_object_unref (sec);
347
 
        return NULL;
348
 
}
349
 
 
350
312
#ifdef ENABLE_INDICATOR
351
313
static gchar *
352
314
get_best_icon_name_for_ap (NMAccessPoint *ap, gboolean need_sec, gboolean encrypted)
415
377
        }
416
378
}
417
379
 
 
380
typedef struct {
 
381
        NMApplet *applet;
 
382
        AppletNewAutoConnectionCallback callback;
 
383
        gpointer callback_data;
 
384
} MoreInfo;
 
385
 
 
386
static void
 
387
more_info_wifi_dialog_response_cb (GtkDialog *foo,
 
388
                                   gint response,
 
389
                                   gpointer user_data)
 
390
{
 
391
        NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (foo);
 
392
        MoreInfo *info = user_data;
 
393
        NMConnection *connection = NULL;
 
394
        NMDevice *device = NULL;
 
395
        NMAccessPoint *ap = NULL;
 
396
 
 
397
        if (response != GTK_RESPONSE_OK) {
 
398
                info->callback (NULL, FALSE, TRUE, info->callback_data);
 
399
                goto done;
 
400
        }
 
401
 
 
402
        if (!nma_wireless_dialog_get_nag_ignored (dialog)) {
 
403
                GtkWidget *nag_dialog;
 
404
 
 
405
                /* Nag the user about certificates or whatever.  Only destroy the dialog
 
406
                 * if no nagging was done.
 
407
                 */
 
408
                nag_dialog = nma_wireless_dialog_nag_user (dialog);
 
409
                if (nag_dialog) {
 
410
                        gtk_window_set_transient_for (GTK_WINDOW (nag_dialog), GTK_WINDOW (dialog));
 
411
                        g_signal_connect (nag_dialog, "response",
 
412
                                          G_CALLBACK (nag_dialog_response_cb),
 
413
                                          dialog);
 
414
                        return;
 
415
                }
 
416
        }
 
417
 
 
418
        /* nma_wireless_dialog_get_connection() returns a connection with the
 
419
         * refcount incremented, so the caller must remember to unref it.
 
420
         */
 
421
        connection = nma_wireless_dialog_get_connection (dialog, &device, &ap);
 
422
        g_assert (connection);
 
423
        g_assert (device);
 
424
 
 
425
        info->callback (connection, TRUE, FALSE, info->callback_data);
 
426
 
 
427
        /* Balance nma_wireless_dialog_get_connection() */
 
428
        g_object_unref (connection);
 
429
 
 
430
done:
 
431
        g_free (info);
 
432
        gtk_widget_hide (GTK_WIDGET (dialog));
 
433
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
434
}
 
435
 
 
436
static void
 
437
_do_new_auto_connection (NMApplet *applet,
 
438
                         NMDevice *device,
 
439
                         NMAccessPoint *ap,
 
440
                         AppletNewAutoConnectionCallback callback,
 
441
                         gpointer callback_data)
 
442
{
 
443
        NMConnection *connection = NULL;
 
444
        NMSettingConnection *s_con = NULL;
 
445
        NMSettingWireless *s_wifi = NULL;
 
446
        NMSettingWirelessSecurity *s_wsec = NULL;
 
447
        NMSetting8021x *s_8021x = NULL;
 
448
        const GByteArray *ssid;
 
449
        NM80211ApSecurityFlags wpa_flags, rsn_flags;
 
450
        GtkWidget *dialog;
 
451
        MoreInfo *more_info;
 
452
        char *uuid;
 
453
 
 
454
        g_assert (applet);
 
455
        g_assert (device);
 
456
        g_assert (ap);
 
457
 
 
458
        connection = nm_connection_new ();
 
459
 
 
460
        ssid = nm_access_point_get_ssid (ap);
 
461
        if (   (nm_access_point_get_mode (ap) == NM_802_11_MODE_INFRA)
 
462
            && (is_manufacturer_default_ssid (ssid) == TRUE)) {
 
463
 
 
464
                /* Lock connection to this AP if it's a manufacturer-default SSID
 
465
                 * so that we don't randomly connect to some other 'linksys'
 
466
                 */
 
467
                s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
 
468
                clamp_ap_to_bssid (ap, s_wifi);
 
469
                nm_connection_add_setting (connection, NM_SETTING (s_wifi));
 
470
        }
 
471
 
 
472
        /* If the AP is WPA[2]-Enterprise then we need to set up a minimal 802.1x
 
473
         * setting and ask the user for more information.
 
474
         */
 
475
        rsn_flags = nm_access_point_get_rsn_flags (ap);
 
476
        wpa_flags = nm_access_point_get_wpa_flags (ap);
 
477
        if (   (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
 
478
            || (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
 
479
 
 
480
                /* Need a UUID for the "always ask" stuff in the Dialog of Doom */
 
481
                s_con = (NMSettingConnection *) nm_setting_connection_new ();
 
482
                uuid = nm_utils_uuid_generate ();
 
483
                g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL);
 
484
                g_free (uuid);
 
485
                nm_connection_add_setting (connection, NM_SETTING (s_con));
 
486
 
 
487
                if (!s_wifi) {
 
488
                        s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
 
489
                        nm_connection_add_setting (connection, NM_SETTING (s_wifi));
 
490
                }
 
491
                g_object_set (s_wifi,
 
492
                              NM_SETTING_WIRELESS_SSID, ssid,
 
493
                              NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 
494
                              NULL);
 
495
 
 
496
                s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
 
497
                g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
 
498
                nm_connection_add_setting (connection, NM_SETTING (s_wsec));
 
499
 
 
500
                s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
 
501
                nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
 
502
                g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
 
503
                nm_connection_add_setting (connection, NM_SETTING (s_8021x));
 
504
        }
 
505
 
 
506
        /* If it's an 802.1x connection, we need more information, so pop up the
 
507
         * Dialog Of Doom.
 
508
         */
 
509
        if (s_8021x) {
 
510
                more_info = g_malloc0 (sizeof (*more_info));
 
511
                more_info->applet = applet;
 
512
                more_info->callback = callback;
 
513
                more_info->callback_data = callback_data;
 
514
 
 
515
                dialog = nma_wireless_dialog_new (applet, connection, device, ap);
 
516
                if (dialog) {
 
517
                        g_signal_connect (dialog, "response",
 
518
                                              G_CALLBACK (more_info_wifi_dialog_response_cb),
 
519
                                              more_info);
 
520
                        show_ignore_focus_stealing_prevention (dialog);
 
521
                }
 
522
        } else {
 
523
                /* Everything else can just get activated right away */
 
524
                callback (connection, TRUE, FALSE, callback_data);
 
525
        }
 
526
}
 
527
 
418
528
static gboolean
419
529
wireless_new_auto_connection (NMDevice *device,
420
530
                              gpointer dclass_data,
422
532
                              gpointer callback_data)
423
533
{
424
534
        WirelessMenuItemInfo *info = (WirelessMenuItemInfo *) dclass_data;
425
 
        NMConnection *connection = NULL;
426
 
        NMSettingConnection *s_con = NULL;
427
 
        NMSettingWireless *s_wireless = NULL;
428
 
        NMSettingWirelessSecurity *s_wireless_sec = NULL;
429
 
        NMSetting8021x *s_8021x = NULL;
430
 
        const GByteArray *ap_ssid;
431
 
        char *id;
432
 
        char buf[33];
433
 
        int buf_len;
434
 
        NM80211Mode mode;
435
 
        guint32 dev_caps;
436
 
        gboolean supported = TRUE;
437
 
 
438
 
        if (!info->ap) {
439
 
                g_warning ("%s: AP not set", __func__);
440
 
                return FALSE;
441
 
        }
442
 
 
443
 
        s_wireless = (NMSettingWireless *) nm_setting_wireless_new ();
444
 
 
445
 
        ap_ssid = nm_access_point_get_ssid (info->ap);
446
 
        g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ap_ssid, NULL);
447
 
 
448
 
        mode = nm_access_point_get_mode (info->ap);
449
 
        if (mode == NM_802_11_MODE_ADHOC)
450
 
                g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, "adhoc", NULL);
451
 
        else if (mode == NM_802_11_MODE_INFRA) {
452
 
                g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL);
453
 
                /* Lock connection to this AP if it's a manufacturer-default SSID */
454
 
                if (is_manufacturer_default_ssid (ap_ssid))
455
 
                        clamp_ap_to_bssid (info->ap, s_wireless);
456
 
        } else
457
 
                g_assert_not_reached ();
458
 
 
459
 
        dev_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
460
 
        s_wireless_sec = get_security_for_ap (info->ap, dev_caps, &supported, &s_8021x);
461
 
        if (!supported) {
462
 
                g_warning ("Unsupported AP configuration: dev_caps 0x%X, ap_flags 0x%X, "
463
 
                           "wpa_flags 0x%X, rsn_flags 0x%x, mode %d",
464
 
                           dev_caps,
465
 
                           nm_access_point_get_flags (info->ap),
466
 
                           nm_access_point_get_wpa_flags (info->ap),
467
 
                           nm_access_point_get_rsn_flags (info->ap),
468
 
                           nm_access_point_get_mode (info->ap));
469
 
                g_object_unref (s_wireless);
470
 
                return FALSE;
471
 
        } else if (s_wireless_sec)
472
 
                g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
473
 
 
474
 
        connection = nm_connection_new ();
475
 
        nm_connection_add_setting (connection, NM_SETTING (s_wireless));
476
 
        if (s_wireless_sec)
477
 
                nm_connection_add_setting (connection, NM_SETTING (s_wireless_sec));
478
 
        if (s_8021x)
479
 
                nm_connection_add_setting (connection, NM_SETTING (s_8021x));
480
 
 
481
 
        s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
482
 
        g_object_set (s_con,
483
 
                      NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
484
 
                      NM_SETTING_CONNECTION_AUTOCONNECT, !is_manufacturer_default_ssid (ap_ssid),
485
 
                      NULL);
486
 
 
487
 
        memset (buf, 0, sizeof (buf));
488
 
        buf_len = MIN(ap_ssid->len, sizeof (buf) - 1);
489
 
        memcpy (buf, ap_ssid->data, buf_len);
490
 
        id = g_strdup_printf ("Auto %s", nm_utils_ssid_to_utf8 (buf, buf_len));
491
 
        g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NULL);
492
 
        g_free (id);
493
 
 
494
 
        id = nm_utils_uuid_generate ();
495
 
        g_object_set (s_con, NM_SETTING_CONNECTION_UUID, id, NULL);
496
 
        g_free (id);
497
 
 
498
 
        nm_connection_add_setting (connection, NM_SETTING (s_con));
499
 
 
500
 
        (*callback) (connection, TRUE, FALSE, callback_data);
 
535
 
 
536
        g_return_val_if_fail (device != NULL, FALSE);
 
537
        g_return_val_if_fail (info->ap != NULL, FALSE);
 
538
 
 
539
        _do_new_auto_connection (info->applet, device, info->ap, callback, callback_data);
501
540
        return TRUE;
502
541
}
503
542
 
 
543
 
504
544
static void
505
545
wireless_menu_item_activate (GtkMenuItem *item, gpointer user_data)
506
546
{
1016
1056
}
1017
1057
 
1018
1058
static void
1019
 
add_seen_bssid (NMSettingsConnectionInterface *connection, NMAccessPoint *ap)
1020
 
{
1021
 
        NMSettingWireless *s_wireless;
1022
 
        const char *bssid;
1023
 
 
1024
 
        if (!NMA_GCONF_CONNECTION (connection))
1025
 
                return;
1026
 
 
1027
 
        s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_WIRELESS));
1028
 
        if (!s_wireless)
1029
 
                return;
1030
 
 
1031
 
        bssid = nm_access_point_get_hw_address (ap);
1032
 
        if (!bssid || !utils_ether_addr_valid (ether_aton (bssid)))
1033
 
                return;
1034
 
 
1035
 
        if (nm_setting_wireless_add_seen_bssid (s_wireless, bssid)) {
1036
 
                /* Ignore secrets since we don't have any here and we're just adding a BSSID */
1037
 
                nma_gconf_connection_update (NMA_GCONF_CONNECTION (connection), TRUE);
1038
 
        }
1039
 
}
1040
 
 
1041
 
static void
1042
1059
notify_active_ap_changed_cb (NMDeviceWifi *device,
1043
1060
                             GParamSpec *pspec,
1044
1061
                             NMApplet *applet)
1045
1062
{
1046
 
        NMSettingsConnectionInterface *connection;
 
1063
        NMRemoteConnection *connection;
1047
1064
        NMSettingWireless *s_wireless;
1048
1065
        NMAccessPoint *new;
1049
1066
        const GByteArray *ssid;
1067
1084
        if (!ssid || !nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), ssid, TRUE))
1068
1085
                return;
1069
1086
 
1070
 
        add_seen_bssid (connection, new);
1071
 
 
1072
1087
        applet_schedule_update_icon (applet);
1073
1088
}
1074
1089
 
1268
1283
}
1269
1284
 
1270
1285
static void
1271
 
on_new_connection (NMSettingsInterface *settings,
1272
 
                   NMSettingsConnectionInterface *connection,
 
1286
on_new_connection (NMRemoteSettings *settings,
 
1287
                   NMRemoteConnection *connection,
1273
1288
                   gpointer datap)
1274
1289
{
1275
1290
        struct ap_notification_data *data = datap;
1280
1295
free_ap_notification_data (gpointer user_data)
1281
1296
{
1282
1297
        struct ap_notification_data *data = user_data;
1283
 
        NMSettingsInterface *settings = applet_get_settings (data->applet);
 
1298
        NMRemoteSettings *settings = applet_get_settings (data->applet);
1284
1299
 
1285
1300
        if (data->id)
1286
1301
                g_source_remove (data->id);
1326
1341
         * when the device is destroyed.
1327
1342
         */ 
1328
1343
        id = g_signal_connect (applet_get_settings (applet),
1329
 
                               NM_SETTINGS_INTERFACE_NEW_CONNECTION,
 
1344
                               NM_REMOTE_SETTINGS_NEW_CONNECTION,
1330
1345
                               G_CALLBACK (on_new_connection),
1331
1346
                               data);
1332
1347
        data->new_con_id = id;
1389
1404
                               NMDeviceStateReason reason,
1390
1405
                               NMApplet *applet)
1391
1406
{
1392
 
        NMSettingsConnectionInterface *connection;
1393
1407
        NMAccessPoint *new = NULL;
1394
1408
        char *esc_ssid = NULL;
1395
1409
 
1401
1415
        if (new_state != NM_DEVICE_STATE_ACTIVATED)
1402
1416
                return;
1403
1417
 
1404
 
        if (new) {
1405
 
                const GByteArray *ssid = nm_access_point_get_ssid (new);
1406
 
 
1407
 
                if (ssid) {
1408
 
                        esc_ssid = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len);
1409
 
                        g_object_set_data_full (G_OBJECT(device), "canonical-last-essid", g_strdup (esc_ssid), (GDestroyNotify) g_free);
1410
 
                }
1411
 
 
1412
 
                /* Save this BSSID to seen-bssids list */
1413
 
                connection = applet_get_exported_connection_for_device (device, applet);
1414
 
                if (connection)
1415
 
                        add_seen_bssid (connection, new);
1416
 
        }
1417
 
 
 
1418
        esc_ssid = get_ssid_utf8 (new);
 
1419
        g_object_set_data_full (G_OBJECT(device), "canonical-last-essid", g_strdup (esc_ssid), (GDestroyNotify) g_free);
1418
1420
        applet_do_notify_with_pref (applet,
1419
 
                                    esc_ssid ? esc_ssid : _("(none)"),
1420
 
                                    _("Connection Established"),
1421
 
                                    "notification-network-wireless-full",
 
1421
                                    esc_ssid ? esc_ssid : _("(none)"),
 
1422
                                    _("Connection Established"),
 
1423
                                    "notification-network-wireless-full",
1422
1424
                                    PREF_DISABLE_CONNECTED_NOTIFICATIONS);
1423
1425
        g_free (esc_ssid);
1424
1426
}
1438
1440
        char *ssid = NULL;
1439
1441
 
1440
1442
        ap = g_object_get_data (G_OBJECT (device), ACTIVE_AP_TAG);
1441
 
        if (ap) {
1442
 
                const GByteArray *tmp;
1443
 
 
1444
 
                tmp = nm_access_point_get_ssid (ap);
1445
 
                if (tmp)
1446
 
                        ssid = nm_utils_ssid_to_utf8 ((const char *) tmp->data, tmp->len);
1447
 
        }
1448
 
 
1449
 
        if (!ssid)
1450
 
                ssid = g_strdup (_("(none)"));
1451
1443
 
1452
1444
        id = nm_device_get_iface (device);
1453
1445
        if (connection) {
1488
1480
 
1489
1481
                        *out_indicator_icon = get_best_icon_name_for_ap (ap, FALSE, FALSE);
1490
1482
 
 
1483
                        ssid = get_ssid_utf8 (ap);
1491
1484
                        *tip = g_strdup_printf (_("Wireless network connection '%s' active: %s (%d%%)"),
1492
1485
                                                id, ssid, strength);
 
1486
                        g_free (ssid);
1493
1487
                } else {
1494
1488
                        *out_indicator_icon = g_strdup_printf ("nm-signal-00");
1495
1489
                        *out_pixbuf = nma_icon_check_and_load (*out_indicator_icon, &applet->wireless_00_icon, applet);
1499
1493
        default:
1500
1494
                break;
1501
1495
        }
1502
 
 
1503
 
        g_free (ssid);
1504
 
}
1505
 
 
1506
 
static void
1507
 
activate_device_cb (gpointer user_data, const char *path, GError *error)
1508
 
{
1509
 
        if (error)
1510
 
                nm_warning ("Device Activation failed: %s", error->message);
1511
 
        applet_schedule_update_icon (NM_APPLET (user_data));
1512
1496
}
1513
1497
 
1514
1498
static gboolean
1541
1525
        }
1542
1526
}
1543
1527
 
1544
 
static void
1545
 
update_cb (NMSettingsConnectionInterface *connection,
1546
 
           GError *error,
1547
 
           gpointer user_data)
1548
 
{
1549
 
        if (error) {
1550
 
                g_warning ("%s: failed to update connection: (%d) %s",
1551
 
                           __func__, error->code, error->message);
1552
 
        }
 
1528
 
 
1529
static void
 
1530
activate_existing_cb (NMClient *client,
 
1531
                      NMActiveConnection *active,
 
1532
                      GError *error,
 
1533
                      gpointer user_data)
 
1534
{
 
1535
        if (error)
 
1536
                g_warning ("Failed to activate connection: (%d) %s", error->code, error->message);
 
1537
        applet_schedule_update_icon (NM_APPLET (user_data));
 
1538
}
 
1539
 
 
1540
static void
 
1541
activate_new_cb (NMClient *client,
 
1542
                 NMActiveConnection *active,
 
1543
                 const char *connection_path,
 
1544
                 GError *error,
 
1545
                 gpointer user_data)
 
1546
{
 
1547
        if (error)
 
1548
                g_warning ("Failed to add new connection: (%d) %s", error->code, error->message);
 
1549
        applet_schedule_update_icon (NM_APPLET (user_data));
1553
1550
}
1554
1551
 
1555
1552
static void
1562
1559
        NMConnection *connection = NULL, *fuzzy_match = NULL;
1563
1560
        NMDevice *device = NULL;
1564
1561
        NMAccessPoint *ap = NULL;
1565
 
        const char *service = NM_DBUS_SERVICE_USER_SETTINGS;
 
1562
        GSList *all, *iter;
1566
1563
 
1567
1564
        if (response != GTK_RESPONSE_OK)
1568
1565
                goto done;
1590
1587
        g_assert (connection);
1591
1588
        g_assert (device);
1592
1589
 
1593
 
        /* If it's a system connection we just need to tell NM to activate it */
1594
 
        if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) {
1595
 
                service = NM_DBUS_SERVICE_SYSTEM_SETTINGS;
1596
 
                goto activate;
 
1590
        /* Find a similar connection and use that instead */
 
1591
        all = applet_get_all_connections (applet);
 
1592
        for (iter = all; iter; iter = g_slist_next (iter)) {
 
1593
                if (nm_connection_compare (connection,
 
1594
                                           NM_CONNECTION (iter->data),
 
1595
                                           (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) {
 
1596
                        fuzzy_match = NM_CONNECTION (iter->data);
 
1597
                        break;
 
1598
                }
1597
1599
        }
 
1600
        g_slist_free (all);
1598
1601
 
1599
 
        if (NMA_IS_GCONF_CONNECTION (connection)) {
1600
 
                /* Not a new or system connection, save the updated settings to GConf */
1601
 
                nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
1602
 
                                                         update_cb,
1603
 
                                                         NULL);
 
1602
        if (fuzzy_match) {
 
1603
                nm_client_activate_connection (applet->nm_client,
 
1604
                                               fuzzy_match,
 
1605
                                               device,
 
1606
                                               ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
 
1607
                                               activate_existing_cb,
 
1608
                                               applet);
1604
1609
        } else {
1605
 
                GSList *all, *iter;
1606
 
 
1607
 
                /* Find a similar connection and use that instead */
1608
 
                all = applet_get_all_connections (applet);
1609
 
                for (iter = all; iter; iter = g_slist_next (iter)) {
1610
 
                        if (nm_connection_compare (connection,
1611
 
                                                   NM_CONNECTION (iter->data),
1612
 
                                                   (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) {
1613
 
                                fuzzy_match = g_object_ref (NM_CONNECTION (iter->data));
1614
 
                                break;
1615
 
                        }
1616
 
                }
1617
 
                g_slist_free (all);
1618
 
 
1619
 
                if (fuzzy_match) {
1620
 
                        if (nm_connection_get_scope (fuzzy_match) == NM_CONNECTION_SCOPE_SYSTEM) {
1621
 
                                // FIXME: do something other than just use the system connection?
1622
 
                        } else {
1623
 
                                NMSettingWirelessSecurity *s_wireless_sec;
1624
 
 
1625
 
                                /* Copy secrets & wireless security */
1626
 
                                s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
1627
 
                                if (s_wireless_sec) {
1628
 
                                        GHashTable *hash;
1629
 
                                        NMSetting *dup_setting;
1630
 
 
1631
 
                                        hash = nm_setting_to_hash (NM_SETTING (s_wireless_sec));
1632
 
                                        dup_setting = nm_setting_new_from_hash (NM_TYPE_SETTING_WIRELESS_SECURITY, hash);
1633
 
                                        g_hash_table_destroy (hash);
1634
 
                                        nm_connection_add_setting (fuzzy_match, dup_setting);
1635
 
                                }
1636
 
                        }
1637
 
 
1638
 
                        /* Balance nma_wireless_dialog_get_connection() */
1639
 
                        g_object_unref (connection);
1640
 
                        connection = g_object_ref (fuzzy_match);
1641
 
                } else {
1642
 
                        /* Entirely new connection */
1643
 
                        NMAGConfConnection *new_gconf_connection;
1644
 
                        NMSettingConnection *s_con;
1645
 
                        char *id;
1646
 
 
1647
 
                        /* Update a new connection's name and autoconnect status */
1648
 
                        s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
1649
 
                        id = (char *) nm_setting_connection_get_id (s_con);
1650
 
 
1651
 
                        if (!id) {
1652
 
                                NMSettingWireless *s_wireless;
1653
 
                                const GByteArray *ssid;
1654
 
                                const char *mode;
1655
 
 
1656
 
                                s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
1657
 
                                ssid = nm_setting_wireless_get_ssid (s_wireless);
1658
 
 
1659
 
                                id = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len);
1660
 
                                g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NULL);
1661
 
                                g_free (id);
1662
 
 
1663
 
                                // FIXME: don't autoconnect until the connection is successful at least once
1664
 
                                /* Don't autoconnect adhoc networks by default for now */
1665
 
                                mode = nm_setting_wireless_get_mode (s_wireless);
1666
 
                                if (!mode || !strcmp (mode, "infrastructure"))
1667
 
                                        g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
1668
 
                        }
1669
 
 
1670
 
                        /* Export it over D-Bus */
1671
 
                        new_gconf_connection = nma_gconf_settings_add_connection (applet->gconf_settings, connection);
1672
 
                        if (!new_gconf_connection) {
1673
 
                                nm_warning ("Couldn't create new network connection.");
1674
 
                                goto done;
1675
 
                        }
1676
 
 
1677
 
                        /* Balance nma_wireless_dialog_get_connection() */
1678
 
                        g_object_unref (connection);
1679
 
                        connection = g_object_ref (new_gconf_connection);
1680
 
                }
 
1610
                NMSetting *s_con;
 
1611
                NMSettingWireless *s_wifi = NULL;
 
1612
                const char *mode = NULL;
 
1613
 
 
1614
                /* Entirely new connection */
 
1615
 
 
1616
                /* Don't autoconnect adhoc networks by default for now */
 
1617
                s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
 
1618
                if (s_wifi)
 
1619
                        mode = nm_setting_wireless_get_mode (s_wifi);
 
1620
                if (g_strcmp0 (mode, "adhoc") == 0) {
 
1621
                        s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
 
1622
                        if (!s_con) {
 
1623
                                s_con = nm_setting_connection_new ();
 
1624
                                nm_connection_add_setting (connection, s_con);
 
1625
                        }
 
1626
                        g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL);
 
1627
                }
 
1628
 
 
1629
                nm_client_add_and_activate_connection (applet->nm_client,
 
1630
                                                       connection,
 
1631
                                                       device,
 
1632
                                                       ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
 
1633
                                                       activate_new_cb,
 
1634
                                                       applet);
1681
1635
        }
1682
1636
 
1683
 
activate:
1684
 
        nm_client_activate_connection (applet->nm_client,
1685
 
                                       service,
1686
 
                                       nm_connection_get_path (connection),
1687
 
                                       device,
1688
 
                                       ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
1689
 
                                       activate_device_cb,
1690
 
                                       applet);
 
1637
        /* Balance nma_wireless_dialog_get_connection() */
 
1638
        g_object_unref (connection);
1691
1639
 
1692
1640
done:
1693
 
        /* Balance nma_wireless_dialog_get_connection() */
1694
 
        if (connection)
1695
 
                g_object_unref (connection);
1696
 
 
1697
1641
        gtk_widget_hide (GTK_WIDGET (dialog));
1698
1642
        gtk_widget_destroy (GTK_WIDGET (dialog));
1699
1643
}
1700
1644
 
1701
 
static void
1702
 
wireless_get_more_info (NMDevice *device,
1703
 
                        NMConnection *connection,
1704
 
                        NMApplet *applet,
1705
 
                        gpointer user_data)
1706
 
{
1707
 
        WirelessMenuItemInfo *info = (WirelessMenuItemInfo *) user_data;
1708
 
        GtkWidget *dialog;
1709
 
 
1710
 
        dialog = nma_wireless_dialog_new (applet, connection, device, info->ap);
1711
 
        g_return_if_fail (dialog != NULL);
1712
 
 
1713
 
        g_signal_connect (dialog, "response",
1714
 
                          G_CALLBACK (wireless_dialog_response_cb),
1715
 
                          applet);
1716
 
 
1717
 
        show_ignore_focus_stealing_prevention (dialog);
1718
 
}
1719
 
 
1720
1645
static gboolean
1721
1646
add_one_setting (GHashTable *settings,
1722
1647
                 NMConnection *connection,
1731
1656
        g_return_val_if_fail (error != NULL, FALSE);
1732
1657
        g_return_val_if_fail (*error == NULL, FALSE);
1733
1658
 
1734
 
        secrets = nm_setting_to_hash (setting);
 
1659
        secrets = nm_setting_to_hash (setting, NM_SETTING_HASH_FLAG_ALL);
1735
1660
        if (secrets) {
1736
1661
                g_hash_table_insert (settings, g_strdup (nm_setting_get_name (setting)), secrets);
1737
1662
        } else {
1738
1663
                g_set_error (error,
1739
 
                             NM_SETTINGS_INTERFACE_ERROR,
1740
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1664
                             NM_SECRET_AGENT_ERROR,
 
1665
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1741
1666
                             "%s.%d (%s): failed to hash setting '%s'.",
1742
1667
                             __FILE__, __LINE__, __func__, nm_setting_get_name (setting));
1743
1668
        }
1746
1671
}
1747
1672
 
1748
1673
typedef struct {
1749
 
        NMApplet *applet;
1750
 
        NMActiveConnection *active_connection;
 
1674
        SecretsRequest req;
 
1675
 
1751
1676
        GtkWidget *dialog;
1752
1677
        GtkWidget *nag_dialog;
1753
 
        NMANewSecretsRequestedFunc callback;
1754
 
        gpointer callback_data;
1755
 
        char *setting_name;
1756
1678
} NMWifiInfo;
1757
1679
 
1758
1680
static void
1759
 
destroy_wifi_dialog (gpointer user_data, GObject *finalized)
 
1681
free_wifi_info (SecretsRequest *req)
1760
1682
{
1761
 
        NMWifiInfo *info = user_data;
 
1683
        NMWifiInfo *info = (NMWifiInfo *) req;
1762
1684
 
1763
 
        gtk_widget_hide (info->dialog);
1764
 
        gtk_widget_destroy (info->dialog);
1765
 
        g_free (info->setting_name);
1766
 
        g_free (info);
 
1685
        if (info->dialog) {
 
1686
                gtk_widget_hide (info->dialog);
 
1687
                gtk_widget_destroy (info->dialog);
 
1688
        }
1767
1689
}
1768
1690
 
1769
1691
static void
1771
1693
                                gint response,
1772
1694
                                gpointer user_data)
1773
1695
{
1774
 
        NMWifiInfo *info = user_data;
 
1696
        SecretsRequest *req = user_data;
 
1697
        NMWifiInfo *info = (NMWifiInfo *) req;
1775
1698
        NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (info->dialog);
1776
1699
        NMConnection *connection = NULL;
1777
1700
        NMSettingWirelessSecurity *s_wireless_sec;
1778
 
        NMDevice *device = NULL;
1779
1701
        GHashTable *settings = NULL;
1780
1702
        const char *key_mgmt, *auth_alg;
1781
1703
        GError *error = NULL;
1799
1721
                }
1800
1722
        }
1801
1723
 
1802
 
        /* Got a user response, clear the NMActiveConnection destroy handler for
1803
 
         * this dialog since this function will now take over dialog destruction.
1804
 
         */
1805
 
        g_object_weak_unref (G_OBJECT (info->active_connection), destroy_wifi_dialog, info);
1806
 
 
1807
1724
        if (response != GTK_RESPONSE_OK) {
1808
1725
                g_set_error (&error,
1809
 
                             NM_SETTINGS_INTERFACE_ERROR,
1810
 
                             NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED,
 
1726
                             NM_SECRET_AGENT_ERROR,
 
1727
                             NM_SECRET_AGENT_ERROR_USER_CANCELED,
1811
1728
                             "%s.%d (%s): canceled",
1812
1729
                             __FILE__, __LINE__, __func__);
1813
1730
                goto done;
1814
1731
        }
1815
1732
 
1816
 
        connection = nma_wireless_dialog_get_connection (dialog, &device, NULL);
 
1733
        connection = nma_wireless_dialog_get_connection (dialog, NULL, NULL);
1817
1734
        if (!connection) {
1818
1735
                g_set_error (&error,
1819
 
                             NM_SETTINGS_INTERFACE_ERROR,
1820
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1736
                             NM_SECRET_AGENT_ERROR,
 
1737
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1821
1738
                             "%s.%d (%s): couldn't get connection from wireless dialog.",
1822
1739
                             __FILE__, __LINE__, __func__);
1823
1740
                goto done;
1827
1744
        s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
1828
1745
        if (!s_wireless_sec) {
1829
1746
                g_set_error (&error,
1830
 
                             NM_SETTINGS_INTERFACE_ERROR,
1831
 
                             NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
 
1747
                             NM_SECRET_AGENT_ERROR,
 
1748
                             NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
1832
1749
                             "%s.%d (%s): requested setting '802-11-wireless-security'"
1833
1750
                             " didn't exist in the connection.",
1834
1751
                             __FILE__, __LINE__, __func__);
1842
1759
                                          g_free, (GDestroyNotify) g_hash_table_destroy);
1843
1760
        if (!settings) {
1844
1761
                g_set_error (&error,
1845
 
                             NM_SETTINGS_INTERFACE_ERROR,
1846
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1762
                             NM_SECRET_AGENT_ERROR,
 
1763
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1847
1764
                             "%s.%d (%s): not enough memory to return secrets.",
1848
1765
                             __FILE__, __LINE__, __func__);
1849
1766
                goto done;
1865
1782
                        s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
1866
1783
                        if (!s_8021x) {
1867
1784
                                g_set_error (&error,
1868
 
                                             NM_SETTINGS_INTERFACE_ERROR,
1869
 
                                             NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
 
1785
                                             NM_SECRET_AGENT_ERROR,
 
1786
                                             NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
1870
1787
                                             "%s.%d (%s): requested setting '802-1x' didn't"
1871
1788
                                             " exist in the connection.",
1872
1789
                                             __FILE__, __LINE__, __func__);
1880
1797
        }
1881
1798
 
1882
1799
        /* Add the 802-11-wireless-security setting no matter what */
1883
 
        if (!add_one_setting (settings, connection, NM_SETTING (s_wireless_sec), &error))
1884
 
                goto done;
1885
 
 
1886
 
        info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), settings, NULL, info->callback_data);
1887
 
 
1888
 
        /* Save the connection back to GConf _after_ hashing it, because
1889
 
         * saving to GConf might trigger the GConf change notifiers, resulting
1890
 
         * in the connection being read back in from GConf which clears secrets.
1891
 
         */
1892
 
        if (NMA_IS_GCONF_CONNECTION (connection)) {
1893
 
                nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
1894
 
                                                         update_cb,
1895
 
                                                         NULL);
1896
 
        }
 
1800
        add_one_setting (settings, connection, NM_SETTING (s_wireless_sec), &error);
1897
1801
 
1898
1802
done:
 
1803
        applet_secrets_request_complete (req, settings, error);
 
1804
        applet_secrets_request_free (req);
 
1805
 
1899
1806
        if (settings)
1900
1807
                g_hash_table_destroy (settings);
1901
 
 
1902
 
        if (error) {
1903
 
                g_warning ("%s", error->message);
1904
 
                info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), NULL, error, info->callback_data);
1905
 
                g_error_free (error);
1906
 
        }
1907
 
 
1908
1808
        if (connection)
1909
1809
                nm_connection_clear_secrets (connection);
1910
 
 
1911
 
        destroy_wifi_dialog (info, NULL);
1912
1810
}
1913
1811
 
1914
1812
static gboolean
1915
 
wireless_get_secrets (NMDevice *device,
1916
 
                      NMSettingsConnectionInterface *connection,
1917
 
                      NMActiveConnection *active_connection,
1918
 
                      const char *setting_name,
1919
 
                      const char **hints,
1920
 
                      NMANewSecretsRequestedFunc callback,
1921
 
                      gpointer callback_data,
1922
 
                      NMApplet *applet,
1923
 
                      GError **error)
 
1813
wireless_get_secrets (SecretsRequest *req, GError **error)
1924
1814
{
1925
 
        NMWifiInfo *info;
1926
 
        NMAccessPoint *ap;
1927
 
        const char *specific_object;
1928
 
 
1929
 
        if (!setting_name || !active_connection) {
1930
 
                g_set_error (error,
1931
 
                             NM_SETTINGS_INTERFACE_ERROR,
1932
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
1933
 
                             "%s.%d (%s): setting name and active connection object required",
1934
 
                             __FILE__, __LINE__, __func__);
1935
 
                return FALSE;
1936
 
        }
1937
 
 
1938
 
        specific_object = nm_active_connection_get_specific_object (active_connection);
1939
 
        if (!specific_object) {
1940
 
                g_set_error (error,
1941
 
                             NM_SETTINGS_INTERFACE_ERROR,
1942
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
1943
 
                             "%s.%d (%s): could not determine AP for specific object",
1944
 
                             __FILE__, __LINE__, __func__);
1945
 
                return FALSE;
1946
 
        }
1947
 
 
1948
 
        info = g_malloc0 (sizeof (NMWifiInfo));
1949
 
 
1950
 
        ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), specific_object);
1951
 
        info->dialog = nma_wireless_dialog_new (applet, NM_CONNECTION (connection), device, ap);
1952
 
        if (!info->dialog) {
1953
 
                g_set_error (error,
1954
 
                             NM_SETTINGS_INTERFACE_ERROR,
1955
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1815
        NMWifiInfo *info = (NMWifiInfo *) req;
 
1816
 
 
1817
        applet_secrets_request_set_free_func (req, free_wifi_info);
 
1818
 
 
1819
        info->dialog = nma_wireless_dialog_new (req->applet, req->connection, NULL, NULL);
 
1820
        if (info->dialog) {
 
1821
                g_signal_connect (info->dialog, "response",
 
1822
                                  G_CALLBACK (get_secrets_dialog_response_cb),
 
1823
                                  info);
 
1824
                show_ignore_focus_stealing_prevention (info->dialog);
 
1825
        } else {
 
1826
                g_set_error (error,
 
1827
                             NM_SECRET_AGENT_ERROR,
 
1828
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1956
1829
                             "%s.%d (%s): couldn't display secrets UI",
1957
1830
                             __FILE__, __LINE__, __func__);
1958
 
                g_free (info);
1959
 
                return FALSE;
1960
1831
        }
1961
 
 
1962
 
        info->applet = applet;
1963
 
        info->active_connection = active_connection;
1964
 
        info->callback = callback;
1965
 
        info->callback_data = callback_data;
1966
 
        info->setting_name = g_strdup (setting_name);
1967
 
 
1968
 
        g_signal_connect (info->dialog, "response",
1969
 
                          G_CALLBACK (get_secrets_dialog_response_cb),
1970
 
                          info);
1971
 
 
1972
 
        /* Attach a destroy notifier to the NMActiveConnection so we can destroy
1973
 
         * the dialog when the active connection goes away.
1974
 
         */
1975
 
        g_object_weak_ref (G_OBJECT (active_connection), destroy_wifi_dialog, info);
1976
 
 
1977
 
        show_ignore_focus_stealing_prevention (info->dialog);
1978
 
        return TRUE;
 
1832
        return !!info->dialog;
1979
1833
}
1980
1834
 
1981
1835
NMADeviceClass *
1992
1846
        dclass->device_added = wireless_device_added;
1993
1847
        dclass->device_state_changed = wireless_device_state_changed;
1994
1848
        dclass->get_icon = wireless_get_icon;
1995
 
        dclass->get_more_info = wireless_get_more_info;
1996
1849
        dclass->get_secrets = wireless_get_secrets;
 
1850
        dclass->secrets_request_size = sizeof (NMWifiInfo);
1997
1851
 
1998
1852
        return dclass;
1999
1853
}