1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2011 Giovanni Campagna <scampa.giovanni@gmail.com>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
* Portions of this code were taken from network-manager-applet.
20
* Copyright 2008 - 2011 Red Hat, Inc.
23
#include <shell/cc-shell.h>
25
#include <nm-connection.h>
26
#include <nm-setting-gsm.h>
27
#include <nm-setting-cdma.h>
28
#include <nm-setting-serial.h>
29
#include <nm-device-modem.h>
30
#include <nm-device-wifi.h>
32
#include "network-dialogs.h"
33
#include "nm-wireless-dialog.h"
34
#include "nm-mobile-wizard.h"
38
NMRemoteSettings *settings;
39
} WirelessDialogClosure;
43
NMRemoteSettings *settings;
45
} MobileDialogClosure;
48
wireless_dialog_closure_closure_notify (gpointer data,
51
WirelessDialogClosure *closure = data;
52
g_object_unref (closure->client);
53
g_object_unref (closure->settings);
55
g_slice_free (WirelessDialogClosure, data);
59
mobile_dialog_closure_free (gpointer data)
61
MobileDialogClosure *closure = data;
62
g_object_unref (closure->client);
63
g_object_unref (closure->settings);
64
g_object_unref (closure->device);
66
g_slice_free (MobileDialogClosure, data);
70
wifi_can_create_wifi_network (NMClient *client)
72
NMClientPermissionResult perm;
74
/* FIXME: check WIFI_SHARE_PROTECTED too, and make the wireless dialog
75
* handle the permissions as well so that admins can restrict open network
76
* creation separately from protected network creation.
78
perm = nm_client_get_permission_result (client, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN);
79
if (perm == NM_CLIENT_PERMISSION_RESULT_YES || perm == NM_CLIENT_PERMISSION_RESULT_AUTH)
86
activate_existing_cb (NMClient *client,
87
NMActiveConnection *active,
92
g_warning ("Failed to activate connection: (%d) %s", error->code, error->message);
96
activate_new_cb (NMClient *client,
97
NMActiveConnection *active,
98
const char *connection_path,
103
g_warning ("Failed to add new connection: (%d) %s", error->code, error->message);
107
nag_dialog_response_cb (GtkDialog *nag_dialog,
111
NMAWirelessDialog *wireless_dialog = NMA_WIRELESS_DIALOG (user_data);
113
if (response == GTK_RESPONSE_NO) { /* user opted not to correct the warning */
114
nma_wireless_dialog_set_nag_ignored (wireless_dialog, TRUE);
115
gtk_dialog_response (GTK_DIALOG (wireless_dialog), GTK_RESPONSE_OK);
120
wireless_dialog_response_cb (GtkDialog *foo,
124
NMAWirelessDialog *dialog = NMA_WIRELESS_DIALOG (foo);
125
WirelessDialogClosure *closure = user_data;
126
NMConnection *connection, *fuzzy_match = NULL;
131
if (response != GTK_RESPONSE_OK)
134
if (!nma_wireless_dialog_get_nag_ignored (dialog)) {
135
GtkWidget *nag_dialog;
137
/* Nag the user about certificates or whatever. Only destroy the dialog
138
* if no nagging was done.
140
nag_dialog = nma_wireless_dialog_nag_user (dialog);
142
gtk_window_set_transient_for (GTK_WINDOW (nag_dialog), GTK_WINDOW (dialog));
143
g_signal_connect (nag_dialog, "response",
144
G_CALLBACK (nag_dialog_response_cb),
150
/* nma_wireless_dialog_get_connection() returns a connection with the
151
* refcount incremented, so the caller must remember to unref it.
153
connection = nma_wireless_dialog_get_connection (dialog, &device, &ap);
154
g_assert (connection);
157
/* Find a similar connection and use that instead */
158
all = nm_remote_settings_list_connections (closure->settings);
159
for (iter = all; iter; iter = g_slist_next (iter)) {
160
if (nm_connection_compare (connection,
161
NM_CONNECTION (iter->data),
162
(NM_SETTING_COMPARE_FLAG_FUZZY | NM_SETTING_COMPARE_FLAG_IGNORE_ID))) {
163
fuzzy_match = NM_CONNECTION (iter->data);
170
nm_client_activate_connection (closure->client,
173
ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
174
activate_existing_cb,
178
NMSettingWireless *s_wifi;
179
const char *mode = NULL;
181
/* Entirely new connection */
183
/* Don't autoconnect adhoc networks by default for now */
184
s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
186
mode = nm_setting_wireless_get_mode (s_wifi);
187
if (g_strcmp0 (mode, "adhoc") == 0) {
188
s_con = nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
190
s_con = nm_setting_connection_new ();
191
nm_connection_add_setting (connection, s_con);
193
g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL);
196
nm_client_add_and_activate_connection (closure->client,
199
ap ? nm_object_get_path (NM_OBJECT (ap)) : NULL,
204
/* Balance nma_wireless_dialog_get_connection() */
205
g_object_unref (connection);
208
gtk_widget_hide (GTK_WIDGET (dialog));
209
gtk_widget_destroy (GTK_WIDGET (dialog));
213
show_wireless_dialog (CcNetworkPanel *panel,
215
NMRemoteSettings *settings,
218
GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)));
219
WirelessDialogClosure *closure;
221
g_debug ("About to parent and show a network dialog");
223
g_assert (gtk_widget_is_toplevel (toplevel));
224
g_object_set (G_OBJECT (dialog),
226
"transient-for", toplevel,
229
closure = g_slice_new (WirelessDialogClosure);
230
closure->client = g_object_ref (client);
231
closure->settings = g_object_ref (settings);
232
g_signal_connect_data (dialog, "response",
233
G_CALLBACK (wireless_dialog_response_cb),
234
closure, wireless_dialog_closure_closure_notify, 0);
236
g_object_bind_property (G_OBJECT (toplevel), "visible",
237
G_OBJECT (dialog), "visible",
238
G_BINDING_SYNC_CREATE);
242
cc_network_panel_create_wifi_network (CcNetworkPanel *panel,
244
NMRemoteSettings *settings)
246
if (wifi_can_create_wifi_network (client)) {
247
show_wireless_dialog (panel, client, settings,
248
nma_wireless_dialog_new_for_create (client, settings));
253
cc_network_panel_connect_to_hidden_network (CcNetworkPanel *panel,
255
NMRemoteSettings *settings)
257
g_debug ("connect to hidden wifi");
258
show_wireless_dialog (panel, client, settings,
259
nma_wireless_dialog_new_for_other (client, settings));
263
cc_network_panel_connect_to_8021x_network (CcNetworkPanel *panel,
265
NMRemoteSettings *settings,
267
const gchar *arg_access_point)
269
NMConnection *connection;
270
NMSettingConnection *s_con;
271
NMSettingWireless *s_wifi;
272
NMSettingWirelessSecurity *s_wsec;
273
NMSetting8021x *s_8021x;
274
NM80211ApSecurityFlags wpa_flags, rsn_flags;
279
g_debug ("connect to 8021x wifi");
280
ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), arg_access_point);
282
g_warning ("didn't find access point with path %s", arg_access_point);
286
/* If the AP is WPA[2]-Enterprise then we need to set up a minimal 802.1x
287
* setting and ask the user for more information.
289
rsn_flags = nm_access_point_get_rsn_flags (ap);
290
wpa_flags = nm_access_point_get_wpa_flags (ap);
291
if (!(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
292
&& !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
293
g_warning ("Network panel loaded with connect-8021x-wifi but the "
294
"access point does not support 802.1x");
298
connection = nm_connection_new ();
300
/* Need a UUID for the "always ask" stuff in the Dialog of Doom */
301
s_con = (NMSettingConnection *) nm_setting_connection_new ();
302
uuid = nm_utils_uuid_generate ();
303
g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL);
305
nm_connection_add_setting (connection, NM_SETTING (s_con));
307
s_wifi = (NMSettingWireless *) nm_setting_wireless_new ();
308
nm_connection_add_setting (connection, NM_SETTING (s_wifi));
309
g_object_set (s_wifi,
310
NM_SETTING_WIRELESS_SSID, nm_access_point_get_ssid (ap),
311
NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
314
s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
315
g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
316
nm_connection_add_setting (connection, NM_SETTING (s_wsec));
318
s_8021x = (NMSetting8021x *) nm_setting_802_1x_new ();
319
nm_setting_802_1x_add_eap_method (s_8021x, "ttls");
320
g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
321
nm_connection_add_setting (connection, NM_SETTING (s_8021x));
323
dialog = nma_wireless_dialog_new (client, settings, connection, device, ap, FALSE);
324
show_wireless_dialog (panel, client, settings, dialog);
328
connect_3g (NMConnection *connection,
332
MobileDialogClosure *closure = user_data;
334
if (canceled == FALSE) {
335
g_return_if_fail (connection != NULL);
337
/* Ask NM to add the new connection and activate it; NM will fill in the
338
* missing details based on the specific object and the device.
340
nm_client_add_and_activate_connection (closure->client,
348
mobile_dialog_closure_free (closure);
352
cdma_mobile_wizard_done (NMAMobileWizard *wizard,
354
NMAMobileWizardAccessMethod *method,
357
NMConnection *connection = NULL;
359
if (!canceled && method) {
363
if (method->devtype != NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
364
g_warning ("Unexpected device type (not CDMA).");
369
connection = nm_connection_new ();
371
setting = nm_setting_cdma_new ();
372
g_object_set (setting,
373
NM_SETTING_CDMA_NUMBER, "#777",
374
NM_SETTING_CDMA_USERNAME, method->username,
375
NM_SETTING_CDMA_PASSWORD, method->password,
377
nm_connection_add_setting (connection, setting);
380
setting = nm_setting_serial_new ();
381
g_object_set (setting,
382
NM_SETTING_SERIAL_BAUD, 115200,
383
NM_SETTING_SERIAL_BITS, 8,
384
NM_SETTING_SERIAL_PARITY, 'n',
385
NM_SETTING_SERIAL_STOPBITS, 1,
387
nm_connection_add_setting (connection, setting);
389
nm_connection_add_setting (connection, nm_setting_ppp_new ());
391
setting = nm_setting_connection_new ();
392
if (method->plan_name)
393
id = g_strdup_printf ("%s %s", method->provider_name, method->plan_name);
395
id = g_strdup_printf ("%s connection", method->provider_name);
396
uuid = nm_utils_uuid_generate ();
397
g_object_set (setting,
398
NM_SETTING_CONNECTION_ID, id,
399
NM_SETTING_CONNECTION_TYPE, NM_SETTING_CDMA_SETTING_NAME,
400
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
401
NM_SETTING_CONNECTION_UUID, uuid,
405
nm_connection_add_setting (connection, setting);
409
connect_3g (connection, canceled, user_data);
410
nma_mobile_wizard_destroy (wizard);
414
gsm_mobile_wizard_done (NMAMobileWizard *wizard,
416
NMAMobileWizardAccessMethod *method,
419
NMConnection *connection = NULL;
421
if (!canceled && method) {
425
if (method->devtype != NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
426
g_warning ("Unexpected device type (not GSM).");
431
connection = nm_connection_new ();
433
setting = nm_setting_gsm_new ();
434
g_object_set (setting,
435
NM_SETTING_GSM_NUMBER, "*99#",
436
NM_SETTING_GSM_USERNAME, method->username,
437
NM_SETTING_GSM_PASSWORD, method->password,
438
NM_SETTING_GSM_APN, method->gsm_apn,
440
nm_connection_add_setting (connection, setting);
443
setting = nm_setting_serial_new ();
444
g_object_set (setting,
445
NM_SETTING_SERIAL_BAUD, 115200,
446
NM_SETTING_SERIAL_BITS, 8,
447
NM_SETTING_SERIAL_PARITY, 'n',
448
NM_SETTING_SERIAL_STOPBITS, 1,
450
nm_connection_add_setting (connection, setting);
452
nm_connection_add_setting (connection, nm_setting_ppp_new ());
454
setting = nm_setting_connection_new ();
455
if (method->plan_name)
456
id = g_strdup_printf ("%s %s", method->provider_name, method->plan_name);
458
id = g_strdup_printf ("%s connection", method->provider_name);
459
uuid = nm_utils_uuid_generate ();
460
g_object_set (setting,
461
NM_SETTING_CONNECTION_ID, id,
462
NM_SETTING_CONNECTION_TYPE, NM_SETTING_GSM_SETTING_NAME,
463
NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
464
NM_SETTING_CONNECTION_UUID, uuid,
468
nm_connection_add_setting (connection, setting);
472
connect_3g (connection, canceled, user_data);
473
nma_mobile_wizard_destroy (wizard);
477
toplevel_shown (GtkWindow *toplevel,
479
NMAMobileWizard *wizard)
481
gboolean visible = FALSE;
483
g_object_get (G_OBJECT (toplevel), "visible", &visible, NULL);
485
nma_mobile_wizard_present (wizard);
489
show_wizard_idle_cb (NMAMobileWizard *wizard)
491
nma_mobile_wizard_present (wizard);
496
cc_network_panel_connect_to_3g_network (CcNetworkPanel *panel,
498
NMRemoteSettings *settings,
501
GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)));
502
MobileDialogClosure *closure;
503
NMAMobileWizard *wizard;
504
NMDeviceModemCapabilities caps;
505
gboolean visible = FALSE;
507
g_debug ("connect to 3g");
508
if (!NM_IS_DEVICE_MODEM (device)) {
509
g_warning ("Network panel loaded with connect-3g but the selected device"
514
closure = g_slice_new (MobileDialogClosure);
515
closure->client = g_object_ref (client);
516
closure->settings = g_object_ref (settings);
517
closure->device = g_object_ref (device);
519
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
520
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
521
wizard = nma_mobile_wizard_new (GTK_WINDOW (toplevel), NULL, NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS, FALSE,
522
gsm_mobile_wizard_done, closure);
523
if (wizard == NULL) {
524
g_warning ("failed to construct GSM wizard");
527
} else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
528
wizard = nma_mobile_wizard_new (GTK_WINDOW (toplevel), NULL, NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO, FALSE,
529
cdma_mobile_wizard_done, closure);
530
if (wizard == NULL) {
531
g_warning ("failed to construct CDMA wizard");
535
g_warning ("Network panel loaded with connect-3g but the selected device"
536
" does not support GSM or CDMA");
537
mobile_dialog_closure_free (closure);
541
g_object_get (G_OBJECT (toplevel), "visible", &visible, NULL);
543
g_debug ("Scheduling showing the Mobile wizard");
544
g_idle_add ((GSourceFunc) show_wizard_idle_cb, wizard);
546
g_debug ("Will show wizard a bit later, toplevel is not visible");
547
g_signal_connect (G_OBJECT (toplevel), "notify::visible",
548
G_CALLBACK (toplevel_shown), wizard);