~dylanmccall/ubuntu/oneiric/network-manager-applet/lp852961-disable-autostart-for-gnome-shell

« 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
  • mto: This revision was merged to the branch mainline in revision 68.
  • Revision ID: james.westby@ubuntu.com-20110530132518-ya5i5mcrl8szsmoj
Tags: upstream-0.8.9997+git.20110529t170033.9ec4c5d
ImportĀ upstreamĀ versionĀ 0.8.9997+git.20110529t170033.9ec4c5d

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 */
207
310
}
208
311
 
209
312
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
 
static void
351
313
clamp_ap_to_bssid (NMAccessPoint *ap, NMSettingWireless *s_wifi)
352
314
{
353
315
        const char *str_bssid;
374
336
        }
375
337
}
376
338
 
 
339
typedef struct {
 
340
        NMApplet *applet;
 
341
        AppletNewAutoConnectionCallback callback;
 
342
        gpointer callback_data;
 
343
} MoreInfo;
 
344
 
 
345
static void
 
346
more_info_wifi_dialog_response_cb (GtkDialog *foo,
 
347
                                   gint response,
 
348
                                   gpointer user_data)
 
349
{
 
350
        NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (foo);
 
351
        MoreInfo *info = user_data;
 
352
        NMConnection *connection = NULL;
 
353
        NMDevice *device = NULL;
 
354
        NMAccessPoint *ap = NULL;
 
355
 
 
356
        if (response != GTK_RESPONSE_OK) {
 
357
                info->callback (NULL, FALSE, TRUE, info->callback_data);
 
358
                goto done;
 
359
        }
 
360
 
 
361
        if (!nma_wireless_dialog_get_nag_ignored (dialog)) {
 
362
                GtkWidget *nag_dialog;
 
363
 
 
364
                /* Nag the user about certificates or whatever.  Only destroy the dialog
 
365
                 * if no nagging was done.
 
366
                 */
 
367
                nag_dialog = nma_wireless_dialog_nag_user (dialog);
 
368
                if (nag_dialog) {
 
369
                        gtk_window_set_transient_for (GTK_WINDOW (nag_dialog), GTK_WINDOW (dialog));
 
370
                        g_signal_connect (nag_dialog, "response",
 
371
                                          G_CALLBACK (nag_dialog_response_cb),
 
372
                                          dialog);
 
373
                        return;
 
374
                }
 
375
        }
 
376
 
 
377
        /* nma_wireless_dialog_get_connection() returns a connection with the
 
378
         * refcount incremented, so the caller must remember to unref it.
 
379
         */
 
380
        connection = nma_wireless_dialog_get_connection (dialog, &device, &ap);
 
381
        g_assert (connection);
 
382
        g_assert (device);
 
383
 
 
384
        info->callback (connection, TRUE, FALSE, info->callback_data);
 
385
 
 
386
        /* Balance nma_wireless_dialog_get_connection() */
 
387
        g_object_unref (connection);
 
388
 
 
389
done:
 
390
        g_free (info);
 
391
        gtk_widget_hide (GTK_WIDGET (dialog));
 
392
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
393
}
 
394
 
 
395
static void
 
396
_do_new_auto_connection (NMApplet *applet,
 
397
                         NMDevice *device,
 
398
                         NMAccessPoint *ap,
 
399
                         AppletNewAutoConnectionCallback callback,
 
400
                         gpointer callback_data)
 
