63
72
#include "applet-device-gsm.h"
64
73
#include "applet-device-cdma.h"
65
74
#include "applet-device-bt.h"
75
#include "applet-device-wimax.h"
66
76
#include "applet-dialogs.h"
67
#include "vpn-password-dialog.h"
68
#include "applet-dbus-manager.h"
77
#include "wireless-dialog.h"
78
#include "applet-vpn-request.h"
70
80
#include "gconf-helpers.h"
72
82
#define NOTIFY_CAPS_ACTIONS_KEY "actions"
84
extern gboolean shell_debug;
74
86
G_DEFINE_TYPE(NMApplet, nma, G_TYPE_OBJECT)
88
/********************************************************************/
89
/* Temporary dbus interface stuff */
92
impl_dbus_connect_to_hidden_network (NMApplet *applet, GError **error)
94
if (!applet_wifi_connect_to_hidden_network (applet)) {
95
g_set_error_literal (error,
96
NM_SECRET_AGENT_ERROR,
97
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
98
"Failed to create wireless dialog");
106
impl_dbus_create_wifi_network (NMApplet *applet, GError **error)
108
if (!applet_wifi_can_create_wifi_network (applet)) {
109
g_set_error_literal (error,
110
NM_SECRET_AGENT_ERROR,
111
NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED,
112
"Creation of wifi networks has been disabled by system policy.");
116
if (!applet_wifi_create_wifi_network (applet)) {
117
g_set_error_literal (error,
118
NM_SECRET_AGENT_ERROR,
119
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
120
"Failed to create wireless dialog");
128
impl_dbus_connect_to_8021x_network (NMApplet *applet,
129
const char *device_path,
136
device = nm_client_get_device_by_path (applet->nm_client, device_path);
137
if (!device || NM_IS_DEVICE_WIFI (device) == FALSE) {
138
g_set_error_literal (error,
139
NM_SECRET_AGENT_ERROR,
140
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
141
"The device could not be found.");
145
ap = nm_device_wifi_get_access_point_by_path (NM_DEVICE_WIFI (device), ap_path);
147
g_set_error_literal (error,
148
NM_SECRET_AGENT_ERROR,
149
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
150
"The access point could not be found.");
154
/* FIXME: this doesn't account for Dynamic WEP */
155
if ( !(nm_access_point_get_wpa_flags (ap) & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
156
&& !(nm_access_point_get_rsn_flags (ap) & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) {
157
g_set_error_literal (error,
158
NM_SECRET_AGENT_ERROR,
159
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
160
"The access point had no 802.1x capabilities");
164
if (!applet_wifi_connect_to_8021x_network (applet, device, ap)) {
165
g_set_error_literal (error,
166
NM_SECRET_AGENT_ERROR,
167
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
168
"Failed to create wireless dialog");
176
impl_dbus_connect_to_3g_network (NMApplet *applet,
177
const char *device_path,
181
NMDeviceModemCapabilities caps;
183
device = nm_client_get_device_by_path (applet->nm_client, device_path);
184
if (!device || NM_IS_DEVICE_MODEM (device) == FALSE) {
185
g_set_error_literal (error,
186
NM_SECRET_AGENT_ERROR,
187
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
188
"The device could not be found.");
192
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
193
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS) {
194
applet_gsm_connect_network (applet, device);
195
} else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO) {
196
applet_cdma_connect_network (applet, device);
198
g_set_error_literal (error,
199
NM_SECRET_AGENT_ERROR,
200
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
201
"The device had no GSM or CDMA capabilities.");
208
#include "applet-dbus-bindings.h"
210
/********************************************************************/
76
212
static NMActiveConnection *
77
213
applet_get_best_activating_connection (NMApplet *applet, NMDevice **device)
255
407
return applet->wired_class;
256
408
else if (NM_IS_DEVICE_WIFI (device))
257
409
return applet->wifi_class;
258
else if (NM_IS_GSM_DEVICE (device))
410
else if (NM_IS_DEVICE_MODEM (device)) {
411
NMDeviceModemCapabilities caps;
413
caps = nm_device_modem_get_current_capabilities (NM_DEVICE_MODEM (device));
414
if (caps & NM_DEVICE_MODEM_CAPABILITY_GSM_UMTS)
415
return applet->gsm_class;
416
else if (caps & NM_DEVICE_MODEM_CAPABILITY_CDMA_EVDO)
417
return applet->cdma_class;
419
g_message ("%s: unhandled modem capabilities 0x%X", __func__, caps);
420
} else if (NM_IS_DEVICE_BT (device))
421
return applet->bt_class;
422
else if (NM_IS_DEVICE_WIMAX (device))
423
return applet->wimax_class;
425
g_message ("%s: Unknown device type '%s'", __func__, G_OBJECT_TYPE_NAME (device));
429
static inline NMADeviceClass *
430
get_device_class_from_connection (NMConnection *connection, NMApplet *applet)
432
NMSettingConnection *s_con;
435
g_return_val_if_fail (connection != NULL, NULL);
436
g_return_val_if_fail (applet != NULL, NULL);
438
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
439
g_return_val_if_fail (s_con != NULL, NULL);
441
ctype = nm_setting_connection_get_connection_type (s_con);
442
g_return_val_if_fail (ctype != NULL, NULL);
444
if (!strcmp (ctype, NM_SETTING_WIRED_SETTING_NAME) || !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME))
445
return applet->wired_class;
446
else if (!strcmp (ctype, NM_SETTING_WIRELESS_SETTING_NAME))
447
return applet->wifi_class;
448
else if (!strcmp (ctype, NM_SETTING_GSM_SETTING_NAME))
259
449
return applet->gsm_class;
260
else if (NM_IS_CDMA_DEVICE (device))
450
else if (!strcmp (ctype, NM_SETTING_CDMA_SETTING_NAME))
261
451
return applet->cdma_class;
262
else if (NM_IS_DEVICE_BT (device))
452
else if (!strcmp (ctype, NM_SETTING_BLUETOOTH_SETTING_NAME))
263
453
return applet->bt_class;
265
g_message ("%s: Unknown device type '%s'", __func__, G_OBJECT_TYPE_NAME (device));
455
g_warning ("%s: unhandled connection type '%s'", __func__, ctype);
270
is_system_connection (NMConnection *connection)
272
return (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) ? TRUE : FALSE;
276
activate_connection_cb (gpointer user_data, const char *path, GError *error)
279
nm_warning ("Connection activation failed: %s", error->message);
281
applet_schedule_update_icon (NM_APPLET (user_data));
285
460
NMApplet *applet;
286
461
NMDevice *device;
287
462
char *specific_object;
288
gpointer dclass_data;
463
NMConnection *connection;
289
464
} AppletItemActivateInfo;
2526
2667
applet->update_icon_id = g_idle_add (applet_update_icon, applet);
2530
find_active_device (NMAGConfConnection *connection,
2532
NMActiveConnection **out_active_connection)
2670
/*****************************************************************************/
2672
static SecretsRequest *
2673
applet_secrets_request_new (size_t totsize,
2674
NMConnection *connection,
2675
gpointer request_id,
2676
const char *setting_name,
2679
AppletAgentSecretsCallback callback,
2680
gpointer callback_data,
2534
const GPtrArray *active_connections;
2683
SecretsRequest *req;
2685
g_return_val_if_fail (totsize >= sizeof (SecretsRequest), NULL);
2537
2686
g_return_val_if_fail (connection != NULL, NULL);
2538
g_return_val_if_fail (applet != NULL, NULL);
2539
g_return_val_if_fail (out_active_connection != NULL, NULL);
2540
g_return_val_if_fail (*out_active_connection == NULL, NULL);
2542
/* Look through the active connection list trying to find the D-Bus
2543
* object path of applet_connection.
2545
active_connections = nm_client_get_active_connections (applet->nm_client);
2546
for (i = 0; active_connections && (i < active_connections->len); i++) {
2547
NMActiveConnection *active;
2548
const char *service_name;
2549
const char *connection_path;
2550
const GPtrArray *devices;
2552
active = NM_ACTIVE_CONNECTION (g_ptr_array_index (active_connections, i));
2553
service_name = nm_active_connection_get_service_name (active);
2554
if (!service_name) {
2555
/* Shouldn't happen; but we shouldn't crash either */
2556
g_warning ("%s: couldn't get service name for active connection!", __func__);
2560
if (strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS))
2563
connection_path = nm_active_connection_get_connection (active);
2564
if (!connection_path) {
2565
/* Shouldn't happen; but we shouldn't crash either */
2566
g_warning ("%s: couldn't get connection path for active connection!", __func__);
2570
if (!strcmp (connection_path, nm_connection_get_path (NM_CONNECTION (connection)))) {
2571
devices = nm_active_connection_get_devices (active);
2573
*out_active_connection = active;
2574
return devices ? NM_DEVICE (g_ptr_array_index (devices, 0)) : NULL;
2582
applet_settings_new_secrets_requested_cb (NMAGConfSettings *settings,
2583
NMAGConfConnection *connection,
2584
const char *setting_name,
2587
NMANewSecretsRequestedFunc callback,
2588
gpointer callback_data,
2688
req = g_malloc0 (totsize);
2689
req->totsize = totsize;
2690
req->connection = g_object_ref (connection);
2691
req->reqid = request_id;
2692
req->setting_name = g_strdup (setting_name);
2693
req->hints = g_strdupv ((char **) hints);
2695
req->callback = callback;
2696
req->callback_data = callback_data;
2697
req->applet = applet;
2702
applet_secrets_request_set_free_func (SecretsRequest *req,
2703
SecretsRequestFreeFunc free_func)
2705
req->free_func = free_func;
2709
applet_secrets_request_complete (SecretsRequest *req,
2710
GHashTable *settings,
2713
req->callback (req->applet->agent, error ? NULL : settings, error, req->callback_data);
2717
applet_secrets_request_complete_setting (SecretsRequest *req,
2718
const char *setting_name,
2722
GHashTable *settings = NULL, *secrets;
2724
if (setting_name && !error) {
2725
setting = nm_connection_get_setting_by_name (req->connection, setting_name);
2727
secrets = nm_setting_to_hash (NM_SETTING (setting), NM_SETTING_HASH_FLAG_ALL);
2729
/* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
2730
* will contain all the individual settings hashes.
2732
settings = g_hash_table_new_full (g_str_hash,
2735
(GDestroyNotify) g_hash_table_destroy);
2736
g_hash_table_insert (settings, g_strdup (setting_name), secrets);
2738
g_set_error (&error,
2739
NM_SECRET_AGENT_ERROR,
2740
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
2741
"%s.%d (%s): failed to hash setting '%s'.",
2742
__FILE__, __LINE__, __func__, setting_name);
2745
g_set_error (&error,
2746
NM_SECRET_AGENT_ERROR,
2747
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
2748
"%s.%d (%s): unhandled setting '%s'",
2749
__FILE__, __LINE__, __func__, setting_name);
2753
req->callback (req->applet->agent, settings, error, req->callback_data);
2757
applet_secrets_request_free (SecretsRequest *req)
2759
g_return_if_fail (req != NULL);
2762
req->free_func (req);
2764
req->applet->secrets_reqs = g_slist_remove (req->applet->secrets_reqs, req);
2766
g_object_unref (req->connection);
2767
g_free (req->setting_name);
2768
g_strfreev (req->hints);
2769
memset (req, 0, req->totsize);
2774
get_existing_secrets_cb (NMSecretAgent *agent,
2775
NMConnection *connection,
2776
GHashTable *secrets,
2777
GError *secrets_error,
2780
SecretsRequest *req = user_data;
2781
NMADeviceClass *dclass;
2782
GError *error = NULL;
2784
/* Merge existing secrets into connection; ignore errors */
2785
nm_connection_update_secrets (connection, req->setting_name, secrets, NULL);
2787
dclass = get_device_class_from_connection (connection, req->applet);
2790
/* Let the device class handle secrets */
2791
if (!dclass->get_secrets (req, &error)) {
2792
g_warning ("%s:%d - %s", __func__, __LINE__, error ? error->message : "(unknown)");
2793
applet_secrets_request_complete (req, NULL, error);
2794
applet_secrets_request_free (req);
2795
g_error_free (error);
2797
/* Otherwise success; wait for the secrets callback */
2801
applet_agent_get_secrets_cb (AppletAgent *agent,
2802
gpointer request_id,
2803
NMConnection *connection,
2804
const char *setting_name,
2807
AppletAgentSecretsCallback callback,
2808
gpointer callback_data,
2591
2811
NMApplet *applet = NM_APPLET (user_data);
2592
NMActiveConnection *active_connection = NULL;
2593
2812
NMSettingConnection *s_con;
2595
2813
NMADeviceClass *dclass;
2596
2814
GError *error = NULL;
2815
SecretsRequest *req = NULL;
2598
s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
2817
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
2599
2818
g_return_if_fail (s_con != NULL);
2601
2820
/* VPN secrets get handled a bit differently */
2602
2821
if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) {
2603
nma_vpn_request_password (NM_SETTINGS_CONNECTION_INTERFACE (connection), ask_user, callback, callback_data);
2822
req = applet_secrets_request_new (applet_vpn_request_get_secrets_size (),
2831
if (!applet_vpn_request_get_secrets (req, &error))
2834
applet->secrets_reqs = g_slist_prepend (applet->secrets_reqs, req);
2607
/* Find the active device for this connection */
2608
device = find_active_device (connection, applet, &active_connection);
2609
if (!device || !active_connection) {
2610
g_set_error (&error,
2611
NM_SETTINGS_INTERFACE_ERROR,
2612
NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
2613
"%s.%d (%s): couldn't find details for connection",
2614
__FILE__, __LINE__, __func__);
2618
dclass = get_device_class (device, applet);
2838
dclass = get_device_class_from_connection (connection, applet);
2620
g_set_error (&error,
2621
NM_SETTINGS_INTERFACE_ERROR,
2622
NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR,
2623
"%s.%d (%s): device type unknown",
2624
__FILE__, __LINE__, __func__);
2840
error = g_error_new (NM_SECRET_AGENT_ERROR,
2841
NM_SECRET_AGENT_ERROR_INTERNAL_ERROR,
2842
"%s.%d (%s): device type unknown",
2843
__FILE__, __LINE__, __func__);
2628
2847
if (!dclass->get_secrets) {
2629
g_set_error (&error,
2630
NM_SETTINGS_INTERFACE_ERROR,
2631
NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE,
2632
"%s.%d (%s): no secrets found",
2633
__FILE__, __LINE__, __func__);
2848
error = g_error_new (NM_SECRET_AGENT_ERROR,
2849
NM_SECRET_AGENT_ERROR_NO_SECRETS,
2850
"%s.%d (%s): no secrets found",
2851
__FILE__, __LINE__, __func__);
2637
// FIXME: get secrets locally and populate connection with previous secrets
2638
// before asking user for other secrets
2855
g_assert (dclass->secrets_request_size);
2856
req = applet_secrets_request_new (dclass->secrets_request_size,
2865
applet->secrets_reqs = g_slist_prepend (applet->secrets_reqs, req);
2640
/* Let the device class handle secrets */
2641
if (dclass->get_secrets (device, NM_SETTINGS_CONNECTION_INTERFACE (connection),
2642
active_connection, setting_name, hints, callback,
2643
callback_data, applet, &error))
2644
return; /* success */
2867
/* Get existing secrets, if any */
2868
nm_secret_agent_get_secrets (NM_SECRET_AGENT (applet->agent),
2872
NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE,
2873
get_existing_secrets_cb,
2647
2878
g_warning ("%s", error->message);
2648
callback (NM_SETTINGS_CONNECTION_INTERFACE (connection), NULL, error, callback_data);
2879
callback (agent, NULL, error, callback_data);
2649
2880
g_error_free (error);
2883
applet_secrets_request_free (req);
2653
periodic_update_active_connection_timestamps (gpointer user_data)
2887
applet_agent_cancel_secrets_cb (AppletAgent *agent,
2888
gpointer request_id,
2655
2891
NMApplet *applet = NM_APPLET (user_data);
2656
const GPtrArray *connections;
2659
if (!applet->nm_client || !nm_client_get_manager_running (applet->nm_client))
2662
connections = nm_client_get_active_connections (applet->nm_client);
2663
for (i = 0; connections && (i < connections->len); i++) {
2664
NMActiveConnection *active = NM_ACTIVE_CONNECTION (g_ptr_array_index (connections, i));
2666
NMSettingsConnectionInterface *connection;
2667
const GPtrArray *devices;
2670
if (nm_active_connection_get_scope (active) == NM_CONNECTION_SCOPE_SYSTEM)
2673
path = nm_active_connection_get_connection (active);
2674
connection = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (applet->gconf_settings), path);
2675
if (!connection || !NMA_IS_GCONF_CONNECTION (connection))
2678
devices = nm_active_connection_get_devices (active);
2679
if (!devices || !devices->len)
2682
/* Check if a device owned by the active connection is completely
2683
* activated before updating timestamp.
2685
for (k = 0; devices && (k < devices->len); k++) {
2686
NMDevice *device = NM_DEVICE (g_ptr_array_index (devices, k));
2688
if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
2689
NMSettingConnection *s_con;
2691
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION));
2694
g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), NULL);
2695
/* Ignore secrets since we're just updating the timestamp */
2696
nma_gconf_connection_update (NMA_GCONF_CONNECTION (connection), TRUE);
2894
for (iter = applet->secrets_reqs; iter; iter = g_slist_next (iter)) {
2895
SecretsRequest *req = iter->data;
2897
if (req->reqid == request_id) {
2898
/* cancel and free this password request */
2899
applet_secrets_request_free (req);
2705
2904
/*****************************************************************************/