401
{
 
402
        NMConnection *connection = NULL;
 
403
        NMSettingConnection *s_con = NULL;
 
404
        NMSettingWireless *s_wifi = NULL;
 
405
        NMSettingWirelessSecurity *s_wsec = NULL;
 
406
        NMSetting8021x *s_8021x = NULL;
 
407
        const GByteArray *ssid;
 
408
        NM80211ApSecurityFlags wpa_flags, rsn_flags;
 
409
        GtkWidget *dialog;
 
410
        MoreInfo *more_info;
 
411
        char *uuid;
 
412
 
 
413
        g_assert (applet);
 
414
        g_assert (device);
 
415
        g_assert (ap);
 
416
 
 
417
        connection = nm_connection_new ();
 
418
 
 
419
        ssid = nm_access_point_get_ssid (ap);
 
420
        if (   (nm_access_point_get_mode (ap) == NM_802_11_MODE_INFRA)
 
421
            && (is_manufacturer_default_ssid (ssid) == TRUE)) {
 
422
 
 
423
                /* Lock connection to this AP if it's a manufacturer-default SSID
 
424
                 * so that we don't randomly connect to some other 'linksys'
 
425
                 */
 
426
                s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
 
427
                clamp_ap_to_bssid (ap, s_wifi);
 
428
                nm_connection_add_setting (connection, NM_SETTING (s_wifi));
 
429
        }
 
430
 
 
431
        /* If the AP is WPA[2]-Enterprise then we need to set up a minimal 802.1x
 
432
         * setting and ask the user for more information.
 
433
         */
 
434
        rsn_flags = nm_access_point_get_rsn_flags (ap);
 
435
        wpa_flags = nm_access_point_get_wpa_flags (ap);
 
436
        if (   (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
 
437
            || (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
 
438
 
 
439
                /* Need a UUID for the "always ask" stuff in the Dialog of Doom */
 
440
                s_con = (NMSettingConnection *) nm_setting_connection_new ();
 
441
                uuid = nm_utils_uuid_generate ();
 
442
                g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL);
 
443
                g_free (uuid);
 
444
                nm_connection_add_setting (connection, NM_SETTING (s_con));
 
445
 
 
446
                if (!s_wifi) {
 
447
                        s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
 
448
                        nm_connection_add_setting (connection, NM_SETTING (s_wifi));
 
449
                }
 
450
                g_object_set (s_wifi,
 
451
                              NM_SETTING_WIRELESS_SSID, ssid,
 
452
                              NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
 
453
                              NULL);
 
454
 
 
455
                s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
 
456
                g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
 
457
                nm_connection_add_setting (connection, NM_SETTING (s_wsec));
 
458
 
 
459
                s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
 
460
                nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
 
461
                g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
 
462
                nm_connection_add_setting (connection, NM_SETTING (s_8021x));
 
463
        }
 
464
 
 
465
        /* If it's an 802.1x connection, we need more information, so pop up the
 
466
         * Dialog Of Doom.
 
467
         */
 
468
        if (s_8021x) {
 
469
                more_info = g_malloc0 (sizeof (*more_info));
 
470
                more_info->applet = applet;
 
471
                more_info->callback = callback;
 
472
                more_info->callback_data = callback_data;
 
473
 
 
474
                dialog = nma_wireless_dialog_new (applet, connection, device, ap);
 
475
                if (dialog) {
 
476
                        g_signal_connect (dialog, "response",
 
477
                                              G_CALLBACK (more_info_wifi_dialog_response_cb),
 
478
                                              more_info);
 
479
                        show_ignore_focus_stealing_prevention (dialog);
 
480
                }
 
481
        } else {
 
482
                /* Everything else can just get activated right away */
 
483
                callback (connection, TRUE, FALSE, callback_data);
 
484
        }
 
485
}
 
486
 
377
487
static gboolean
378
488
wireless_new_auto_connection (NMDevice *device,
379
489
                              gpointer dclass_data,
381
491
                              gpointer callback_data)
382
492
{
383
493
        WirelessMenuItemInfo *info = (WirelessMenuItemInfo *) dclass_data;
384
 
        NMConnection *connection = NULL;
385
 
        NMSettingConnection *s_con = NULL;
386
 
        NMSettingWireless *s_wireless = NULL;
387
 
        NMSettingWirelessSecurity *s_wireless_sec = NULL;
388
 
        NMSetting8021x *s_8021x = NULL;
389
 
        const GByteArray *ap_ssid;
390
 
        char *id;
391
 
        char buf[33];
392
 
        int buf_len;
393
 
        NM80211Mode mode;
394
 
        guint32 dev_caps;
395
 
        gboolean supported = TRUE;
396
 
 
397
 
        if (!info->ap) {
398
 
                g_warning ("%s: AP not set", __func__);
399
 
                return FALSE;
400
 
        }
401
 
 
402
 
        s_wireless = (NMSettingWireless *) nm_setting_wireless_new ();
403
 
 
404
 
        ap_ssid = nm_access_point_get_ssid (info->ap);
405
 
        g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ap_ssid, NULL);
406
 
 
407
 
        mode = nm_access_point_get_mode (info->ap);
408
 
        if (mode == NM_802_11_MODE_ADHOC)
409
 
                g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, "adhoc", NULL);
410
 
        else if (mode == NM_802_11_MODE_INFRA) {
411
 
                g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL);
412
 
                /* Lock connection to this AP if it's a manufacturer-default SSID */
413
 
                if (is_manufacturer_default_ssid (ap_ssid))
414
 
                        clamp_ap_to_bssid (info->ap, s_wireless);
415
 
        } else
416
 
                g_assert_not_reached ();
417
 
 
418
 
        dev_caps = nm_device_wifi_get_capabilities (NM_DEVICE_WIFI (device));
419
 
        s_wireless_sec = get_security_for_ap (info->ap, dev_caps, &supported, &s_8021x);
420
 
        if (!supported) {
421
 
                g_warning ("Unsupported AP configuration: dev_caps 0x%X, ap_flags 0x%X, "
422
 
                           "wpa_flags 0x%X, rsn_flags 0x%x, mode %d",
423
 
                           dev_caps,
424
 
                           nm_access_point_get_flags (info->ap),
425
 
                           nm_access_point_get_wpa_flags (info->ap),
426
 
                           nm_access_point_get_rsn_flags (info->ap),
427
 
                           nm_access_point_get_mode (info->ap));
428
 
                g_object_unref (s_wireless);
429
 
                return FALSE;
430
 
        } else if (s_wireless_sec)
431
 
                g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
432
 
 
433
 
        connection = nm_connection_new ();
434
 
        nm_connection_add_setting (connection, NM_SETTING (s_wireless));
435
 
        if (s_wireless_sec)
436
 
                nm_connection_add_setting (connection, NM_SETTING (s_wireless_sec));
437
 
        if (s_8021x)
438
 
                nm_connection_add_setting (connection, NM_SETTING (s_8021x));
439
 
 
440
 
        s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
441
 
        g_object_set (s_con,
442
 
                      NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME,
443
 
                      NM_SETTING_CONNECTION_AUTOCONNECT, !is_manufacturer_default_ssid (ap_ssid),
444
 
                      NULL);
445
 
 
446
 
        memset (buf, 0, sizeof (buf));
447
 
        buf_len = MIN(ap_ssid->len, sizeof (buf) - 1);
448
 
        memcpy (buf, ap_ssid->data, buf_len);
449
 
        id = g_strdup_printf ("Auto %s", nm_utils_ssid_to_utf8 (buf, buf_len));
450
 
        g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NULL);
451
 
        g_free (id);
452
 
 
453
 
        id = nm_utils_uuid_generate ();
454
 
        g_object_set (s_con, NM_SETTING_CONNECTION_UUID, id, NULL);
455
 
        g_free (id);
456
 
 
457
 
        nm_connection_add_setting (connection, NM_SETTING (s_con));
458
 
 
459
 
        (*callback) (connection, TRUE, FALSE, callback_data);
 
494
 
 
495
        g_return_val_if_fail (device != NULL, FALSE);
 
496
        g_return_val_if_fail (info->ap != NULL, FALSE);
 
497
 
 
498
        _do_new_auto_connection (info->applet, device, info->ap, callback, callback_data);
460
499
        return TRUE;
461
500
}
462
501
 
 
502
 
463
503
static void
464
504
wireless_menu_item_activate (GtkMenuItem *item, gpointer user_data)
465
505
{
883
923
}
884
924
 
885
925
static void
886
 
add_seen_bssid (NMSettingsConnectionInterface *connection, NMAccessPoint *ap)
887
 
{
888
 
        NMSettingWireless *s_wireless;
889
 
        const char *bssid;
890
 
 
891
 
        if (!NMA_GCONF_CONNECTION (connection))
892
 
                return;
893
 
 
894
 
        s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_WIRELESS));
895
 
        if (!s_wireless)
896
 
                return;
897
 
 
898
 
        bssid = nm_access_point_get_hw_address (ap);
899
 
        if (!bssid || !utils_ether_addr_valid (ether_aton (bssid)))
900
 
                return;
901
 
 
902
 
        if (nm_setting_wireless_add_seen_bssid (s_wireless, bssid)) {
903
 
                /* Ignore secrets since we don't have any here and we're just adding a BSSID */
904
 
                nma_gconf_connection_update (NMA_GCONF_CONNECTION (connection), TRUE);
905
 
        }
906
 
}
907
 
 
908
 
static void
909
926
notify_active_ap_changed_cb (NMDeviceWifi *device,
910
927
                             GParamSpec *pspec,
911
928
                             NMApplet *applet)
912
929
{
913
 
        NMSettingsConnectionInterface *connection;
 
930
        NMRemoteConnection *connection;
914
931
        NMSettingWireless *s_wireless;
915
932
        NMAccessPoint *new;
916
933
        const GByteArray *ssid;
934
951
        if (!ssid || !nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), ssid, TRUE))
935
952
                return;
936
953
 
937
 
        add_seen_bssid (connection, new);
938
 
 
939
954
        applet_schedule_update_icon (applet);
940
955
}
941
956
 
1127
1142
}
1128
1143
 
1129
1144
static void
1130
 
on_new_connection (NMSettingsInterface *settings,
1131
 
                   NMSettingsConnectionInterface *connection,
 
1145
on_new_connection (NMRemoteSettings *settings,
 
1146
                   NMRemoteConnection *connection,
1132
1147
                   gpointer datap)
1133
1148
{
1134
1149
        struct ap_notification_data *data = datap;
1139
1154
free_ap_notification_data (gpointer user_data)
1140
1155
{
1141
1156
        struct ap_notification_data *data = user_data;
1142
 
        NMSettingsInterface *settings = applet_get_settings (data->applet);
 
1157
        NMRemoteSettings *settings = applet_get_settings (data->applet);
1143
1158
 
1144
1159
        if (data->id)
1145
1160
                g_source_remove (data->id);
1185
1200
         * when the device is destroyed.
1186
1201
         */ 
1187
1202
        id = g_signal_connect (applet_get_settings (applet),
1188
 
                               NM_SETTINGS_INTERFACE_NEW_CONNECTION,
 
1203
                               NM_REMOTE_SETTINGS_NEW_CONNECTION,
1189
1204
                               G_CALLBACK (on_new_connection),
1190
1205
                               data);
1191
1206
        data->new_con_id = id;
1248
1263
                               NMDeviceStateReason reason,
1249
1264
                               NMApplet *applet)
1250
1265
{
1251
 
        NMSettingsConnectionInterface *connection;
1252
1266
        NMAccessPoint *new = NULL;
1253
1267
        char *msg;
1254
1268
        char *esc_ssid = NULL;
1261
1275
        if (new_state != NM_DEVICE_STATE_ACTIVATED)
1262
1276
                return;
1263
1277
 
1264
 
        if (new) {
1265
 
                const GByteArray *ssid = nm_access_point_get_ssid (new);
1266
 
 
1267
 
                if (ssid)
1268
 
                        esc_ssid = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len);
1269
 
 
1270
 
                /* Save this BSSID to seen-bssids list */
1271
 
                connection = applet_get_exported_connection_for_device (device, applet);
1272
 
                if (connection)
1273
 
                        add_seen_bssid (connection, new);
1274
 
        }
1275
 
 
1276
 
        msg = g_strdup_printf (_("You are now connected to the wireless network '%s'."),
1277
 
                               esc_ssid ? esc_ssid : _("(none)"));
 
1278
        esc_ssid = get_ssid_utf8 (new);
 
1279
        msg = g_strdup_printf (_("You are now connected to the wireless network '%s'."), esc_ssid);
1278
1280
        applet_do_notify_with_pref (applet, _("Connection Established"),
1279
1281
                                    msg, "nm-device-wireless",
1280
1282
                                    PREF_DISABLE_CONNECTED_NOTIFICATIONS);
1296
1298
        char *ssid = NULL;
1297
1299
 
1298
1300
        ap = g_object_get_data (G_OBJECT (device), ACTIVE_AP_TAG);
1299
 
        if (ap) {
1300
 
                const GByteArray *tmp;
1301
 
 
1302
 
                tmp = nm_access_point_get_ssid (ap);
1303
 
                if (tmp)
1304
 
                        ssid = nm_utils_ssid_to_utf8 ((const char *) tmp->data, tmp->len);
1305
 
        }
1306
 
 
1307
 
        if (!ssid)
1308
 
                ssid = g_strdup (_("(none)"));
1309
1301
 
1310
1302
        id = nm_device_get_iface (device);
1311
1303
        if (connection) {
1344
1336
                        else
1345
1337
                                pixbuf = nma_icon_check_and_load ("nm-signal-00", &applet->wireless_00_icon, applet);
1346
1338
 
 
1339
                        ssid = get_ssid_utf8 (ap);
1347
1340
                        *tip = g_strdup_printf (_("Wireless network connection '%s' active: %s (%d%%)"),
1348
1341
                                                id, ssid, strength);
 
1342
                        g_free (ssid);
1349
1343
                } else {
1350
1344
                        pixbuf = nma_icon_check_and_load ("nm-signal-00", &applet->wireless_00_icon, applet);
1351
1345
                        *tip = g_strdup_printf (_("Wireless network connection '%s' active"), id);
1355
1349
                break;
1356
1350
        }
1357
1351
 
1358
 
        g_free (ssid);
1359
1352
        return pixbuf;
1360
1353
}
1361
1354
 
1362
 
static void
1363
 
activate_device_cb (gpointer user_data, const char *path, GError *error)
1364
 
{
1365
 
        if (error)
1366
 
                nm_warning ("Device Activation failed: %s", error->message);
1367
 
        applet_schedule_update_icon (NM_APPLET (user_data));
1368
 
}
1369
 
 
1370
1355
static gboolean
1371
1356
wireless_dialog_close (gpointer user_data)
1372
1357
{
1397
1382
        }
1398
1383
}
1399
1384
 
1400
 
static void
1401
 
update_cb (NMSettingsConnectionInterface *connection,
1402
 
           GError *error,
1403
 
           gpointer user_data)
1404
 
{
1405
 
        if (error) {
1406
 
                g_warning ("%s: failed to update connection: (%d) %s",
1407
 
                           __func__, error->code, error->message);
1408
 
        }
 
1385
 
 
1386
static void
 
1387
activate_existing_cb (NMClient *client,
 
1388
                      NMActiveConnection *active,
 
1389
                      GError *error,
 
1390
                      gpointer user_data)
 
1391
{
 
1392
        if (error)
 
1393
                g_warning ("Failed to activate connection: (%d) %s", error->code, error->message);
 
1394
        applet_schedule_update_icon (NM_APPLET (user_data));
 
1395
}
 
1396
 
 
1397
static void
 
1398
activate_new_cb (NMClient *client,
 
1399
                 NMActiveConnection *active,
 
1400
                 const char *connection_path,
 
1401
                 GError *error,
 
1402
                 gpointer user_data)
 
1403
{
 
1404
        if (error)
 
1405
                g_warning ("Failed to add new connection: (%d) %s", error->code, error->message);
 
1406
        applet_schedule_update_icon (NM_APPLET (user_data));
1409
1407
}
1410
1408
 
1411
1409
static void
1418
1416
        NMConnection *connection = NULL, *fuzzy_match = NULL;
1419
1417
        NMDevice *device = NULL;
1420
1418
        NMAccessPoint *ap = NULL;
1421
 
        const char *service = NM_DBUS_SERVICE_USER_SETTINGS;
 
1419
        GSList *all, *iter;
1422
1420
 
1423
1421
        if (response != GTK_RESPONSE_OK)
1424
1422
                goto done;
1446
1444
        g_assert (connection);
1447
1445
        g_assert (device);
1448
1446
 
1449
 
        /* If it's a system connection we just need to tell NM to activate it */
1450
 
        if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) {
1451
 
                service = NM_DBUS_SERVICE_SYSTEM_SETTINGS;
1452
 
                goto activate;
 
1447
        /* Find a similar connection and use that instead */
 
1448
        all = applet_get_all_connections (applet);
 
1449
        for (iter = all; iter; iter = g_slist_next (iter)) {
 
1450
                if (nm_connection_compare (connection,
 
1451
                                           NM_CONNECTION (iter->data),
 
1452
                                           (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) {
 
1453
                        fuzzy_match = NM_CONNECTION (iter->data);
 
1454
                        break;
 
1455
                }
1453
1456
        }
 
1457
        g_slist_free (all);
1454
1458
 
1455
 
        if (NMA_IS_GCONF_CONNECTION (connection)) {
1456
 
                /* Not a new or system connection, save the updated settings to GConf */
1457
 
                nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
1458
 
                                                         update_cb,
1459
 
                                                         NULL);
 
1459
        if (fuzzy_match) {
 
1460
                nm_client_activate_connection (applet->nm_client,
 
1461
                                               fuzzy_match,
 
1462
                                               device,
 
1463
                                               ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
 
1464
                                               activate_existing_cb,
 
1465
                                               applet);
1460
1466
        } else {
1461
 
                GSList *all, *iter;
1462
 
 
1463
 
                /* Find a similar connection and use that instead */
1464
 
                all = applet_get_all_connections (applet);
1465
 
                for (iter = all; iter; iter = g_slist_next (iter)) {
1466
 
                        if (nm_connection_compare (connection,
1467
 
                                                   NM_CONNECTION (iter->data),
1468
 
                                                   (NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) {
1469
 
                                fuzzy_match = g_object_ref (NM_CONNECTION (iter->data));
1470
 
                                break;
1471
 
                        }
1472
 
                }
1473
 
                g_slist_free (all);
1474
 
 
1475
 
                if (fuzzy_match) {
1476
 
                        if (nm_connection_get_scope (fuzzy_match) == NM_CONNECTION_SCOPE_SYSTEM) {
1477
 
                                // FIXME: do something other than just use the system connection?
1478
 
                        } else {
1479
 
                                NMSettingWirelessSecurity *s_wireless_sec;
1480
 
 
1481
 
                                /* Copy secrets & wireless security */
1482
 
                                s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
1483
 
                                if (s_wireless_sec) {
1484
 
                                        GHashTable *hash;
1485
 
                                        NMSetting *dup_setting;
1486
 
 
1487
 
                                        hash = nm_setting_to_hash (NM_SETTING (s_wireless_sec));
1488
 
                                        dup_setting = nm_setting_new_from_hash (NM_TYPE_SETTING_WIRELESS_SECURITY, hash);
1489
 
                                        g_hash_table_destroy (hash);
1490
 
                                        nm_connection_add_setting (fuzzy_match, dup_setting);
1491
 
                                }
1492
 
                        }
1493
 
 
1494
 
                        /* Balance nma_wireless_dialog_get_connection() */
1495
 
                        g_object_unref (connection);
1496
 
                        connection = g_object_ref (fuzzy_match);
1497
 
                } else {
1498
 
                        /* Entirely new connection */
1499
 
                        NMAGConfConnection *new_gconf_connection;
1500
 
                        NMSettingConnection *s_con;
1501
 
                        char *id;
1502
 
 
1503
 
                        /* Update a new connection's name and autoconnect status */
1504
 
                        s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
1505
 
                        id = (char *) nm_setting_connection_get_id (s_con);
1506
 
 
1507
 
                        if (!id) {
1508
 
                                NMSettingWireless *s_wireless;
1509
 
                                const GByteArray *ssid;
1510
 
                                const char *mode;
1511
 
 
1512
 
                                s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
1513
 
                                ssid = nm_setting_wireless_get_ssid (s_wireless);
1514
 
 
1515
 
                                id = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len);
1516
 
                                g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NULL);
1517
 
                                g_free (id);
1518
 
 
1519
 
                                // FIXME: don't autoconnect until the connection is successful at least once
1520
 
                                /* Don't autoconnect adhoc networks by default for now */
1521
 
                                mode = nm_setting_wireless_get_mode (s_wireless);
1522
 
                                if (!mode || !strcmp (mode, "infrastructure"))
1523
 
                                        g_object_set (s_con, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL);
1524
 
                        }
1525
 
 
1526
 
                        /* Export it over D-Bus */
1527
 
                        new_gconf_connection = nma_gconf_settings_add_connection (applet->gconf_settings, connection);
1528
 
                        if (!new_gconf_connection) {
1529
 
                                nm_warning ("Couldn't create new network connection.");
1530
 
                                goto done;
1531
 
                        }
1532
 
 
1533
 
                        /* Balance nma_wireless_dialog_get_connection() */
1534
 
                        g_object_unref (connection);
1535
 
                        connection = g_object_ref (new_gconf_connection);
1536
 
                }
 
1467
                NMSetting *s_con;
 
1468
                NMSettingWireless *s_wifi = NULL;
 
1469
                const char *mode = NULL;
 
1470
 
 
1471
                /* Entirely new connection */
 
1472
 
 
1473
                /* Don't autoconnect adhoc networks by default for now */
 
1474
                s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
 
1475
                if (s_wifi)
 
1476
                        mode = nm_setting_wireless_get_mode (s_wifi);
 
1477
                if (g_strcmp0 (mode, "adhoc") == 0) {
 
1478
                        s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
 
1479
                        if (!s_con) {
 
1480
                                s_con = nm_setting_connection_new ();
 
1481
                                nm_connection_add_setting (connection, s_con);
 
1482
                        }
 
1483
                        g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL);
 
1484
                }
 
1485
 
 
1486
                nm_client_add_and_activate_connection (applet->nm_client,
 
1487
                                                       connection,
 
1488
                                                       device,
 
1489
                                                       ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
 
1490
                                                       activate_new_cb,
 
1491
                                                       applet);
1537
1492
        }
1538
1493
 
1539
 
activate:
1540
 
        nm_client_activate_connection (applet->nm_client,
1541
 
                                       service,
1542
 
                                       nm_connection_get_path (connection),
1543
 
                                       device,
1544
 
                                       ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
1545
 
                                       activate_device_cb,
1546
 
                                       applet);
 
1494
        /* Balance nma_wireless_dialog_get_connection() */
 
1495
        g_object_unref (connection);
1547
1496
 
1548
1497
done:
1549
 
        /* Balance nma_wireless_dialog_get_connection() */
1550
 
        if (connection)
1551
 
                g_object_unref (connection);
1552
 
 
1553
1498
        gtk_widget_hide (GTK_WIDGET (dialog));
1554
1499
        gtk_widget_destroy (GTK_WIDGET (dialog));
1555
1500
}
1556
1501
 
1557
 
static void
1558
 
wireless_get_more_info (NMDevice *device,
1559
 
                        NMConnection *connection,
1560
 
                        NMApplet *applet,
1561
 
                        gpointer user_data)
1562
 
{
1563
 
        WirelessMenuItemInfo *info = (WirelessMenuItemInfo *) user_data;
1564
 
        GtkWidget *dialog;
1565
 
 
1566
 
        dialog = nma_wireless_dialog_new (applet, connection, device, info->ap);
1567
 
        g_return_if_fail (dialog != NULL);
1568
 
 
1569
 
        g_signal_connect (dialog, "response",
1570
 
                          G_CALLBACK (wireless_dialog_response_cb),
1571
 
                          applet);
1572
 
 
1573
 
        show_ignore_focus_stealing_prevention (dialog);
1574
 
}
1575
 
 
1576
1502
static gboolean
1577
1503
add_one_setting (GHashTable *settings,
1578
1504
                 NMConnection *connection,
1587
1513
        g_return_val_if_fail (error != NULL, FALSE);
1588
1514
        g_return_val_if_fail (*error == NULL, FALSE);
1589
1515
 
1590
 
        secrets = nm_setting_to_hash (setting);
 
1516
        secrets = nm_setting_to_hash (setting, NM_SETTING_HASH_FLAG_ALL);
1591
1517
        if (secrets) {
1592
1518
                g_hash_table_insert (settings, g_strdup (nm_setting_get_name (setting)), secrets);
1593
1519
        } else {
1594
1520
                g_set_error (error,
1595
 
                             NM_SETTINGS_INTERFACE_ERROR,
1596
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1521
                             NM_SECRET_AGENT_ERROR,
 
1522
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1597
1523
                             "%s.%d (%s): failed to hash setting '%s'.",
1598
1524
                             __FILE__, __LINE__, __func__, nm_setting_get_name (setting));
1599
1525
        }
1602
1528
}
1603
1529
 
1604
1530
typedef struct {
1605
 
        NMApplet *applet;
1606
 
        NMActiveConnection *active_connection;
 
1531
        SecretsRequest req;
 
1532
 
1607
1533
        GtkWidget *dialog;
1608
1534
        GtkWidget *nag_dialog;
1609
 
        NMANewSecretsRequestedFunc callback;
1610
 
        gpointer callback_data;
1611
 
        char *setting_name;
1612
1535
} NMWifiInfo;
1613
1536
 
1614
1537
static void
1615
 
destroy_wifi_dialog (gpointer user_data, GObject *finalized)
 
1538
free_wifi_info (SecretsRequest *req)
1616
1539
{
1617
 
        NMWifiInfo *info = user_data;
 
1540
        NMWifiInfo *info = (NMWifiInfo *) req;
1618
1541
 
1619
 
        gtk_widget_hide (info->dialog);
1620
 
        gtk_widget_destroy (info->dialog);
1621
 
        g_free (info->setting_name);
1622
 
        g_free (info);
 
1542
        if (info->dialog) {
 
1543
                gtk_widget_hide (info->dialog);
 
1544
                gtk_widget_destroy (info->dialog);
 
1545
        }
1623
1546
}
1624
1547
 
1625
1548
static void
1627
1550
                                gint response,
1628
1551
                                gpointer user_data)
1629
1552
{
1630
 
        NMWifiInfo *info = user_data;
 
1553
        SecretsRequest *req = user_data;
 
1554
        NMWifiInfo *info = (NMWifiInfo *) req;
1631
1555
        NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (info->dialog);
1632
1556
        NMConnection *connection = NULL;
1633
1557
        NMSettingWirelessSecurity *s_wireless_sec;
1634
 
        NMDevice *device = NULL;
1635
1558
        GHashTable *settings = NULL;
1636
1559
        const char *key_mgmt, *auth_alg;
1637
1560
        GError *error = NULL;
1655
1578
                }
1656
1579
        }
1657
1580
 
1658
 
        /* Got a user response, clear the NMActiveConnection destroy handler for
1659
 
         * this dialog since this function will now take over dialog destruction.
1660
 
         */
1661
 
        g_object_weak_unref (G_OBJECT (info->active_connection), destroy_wifi_dialog, info);
1662
 
 
1663
1581
        if (response != GTK_RESPONSE_OK) {
1664
1582
                g_set_error (&error,
1665
 
                             NM_SETTINGS_INTERFACE_ERROR,
1666
 
                             NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED,
 
1583
                             NM_SECRET_AGENT_ERROR,
 
1584
                             NM_SECRET_AGENT_ERROR_USER_CANCELED,
1667
1585
                             "%s.%d (%s): canceled",
1668
1586
                             __FILE__, __LINE__, __func__);
1669
1587
                goto done;
1670
1588
        }
1671
1589
 
1672
 
        connection = nma_wireless_dialog_get_connection (dialog, &device, NULL);
 
1590
        connection = nma_wireless_dialog_get_connection (dialog, NULL, NULL);
1673
1591
        if (!connection) {
1674
1592
                g_set_error (&error,
1675
 
                             NM_SETTINGS_INTERFACE_ERROR,
1676
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1593
                             NM_SECRET_AGENT_ERROR,
 
1594
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1677
1595
                             "%s.%d (%s): couldn't get connection from wireless dialog.",
1678
1596
                             __FILE__, __LINE__, __func__);
1679
1597
                goto done;
1683
1601
        s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
1684
1602
        if (!s_wireless_sec) {
1685
1603
                g_set_error (&error,
1686
 
                             NM_SETTINGS_INTERFACE_ERROR,
1687
 
                             NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
 
1604
                             NM_SECRET_AGENT_ERROR,
 
1605
                             NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
1688
1606
                             "%s.%d (%s): requested setting '802-11-wireless-security'"
1689
1607
                             " didn't exist in the connection.",
1690
1608
                             __FILE__, __LINE__, __func__);
1698
1616
                                          g_free, (GDestroyNotify) g_hash_table_destroy);
1699
1617
        if (!settings) {
1700
1618
                g_set_error (&error,
1701
 
                             NM_SETTINGS_INTERFACE_ERROR,
1702
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1619
                             NM_SECRET_AGENT_ERROR,
 
1620
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1703
1621
                             "%s.%d (%s): not enough memory to return secrets.",
1704
1622
                             __FILE__, __LINE__, __func__);
1705
1623
                goto done;
1721
1639
                        s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
1722
1640
                        if (!s_8021x) {
1723
1641
                                g_set_error (&error,
1724
 
                                             NM_SETTINGS_INTERFACE_ERROR,
1725
 
                                             NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
 
1642
                                             NM_SECRET_AGENT_ERROR,
 
1643
                                             NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
1726
1644
                                             "%s.%d (%s): requested setting '802-1x' didn't"
1727
1645
                                             " exist in the connection.",
1728
1646
                                             __FILE__, __LINE__, __func__);
1736
1654
        }
1737
1655
 
1738
1656
        /* Add the 802-11-wireless-security setting no matter what */
1739
 
        if (!add_one_setting (settings, connection, NM_SETTING (s_wireless_sec), &error))
1740
 
                goto done;
1741
 
 
1742
 
        info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), settings, NULL, info->callback_data);
1743
 
 
1744
 
        /* Save the connection back to GConf _after_ hashing it, because
1745
 
         * saving to GConf might trigger the GConf change notifiers, resulting
1746
 
         * in the connection being read back in from GConf which clears secrets.
1747
 
         */
1748
 
        if (NMA_IS_GCONF_CONNECTION (connection)) {
1749
 
                nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
1750
 
                                                         update_cb,
1751
 
                                                         NULL);
1752
 
        }
 
1657
        add_one_setting (settings, connection, NM_SETTING (s_wireless_sec), &error);
1753
1658
 
1754
1659
done:
 
1660
        applet_secrets_request_complete (req, settings, error);
 
1661
        applet_secrets_request_free (req);
 
1662
 
1755
1663
        if (settings)
1756
1664
                g_hash_table_destroy (settings);
1757
 
 
1758
 
        if (error) {
1759
 
                g_warning ("%s", error->message);
1760
 
                info->callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), NULL, error, info->callback_data);
1761
 
                g_error_free (error);
1762
 
        }
1763
 
 
1764
1665
        if (connection)
1765
1666
                nm_connection_clear_secrets (connection);
1766
 
 
1767
 
        destroy_wifi_dialog (info, NULL);
1768
1667
}
1769
1668
 
1770
1669
static gboolean
1771
 
wireless_get_secrets (NMDevice *device,
1772
 
                      NMSettingsConnectionInterface *connection,
1773
 
                      NMActiveConnection *active_connection,
1774
 
                      const char *setting_name,
1775
 
                      const char **hints,
1776
 
                      NMANewSecretsRequestedFunc callback,
1777
 
                      gpointer callback_data,
1778
 
                      NMApplet *applet,
1779
 
                      GError **error)
 
1670
wireless_get_secrets (SecretsRequest *req, GError **error)
1780
1671
{
1781
 
        NMWifiInfo *info;
1782
 
        NMAccessPoint *ap;
1783
 
        const char *specific_object;
1784
 
 
1785
 
        if (!setting_name || !active_connection) {
1786
 
                g_set_error (error,
1787
 
                             NM_SETTINGS_INTERFACE_ERROR,
1788
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
1789
 
                             "%s.%d (%s): setting name and active connection object required",
1790
 
                             __FILE__, __LINE__, __func__);
1791
 
                return FALSE;
1792
 
        }
1793
 
 
1794
 
        specific_object = nm_active_connection_get_specific_object (active_connection);
1795
 
        if (!specific_object) {
1796
 
                g_set_error (error,
1797
 
                             NM_SETTINGS_INTERFACE_ERROR,
1798
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
1799
 
                             "%s.%d (%s): could not determine AP for specific object",
1800
 
                             __FILE__, __LINE__, __func__);
1801
 
                return FALSE;
1802
 
        }
1803
 
 
1804
 
        info = g_malloc0 (sizeof (NMWifiInfo));
1805
 
 
1806
 
        ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), specific_object);
1807
 
        info->dialog = nma_wireless_dialog_new (applet, NM_CONNECTION (connection), device, ap);
1808
 
        if (!info->dialog) {
1809
 
                g_set_error (error,
1810
 
                             NM_SETTINGS_INTERFACE_ERROR,
1811
 
                             NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
 
1672
        NMWifiInfo *info = (NMWifiInfo *) req;
 
1673
 
 
1674
        applet_secrets_request_set_free_func (req, free_wifi_info);
 
1675
 
 
1676
        info->dialog = nma_wireless_dialog_new (req->applet, req->connection, NULL, NULL);
 
1677
        if (info->dialog) {
 
1678
                g_signal_connect (info->dialog, "response",
 
1679
                                  G_CALLBACK (get_secrets_dialog_response_cb),
 
1680
                                  info);
 
1681
                show_ignore_focus_stealing_prevention (info->dialog);
 
1682
        } else {
 
1683
                g_set_error (error,
 
1684
                             NM_SECRET_AGENT_ERROR,
 
1685
                             NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
1812
1686
                             "%s.%d (%s): couldn't display secrets UI",
1813
1687
                             __FILE__, __LINE__, __func__);
1814
 
                g_free (info);
1815
 
                return FALSE;
1816
1688
        }
1817
 
 
1818
 
        info->applet = applet;
1819
 
        info->active_connection = active_connection;
1820
 
        info->callback = callback;
1821
 
        info->callback_data = callback_data;
1822
 
        info->setting_name = g_strdup (setting_name);
1823
 
 
1824
 
        g_signal_connect (info->dialog, "response",
1825
 
                          G_CALLBACK (get_secrets_dialog_response_cb),
1826
 
                          info);
1827
 
 
1828
 
        /* Attach a destroy notifier to the NMActiveConnection so we can destroy
1829
 
         * the dialog when the active connection goes away.
1830
 
         */
1831
 
        g_object_weak_ref (G_OBJECT (active_connection), destroy_wifi_dialog, info);
1832
 
 
1833
 
        show_ignore_focus_stealing_prevention (info->dialog);
1834
 
        return TRUE;
 
1689
        return !!info->dialog;
1835
1690
}
1836
1691
 
1837
1692
NMADeviceClass *
1848
1703
        dclass->device_added = wireless_device_added;
1849
1704
        dclass->device_state_changed = wireless_device_state_changed;
1850
1705
        dclass->get_icon = wireless_get_icon;
1851
 
        dclass->get_more_info = wireless_get_more_info;
1852
1706
        dclass->get_secrets = wireless_get_secrets;
 
1707
        dclass->secrets_request_size = sizeof (NMWifiInfo);
1853
1708
 
1854
1709
        return dclass;
1855
1710
}