From 443c95a6b9c8709f5d9038421df1856f190eeb24 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Tue, 13 Jul 2010 18:09:56 -0400 Subject: [PATCH 001/264] nm-manager: start removing user settings services It turns out that user settings services are strange and complicated beasts. We will remove support for them, and we will later implement security mechanisms on the system settings service that will do what user settings services were intended to do. This commit is a bulk removal of nm-manager's internal support code for user settings services. The external API is largely unchanged, but errors are returned if anyone ties to do something with user settings. Work remaining includes some possible flattening of nm-manager's internal code, along with code removal and API changes in other modules. --- src/nm-manager.c | 1061 +++------------------------------------------- src/nm-manager.h | 2 - src/nm-policy.c | 4 - 3 files changed, 51 insertions(+), 1016 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 8c3119799..d1d42af0c 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -95,10 +95,6 @@ static gboolean impl_manager_legacy_state (NMManager *manager, guint32 *state, G #include "nm-manager-glue.h" -static void connection_added_default_handler (NMManager *manager, - NMConnection *connection, - NMConnectionScope scope); - static void udev_device_added_cb (NMUdevManager *udev_mgr, GUdevDevice *device, NMDeviceCreatorFn creator_fn, @@ -159,14 +155,11 @@ struct PendingActivation { PendingActivationFunc callback; NMAuthChain *chain; - gboolean have_connection; gboolean authorized; - NMConnectionScope scope; char *connection_path; char *specific_object_path; char *device_path; - guint timeout_id; }; typedef struct { @@ -191,19 +184,12 @@ typedef struct { NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; - GHashTable *user_connections; - DBusGProxy *user_proxy; - NMAuthCallResult user_con_perm; - NMAuthCallResult user_net_perm; - GHashTable *system_connections; NMSysconfigSettings *sys_settings; char *hostname; GSList *secrets_calls; - GSList *pending_activations; - RadioState radio_states[RFKILL_TYPE_MAX]; gboolean sleeping; gboolean net_enabled; @@ -591,21 +577,11 @@ emit_removed (gpointer key, gpointer value, gpointer user_data) nm_connection_get_scope (connection)); } -static void -nm_manager_pending_activation_remove (NMManager *self, - PendingActivation *pending) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - - priv->pending_activations = g_slist_remove (priv->pending_activations, pending); -} - static PendingActivation * pending_activation_new (NMManager *manager, PolkitAuthority *authority, DBusGMethodInvocation *context, const char *device_path, - NMConnectionScope scope, const char *connection_path, const char *specific_object_path, PendingActivationFunc callback) @@ -625,7 +601,6 @@ pending_activation_new (NMManager *manager, pending->callback = callback; pending->device_path = g_strdup (device_path); - pending->scope = scope; pending->connection_path = g_strdup (connection_path); /* "/" is special-cased to NULL to get through D-Bus */ @@ -635,39 +610,6 @@ pending_activation_new (NMManager *manager, return pending; } -static void -pending_auth_user_done (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - PendingActivation *pending = user_data; - NMAuthCallResult result; - - pending->chain = NULL; - - if (error) { - pending->callback (pending, error); - goto out; - } - - /* Caller has had a chance to obtain authorization, so we only need to - * check for 'yes' here. - */ - result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS)); - if (result != NM_AUTH_CALL_RESULT_YES) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_PERMISSION_DENIED, - "Not authorized to use user connections."); - pending->callback (pending, error); - g_error_free (error); - } else - pending->callback (pending, NULL); - -out: - nm_auth_chain_unref (chain); -} - static void pending_auth_net_done (NMAuthChain *chain, GError *error, @@ -697,67 +639,15 @@ pending_auth_net_done (NMAuthChain *chain, goto out; } - if (pending->scope == NM_CONNECTION_SCOPE_SYSTEM) { - /* System connection and the user is authorized for that if they have - * the network-control permission. - */ - pending->callback (pending, NULL); - } else { - g_assert (pending->scope == NM_CONNECTION_SCOPE_USER); - - /* User connection, check the 'use-user-connections' permission */ - pending->chain = nm_auth_chain_new (pending->authority, - pending->context, - NULL, - pending_auth_user_done, - pending); - nm_auth_chain_add_call (pending->chain, - NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, - TRUE); - } + pending->callback (pending, NULL); out: nm_auth_chain_unref (chain); } -static gboolean -check_user_authorized (NMDBusManager *dbus_mgr, - DBusGProxy *user_proxy, - DBusGMethodInvocation *context, - NMConnectionScope scope, - gulong *out_sender_uid, - const char **out_error_desc) -{ - g_return_val_if_fail (dbus_mgr != NULL, FALSE); - g_return_val_if_fail (context != NULL, FALSE); - g_return_val_if_fail (out_sender_uid != NULL, FALSE); - g_return_val_if_fail (out_error_desc != NULL, FALSE); - - *out_sender_uid = G_MAXULONG; - - /* Get the UID */ - if (!nm_auth_get_caller_uid (context, dbus_mgr, out_sender_uid, out_error_desc)) - return FALSE; - - /* root gets to do anything */ - if (0 == *out_sender_uid) - return TRUE; - - /* Check whether the UID is authorized for user connections */ - if ( scope == NM_CONNECTION_SCOPE_USER - && !nm_auth_uid_authorized (*out_sender_uid, - dbus_mgr, - user_proxy, - out_error_desc)) - return FALSE; - - return TRUE; -} - static void pending_activation_check_authorized (PendingActivation *pending, - NMDBusManager *dbus_mgr, - DBusGProxy *user_proxy) + NMDBusManager *dbus_mgr) { const char *error_desc = NULL; gulong sender_uid = G_MAXULONG; @@ -766,12 +656,10 @@ pending_activation_check_authorized (PendingActivation *pending, g_return_if_fail (pending != NULL); g_return_if_fail (dbus_mgr != NULL); - if (!check_user_authorized (dbus_mgr, - user_proxy, - pending->context, - pending->scope, - &sender_uid, - &error_desc)) { + if (!nm_auth_get_caller_uid (pending->context, + dbus_mgr, + &sender_uid, + &error_desc)) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, error_desc); @@ -807,8 +695,6 @@ pending_activation_destroy (PendingActivation *pending, { g_return_if_fail (pending != NULL); - if (pending->timeout_id) - g_source_remove (pending->timeout_id); g_free (pending->connection_path); g_free (pending->specific_object_path); g_free (pending->device_path); @@ -877,457 +763,6 @@ remove_connection (NMManager *manager, bluez_manager_resync_devices (manager); } -/*******************************************************************/ -/* User settings stuff via D-Bus */ -/*******************************************************************/ - -static void -user_proxy_cleanup (NMManager *self, gboolean resync_bt) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - - if (priv->user_connections) { - g_hash_table_foreach (priv->user_connections, emit_removed, self); - g_hash_table_remove_all (priv->user_connections); - } - - priv->user_net_perm = NM_AUTH_CALL_RESULT_UNKNOWN; - priv->user_con_perm = NM_AUTH_CALL_RESULT_UNKNOWN; - - if (priv->user_proxy) { - g_object_unref (priv->user_proxy); - priv->user_proxy = NULL; - } - - if (resync_bt) { - /* Resync BT devices since they are generated from connections */ - bluez_manager_resync_devices (self); - } -} - -typedef struct GetSettingsInfo { - NMManager *manager; - NMConnection *connection; - DBusGProxy *proxy; - DBusGProxyCall *call; - GSList **calls; -} GetSettingsInfo; - -static void -free_get_settings_info (gpointer data) -{ - GetSettingsInfo *info = (GetSettingsInfo *) data; - - /* If this was the last pending call for a batch of GetSettings calls, - * send out the connections-added signal. - */ - if (info->calls) { - *(info->calls) = g_slist_remove (*(info->calls), info->call); - if (g_slist_length (*(info->calls)) == 0) { - g_slist_free (*(info->calls)); - g_slice_free (GSList, (gpointer) info->calls); - g_signal_emit (info->manager, signals[CONNECTIONS_ADDED], 0, NM_CONNECTION_SCOPE_USER); - - /* Update the Bluetooth connections for all the new connections */ - bluez_manager_resync_devices (info->manager); - } - } - - if (info->manager) { - g_object_unref (info->manager); - info->manager = NULL; - } - if (info->connection) { - g_object_unref (info->connection); - info->connection = NULL; - } - if (info->proxy) { - g_object_unref (info->proxy); - info->proxy = NULL; - } - - g_slice_free (GetSettingsInfo, data); -} - -static void -user_connection_get_settings_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) -{ - GetSettingsInfo *info = (GetSettingsInfo *) user_data; - GError *err = NULL; - GHashTable *settings = NULL; - NMConnection *connection; - NMManager *manager; - - g_return_if_fail (info != NULL); - - if (!dbus_g_proxy_end_call (proxy, call_id, &err, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, - G_TYPE_INVALID)) { - nm_log_info (LOGD_USER_SET, "couldn't retrieve connection settings: %s.", - err && err->message ? err->message : "(unknown)"); - g_error_free (err); - goto out; - } - - manager = info->manager; - connection = info->connection; - if (connection == NULL) { - const char *path = dbus_g_proxy_get_path (proxy); - NMManagerPrivate *priv; - GError *error = NULL; - NMConnection *existing = NULL; - - connection = nm_connection_new_from_hash (settings, &error); - if (connection == NULL) { - nm_log_warn (LOGD_USER_SET, "invalid connection: '%s' / '%s' invalid: %d", - g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), - error->message, error->code); - g_error_free (error); - goto out; - } - - nm_connection_set_path (connection, path); - nm_connection_set_scope (connection, NM_CONNECTION_SCOPE_USER); - - /* Add the new connection to the internal hashes only if the same - * connection isn't already there. - */ - priv = NM_MANAGER_GET_PRIVATE (manager); - - existing = g_hash_table_lookup (priv->user_connections, path); - if (!existing || !nm_connection_compare (existing, connection, NM_SETTING_COMPARE_FLAG_EXACT)) { - g_hash_table_insert (priv->user_connections, - g_strdup (path), - connection); - existing = NULL; - - /* Attach the D-Bus proxy representing the remote NMConnection - * to the local NMConnection object to ensure it stays alive to - * continue delivering signals. It'll be destroyed once the - * NMConnection is destroyed. - */ - g_object_set_data_full (G_OBJECT (connection), - "proxy", - g_object_ref (info->proxy), - g_object_unref); - } else - g_object_unref (connection); - - /* If the connection-added signal is supposed to be batched, don't - * emit the single connection-added here. Also, don't emit the signal - * if the connection wasn't actually added to the system or user hashes. - */ - if (!info->calls && !existing) { - g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection, NM_CONNECTION_SCOPE_USER); - /* Update the Bluetooth connections for that single new connection */ - bluez_manager_resync_devices (manager); - } - } else { - // FIXME: merge settings? or just replace? - nm_log_dbg (LOGD_USER_SET, "implement merge settings"); - } - -out: - if (settings) - g_hash_table_destroy (settings); - - return; -} - -static void -user_connection_removed_cb (DBusGProxy *proxy, gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - NMConnection *connection = NULL; - const char *path; - - path = dbus_g_proxy_get_path (proxy); - if (path) { - connection = g_hash_table_lookup (priv->user_connections, path); - if (connection) - remove_connection (manager, connection, priv->user_connections); - } -} - -static void -user_connection_updated_cb (DBusGProxy *proxy, - GHashTable *settings, - gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - NMConnection *new_connection; - NMConnection *old_connection = NULL; - gboolean valid = FALSE; - GError *error = NULL; - const char *path; - - path = dbus_g_proxy_get_path (proxy); - if (path) - old_connection = g_hash_table_lookup (priv->user_connections, path); - - g_return_if_fail (old_connection != NULL); - - new_connection = nm_connection_new_from_hash (settings, &error); - if (!new_connection) { - /* New connection invalid, remove existing connection */ - nm_log_warn (LOGD_USER_SET, "invalid connection: '%s' / '%s' invalid: %d", - g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), - error->message, error->code); - g_error_free (error); - remove_connection (manager, old_connection, priv->user_connections); - return; - } - g_object_unref (new_connection); - - valid = nm_connection_replace_settings (old_connection, settings, NULL); - if (valid) { - g_signal_emit (manager, signals[CONNECTION_UPDATED], 0, - old_connection, - nm_connection_get_scope (old_connection)); - - bluez_manager_resync_devices (manager); - } else { - remove_connection (manager, old_connection, priv->user_connections); - } -} - -static void -user_internal_new_connection_cb (DBusGProxy *proxy, - const char *path, - NMManager *manager, - GSList **calls) -{ - struct GetSettingsInfo *info; - DBusGProxy *con_proxy; - DBusGConnection *g_connection; - DBusGProxyCall *call; - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - con_proxy = dbus_g_proxy_new_for_name (g_connection, - dbus_g_proxy_get_bus_name (proxy), - path, - NM_DBUS_IFACE_SETTINGS_CONNECTION); - if (!con_proxy) { - nm_log_err (LOGD_USER_SET, "could not init user connection proxy"); - return; - } - - dbus_g_proxy_add_signal (con_proxy, "Updated", - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (con_proxy, "Updated", - G_CALLBACK (user_connection_updated_cb), - manager, - NULL); - - dbus_g_proxy_add_signal (con_proxy, "Removed", G_TYPE_INVALID, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (con_proxy, "Removed", - G_CALLBACK (user_connection_removed_cb), - manager, - NULL); - - info = g_slice_new0 (GetSettingsInfo); - info->manager = g_object_ref (manager); - info->calls = calls; - call = dbus_g_proxy_begin_call (con_proxy, "GetSettings", - user_connection_get_settings_cb, - info, - free_get_settings_info, - G_TYPE_INVALID); - info->call = call; - info->proxy = con_proxy; - if (info->calls) - *(info->calls) = g_slist_prepend (*(info->calls), call); -} - -static void -user_list_connections_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - GError *err = NULL; - GPtrArray *ops; - GSList **calls = NULL; - int i; - - if (!dbus_g_proxy_end_call (proxy, call_id, &err, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &ops, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_USER_SET, "couldn't retrieve connections: %s", - err && err->message ? err->message : "(unknown)"); - g_error_free (err); - goto out; - } - - /* Keep track of all calls made here; don't want to emit connection-added for - * each one, but emit connections-added when they are all done. - */ - calls = g_slice_new0 (GSList *); - - for (i = 0; i < ops->len; i++) { - char *op = g_ptr_array_index (ops, i); - - user_internal_new_connection_cb (proxy, op, manager, calls); - g_free (op); - } - - g_ptr_array_free (ops, TRUE); - -out: - return; -} - -static void -user_proxy_destroyed_cb (DBusGProxy *proxy, NMManager *self) -{ - nm_log_dbg (LOGD_USER_SET, "Removing user connections..."); - - /* At this point the user proxy is already being disposed */ - NM_MANAGER_GET_PRIVATE (self)->user_proxy = NULL; - - /* User Settings service disappeared; throw away user connections */ - user_proxy_cleanup (self, TRUE); -} - -static void -user_new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) -{ - user_internal_new_connection_cb (proxy, path, NM_MANAGER (user_data), NULL); -} - -static gboolean -user_settings_authorized (NMManager *self, NMAuthChain *chain) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMAuthCallResult old_net_perm = priv->user_net_perm; - NMAuthCallResult old_con_perm = priv->user_con_perm; - - /* If the user could potentially get authorization to use networking and/or - * to use user connections, the user settings service is authorized. - */ - priv->user_net_perm = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL)); - priv->user_con_perm = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS)); - - nm_log_dbg (LOGD_USER_SET, "User connections permissions: net %d, con %d", - priv->user_net_perm, priv->user_con_perm); - - if (old_net_perm != priv->user_net_perm || old_con_perm != priv->user_con_perm) - g_signal_emit (self, signals[USER_PERMISSIONS_CHANGED], 0); - - /* If the user can't control the network they certainly aren't allowed - * to provide user connections. - */ - if ( priv->user_net_perm == NM_AUTH_CALL_RESULT_UNKNOWN - || priv->user_net_perm == NM_AUTH_CALL_RESULT_NO) - return FALSE; - - /* And of course if they aren't allowed to use user connections, they can't - * provide them either. - */ - if ( priv->user_con_perm == NM_AUTH_CALL_RESULT_UNKNOWN - || priv->user_con_perm == NM_AUTH_CALL_RESULT_NO) - return FALSE; - - return TRUE; -} - -static void -user_proxy_auth_done (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gboolean authorized = FALSE; - - priv->auth_chains = g_slist_remove (priv->auth_chains, chain); - - if (error) { - nm_log_warn (LOGD_USER_SET, "User connections unavailable: (%d) %s", - error->code, error->message ? error->message : "(unknown)"); - } else - authorized = user_settings_authorized (self, chain); - - if (authorized) { - /* If authorized, finish setting up the user settings service proxy */ - nm_log_dbg (LOGD_USER_SET, "Requesting user connections..."); - - authorized = TRUE; - - dbus_g_proxy_add_signal (priv->user_proxy, - "NewConnection", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->user_proxy, "NewConnection", - G_CALLBACK (user_new_connection_cb), - self, - NULL); - - /* Clean up when the user settings proxy goes away */ - g_signal_connect (priv->user_proxy, "destroy", - G_CALLBACK (user_proxy_destroyed_cb), - self); - - /* Request user connections */ - dbus_g_proxy_begin_call (priv->user_proxy, "ListConnections", - user_list_connections_cb, - self, - NULL, - G_TYPE_INVALID); - } else { - /* Otherwise, we ignore the user settings service completely */ - user_proxy_cleanup (self, TRUE); - } - - nm_auth_chain_unref (chain); -} - -static void -user_proxy_init (NMManager *self) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - DBusGConnection *bus; - NMAuthChain *chain; - GError *error = NULL; - - g_return_if_fail (self != NULL); - g_return_if_fail (priv->user_proxy == NULL); - - bus = nm_dbus_manager_get_connection (priv->dbus_mgr); - priv->user_proxy = dbus_g_proxy_new_for_name_owner (bus, - NM_DBUS_SERVICE_USER_SETTINGS, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_IFACE_SETTINGS, - &error); - if (!priv->user_proxy) { - nm_log_err (LOGD_USER_SET, "could not init user settings proxy: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - return; - } - - /* Kick off some PolicyKit authorization requests to figure out what - * permissions this user settings service has. - */ - chain = nm_auth_chain_new (priv->authority, - NULL, - priv->user_proxy, - user_proxy_auth_done, - self); - priv->auth_chains = g_slist_prepend (priv->auth_chains, chain); - - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE); -} - /*******************************************************************/ /* System settings stuff via NMSysconfigSettings */ /*******************************************************************/ @@ -1495,25 +930,6 @@ nm_manager_get_device_by_path (NMManager *manager, const char *path) return NULL; } -static void -nm_manager_name_owner_changed (NMDBusManager *mgr, - const char *name, - const char *old, - const char *new, - gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - gboolean old_owner_good = (old && (strlen (old) > 0)); - gboolean new_owner_good = (new && (strlen (new) > 0)); - - if (strcmp (name, NM_DBUS_SERVICE_USER_SETTINGS) == 0) { - if (!old_owner_good && new_owner_good) - user_proxy_init (manager); - else - user_proxy_cleanup (manager, TRUE); - } -} - /* Store value into key-file; supported types: boolean, int, string */ static gboolean write_value_to_state_file (const char *filename, @@ -1641,7 +1057,6 @@ manager_hidden_ap_found (NMDeviceInterface *device, /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); - connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER)); for (iter = connections; iter && !done; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); @@ -1831,42 +1246,12 @@ deactivate_disconnect_check_error (GError *auth_error, } else if (result != NM_AUTH_CALL_RESULT_YES) { return g_error_new (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, - "Not authorized to %s user connections", + "Not authorized to %s connections", detail); } return NULL; } -static void -disconnect_user_auth_done_cb (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *ret_error = NULL; - NMAuthCallResult result; - NMDevice *device; - - priv->auth_chains = g_slist_remove (priv->auth_chains, chain); - - result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS)); - ret_error = deactivate_disconnect_check_error (error, result, "Disconnect"); - if (!ret_error) { - /* Everything authorized, deactivate the connection */ - device = nm_auth_chain_get_data (chain, "device"); - if (nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error)) - dbus_g_method_return (context); - } - - if (ret_error) - dbus_g_method_return_error (context, ret_error); - g_clear_error (&ret_error); - - nm_auth_chain_unref (chain); -} - static void disconnect_net_auth_done_cb (NMAuthChain *chain, GError *error, @@ -1877,7 +1262,6 @@ disconnect_net_auth_done_cb (NMAuthChain *chain, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GError *ret_error = NULL; NMAuthCallResult result; - NMConnectionScope scope; NMDevice *device; priv->auth_chains = g_slist_remove (priv->auth_chains, chain); @@ -1890,29 +1274,12 @@ disconnect_net_auth_done_cb (NMAuthChain *chain, goto done; } - /* If it's a system connection, we're done */ device = nm_auth_chain_get_data (chain, "device"); - scope = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "scope")); - if (scope == NM_CONNECTION_SCOPE_USER) { - NMAuthChain *user_chain; - - /* It's a user connection, so we need to ensure the caller is - * authorized to manipulate user connections. - */ - user_chain = nm_auth_chain_new (priv->authority, context, NULL, disconnect_user_auth_done_cb, self); - g_assert (user_chain); - priv->auth_chains = g_slist_append (priv->auth_chains, user_chain); - - nm_auth_chain_set_data (user_chain, "device", g_object_ref (device), g_object_unref); - nm_auth_chain_set_data (user_chain, "scope", GUINT_TO_POINTER (scope), NULL); - nm_auth_chain_add_call (user_chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, TRUE); - } else { - if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error)) { - dbus_g_method_return_error (context, ret_error); - g_clear_error (&ret_error); - } else - dbus_g_method_return (context); - } + if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error)) { + dbus_g_method_return_error (context, ret_error); + g_clear_error (&ret_error); + } else + dbus_g_method_return (context); done: nm_auth_chain_unref (chain); @@ -1925,9 +1292,7 @@ manager_device_disconnect_request (NMDevice *device, { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActRequest *req; - NMConnection *connection; GError *error = NULL; - NMConnectionScope scope; gulong sender_uid = G_MAXULONG; const char *error_desc = NULL; @@ -1941,19 +1306,13 @@ manager_device_disconnect_request (NMDevice *device, return; } - connection = nm_act_request_get_connection (req); - g_assert (connection); - /* Need to check the caller's permissions and stuff before we can * deactivate the connection. */ - scope = nm_connection_get_scope (connection); - if (!check_user_authorized (priv->dbus_mgr, - priv->user_proxy, - context, - scope, - &sender_uid, - &error_desc)) { + if (!nm_auth_get_caller_uid (context, + priv->dbus_mgr, + &sender_uid, + &error_desc)) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, error_desc); @@ -1978,7 +1337,6 @@ manager_device_disconnect_request (NMDevice *device, priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref); - nm_auth_chain_set_data (chain, "scope", GUINT_TO_POINTER (scope), NULL); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE); } } @@ -2114,8 +1472,7 @@ add_device (NMManager *self, NMDevice *device) if (ac_path) g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS); else { - nm_log_warn (LOGD_DEVICE, "assumed connection (%d) %s failed to activate: (%d) %s", - nm_connection_get_scope (existing), + nm_log_warn (LOGD_DEVICE, "assumed connection %s failed to activate: (%d) %s", nm_connection_get_path (existing), error ? error->code : -1, error && error->message ? error->message : "(unknown)"); @@ -2159,7 +1516,6 @@ bluez_manager_find_connection (NMManager *manager, GSList *connections, *l; connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); - connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER)); for (l = connections; l != NULL; l = l->next) { NMConnection *candidate = NM_CONNECTION (l->data); @@ -2493,100 +1849,6 @@ provider_cancel_secrets (NMSecretsProviderInterface *provider, gpointer user_dat } } -static void -user_get_secrets_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - GetSecretsInfo *info = (GetSecretsInfo *) user_data; - GHashTable *settings = NULL; - GError *error = NULL; - GObject *provider; - - g_return_if_fail (info != NULL); - g_return_if_fail (info->provider); - g_return_if_fail (info->setting_name); - - provider = g_object_ref (info->provider); - - if (dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &settings, - G_TYPE_INVALID)) { - nm_secrets_provider_interface_get_secrets_result (info->provider, - info->setting_name, - info->caller, - settings, - NULL); - g_hash_table_destroy (settings); - } else { - nm_secrets_provider_interface_get_secrets_result (info->provider, - info->setting_name, - info->caller, - NULL, - error); - g_clear_error (&error); - } - - info->call = NULL; - free_get_secrets_info (info); - - g_object_unref (provider); -} - -static GetSecretsInfo * -user_get_secrets (NMManager *self, - NMSecretsProviderInterface *provider, - NMConnection *connection, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller_id, - const char *hint1, - const char *hint2) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - DBusGConnection *g_connection; - GetSecretsInfo *info = NULL; - GPtrArray *hints = NULL; - - info = g_malloc0 (sizeof (GetSecretsInfo)); - - g_connection = nm_dbus_manager_get_connection (priv->dbus_mgr); - info->proxy = dbus_g_proxy_new_for_name (g_connection, - NM_DBUS_SERVICE_USER_SETTINGS, - nm_connection_get_path (connection), - NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS); - if (!info->proxy) { - nm_log_warn (LOGD_USER_SET, "could not create user connection secrets proxy"); - g_free (info); - return NULL; - } - - info->manager = self; - info->provider = provider; - info->caller = caller_id; - info->setting_name = g_strdup (setting_name); - - g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info); - - hints = g_ptr_array_sized_new (2); - if (hint1) - g_ptr_array_add (hints, (char *) hint1); - if (hint2) - g_ptr_array_add (hints, (char *) hint2); - - info->call = dbus_g_proxy_begin_call_with_timeout (info->proxy, "GetSecrets", - user_get_secrets_cb, - info, - NULL, - G_MAXINT32, - G_TYPE_STRING, setting_name, - DBUS_TYPE_G_ARRAY_OF_STRING, hints, - G_TYPE_BOOLEAN, request_new, - G_TYPE_INVALID); - g_ptr_array_free (hints, TRUE); - return info; -} - static void system_get_secrets_reply_cb (NMSettingsConnectionInterface *connection, GHashTable *secrets, @@ -2689,7 +1951,6 @@ provider_get_secrets (NMSecretsProviderInterface *provider, NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); GetSecretsInfo *info = NULL; - NMConnectionScope scope; GSList *iter; g_return_val_if_fail (connection != NULL, FALSE); @@ -2706,14 +1967,10 @@ provider_get_secrets (NMSecretsProviderInterface *provider, } /* Build up the new secrets request */ - scope = nm_connection_get_scope (connection); - if (scope == NM_CONNECTION_SCOPE_SYSTEM) { - info = system_get_secrets (self, provider, connection, setting_name, - request_new, caller_id, hint1, hint2); - } else if (scope == NM_CONNECTION_SCOPE_USER) { - info = user_get_secrets (self, provider, connection, setting_name, - request_new, caller_id, hint1, hint2); - } + g_assert (nm_connection_get_scope (connection) == + NM_CONNECTION_SCOPE_SYSTEM); + info = system_get_secrets (self, provider, connection, setting_name, + request_new, caller_id, hint1, hint2); if (info) priv->secrets_calls = g_slist_append (priv->secrets_calls, info); @@ -2760,27 +2017,6 @@ internal_activate_device (NMManager *manager, return success ? nm_act_request_get_active_connection_path (req) : NULL; } -static gboolean -wait_for_connection_expired (gpointer data) -{ - PendingActivation *pending = data; - GError *error = NULL; - - g_return_val_if_fail (pending != NULL, FALSE); - - nm_log_warn (LOGD_CORE, "connection %s (scope %d) failed to activate (timeout)", - pending->connection_path, pending->scope); - - nm_manager_pending_activation_remove (pending->manager, pending); - - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "Connection was not provided by any settings service"); - pending_activation_destroy (pending, error, NULL); - g_error_free (error); - return FALSE; -} - const char * nm_manager_activate_connection (NMManager *manager, NMConnection *connection, @@ -2888,23 +2124,12 @@ nm_manager_activate_connection (NMManager *manager, return path; } -static PendingActivation * -nm_manager_pending_activation_find (NMManager *self, - const char *path, - NMConnectionScope scope) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter; - - for (iter = priv->pending_activations; iter; iter = g_slist_next (iter)) { - PendingActivation *pending = iter->data; - - if (!strcmp (pending->connection_path, path) && (pending->scope == scope)) - return pending; - } - return NULL; -} - +/* + * TODO this function was created and named in the era of user settings, where + * we could get activation requests for a connection before we got the settings + * data of that connection. Now that user settings are gone, flatten or rename + * it. + */ static void check_pending_ready (NMManager *self, PendingActivation *pending) { @@ -2912,15 +2137,10 @@ check_pending_ready (NMManager *self, PendingActivation *pending) const char *path = NULL; GError *error = NULL; - if (!pending->have_connection || !pending->authorized) - return; - - /* Ok, we're authorized and the connection is available */ - - nm_manager_pending_activation_remove (self, pending); + /* Ok, we're authorized */ connection = nm_manager_get_connection_by_object_path (self, - pending->scope, + NM_CONNECTION_SCOPE_SYSTEM, pending->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -2936,8 +2156,8 @@ check_pending_ready (NMManager *self, PendingActivation *pending) TRUE, &error); if (!path) { - nm_log_warn (LOGD_CORE, "connection (%d) %s failed to activate: (%d) %s", - pending->scope, pending->connection_path, error->code, error->message); + nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s", + pending->connection_path, error->code, error->message); } else g_object_notify (G_OBJECT (pending->manager), NM_MANAGER_ACTIVE_CONNECTIONS); @@ -2946,38 +2166,15 @@ out: g_clear_error (&error); } -static void -connection_added_default_handler (NMManager *self, - NMConnection *connection, - NMConnectionScope scope) -{ - PendingActivation *pending; - - pending = nm_manager_pending_activation_find (self, - nm_connection_get_path (connection), - scope); - if (pending) { - pending->have_connection = TRUE; - check_pending_ready (self, pending); - } -} - static void activation_auth_done (PendingActivation *pending, GError *error) { if (error) { - nm_manager_pending_activation_remove (pending->manager, pending); pending_activation_destroy (pending, error, NULL); return; } else { pending->authorized = TRUE; - /* Now that we're authorized, if the connection hasn't shown up yet, - * start a timer and wait for it. - */ - if (!pending->have_connection && !pending->timeout_id) - pending->timeout_id = g_timeout_add_seconds (5, wait_for_connection_expired, pending); - check_pending_ready (pending->manager, pending); } } @@ -2991,21 +2188,18 @@ impl_manager_activate_connection (NMManager *self, DBusGMethodInvocation *context) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMConnectionScope scope = NM_CONNECTION_SCOPE_UNKNOWN; PendingActivation *pending; GError *error = NULL; - if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) - scope = NM_CONNECTION_SCOPE_USER; - else if (!strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) - scope = NM_CONNECTION_SCOPE_SYSTEM; - else { + // TODO user settings services are gone, so service_name is no longer + // meaningful. Remove the parameter and this check. + if (strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_INVALID_SERVICE, "Invalid settings service name"); dbus_g_method_return_error (context, error); - nm_log_warn (LOGD_CORE, "connection (%d) %s failed to activate: (%d) %s", - scope, connection_path, error->code, error->message); + nm_log_warn (LOGD_CORE, "connection %s:%s failed to activate: (%d) %s", + service_name, connection_path, error->code, error->message); g_error_free (error); return; } @@ -3017,16 +2211,11 @@ impl_manager_activate_connection (NMManager *self, priv->authority, context, device_path, - scope, connection_path, specific_object_path, activation_auth_done); - priv->pending_activations = g_slist_prepend (priv->pending_activations, pending); - if (nm_manager_get_connection_by_object_path (self, scope, connection_path)) - pending->have_connection = TRUE; - - pending_activation_check_authorized (pending, priv->dbus_mgr, priv->user_proxy); + pending_activation_check_authorized (pending, priv->dbus_mgr); } gboolean @@ -3077,37 +2266,6 @@ done: return success; } -static void -deactivate_user_auth_done_cb (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *ret_error = NULL; - NMAuthCallResult result; - - priv->auth_chains = g_slist_remove (priv->auth_chains, chain); - - result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS)); - ret_error = deactivate_disconnect_check_error (error, result, "Deactivate"); - if (!ret_error) { - /* Everything authorized, deactivate the connection */ - if (nm_manager_deactivate_connection (self, - nm_auth_chain_get_data (chain, "path"), - NM_DEVICE_STATE_REASON_USER_REQUESTED, - &ret_error)) - dbus_g_method_return (context); - } - - if (ret_error) - dbus_g_method_return_error (context, ret_error); - g_clear_error (&ret_error); - - nm_auth_chain_unref (chain); -} - static void deactivate_net_auth_done_cb (NMAuthChain *chain, GError *error, @@ -3119,7 +2277,6 @@ deactivate_net_auth_done_cb (NMAuthChain *chain, GError *ret_error = NULL; NMAuthCallResult result; const char *active_path; - NMConnectionScope scope; priv->auth_chains = g_slist_remove (priv->auth_chains, chain); @@ -3131,32 +2288,15 @@ deactivate_net_auth_done_cb (NMAuthChain *chain, goto done; } - /* If it's a system connection, we're done */ active_path = nm_auth_chain_get_data (chain, "path"); - scope = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "scope")); - if (scope == NM_CONNECTION_SCOPE_USER) { - NMAuthChain *user_chain; - - /* It's a user connection, so we need to ensure the caller is - * authorized to manipulate user connections. - */ - user_chain = nm_auth_chain_new (priv->authority, context, NULL, deactivate_user_auth_done_cb, self); - g_assert (user_chain); - priv->auth_chains = g_slist_append (priv->auth_chains, user_chain); - - nm_auth_chain_set_data (user_chain, "path", g_strdup (active_path), g_free); - nm_auth_chain_set_data (user_chain, "scope", GUINT_TO_POINTER (scope), NULL); - nm_auth_chain_add_call (user_chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, TRUE); - } else { - if (!nm_manager_deactivate_connection (self, - active_path, - NM_DEVICE_STATE_REASON_USER_REQUESTED, - &ret_error)) { - dbus_g_method_return_error (context, ret_error); - g_clear_error (&ret_error); - } else - dbus_g_method_return (context); - } + if (!nm_manager_deactivate_connection (self, + active_path, + NM_DEVICE_STATE_REASON_USER_REQUESTED, + &ret_error)) { + dbus_g_method_return_error (context, ret_error); + g_clear_error (&ret_error); + } else + dbus_g_method_return (context); done: nm_auth_chain_unref (chain); @@ -3173,7 +2313,6 @@ impl_manager_deactivate_connection (NMManager *self, GSList *iter; NMAuthChain *chain; gulong sender_uid = G_MAXULONG; - NMConnectionScope scope; const char *error_desc = NULL; /* Check for device connections first */ @@ -3207,13 +2346,10 @@ impl_manager_deactivate_connection (NMManager *self, /* Need to check the caller's permissions and stuff before we can * deactivate the connection. */ - scope = nm_connection_get_scope (connection); - if (!check_user_authorized (priv->dbus_mgr, - priv->user_proxy, - context, - scope, - &sender_uid, - &error_desc)) { + if (!nm_auth_get_caller_uid (context, + priv->dbus_mgr, + &sender_uid, + &error_desc)) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, error_desc); @@ -3242,7 +2378,6 @@ impl_manager_deactivate_connection (NMManager *self, priv->auth_chains = g_slist_append (priv->auth_chains, chain); nm_auth_chain_set_data (chain, "path", g_strdup (active_path), g_free); - nm_auth_chain_set_data (chain, "scope", GUINT_TO_POINTER (scope), NULL); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE); } @@ -3561,61 +2696,9 @@ impl_manager_enable (NMManager *self, /* Permissions */ -static void -user_proxy_permissions_changed_done (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gboolean authorized = FALSE; - - priv->auth_chains = g_slist_remove (priv->auth_chains, chain); - - if (error) { - nm_log_warn (LOGD_USER_SET, "User connections unavailable: (%d) %s", - error->code, error->message ? error->message : "(unknown)"); - } else - authorized = user_settings_authorized (self, chain); - - if (authorized) { - /* User connections are authorized */ - if (!priv->user_proxy) - user_proxy_init (self); - } else - user_proxy_cleanup (self, TRUE); - - nm_auth_chain_unref (chain); -} - static void pk_authority_changed_cb (GObject *object, gpointer user_data) { - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMAuthChain *chain; - - /* If the user settings service wasn't previously authorized, we wouldn't - * care about it. But it might be authorized now, so lets check. - */ - if (!priv->user_proxy) - user_proxy_init (self); - else { - /* Otherwise the user settings permissions could have changed so we - * need to recheck them. - */ - chain = nm_auth_chain_new (priv->authority, - NULL, - priv->user_proxy, - user_proxy_permissions_changed_done, - self); - priv->auth_chains = g_slist_prepend (priv->auth_chains, chain); - - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE); - } - /* Let clients know they should re-check their authorization */ g_signal_emit (NM_MANAGER (user_data), signals[CHECK_PERMISSIONS], 0); } @@ -3738,15 +2821,6 @@ impl_manager_set_logging (NMManager *manager, /* Connections */ -gboolean -nm_manager_auto_user_connections_allowed (NMManager *self) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - - return priv->user_net_perm == NM_AUTH_CALL_RESULT_YES - && priv->user_con_perm == NM_AUTH_CALL_RESULT_YES; -} - static int connection_sort (gconstpointer pa, gconstpointer pb) { @@ -3794,9 +2868,7 @@ nm_manager_get_connections (NMManager *manager, g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); priv = NM_MANAGER_GET_PRIVATE (manager); - if (scope == NM_CONNECTION_SCOPE_USER) - g_hash_table_foreach (priv->user_connections, connections_to_slist, &list); - else if (scope == NM_CONNECTION_SCOPE_SYSTEM) + if (scope == NM_CONNECTION_SCOPE_SYSTEM) g_hash_table_foreach (priv->system_connections, connections_to_slist, &list); else nm_log_err (LOGD_CORE, "unknown NMConnectionScope %d", scope); @@ -3815,9 +2887,7 @@ nm_manager_get_connection_by_object_path (NMManager *manager, g_return_val_if_fail (path != NULL, NULL); priv = NM_MANAGER_GET_PRIVATE (manager); - if (scope == NM_CONNECTION_SCOPE_USER) - connection = (NMConnection *) g_hash_table_lookup (priv->user_connections, path); - else if (scope == NM_CONNECTION_SCOPE_SYSTEM) + if (scope == NM_CONNECTION_SCOPE_SYSTEM) connection = (NMConnection *) g_hash_table_lookup (priv->system_connections, path); else nm_log_err (LOGD_CORE, "unknown NMConnectionScope %d", scope); @@ -3878,13 +2948,6 @@ nm_manager_start (NMManager *self) system_hostname_changed_cb (priv->sys_settings, NULL, self); system_query_connections (self); - /* Get user connections if the user settings service is around, otherwise - * they will be queried when the user settings service shows up on the - * bus in nm_manager_name_owner_changed(). - */ - if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, NM_DBUS_SERVICE_USER_SETTINGS)) - user_proxy_init (self); - nm_udev_manager_query_devices (priv->udev_mgr); bluez_manager_resync_devices (self); } @@ -4001,11 +3064,6 @@ nm_manager_get (const char *config_file, NM_DBUS_PATH, G_OBJECT (singleton)); - g_signal_connect (priv->dbus_mgr, - "name-owner-changed", - G_CALLBACK (nm_manager_name_owner_changed), - singleton); - priv->udev_mgr = nm_udev_manager_new (); g_signal_connect (priv->udev_mgr, "device-added", @@ -4040,7 +3098,6 @@ dispose (GObject *object) { NMManager *manager = NM_MANAGER (object); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - GSList *iter; if (priv->disposed) { G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); @@ -4048,11 +3105,6 @@ dispose (GObject *object) } priv->disposed = TRUE; - for (iter = priv->pending_activations; iter; iter = g_slist_next (iter)) - pending_activation_destroy ((PendingActivation *) iter->data, NULL, NULL); - g_slist_free (priv->pending_activations); - priv->pending_activations = NULL; - g_slist_foreach (priv->auth_chains, (GFunc) nm_auth_chain_unref, NULL); g_slist_free (priv->auth_chains); g_object_unref (priv->authority); @@ -4068,10 +3120,6 @@ dispose (GObject *object) FALSE); } - user_proxy_cleanup (manager, FALSE); - g_hash_table_destroy (priv->user_connections); - priv->user_connections = NULL; - g_hash_table_foreach (priv->system_connections, emit_removed, manager); g_hash_table_remove_all (priv->system_connections); g_hash_table_destroy (priv->system_connections); @@ -4232,11 +3280,6 @@ nm_manager_init (NMManager *manager) priv->dbus_mgr = nm_dbus_manager_get (); - priv->user_connections = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - priv->system_connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, @@ -4314,8 +3357,6 @@ nm_manager_class_init (NMManagerClass *manager_class) g_type_class_add_private (manager_class, sizeof (NMManagerPrivate)); /* virtual methods */ - manager_class->connection_added = connection_added_default_handler; - object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; diff --git a/src/nm-manager.h b/src/nm-manager.h index 889938d97..0f4d72f2f 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -111,8 +111,6 @@ NMState nm_manager_get_state (NMManager *manager); GSList *nm_manager_get_connections (NMManager *manager, NMConnectionScope scope); -gboolean nm_manager_auto_user_connections_allowed (NMManager *manager); - NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager, NMConnectionScope scope, const char *path); diff --git a/src/nm-policy.c b/src/nm-policy.c index ddf48ad87..ce00d032b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -731,10 +731,7 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - /* System connections first, then user connections */ connections = nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_SYSTEM); - if (nm_manager_auto_user_connections_allowed (policy->manager)) - connections = g_slist_concat (connections, nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_USER)); /* Remove connections that are in the invalid list. */ iter = connections; @@ -826,7 +823,6 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) /* Clear the invalid flag on all connections so they'll get retried on wakeup */ if (sleeping || !enabled) { connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); - connections = g_slist_concat (connections, nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_USER)); for (iter = connections; iter; iter = g_slist_next (iter)) g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL); g_slist_free (connections); From 5fda5283b9145994e272ce818fd7c4096a81d5fb Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Fri, 16 Jul 2010 17:45:48 -0400 Subject: [PATCH 002/264] core: remove internal API refs. to user settings Remove all references to connection scope and user-settings services from the various internal APIs of the daemon. The external DBus API remains unchanged, albeit in stub form for scope stuff. --- src/NetworkManagerUtils.c | 16 ++---- src/nm-activation-request.c | 3 +- src/nm-active-connection.c | 22 ------- src/nm-active-connection.h | 2 - src/nm-device.c | 4 +- src/nm-manager-auth.c | 63 --------------------- src/nm-manager-auth.h | 5 -- src/nm-manager.c | 51 ++++++----------- src/nm-manager.h | 14 ++--- src/nm-policy.c | 8 +-- src/system-settings/nm-sysconfig-settings.c | 1 + src/vpn-manager/nm-vpn-connection.c | 3 +- 12 files changed, 36 insertions(+), 156 deletions(-) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 10240960b..c91daffbe 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -406,16 +406,12 @@ nm_utils_call_dispatcher (const char *action, connection_props = value_hash_create (); - /* Service name */ - if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_USER) { - value_hash_add_str (connection_props, - NMD_CONNECTION_PROPS_SERVICE_NAME, - NM_DBUS_SERVICE_USER_SETTINGS); - } else if (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) { - value_hash_add_str (connection_props, - NMD_CONNECTION_PROPS_SERVICE_NAME, - NM_DBUS_SERVICE_SYSTEM_SETTINGS); - } + /* Backwards compatibility for the days of user settings services: + * Claim that this connection is from the system settings service. + */ + value_hash_add_str (connection_props, + NMD_CONNECTION_PROPS_SERVICE_NAME, + NM_DBUS_SERVICE_SYSTEM_SETTINGS); /* path */ value_hash_add_object_path (connection_props, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 2529e77f6..e13d95fee 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -257,7 +257,8 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_SERVICE_NAME: - nm_active_connection_scope_to_value (priv->connection, value); + /* TODO Remove this propery. */ + g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); break; case PROP_CONNECTION: g_value_set_boxed (value, nm_connection_get_path (priv->connection)); diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 4207e1450..fc8eb6490 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -39,25 +39,3 @@ nm_active_connection_install_type_info (GObjectClass *klass) &dbus_glib_nm_active_connection_object_info); } -void -nm_active_connection_scope_to_value (NMConnection *connection, GValue *value) -{ - if (!connection) { - g_value_set_string (value, ""); - return; - } - - switch (nm_connection_get_scope (connection)) { - case NM_CONNECTION_SCOPE_SYSTEM: - g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); - break; - case NM_CONNECTION_SCOPE_USER: - g_value_set_string (value, NM_DBUS_SERVICE_USER_SETTINGS); - break; - default: - nm_log_err (LOGD_CORE, "unknown connection scope!"); - break; - } -} - - diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 6a463cb25..55d27e739 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -37,6 +37,4 @@ char *nm_active_connection_get_next_object_path (void); void nm_active_connection_install_type_info (GObjectClass *klass); -void nm_active_connection_scope_to_value (NMConnection *connection, GValue *value); - #endif /* NM_ACTIVE_CONNECTION_H */ diff --git a/src/nm-device.c b/src/nm-device.c index 640ef62e3..728ba154f 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -3295,10 +3295,8 @@ dispose (GObject *object) NMSettingIP4Config *s_ip4; const char *method = NULL; - /* Only system connections can be left up */ connection = nm_act_request_get_connection (priv->act_request); - if ( connection - && (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM)) { + if (connection) { /* Only static or DHCP IPv4 connections can be left up. * All IPv6 connections can be left up, so we don't have diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index 5bd480f38..7c33d4669 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -337,66 +337,3 @@ out: g_free (sender); return success; } - -gboolean -nm_auth_uid_authorized (gulong uid, - NMDBusManager *dbus_mgr, - DBusGProxy *user_proxy, - const char **out_error_desc) -{ - DBusConnection *connection; - DBusError dbus_error; - char *service_owner = NULL; - const char *service_name; - gulong service_uid = G_MAXULONG; - - g_return_val_if_fail (dbus_mgr != NULL, FALSE); - g_return_val_if_fail (out_error_desc != NULL, FALSE); - - /* Ensure the request to activate the user connection came from the - * same session as the user settings service. FIXME: use ConsoleKit - * too. - */ - - if (!user_proxy) { - *out_error_desc = "No user settings service available"; - return FALSE; - } - - service_name = dbus_g_proxy_get_bus_name (user_proxy); - if (!service_name) { - *out_error_desc = "Could not determine user settings service name"; - return FALSE; - } - - connection = nm_dbus_manager_get_dbus_connection (dbus_mgr); - if (!connection) { - *out_error_desc = "Could not get the D-Bus system bus"; - return FALSE; - } - - service_owner = nm_dbus_manager_get_name_owner (dbus_mgr, service_name, NULL); - if (!service_owner) { - *out_error_desc = "Could not determine D-Bus owner of the user settings service"; - return FALSE; - } - - dbus_error_init (&dbus_error); - service_uid = dbus_bus_get_unix_user (connection, service_owner, &dbus_error); - g_free (service_owner); - - if (dbus_error_is_set (&dbus_error)) { - dbus_error_free (&dbus_error); - *out_error_desc = "Could not determine the Unix UID of the sender of the request"; - return FALSE; - } - - /* And finally, the actual UID check */ - if (uid != service_uid) { - *out_error_desc = "Requestor UID does not match the UID of the user settings service"; - return FALSE; - } - - return TRUE; -} - diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index dab32b0f5..6eedb2836 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -80,10 +80,5 @@ gboolean nm_auth_get_caller_uid (DBusGMethodInvocation *context, gulong *out_uid, const char **out_error_desc); -gboolean nm_auth_uid_authorized (gulong uid, - NMDBusManager *dbus_mgr, - DBusGProxy *user_proxy, - const char **out_error_desc); - #endif /* NM_MANAGER_AUTH_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index d1d42af0c..e00a0ccad 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -572,9 +572,7 @@ emit_removed (gpointer key, gpointer value, gpointer user_data) NMManager *manager = NM_MANAGER (user_data); NMConnection *connection = NM_CONNECTION (value); - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, - connection, - nm_connection_get_scope (connection)); + g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, connection); } static PendingActivation * @@ -755,9 +753,7 @@ remove_connection (NMManager *manager, */ g_object_ref (connection); g_hash_table_remove (hash, nm_connection_get_path (connection)); - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, - connection, - nm_connection_get_scope (connection)); + g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, connection); g_object_unref (connection); bluez_manager_resync_devices (manager); @@ -797,8 +793,7 @@ system_connection_updated_cb (NMSettingsConnectionInterface *connection, return; } - g_signal_emit (manager, signals[CONNECTION_UPDATED], 0, - existing, NM_CONNECTION_SCOPE_SYSTEM); + g_signal_emit (manager, signals[CONNECTION_UPDATED], 0, existing); bluez_manager_resync_devices (manager); } @@ -1056,7 +1051,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ - connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); + connections = nm_manager_get_connections (manager); for (iter = connections; iter && !done; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); @@ -1515,7 +1510,7 @@ bluez_manager_find_connection (NMManager *manager, NMConnection *found = NULL; GSList *connections, *l; - connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); + connections = nm_manager_get_connections (manager); for (l = connections; l != NULL; l = l->next) { NMConnection *candidate = NM_CONNECTION (l->data); @@ -1967,8 +1962,6 @@ provider_get_secrets (NMSecretsProviderInterface *provider, } /* Build up the new secrets request */ - g_assert (nm_connection_get_scope (connection) == - NM_CONNECTION_SCOPE_SYSTEM); info = system_get_secrets (self, provider, connection, setting_name, request_new, caller_id, hint1, hint2); @@ -2139,9 +2132,7 @@ check_pending_ready (NMManager *self, PendingActivation *pending) /* Ok, we're authorized */ - connection = nm_manager_get_connection_by_object_path (self, - NM_CONNECTION_SCOPE_SYSTEM, - pending->connection_path); + connection = nm_manager_get_connection_by_object_path (self, pending->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, @@ -2859,8 +2850,7 @@ connections_to_slist (gpointer key, gpointer value, gpointer user_data) * unref the connections in the list and destroy the list. */ GSList * -nm_manager_get_connections (NMManager *manager, - NMConnectionScope scope) +nm_manager_get_connections (NMManager *manager) { NMManagerPrivate *priv; GSList *list = NULL; @@ -2868,16 +2858,12 @@ nm_manager_get_connections (NMManager *manager, g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); priv = NM_MANAGER_GET_PRIVATE (manager); - if (scope == NM_CONNECTION_SCOPE_SYSTEM) - g_hash_table_foreach (priv->system_connections, connections_to_slist, &list); - else - nm_log_err (LOGD_CORE, "unknown NMConnectionScope %d", scope); + g_hash_table_foreach (priv->system_connections, connections_to_slist, &list); return list; } NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager, - NMConnectionScope scope, const char *path) { NMManagerPrivate *priv; @@ -2887,10 +2873,7 @@ nm_manager_get_connection_by_object_path (NMManager *manager, g_return_val_if_fail (path != NULL, NULL); priv = NM_MANAGER_GET_PRIVATE (manager); - if (scope == NM_CONNECTION_SCOPE_SYSTEM) - connection = (NMConnection *) g_hash_table_lookup (priv->system_connections, path); - else - nm_log_err (LOGD_CORE, "unknown NMConnectionScope %d", scope); + connection = (NMConnection *) g_hash_table_lookup (priv->system_connections, path); return connection; } @@ -3474,8 +3457,8 @@ nm_manager_class_init (NMManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMManagerClass, connections_added), NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); signals[CONNECTION_ADDED] = g_signal_new ("connection-added", @@ -3483,8 +3466,8 @@ nm_manager_class_init (NMManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMManagerClass, connection_added), NULL, NULL, - _nm_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_UPDATED] = g_signal_new ("connection-updated", @@ -3492,8 +3475,8 @@ nm_manager_class_init (NMManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMManagerClass, connection_updated), NULL, NULL, - _nm_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_REMOVED] = g_signal_new ("connection-removed", @@ -3501,8 +3484,8 @@ nm_manager_class_init (NMManagerClass *manager_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMManagerClass, connection_removed), NULL, NULL, - _nm_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_UINT); + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CHECK_PERMISSIONS] = g_signal_new ("check-permissions", diff --git a/src/nm-manager.h b/src/nm-manager.h index 0f4d72f2f..6bf12bd1a 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -60,19 +60,16 @@ typedef struct { void (*state_changed) (NMManager *manager, guint state); void (*properties_changed) (NMManager *manager, GHashTable *properties); - void (*connections_added) (NMManager *manager, NMConnectionScope scope); + void (*connections_added) (NMManager *manager); void (*connection_added) (NMManager *manager, - NMConnection *connection, - NMConnectionScope scope); + NMConnection *connection); void (*connection_updated) (NMManager *manager, - NMConnection *connection, - NMConnectionScope scope); + NMConnection *connection); void (*connection_removed) (NMManager *manager, - NMConnection *connection, - NMConnectionScope scope); + NMConnection *connection); } NMManagerClass; GType nm_manager_get_type (void); @@ -109,10 +106,9 @@ NMState nm_manager_get_state (NMManager *manager); /* Connections */ -GSList *nm_manager_get_connections (NMManager *manager, NMConnectionScope scope); +GSList *nm_manager_get_connections (NMManager *manager); NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager, - NMConnectionScope scope, const char *path); GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager, diff --git a/src/nm-policy.c b/src/nm-policy.c index ce00d032b..3944448fd 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -731,7 +731,7 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - connections = nm_manager_get_connections (policy->manager, NM_CONNECTION_SCOPE_SYSTEM); + connections = nm_manager_get_connections (policy->manager); /* Remove connections that are in the invalid list. */ iter = connections; @@ -822,7 +822,7 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) /* Clear the invalid flag on all connections so they'll get retried on wakeup */ if (sleeping || !enabled) { - connections = nm_manager_get_connections (manager, NM_CONNECTION_SCOPE_SYSTEM); + connections = nm_manager_get_connections (manager); for (iter = connections; iter; iter = g_slist_next (iter)) g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL); g_slist_free (connections); @@ -1036,7 +1036,6 @@ schedule_activate_all (NMPolicy *policy) static void connections_added (NMManager *manager, - NMConnectionScope scope, gpointer user_data) { schedule_activate_all ((NMPolicy *) user_data); @@ -1045,7 +1044,6 @@ connections_added (NMManager *manager, static void connection_added (NMManager *manager, NMConnection *connection, - NMConnectionScope scope, gpointer user_data) { schedule_activate_all ((NMPolicy *) user_data); @@ -1054,7 +1052,6 @@ connection_added (NMManager *manager, static void connection_updated (NMManager *manager, NMConnection *connection, - NMConnectionScope scope, gpointer user_data) { /* Clear the invalid tag on the connection if it got updated. */ @@ -1066,7 +1063,6 @@ connection_updated (NMManager *manager, static void connection_removed (NMManager *manager, NMConnection *connection, - NMConnectionScope scope, gpointer user_data) { NMSettingConnection *s_con; diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 4bcfb04bc..aadaab568 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -1312,6 +1312,7 @@ nm_sysconfig_settings_new (const char *config_file, NMSysconfigSettings *self; NMSysconfigSettingsPrivate *priv; + /* TODO remove the scope parameter. */ self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NM_SETTINGS_SERVICE_BUS, bus, NM_SETTINGS_SERVICE_SCOPE, NM_CONNECTION_SCOPE_SYSTEM, diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 16fa64d00..0d618aae8 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1045,7 +1045,8 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_SERVICE_NAME: - nm_active_connection_scope_to_value (priv->connection, value); + /* TODO remove this property */ + g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); break; case PROP_CONNECTION: g_value_set_boxed (value, nm_connection_get_path (priv->connection)); From 227f5664b2d5a0587842bf3dd7275dbfc5fcf3a6 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Fri, 16 Jul 2010 20:37:27 -0400 Subject: [PATCH 003/264] nm-tool: remove user settings support --- test/nm-tool.c | 80 +++++++++++++++++--------------------------------- 1 file changed, 27 insertions(+), 53 deletions(-) diff --git a/test/nm-tool.c b/test/nm-tool.c index b1178eaf0..6682558ff 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -51,8 +51,7 @@ #define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT)) #define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) -static GHashTable *user_connections = NULL; -static GHashTable *system_connections = NULL; +static GHashTable *connections = NULL; static gboolean get_nm_state (NMClient *client) @@ -260,7 +259,6 @@ get_dev_state_string (NMDeviceState state) static NMConnection * get_connection_for_active (NMActiveConnection *active) { - NMConnectionScope scope; const char *path; g_return_val_if_fail (active != NULL, NULL); @@ -268,14 +266,7 @@ get_connection_for_active (NMActiveConnection *active) path = nm_active_connection_get_connection (active); g_return_val_if_fail (path != NULL, NULL); - scope = nm_active_connection_get_scope (active); - if (scope == NM_CONNECTION_SCOPE_USER) - return (NMConnection *) g_hash_table_lookup (user_connections, path); - else if (scope == NM_CONNECTION_SCOPE_SYSTEM) - return (NMConnection *) g_hash_table_lookup (system_connections, path); - - g_warning ("error: unknown connection scope"); - return NULL; + return (NMConnection *) g_hash_table_lookup (connections, path); } struct cb_info { @@ -566,12 +557,10 @@ detail_vpn (gpointer data, gpointer user_data) static void get_one_connection (DBusGConnection *bus, const char *path, - NMConnectionScope scope, GHashTable *table) { DBusGProxy *proxy; NMConnection *connection = NULL; - const char *service; GError *error = NULL; GHashTable *settings = NULL; @@ -579,10 +568,8 @@ get_one_connection (DBusGConnection *bus, g_return_if_fail (path != NULL); g_return_if_fail (table != NULL); - service = (scope == NM_CONNECTION_SCOPE_SYSTEM) ? - NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS; - - proxy = dbus_g_proxy_new_for_name (bus, service, path, NM_DBUS_IFACE_SETTINGS_CONNECTION); + proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE_SYSTEM_SETTINGS, + path, NM_DBUS_IFACE_SETTINGS_CONNECTION); if (!proxy) return; @@ -605,7 +592,6 @@ get_one_connection (DBusGConnection *bus, goto out; } - nm_connection_set_scope (connection, scope); nm_connection_set_path (connection, path); g_hash_table_insert (table, g_strdup (path), g_object_ref (connection)); @@ -616,27 +602,29 @@ out: g_object_unref (proxy); } -static void -get_connections_for_service (DBusGConnection *bus, - NMConnectionScope scope, - GHashTable *table) +static gboolean +get_all_connections (void) { GError *error = NULL; + DBusGConnection *bus; DBusGProxy *proxy; GPtrArray *paths = NULL; int i; - const char *service; + gboolean sucess = FALSE; - service = (scope == NM_CONNECTION_SCOPE_SYSTEM) ? - NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS; + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (error || !bus) { + g_warning ("error: could not connect to dbus"); + goto out; + } proxy = dbus_g_proxy_new_for_name (bus, - service, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, NM_DBUS_PATH_SETTINGS, NM_DBUS_IFACE_SETTINGS); if (!proxy) { - g_warning ("error: failed to create DBus proxy for %s", service); - return; + g_warning ("error: failed to create DBus proxy for settings service"); + goto out; } if (!dbus_g_proxy_call (proxy, "ListConnections", &error, @@ -648,33 +636,20 @@ get_connections_for_service (DBusGConnection *bus, goto out; } + connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + for (i = 0; paths && (i < paths->len); i++) - get_one_connection (bus, g_ptr_array_index (paths, i), scope, table); + get_one_connection (bus, g_ptr_array_index (paths, i), connections); + + sucess = TRUE; out: - g_object_unref (proxy); -} + if (bus) + dbus_g_connection_unref (bus); + if (proxy) + g_object_unref (proxy); -static gboolean -get_all_connections (void) -{ - DBusGConnection *bus; - GError *error = NULL; - - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (error || !bus) { - g_warning ("error: could not connect to dbus"); - return FALSE; - } - - user_connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - get_connections_for_service (bus, NM_CONNECTION_SCOPE_USER, user_connections); - - system_connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - get_connections_for_service (bus, NM_CONNECTION_SCOPE_SYSTEM, system_connections); - - dbus_g_connection_unref (bus); - return TRUE; + return sucess; } int @@ -713,8 +688,7 @@ main (int argc, char *argv[]) g_ptr_array_foreach ((GPtrArray *) info.active, detail_vpn, &info); g_object_unref (client); - g_hash_table_unref (user_connections); - g_hash_table_unref (system_connections); + g_hash_table_unref (connections); return 0; } From c17d0b0980343dd1765d6379afda313f60e4afa8 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Sat, 17 Jul 2010 18:29:08 -0400 Subject: [PATCH 004/264] nmcli: remove user settings support Remove all support for user settings services from nmcli. Update its manpage to reflect this. Manpage edits also anticipate changes to be made in regards to how secrets are managed. --- cli/src/connections.c | 185 ++++++++++++------------------------------ cli/src/nmcli.c | 8 -- cli/src/nmcli.h | 5 -- man/nmcli.1.in | 30 +++---- 4 files changed, 65 insertions(+), 163 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index 9a2075339..e86a88a44 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -60,30 +60,28 @@ static NmcOutputField nmc_fields_con_status[] = { {"NAME", N_("NAME"), 25, NULL, 0}, /* 0 */ {"UUID", N_("UUID"), 38, NULL, 0}, /* 1 */ {"DEVICES", N_("DEVICES"), 10, NULL, 0}, /* 2 */ - {"SCOPE", N_("SCOPE"), 8, NULL, 0}, /* 3 */ - {"DEFAULT", N_("DEFAULT"), 8, NULL, 0}, /* 4 */ - {"DBUS-SERVICE", N_("DBUS-SERVICE"), 45, NULL, 0}, /* 5 */ - {"SPEC-OBJECT", N_("SPEC-OBJECT"), 10, NULL, 0}, /* 6 */ - {"VPN", N_("VPN"), 5, NULL, 0}, /* 7 */ + {"DEFAULT", N_("DEFAULT"), 8, NULL, 0}, /* 3 */ + {"DBUS-SERVICE", N_("DBUS-SERVICE"), 45, NULL, 0}, /* 4 */ + {"SPEC-OBJECT", N_("SPEC-OBJECT"), 10, NULL, 0}, /* 5 */ + {"VPN", N_("VPN"), 5, NULL, 0}, /* 6 */ {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_CON_STATUS_ALL "NAME,UUID,DEVICES,SCOPE,DEFAULT,VPN,DBUS-SERVICE,SPEC-OBJECT" -#define NMC_FIELDS_CON_STATUS_COMMON "NAME,UUID,DEVICES,SCOPE,DEFAULT,VPN" +#define NMC_FIELDS_CON_STATUS_ALL "NAME,UUID,DEVICES,DEFAULT,VPN,DBUS-SERVICE,SPEC-OBJECT" +#define NMC_FIELDS_CON_STATUS_COMMON "NAME,UUID,DEVICES,DEFAULT,VPN" /* Available fields for 'con list' */ static NmcOutputField nmc_fields_con_list[] = { {"NAME", N_("NAME"), 25, NULL, 0}, /* 0 */ {"UUID", N_("UUID"), 38, NULL, 0}, /* 1 */ {"TYPE", N_("TYPE"), 17, NULL, 0}, /* 2 */ - {"SCOPE", N_("SCOPE"), 8, NULL, 0}, /* 3 */ - {"TIMESTAMP", N_("TIMESTAMP"), 12, NULL, 0}, /* 4 */ - {"TIMESTAMP-REAL", N_("TIMESTAMP-REAL"), 34, NULL, 0}, /* 5 */ - {"AUTOCONNECT", N_("AUTOCONNECT"), 13, NULL, 0}, /* 6 */ - {"READONLY", N_("READONLY"), 10, NULL, 0}, /* 7 */ + {"TIMESTAMP", N_("TIMESTAMP"), 12, NULL, 0}, /* 3 */ + {"TIMESTAMP-REAL", N_("TIMESTAMP-REAL"), 34, NULL, 0}, /* 4 */ + {"AUTOCONNECT", N_("AUTOCONNECT"), 13, NULL, 0}, /* 5 */ + {"READONLY", N_("READONLY"), 10, NULL, 0}, /* 6 */ {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_CON_LIST_ALL "NAME,UUID,TYPE,SCOPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY" -#define NMC_FIELDS_CON_LIST_COMMON "NAME,UUID,TYPE,SCOPE,TIMESTAMP-REAL" +#define NMC_FIELDS_CON_LIST_ALL "NAME,UUID,TYPE,TIMESTAMP,TIMESTAMP-REAL,AUTOCONNECT,READONLY" +#define NMC_FIELDS_CON_LIST_COMMON "NAME,UUID,TYPE,TIMESTAMP-REAL" /* Helper macro to define fields */ @@ -157,7 +155,7 @@ usage (void) fprintf (stderr, _("Usage: nmcli con { COMMAND | help }\n" " COMMAND := { list | status | up | down }\n\n" - " list [id | uuid | system | user]\n" + " list [id | uuid ]\n" " status\n" " up id | uuid [iface ] [ap ] [--nowait] [--timeout ]\n" " down id | uuid \n")); @@ -379,11 +377,10 @@ show_connection (NMConnection *data, gpointer user_data) nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con); nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con); nmc->allowed_fields[2].value = nm_setting_connection_get_connection_type (s_con); - nmc->allowed_fields[3].value = nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM ? _("system") : _("user"); - nmc->allowed_fields[4].value = timestamp_str; - nmc->allowed_fields[5].value = timestamp ? timestamp_real_str : _("never"); - nmc->allowed_fields[6].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no"); - nmc->allowed_fields[7].value = nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no"); + nmc->allowed_fields[3].value = timestamp_str; + nmc->allowed_fields[4].value = timestamp ? timestamp_real_str : _("never"); + nmc->allowed_fields[5].value = nm_setting_connection_get_autoconnect (s_con) ? _("yes") : _("no"); + nmc->allowed_fields[6].value = nm_setting_connection_get_read_only (s_con) ? _("yes") : _("no"); nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ print_fields (nmc->print_fields, nmc->allowed_fields); @@ -454,22 +451,15 @@ do_connections_list (NmCli *nmc, int argc, char **argv) goto error; valid_param_specified = TRUE; - nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; - nmc->print_fields.header_name = _("System connections"); + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; print_fields (nmc->print_fields, nmc->allowed_fields); g_slist_foreach (nmc->system_connections, (GFunc) show_connection, nmc); - - nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; - nmc->print_fields.header_name = _("User connections"); - print_fields (nmc->print_fields, nmc->allowed_fields); - g_slist_foreach (nmc->user_connections, (GFunc) show_connection, nmc); } else { while (argc > 0) { if (strcmp (*argv, "id") == 0 || strcmp (*argv, "uuid") == 0) { const char *selector = *argv; - NMConnection *con1; - NMConnection *con2; + NMConnection *con; if (next_arg (&argc, &argv) != 0) { g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); @@ -480,42 +470,16 @@ do_connections_list (NmCli *nmc, int argc, char **argv) if (!nmc->mode_specified) nmc->multiline_output = TRUE; /* multiline mode is default for 'con list id|uuid' */ - con1 = find_connection (nmc->system_connections, selector, *argv); - con2 = find_connection (nmc->user_connections, selector, *argv); - if (con1) nmc_connection_detail (con1, nmc); - if (con2) nmc_connection_detail (con2, nmc); - if (!con1 && !con2) { + con = find_connection (nmc->system_connections, selector, *argv); + if (con) { + nmc_connection_detail (con, nmc); + } + else { g_string_printf (nmc->return_text, _("Error: %s - no such connection."), *argv); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; } break; } - else if (strcmp (*argv, "system") == 0) { - if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2)) - goto error; - if (error1) - goto error; - valid_param_specified = TRUE; - - nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; - nmc->print_fields.header_name = _("System connections"); - print_fields (nmc->print_fields, nmc->allowed_fields); - g_slist_foreach (nmc->system_connections, (GFunc) show_connection, nmc); - break; - } - else if (strcmp (*argv, "user") == 0) { - if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error2)) - goto error; - if (error1) - goto error; - valid_param_specified = TRUE; - - nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; - nmc->print_fields.header_name = _("User connections"); - print_fields (nmc->print_fields, nmc->allowed_fields); - g_slist_foreach (nmc->user_connections, (GFunc) show_connection, nmc); - break; - } else { fprintf (stderr, _("Unknown parameter: %s\n"), *argv); } @@ -549,29 +513,19 @@ error: return nmc->return_value; } -typedef struct { - NmCli *nmc; - NMConnectionScope scope; -} StatusInfo; - static void show_active_connection (gpointer data, gpointer user_data) { NMActiveConnection *active = NM_ACTIVE_CONNECTION (data); - StatusInfo *info = (StatusInfo *) user_data; + NmCli *nmc = (NmCli *) user_data; GSList *con_list, *iter; const char *active_path; - NMConnectionScope active_service_scope; NMSettingConnection *s_con; const GPtrArray *devices; GString *dev_str; int i; active_path = nm_active_connection_get_connection (active); - active_service_scope = nm_active_connection_get_scope (active); - - if (active_service_scope != info->scope) - return; /* Get devices of the active connection */ dev_str = g_string_new (NULL); @@ -585,7 +539,7 @@ show_active_connection (gpointer data, gpointer user_data) if (dev_str->len > 0) g_string_truncate (dev_str, dev_str->len - 1); /* Cut off last ',' */ - con_list = (info->scope == NM_CONNECTION_SCOPE_SYSTEM) ? info->nmc->system_connections : info->nmc->user_connections; + con_list = nmc->system_connections; for (iter = con_list; iter; iter = g_slist_next (iter)) { NMConnection *connection = (NMConnection *) iter->data; const char *con_path = nm_connection_get_path (connection); @@ -596,17 +550,16 @@ show_active_connection (gpointer data, gpointer user_data) g_assert (s_con != NULL); /* Obtain field values */ - info->nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con); - info->nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con); - info->nmc->allowed_fields[2].value = dev_str->str; - info->nmc->allowed_fields[3].value = active_service_scope == NM_CONNECTION_SCOPE_SYSTEM ? _("system") : _("user"); - info->nmc->allowed_fields[4].value = nm_active_connection_get_default (active) ? _("yes") : _("no"); - info->nmc->allowed_fields[5].value = nm_active_connection_get_service_name (active); - info->nmc->allowed_fields[6].value = nm_active_connection_get_specific_object (active); - info->nmc->allowed_fields[7].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no"); + nmc->allowed_fields[0].value = nm_setting_connection_get_id (s_con); + nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con); + nmc->allowed_fields[2].value = dev_str->str; + nmc->allowed_fields[3].value = nm_active_connection_get_default (active) ? _("yes") : _("no"); + nmc->allowed_fields[4].value = nm_active_connection_get_service_name (active); + nmc->allowed_fields[5].value = nm_active_connection_get_specific_object (active); + nmc->allowed_fields[6].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no"); - info->nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ - print_fields (info->nmc->print_fields, info->nmc->allowed_fields); + nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ + print_fields (nmc->print_fields, nmc->allowed_fields); break; } } @@ -619,7 +572,6 @@ do_connections_status (NmCli *nmc, int argc, char **argv) { const GPtrArray *active_cons; GError *error = NULL; - StatusInfo *info; char *fields_str; char *fields_all = NMC_FIELDS_CON_STATUS_ALL; char *fields_common = NMC_FIELDS_CON_STATUS_COMMON; @@ -659,15 +611,8 @@ do_connections_status (NmCli *nmc, int argc, char **argv) nmc->print_fields.header_name = _("Active connections"); print_fields (nmc->print_fields, nmc->allowed_fields); - if (active_cons && active_cons->len) { - info = g_malloc0 (sizeof (StatusInfo)); - info->nmc = nmc; - info->scope = NM_CONNECTION_SCOPE_SYSTEM; - g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) info); - info->scope = NM_CONNECTION_SCOPE_USER; - g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) info); - g_free (info); - } + if (active_cons && active_cons->len) + g_ptr_array_foreach ((GPtrArray *) active_cons, show_active_connection, (gpointer) nmc); error: @@ -1312,7 +1257,6 @@ do_connection_up (NmCli *nmc, int argc, char **argv) gboolean device_found; NMConnection *connection = NULL; NMSettingConnection *s_con; - gboolean is_system; const char *con_path; const char *con_type; const char *iface = NULL; @@ -1337,8 +1281,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv) goto error; } - if ((connection = find_connection (nmc->system_connections, selector, *argv)) == NULL) - connection = find_connection (nmc->user_connections, selector, *argv); + connection = find_connection (nmc->system_connections, selector, *argv); if (!connection) { g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), *argv); @@ -1398,7 +1341,6 @@ do_connection_up (NmCli *nmc, int argc, char **argv) if (!nmc->get_client (nmc)) goto error; - is_system = (nm_connection_get_scope (connection) == NM_CONNECTION_SCOPE_SYSTEM) ? TRUE : FALSE; con_path = nm_connection_get_path (connection); s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); @@ -1421,7 +1363,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv) nmc->nowait_flag = !wait; nmc->should_wait = TRUE; nm_client_activate_connection (nmc->client, - is_system ? NM_DBUS_SERVICE_SYSTEM_SETTINGS : NM_DBUS_SERVICE_USER_SETTINGS, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, con_path, device, spec_object, @@ -1442,7 +1384,6 @@ do_connection_down (NmCli *nmc, int argc, char **argv) const GPtrArray *active_cons; const char *con_path; const char *active_path; - NMConnectionScope active_service_scope, con_scope; gboolean id_specified = FALSE; gboolean wait = TRUE; int i; @@ -1458,8 +1399,7 @@ do_connection_down (NmCli *nmc, int argc, char **argv) goto error; } - if ((connection = find_connection (nmc->system_connections, selector, *argv)) == NULL) - connection = find_connection (nmc->user_connections, selector, *argv); + connection = find_connection (nmc->system_connections, selector, *argv); if (!connection) { g_string_printf (nmc->return_text, _("Error: Unknown connection: %s."), *argv); @@ -1489,20 +1429,21 @@ do_connection_down (NmCli *nmc, int argc, char **argv) goto error; con_path = nm_connection_get_path (connection); - con_scope = nm_connection_get_scope (connection); active_cons = nm_client_get_active_connections (nmc->client); for (i = 0; active_cons && (i < active_cons->len); i++) { NMActiveConnection *candidate = g_ptr_array_index (active_cons, i); active_path = nm_active_connection_get_connection (candidate); - active_service_scope = nm_active_connection_get_scope (candidate); - if (!strcmp (active_path, con_path) && active_service_scope == con_scope) { + if (!strcmp (active_path, con_path)) { active = candidate; break; } } + /* TODO: fail gracefully if we are using an old N-M with user settings + * support */ + if (active) nm_client_deactivate_connection (nmc->client, active); else { @@ -1520,23 +1461,9 @@ static void get_connections_cb (NMSettingsInterface *settings, gpointer user_data) { ArgsInfo *args = (ArgsInfo *) user_data; - static gboolean system_cb_called = FALSE; - static gboolean user_cb_called = FALSE; GError *error = NULL; - if (NM_IS_REMOTE_SETTINGS_SYSTEM (settings)) { - system_cb_called = TRUE; - args->nmc->system_connections = nm_settings_interface_list_connections (settings); - } - else { - user_cb_called = TRUE; - args->nmc->user_connections = nm_settings_interface_list_connections (settings); - } - - /* return and wait for the callback of the second settings is called */ - if ( (args->nmc->system_settings_running && !system_cb_called) - || (args->nmc->user_settings_running && !user_cb_called)) - return; + args->nmc->system_connections = nm_settings_interface_list_connections (settings); if (args->argc == 0) { if (!nmc_terse_option_check (args->nmc->print_output, args->nmc->required_fields, &error)) @@ -1612,31 +1539,19 @@ do_connections (NmCli *nmc, int argc, char **argv) } - /* get user settings */ - if (!(nmc->user_settings = nm_remote_settings_new (bus, NM_CONNECTION_SCOPE_USER))) { - g_string_printf (nmc->return_text, _("Error: Could not get user settings.")); - nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; - return nmc->return_value; - } - - /* find out whether setting services are running */ + /* find out whether settings service is running */ g_object_get (nmc->system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &nmc->system_settings_running, NULL); - g_object_get (nmc->user_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &nmc->user_settings_running, NULL); - if (!nmc->system_settings_running && !nmc->user_settings_running) { - g_string_printf (nmc->return_text, _("Error: Can't obtain connections: settings services are not running.")); + if (!nmc->system_settings_running) { + g_string_printf (nmc->return_text, _("Error: Can't obtain connections: settings service is not running.")); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; return nmc->return_value; } /* connect to signal "connections-read" - emitted when connections are fetched and ready */ - if (nmc->system_settings_running) - g_signal_connect (nmc->system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ, - G_CALLBACK (get_connections_cb), &args_info); + g_signal_connect (nmc->system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ, + G_CALLBACK (get_connections_cb), &args_info); - if (nmc->user_settings_running) - g_signal_connect (nmc->user_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ, - G_CALLBACK (get_connections_cb), &args_info); dbus_g_connection_unref (bus); diff --git a/cli/src/nmcli.c b/cli/src/nmcli.c index d416952c6..10b248a28 100644 --- a/cli/src/nmcli.c +++ b/cli/src/nmcli.c @@ -277,13 +277,8 @@ nmc_init (NmCli *nmc) nmc->timeout = 10; nmc->system_settings = NULL; - nmc->user_settings = NULL; - nmc->system_settings_running = FALSE; - nmc->user_settings_running = FALSE; - nmc->system_connections = NULL; - nmc->user_connections = NULL; nmc->should_wait = FALSE; nmc->nowait_flag = TRUE; @@ -304,10 +299,7 @@ nmc_cleanup (NmCli *nmc) g_string_free (nmc->return_text, TRUE); if (nmc->system_settings) g_object_unref (nmc->system_settings); - if (nmc->user_settings) g_object_unref (nmc->user_settings); - g_slist_free (nmc->system_connections); - g_slist_free (nmc->user_connections); g_free (nmc->required_fields); if (nmc->print_fields.indices) diff --git a/cli/src/nmcli.h b/cli/src/nmcli.h index 9788ef086..50318d5eb 100644 --- a/cli/src/nmcli.h +++ b/cli/src/nmcli.h @@ -93,13 +93,8 @@ typedef struct _NmCli { int timeout; /* Operation timeout */ NMRemoteSettingsSystem *system_settings; /* System settings */ - NMRemoteSettings *user_settings; /* User settings */ - gboolean system_settings_running; /* Is system settings service running? */ - gboolean user_settings_running; /* Is user settings service running? */ - GSList *system_connections; /* List of system connections */ - GSList *user_connections; /* List of user connections */ gboolean should_wait; /* Indication that nmcli should not end yet */ gboolean nowait_flag; /* '--nowait' option; used for passing to callbacks */ diff --git a/man/nmcli.1.in b/man/nmcli.1.in index 056b5bdd4..c0035eb1f 100644 --- a/man/nmcli.1.in +++ b/man/nmcli.1.in @@ -66,16 +66,18 @@ power users who prefer the command line. The use cases comprise: .IP \(em 4 Initscripts: ifup/ifdown can utilize NetworkManager via \fInmcli\fP instead of -having to manage connections itself and possible interfere with NetworkManager. +having to manage connections itself and possibly interfere with NetworkManager. .IP \(em 4 -Servers, headless machines: No GUI is available; then \fInmcli\fP is used to -talk directly to NetworkManager and control only system-wide connections. +Servers, headless machines: No GUI is available; then \fInmcli\fP can be used +to activate/deactivate connections. However, if a connection requires a secret +to activate and if that secret is not stored at the system level, \fInmcli\fP +will not be able to activate it; it is currently unable to supply the needed +secrets to NetworkManager. .IP \(em 4 -User sessions: For this case, \fInmcli\fP can talk to \fInm-applet\fP to find -user connections. It can still talk directly to NetworkManager for manipulating -these connections. As \fInmcli\fP doesn't have direct access to user -configuration data in GConf, \fInm-applet\fP handles that itself. That may, -for example, cause the applet to pop up keyring dialogs when secrets are needed. +User sessions: \fInmcli\fP can be used activate/deactivate connections from the +command line, but a full NetworkManager client (like \fInm-applet\fP) is used +for supplying secrets not stored at the system level. Keyring dialogs and +password prompts may appear if this happens. .SS \fIOPTIONS\fP .TP .B \-t, \-\-terse @@ -200,14 +202,12 @@ Get information about NetworkManager's connections. .sp .RS .TP -.B list [id | uuid | system | user] +.B list [id | uuid ] .br -List configured connections. Without a parameter, configured connection from -both system and user settings services are listed. \fIsystem\fP argument filters -only system-wide connections, \fIuser\fP prints user connections only. -In order to get connection details, \fIid\fP with connection's name or \fIuuid\fP -with connection's UUID shall be specified. -When no command is given to \fIcon\fP object, the default action is 'nmcli con list'. +List configured connections. Without a parameter, all connections +are listed. In order to get connection details, \fIid\fP with connection's +name or \fIuuid\fP with connection's UUID shall be specified. When no command +is given to the \fIcon\fP object, the default action is 'nmcli con list'. .br .nf \fBReference to D-Bus:\fP From 80f14217090df8cf2ff908e3ba11d31d1f8a877f Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Wed, 28 Jul 2010 00:49:35 -0400 Subject: [PATCH 005/264] nmcli: also remove DBUS-SERVICE field Missed this when removing user settings support. Connection service names also become irrelevant without user settings services. --- cli/src/connections.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index e86a88a44..f19e3135a 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -61,12 +61,11 @@ static NmcOutputField nmc_fields_con_status[] = { {"UUID", N_("UUID"), 38, NULL, 0}, /* 1 */ {"DEVICES", N_("DEVICES"), 10, NULL, 0}, /* 2 */ {"DEFAULT", N_("DEFAULT"), 8, NULL, 0}, /* 3 */ - {"DBUS-SERVICE", N_("DBUS-SERVICE"), 45, NULL, 0}, /* 4 */ - {"SPEC-OBJECT", N_("SPEC-OBJECT"), 10, NULL, 0}, /* 5 */ - {"VPN", N_("VPN"), 5, NULL, 0}, /* 6 */ + {"SPEC-OBJECT", N_("SPEC-OBJECT"), 10, NULL, 0}, /* 4 */ + {"VPN", N_("VPN"), 5, NULL, 0}, /* 5 */ {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_CON_STATUS_ALL "NAME,UUID,DEVICES,DEFAULT,VPN,DBUS-SERVICE,SPEC-OBJECT" +#define NMC_FIELDS_CON_STATUS_ALL "NAME,UUID,DEVICES,DEFAULT,VPN,SPEC-OBJECT" #define NMC_FIELDS_CON_STATUS_COMMON "NAME,UUID,DEVICES,DEFAULT,VPN" /* Available fields for 'con list' */ @@ -554,9 +553,8 @@ show_active_connection (gpointer data, gpointer user_data) nmc->allowed_fields[1].value = nm_setting_connection_get_uuid (s_con); nmc->allowed_fields[2].value = dev_str->str; nmc->allowed_fields[3].value = nm_active_connection_get_default (active) ? _("yes") : _("no"); - nmc->allowed_fields[4].value = nm_active_connection_get_service_name (active); - nmc->allowed_fields[5].value = nm_active_connection_get_specific_object (active); - nmc->allowed_fields[6].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no"); + nmc->allowed_fields[4].value = nm_active_connection_get_specific_object (active); + nmc->allowed_fields[5].value = NM_IS_VPN_CONNECTION (active) ? _("yes") : _("no"); nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ print_fields (nmc->print_fields, nmc->allowed_fields); From fa8c9304b5c04591758f9acaaf7d9a84c6df01d0 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Wed, 28 Jul 2010 02:07:53 -0400 Subject: [PATCH 006/264] libnm-*: remove user settings support Remove code related to "connection scope" and such. Later, we will also do lots of code flattening and simplification that's possible now that user settings are gone. --- include/NetworkManager.h | 1 - libnm-glib/libnm-glib.ver | 2 - libnm-glib/nm-active-connection.c | 90 --------------------- libnm-glib/nm-active-connection.h | 3 - libnm-glib/nm-exported-connection.c | 6 +- libnm-glib/nm-exported-connection.h | 2 +- libnm-glib/nm-remote-connection.c | 18 +---- libnm-glib/nm-remote-connection.h | 1 - libnm-glib/nm-remote-settings-system.c | 1 - libnm-glib/nm-remote-settings.c | 43 ++-------- libnm-glib/nm-remote-settings.h | 3 +- libnm-glib/nm-settings-service.c | 26 ------ libnm-glib/nm-settings-service.h | 1 - libnm-util/libnm-util.ver | 2 - libnm-util/nm-connection.c | 71 ---------------- libnm-util/nm-connection.h | 23 ------ src/system-settings/nm-sysconfig-settings.c | 2 - 17 files changed, 13 insertions(+), 282 deletions(-) diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 9df444f27..4001dae03 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -45,7 +45,6 @@ #define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config" -#define NM_DBUS_SERVICE_USER_SETTINGS "org.freedesktop.NetworkManagerUserSettings" #define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings" #define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings" #define NM_DBUS_IFACE_SETTINGS_SYSTEM "org.freedesktop.NetworkManagerSettings.System" diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 1596afaad..d956e6a26 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -20,8 +20,6 @@ global: nm_active_connection_get_default; nm_active_connection_get_default6; nm_active_connection_get_devices; - nm_active_connection_get_scope; - nm_active_connection_get_service_name; nm_active_connection_get_specific_object; nm_active_connection_get_state; nm_active_connection_get_type; diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c index 2468da099..f9e8adbf1 100644 --- a/libnm-glib/nm-active-connection.c +++ b/libnm-glib/nm-active-connection.c @@ -43,8 +43,6 @@ typedef struct { gboolean disposed; DBusGProxy *proxy; - char *service_name; - NMConnectionScope scope; char *connection; char *specific_object; GPtrArray *devices; @@ -55,7 +53,6 @@ typedef struct { enum { PROP_0, - PROP_SERVICE_NAME, PROP_CONNECTION, PROP_SPECIFIC_OBJECT, PROP_DEVICES, @@ -66,7 +63,6 @@ enum { LAST_PROP }; -#define DBUS_PROP_SERVICE_NAME "ServiceName" #define DBUS_PROP_CONNECTION "Connection" #define DBUS_PROP_SPECIFIC_OBJECT "SpecificObject" #define DBUS_PROP_DEVICES "Devices" @@ -95,62 +91,6 @@ nm_active_connection_new (DBusGConnection *connection, const char *path) NULL); } -static NMConnectionScope -get_scope_for_service_name (const char *service_name) -{ - if (service_name && !strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) - return NM_CONNECTION_SCOPE_USER; - else if (service_name && !strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) - return NM_CONNECTION_SCOPE_SYSTEM; - - return NM_CONNECTION_SCOPE_UNKNOWN; -} - -/** - * nm_active_connection_get_service_name: - * @connection: a #NMActiveConnection - * - * Gets the service name of the active connection. - * - * Returns: the service name. This is the internal string used by the - * connection, and must not be modified. - **/ -const char * -nm_active_connection_get_service_name (NMActiveConnection *connection) -{ - NMActiveConnectionPrivate *priv; - - g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NULL); - - priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); - if (!priv->service_name) { - priv->service_name = _nm_object_get_string_property (NM_OBJECT (connection), - NM_DBUS_INTERFACE_ACTIVE_CONNECTION, - DBUS_PROP_SERVICE_NAME); - priv->scope = get_scope_for_service_name (priv->service_name); - } - - return priv->service_name; -} - -/** - * nm_active_connection_get_scope: - * @connection: a #NMActiveConnection - * - * Gets the scope of the active connection. - * - * Returns: the connection's scope - **/ -NMConnectionScope -nm_active_connection_get_scope (NMActiveConnection *connection) -{ - g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NM_CONNECTION_SCOPE_UNKNOWN); - - /* Make sure service_name and scope are up-to-date */ - nm_active_connection_get_service_name (connection); - return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->scope; -} - /** * nm_active_connection_get_connection: * @connection: a #NMActiveConnection @@ -345,7 +285,6 @@ finalize (GObject *object) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); - g_free (priv->service_name); g_free (priv->connection); g_free (priv->specific_object); @@ -361,9 +300,6 @@ get_property (GObject *object, NMActiveConnection *self = NM_ACTIVE_CONNECTION (object); switch (prop_id) { - case PROP_SERVICE_NAME: - g_value_set_string (value, nm_active_connection_get_service_name (self)); - break; case PROP_CONNECTION: g_value_set_boxed (value, nm_active_connection_get_connection (self)); break; @@ -401,24 +337,11 @@ demarshal_devices (NMObject *object, GParamSpec *pspec, GValue *value, gpointer return TRUE; } -static gboolean -demarshal_service (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) -{ - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); - - if (_nm_object_demarshal_generic (object, pspec, value, field)) { - priv->scope = get_scope_for_service_name (priv->service_name); - return TRUE; - } - return FALSE; -} - static void register_for_property_changed (NMActiveConnection *connection) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); const NMPropertiesChangedInfo property_changed_info[] = { - { NM_ACTIVE_CONNECTION_SERVICE_NAME, demarshal_service, &priv->service_name }, { NM_ACTIVE_CONNECTION_CONNECTION, _nm_object_demarshal_generic, &priv->connection }, { NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, _nm_object_demarshal_generic, &priv->specific_object }, { NM_ACTIVE_CONNECTION_DEVICES, demarshal_devices, &priv->devices }, @@ -475,19 +398,6 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class) /* properties */ - /** - * NMActiveConnection:service-name: - * - * The service name of the active connection. - **/ - g_object_class_install_property - (object_class, PROP_SERVICE_NAME, - g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME, - "Service Name", - "Service Name", - NULL, - G_PARAM_READABLE)); - /** * NMActiveConnection:connection: * diff --git a/libnm-glib/nm-active-connection.h b/libnm-glib/nm-active-connection.h index 30edf047a..a641e7c1a 100644 --- a/libnm-glib/nm-active-connection.h +++ b/libnm-glib/nm-active-connection.h @@ -39,7 +39,6 @@ G_BEGIN_DECLS #define NM_IS_ACTIVE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ACTIVE_CONNECTION)) #define NM_ACTIVE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACTIVE_CONNECTION, NMActiveConnectionClass)) -#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name" #define NM_ACTIVE_CONNECTION_CONNECTION "connection" #define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" #define NM_ACTIVE_CONNECTION_DEVICES "devices" @@ -67,8 +66,6 @@ GType nm_active_connection_get_type (void); GObject *nm_active_connection_new (DBusGConnection *connection, const char *path); -const char * nm_active_connection_get_service_name (NMActiveConnection *connection); -NMConnectionScope nm_active_connection_get_scope (NMActiveConnection *connection); const char * nm_active_connection_get_connection (NMActiveConnection *connection); const char * nm_active_connection_get_specific_object (NMActiveConnection *connection); const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection); diff --git a/libnm-glib/nm-exported-connection.c b/libnm-glib/nm-exported-connection.c index 3a8e51ce7..6fda1b553 100644 --- a/libnm-glib/nm-exported-connection.c +++ b/libnm-glib/nm-exported-connection.c @@ -247,19 +247,15 @@ settings_connection_interface_init (NMSettingsConnectionInterface *iface) /** * nm_exported_connection_new: - * @scope: the Connection scope (either user or system) * * Creates a new object representing the remote connection. * * Returns: the new exported connection object on success, or %NULL on failure **/ NMExportedConnection * -nm_exported_connection_new (NMConnectionScope scope) +nm_exported_connection_new () { - g_return_val_if_fail (scope != NM_CONNECTION_SCOPE_UNKNOWN, NULL); - return (NMExportedConnection *) g_object_new (NM_TYPE_EXPORTED_CONNECTION, - NM_CONNECTION_SCOPE, scope, NULL); } diff --git a/libnm-glib/nm-exported-connection.h b/libnm-glib/nm-exported-connection.h index 53dc3b024..e2bf649aa 100644 --- a/libnm-glib/nm-exported-connection.h +++ b/libnm-glib/nm-exported-connection.h @@ -68,7 +68,7 @@ typedef struct { GType nm_exported_connection_get_type (void); -NMExportedConnection *nm_exported_connection_new (NMConnectionScope scope); +NMExportedConnection *nm_exported_connection_new (void); G_END_DECLS diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 1039a7d18..2775329f9 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -206,9 +206,8 @@ replace_settings (NMRemoteConnection *self, GHashTable *new_settings) GError *error = NULL; if (!nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) { - g_warning ("%s: error updating %s connection %s settings: (%d) %s", + g_warning ("%s: error updating connection %s settings: (%d) %s", __func__, - (nm_connection_get_scope (NM_CONNECTION (self)) == NM_CONNECTION_SCOPE_USER) ? "user" : "system", nm_connection_get_path (NM_CONNECTION (self)), error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); @@ -233,9 +232,8 @@ get_settings_cb (DBusGProxy *proxy, NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); if (error) { - g_warning ("%s: error getting %s connection %s settings: (%d) %s", + g_warning ("%s: error getting connection %s settings: (%d) %s", __func__, - (nm_connection_get_scope (NM_CONNECTION (self)) == NM_CONNECTION_SCOPE_USER) ? "user" : "system", nm_connection_get_path (NM_CONNECTION (self)), error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); @@ -276,9 +274,7 @@ settings_connection_interface_init (NMSettingsConnectionInterface *klass) /** * nm_remote_connection_new: * @bus: a valid and connected D-Bus connection - * @scope: the Connection scope (either user or system) * @path: the D-Bus path of the connection as exported by the settings service - * indicated by @scope * * Creates a new object representing the remote connection. * @@ -286,7 +282,6 @@ settings_connection_interface_init (NMSettingsConnectionInterface *klass) **/ NMRemoteConnection * nm_remote_connection_new (DBusGConnection *bus, - NMConnectionScope scope, const char *path) { g_return_val_if_fail (bus != NULL, NULL); @@ -294,7 +289,6 @@ nm_remote_connection_new (DBusGConnection *bus, return (NMRemoteConnection *) g_object_new (NM_TYPE_REMOTE_CONNECTION, NM_REMOTE_CONNECTION_BUS, bus, - NM_CONNECTION_SCOPE, scope, NM_CONNECTION_PATH, path, NULL); } @@ -306,7 +300,6 @@ constructor (GType type, { GObject *object; NMRemoteConnectionPrivate *priv; - const char *service = NM_DBUS_SERVICE_USER_SETTINGS; object = G_OBJECT_CLASS (nm_remote_connection_parent_class)->constructor (type, n_construct_params, construct_params); if (!object) @@ -316,18 +309,15 @@ constructor (GType type, g_assert (priv->bus); g_assert (nm_connection_get_path (NM_CONNECTION (object))); - if (nm_connection_get_scope (NM_CONNECTION (object)) == NM_CONNECTION_SCOPE_SYSTEM) - service = NM_DBUS_SERVICE_SYSTEM_SETTINGS; - priv->proxy = dbus_g_proxy_new_for_name (priv->bus, - service, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, nm_connection_get_path (NM_CONNECTION (object)), NM_DBUS_IFACE_SETTINGS_CONNECTION); g_assert (priv->proxy); dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); priv->secrets_proxy = dbus_g_proxy_new_for_name (priv->bus, - service, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, nm_connection_get_path (NM_CONNECTION (object)), NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS); g_assert (priv->secrets_proxy); diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h index ef5452f99..732ade348 100644 --- a/libnm-glib/nm-remote-connection.h +++ b/libnm-glib/nm-remote-connection.h @@ -57,7 +57,6 @@ typedef struct { GType nm_remote_connection_get_type (void); NMRemoteConnection *nm_remote_connection_new (DBusGConnection *bus, - NMConnectionScope scope, const char *path); G_END_DECLS diff --git a/libnm-glib/nm-remote-settings-system.c b/libnm-glib/nm-remote-settings-system.c index 95098c7e6..033aa0124 100644 --- a/libnm-glib/nm-remote-settings-system.c +++ b/libnm-glib/nm-remote-settings-system.c @@ -240,7 +240,6 @@ nm_remote_settings_system_new (DBusGConnection *bus) return (NMRemoteSettingsSystem *) g_object_new (NM_TYPE_REMOTE_SETTINGS_SYSTEM, NM_REMOTE_SETTINGS_BUS, bus, - NM_REMOTE_SETTINGS_SCOPE, NM_CONNECTION_SCOPE_SYSTEM, NULL); } diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 92814a15c..3e7f481d6 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -40,7 +40,6 @@ G_DEFINE_TYPE_EXTENDED (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT, 0, typedef struct { DBusGConnection *bus; - NMConnectionScope scope; DBusGProxy *proxy; GHashTable *connections; @@ -57,7 +56,6 @@ typedef struct { enum { PROP_0, PROP_BUS, - PROP_SCOPE, PROP_SERVICE_RUNNING, LAST_PROP @@ -137,7 +135,7 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); NMRemoteConnection *connection; - connection = nm_remote_connection_new (priv->bus, priv->scope, path); + connection = nm_remote_connection_new (priv->bus, path); if (connection) { g_signal_connect (connection, "removed", G_CALLBACK (connection_removed_cb), @@ -162,13 +160,11 @@ fetch_connections_done (DBusGProxy *proxy, gpointer user_data) { NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); int i; if (error) { - g_warning ("%s: error fetching %s connections: (%d) %s.", + g_warning ("%s: error fetching connections: (%d) %s.", __func__, - priv->scope == NM_CONNECTION_SCOPE_USER ? "user" : "system", error->code, error->message ? error->message : "(unknown)"); g_clear_error (&error); @@ -296,10 +292,7 @@ name_owner_changed (DBusGProxy *proxy, { NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - const char *sname = NM_DBUS_SERVICE_USER_SETTINGS; - - if (priv->scope == NM_CONNECTION_SCOPE_SYSTEM) - sname = NM_DBUS_SERVICE_SYSTEM_SETTINGS; + const char *sname = NM_DBUS_SERVICE_SYSTEM_SETTINGS; if (!strcmp (name, sname)) { if (priv->fetch_id) @@ -330,21 +323,18 @@ settings_interface_init (NMSettingsInterface *iface) /** * nm_remote_settings_new: * @bus: a valid and connected D-Bus connection - * @scope: the settings service scope (either user or system) * * Creates a new object representing the remote settings service. * * Returns: the new remote settings object on success, or %NULL on failure **/ NMRemoteSettings * -nm_remote_settings_new (DBusGConnection *bus, NMConnectionScope scope) +nm_remote_settings_new (DBusGConnection *bus) { g_return_val_if_fail (bus != NULL, NULL); - g_return_val_if_fail (scope != NM_CONNECTION_SCOPE_UNKNOWN, NULL); return (NMRemoteSettings *) g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, - NM_REMOTE_SETTINGS_SCOPE, scope, NULL); } @@ -364,7 +354,6 @@ constructor (GType type, { GObject *object; NMRemoteSettingsPrivate *priv; - const char *service = NM_DBUS_SERVICE_USER_SETTINGS; GError *error = NULL; object = G_OBJECT_CLASS (nm_remote_settings_parent_class)->constructor (type, n_construct_params, construct_params); @@ -392,12 +381,8 @@ constructor (GType type, G_CALLBACK (name_owner_changed), object, NULL); - /* Settings service proxy */ - if (priv->scope == NM_CONNECTION_SCOPE_SYSTEM) - service = NM_DBUS_SERVICE_SYSTEM_SETTINGS; - if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", &error, - G_TYPE_STRING, service, + G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS, G_TYPE_INVALID, G_TYPE_BOOLEAN, &priv->service_running, G_TYPE_INVALID)) { @@ -410,7 +395,7 @@ constructor (GType type, } priv->proxy = dbus_g_proxy_new_for_name (priv->bus, - service, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, NM_DBUS_PATH_SETTINGS, NM_DBUS_IFACE_SETTINGS); g_assert (priv->proxy); @@ -466,9 +451,6 @@ set_property (GObject *object, guint prop_id, /* Construct only */ priv->bus = dbus_g_connection_ref ((DBusGConnection *) g_value_get_boxed (value)); break; - case PROP_SCOPE: - priv->scope = (NMConnectionScope) g_value_get_uint (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -485,9 +467,6 @@ get_property (GObject *object, guint prop_id, case PROP_BUS: g_value_set_boxed (value, priv->bus); break; - case PROP_SCOPE: - g_value_set_uint (value, priv->scope); - break; case PROP_SERVICE_RUNNING: g_value_set_boolean (value, priv->service_running); break; @@ -519,16 +498,6 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) DBUS_TYPE_G_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property - (object_class, PROP_SCOPE, - g_param_spec_uint (NM_REMOTE_SETTINGS_SCOPE, - "Scope", - "NMConnection scope", - NM_CONNECTION_SCOPE_UNKNOWN, - NM_CONNECTION_SCOPE_USER, - NM_CONNECTION_SCOPE_USER, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_SERVICE_RUNNING, g_param_spec_boolean (NM_REMOTE_SETTINGS_SERVICE_RUNNING, diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index d3085566e..6553e3bbf 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -39,7 +39,6 @@ G_BEGIN_DECLS #define NM_REMOTE_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) #define NM_REMOTE_SETTINGS_BUS "bus" -#define NM_REMOTE_SETTINGS_SCOPE "scope" #define NM_REMOTE_SETTINGS_SERVICE_RUNNING "service-running" typedef struct { @@ -60,7 +59,7 @@ typedef struct { GType nm_remote_settings_get_type (void); -NMRemoteSettings *nm_remote_settings_new (DBusGConnection *bus, NMConnectionScope scope); +NMRemoteSettings *nm_remote_settings_new (DBusGConnection *bus); G_END_DECLS diff --git a/libnm-glib/nm-settings-service.c b/libnm-glib/nm-settings-service.c index 6266d10da..9abce2500 100644 --- a/libnm-glib/nm-settings-service.c +++ b/libnm-glib/nm-settings-service.c @@ -49,7 +49,6 @@ G_DEFINE_TYPE_EXTENDED (NMSettingsService, nm_settings_service, G_TYPE_OBJECT, G typedef struct { DBusGConnection *bus; - NMConnectionScope scope; gboolean exported; gboolean disposed; @@ -58,7 +57,6 @@ typedef struct { enum { PROP_0, PROP_BUS, - PROP_SCOPE, LAST_PROP }; @@ -236,7 +234,6 @@ nm_settings_service_export_connection (NMSettingsService *self, path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); nm_connection_set_path (NM_CONNECTION (connection), path); - nm_connection_set_scope (NM_CONNECTION (connection), priv->scope); dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); g_free (path); @@ -264,9 +261,6 @@ constructor (GType type, GObject *object; object = G_OBJECT_CLASS (nm_settings_service_parent_class)->constructor (type, n_construct_params, construct_params); - if (object) { - g_assert (NM_SETTINGS_SERVICE_GET_PRIVATE (object)->scope != NM_CONNECTION_SCOPE_UNKNOWN); - } return object; } @@ -289,10 +283,6 @@ set_property (GObject *object, guint prop_id, if (bus) priv->bus = dbus_g_connection_ref (bus); break; - case PROP_SCOPE: - /* Construct only */ - priv->scope = g_value_get_uint (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -309,9 +299,6 @@ get_property (GObject *object, guint prop_id, case PROP_BUS: g_value_set_boxed (value, priv->bus); break; - case PROP_SCOPE: - g_value_set_uint (value, priv->scope); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -356,17 +343,4 @@ nm_settings_service_class_init (NMSettingsServiceClass *class) "Bus", DBUS_TYPE_G_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - /** - * NMSettingsService:scope: - * - * The capabilities of the device. - **/ - g_object_class_install_property (object_class, PROP_SCOPE, - g_param_spec_uint (NM_SETTINGS_SERVICE_SCOPE, - "Scope", - "Scope", - NM_CONNECTION_SCOPE_SYSTEM, - NM_CONNECTION_SCOPE_USER, - NM_CONNECTION_SCOPE_USER, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } diff --git a/libnm-glib/nm-settings-service.h b/libnm-glib/nm-settings-service.h index 9f4b95fcc..6a55d1ae6 100644 --- a/libnm-glib/nm-settings-service.h +++ b/libnm-glib/nm-settings-service.h @@ -37,7 +37,6 @@ G_BEGIN_DECLS #define NM_SETTINGS_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_SERVICE, NMSettingsServiceClass)) #define NM_SETTINGS_SERVICE_BUS "bus" -#define NM_SETTINGS_SERVICE_SCOPE "scope" typedef struct { GObject parent; diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 6c2b9fc71..cf3d801fb 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -10,7 +10,6 @@ global: nm_connection_error_quark; nm_connection_for_each_setting_value; nm_connection_get_path; - nm_connection_get_scope; nm_connection_get_setting; nm_connection_get_setting_by_name; nm_connection_get_type; @@ -22,7 +21,6 @@ global: nm_connection_remove_setting; nm_connection_replace_settings; nm_connection_set_path; - nm_connection_set_scope; nm_connection_to_hash; nm_connection_update_secrets; nm_connection_verify; diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 33790a636..820ef3aa0 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -65,12 +65,6 @@ * parameters (MTU, SSID, APN, channel, rate, etc) and IP-level parameters * (addresses, routes, addressing methods, etc). * - * Most connections also have a %NMConnectionScope; a connection will be - * provided over D-Bus either by the user settings service - * (org.freedesktop.NetworkManagerUserSettings) running in an active user - * session, or by the system-wide system settings service - * (org.freedesktop.NetworkManagerSystemSettings) which provides connections - * for all users. */ /** @@ -112,9 +106,6 @@ nm_connection_error_get_type (void) typedef struct { GHashTable *settings; - /* Type of the connection (system or user) */ - NMConnectionScope scope; - /* D-Bus path of the connection, if any */ char *path; } NMConnectionPrivate; @@ -125,7 +116,6 @@ G_DEFINE_TYPE (NMConnection, nm_connection, G_TYPE_OBJECT) enum { PROP_0, - PROP_SCOPE, PROP_PATH, LAST_PROP @@ -900,43 +890,6 @@ nm_connection_dump (NMConnection *connection) g_hash_table_foreach (NM_CONNECTION_GET_PRIVATE (connection)->settings, dump_setting, NULL); } -/** - * nm_connection_set_scope: - * @connection: the #NMConnection - * @scope: the scope of the connection - * - * Sets the scope of the connection. This property is not serialized, and is - * only for the reference of the caller. A connection may have no scope - * (internal, temporary connections), "system" scope (provided by the system - * settings service), or "user" scope, provided by a user settings service. The - * creator of the #NMConnection object is responsible for setting the - * connection's scope if needed. Sets the #NMConnection:scope property. - **/ -void -nm_connection_set_scope (NMConnection *connection, NMConnectionScope scope) -{ - g_return_if_fail (NM_IS_CONNECTION (connection)); - - NM_CONNECTION_GET_PRIVATE (connection)->scope = scope; -} - -/** - * nm_connection_get_scope: - * @connection: the #NMConnection - * - * Returns the connection scope. - * - * Returns: the scope of the connection, previously set by a call to - * nm_connection_set_scope(). - **/ -NMConnectionScope -nm_connection_get_scope (NMConnection *connection) -{ - g_return_val_if_fail (NM_IS_CONNECTION (connection), NM_CONNECTION_SCOPE_UNKNOWN); - - return NM_CONNECTION_GET_PRIVATE (connection)->scope; -} - /** * nm_connection_set_path: * @connection: the #NMConnection @@ -1055,7 +1008,6 @@ nm_connection_duplicate (NMConnection *connection) g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); dup = nm_connection_new (); - nm_connection_set_scope (dup, nm_connection_get_scope (connection)); nm_connection_set_path (dup, nm_connection_get_path (connection)); g_hash_table_foreach (NM_CONNECTION_GET_PRIVATE (connection)->settings, duplicate_cb, dup); @@ -1092,9 +1044,6 @@ set_property (GObject *object, guint prop_id, NMConnection *connection = NM_CONNECTION (object); switch (prop_id) { - case PROP_SCOPE: - nm_connection_set_scope (connection, g_value_get_uint (value)); - break; case PROP_PATH: nm_connection_set_path (connection, g_value_get_string (value)); break; @@ -1111,9 +1060,6 @@ get_property (GObject *object, guint prop_id, NMConnection *connection = NM_CONNECTION (object); switch (prop_id) { - case PROP_SCOPE: - g_value_set_uint (value, nm_connection_get_scope (connection)); - break; case PROP_PATH: g_value_set_string (value, nm_connection_get_path (connection)); break; @@ -1137,23 +1083,6 @@ nm_connection_class_init (NMConnectionClass *klass) /* Properties */ - /** - * NMConnection:scope: - * - * The connection's scope, used only by the calling process as a record - * of which settings service the connection is provided by. One of the - * NM_CONNECTION_SCOPE_* defines. - **/ - g_object_class_install_property - (object_class, PROP_SCOPE, - g_param_spec_uint (NM_CONNECTION_SCOPE, - "Scope", - "Scope", - NM_CONNECTION_SCOPE_UNKNOWN, - NM_CONNECTION_SCOPE_USER, - NM_CONNECTION_SCOPE_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - /** * NMConnection:path: * diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 576db0498..453f9eff0 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -39,23 +39,6 @@ G_BEGIN_DECLS #define NM_IS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CONNECTION)) #define NM_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONNECTION, NMConnectionClass)) -/** - * NMConnectionScope: - * @NM_CONNECTION_SCOPE_UNKNOWN: scope not known or not yet set - * @NM_CONNECTION_SCOPE_SYSTEM: connection is provided by the system settings - * service - * @NM_CONNECTION_SCOPE_USER: connection is provided by a user settings service - * - * Connection scope indicated what settings service, if any, provides the - * connection. - * - **/ -typedef enum { - NM_CONNECTION_SCOPE_UNKNOWN = 0, - NM_CONNECTION_SCOPE_SYSTEM, - NM_CONNECTION_SCOPE_USER -} NMConnectionScope; - /** * NMConnectionError: @@ -79,7 +62,6 @@ GType nm_connection_error_get_type (void); #define NM_CONNECTION_ERROR nm_connection_error_quark () GQuark nm_connection_error_quark (void); -#define NM_CONNECTION_SCOPE "scope" #define NM_CONNECTION_PATH "path" /** @@ -139,11 +121,6 @@ gboolean nm_connection_update_secrets (NMConnection *connection, GHashTable *secrets, GError **error); -void nm_connection_set_scope (NMConnection *connection, - NMConnectionScope scope); - -NMConnectionScope nm_connection_get_scope (NMConnection *connection); - void nm_connection_set_path (NMConnection *connection, const char *path); diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index aadaab568..c5ff49da1 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -1312,10 +1312,8 @@ nm_sysconfig_settings_new (const char *config_file, NMSysconfigSettings *self; NMSysconfigSettingsPrivate *priv; - /* TODO remove the scope parameter. */ self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NM_SETTINGS_SERVICE_BUS, bus, - NM_SETTINGS_SERVICE_SCOPE, NM_CONNECTION_SCOPE_SYSTEM, NULL); if (!self) return NULL; From d503c09466dbd0b58f8ee639311cbf24fac0f360 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Wed, 28 Jul 2010 02:26:39 -0400 Subject: [PATCH 007/264] DBus API: removing user settings support Remove bits from the external DBus API that were once needed for user settings support. --- cli/src/connections.c | 1 - introspection/errors.xml | 14 +------------- introspection/nm-active-connection.xml | 3 --- introspection/nm-manager-client.xml | 1 - introspection/nm-manager.xml | 6 ------ introspection/nm-vpn-connection.xml | 3 --- libnm-glib/nm-client.c | 4 ---- libnm-glib/nm-client.h | 1 - src/nm-activation-request.c | 12 ------------ src/nm-active-connection.h | 1 - src/nm-manager.c | 21 --------------------- src/vpn-manager/nm-vpn-connection.c | 12 ------------ 12 files changed, 1 insertion(+), 78 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index f19e3135a..42fde78aa 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -1361,7 +1361,6 @@ do_connection_up (NmCli *nmc, int argc, char **argv) nmc->nowait_flag = !wait; nmc->should_wait = TRUE; nm_client_activate_connection (nmc->client, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, con_path, device, spec_object, diff --git a/introspection/errors.xml b/introspection/errors.xml index 444b325d5..f2db86679 100644 --- a/introspection/errors.xml +++ b/introspection/errors.xml @@ -5,7 +5,7 @@ - Connection was not provided by any known settings service. + Connection was not provided by the settings service. @@ -15,18 +15,6 @@ - - - Invalid settings service (not a recognized system or user settings service name). - - - - - - Connection was superseded by a system connection. - - - User does not have the permission to activate this connection. diff --git a/introspection/nm-active-connection.xml b/introspection/nm-active-connection.xml index 765830a1d..494eba42b 100644 --- a/introspection/nm-active-connection.xml +++ b/introspection/nm-active-connection.xml @@ -2,9 +2,6 @@ - - The D-Bus service name providing this connection. - The path of the connection. diff --git a/introspection/nm-manager-client.xml b/introspection/nm-manager-client.xml index f30d1d671..375bfc6e9 100644 --- a/introspection/nm-manager-client.xml +++ b/introspection/nm-manager-client.xml @@ -22,7 +22,6 @@ object. dbus-glib generates the same bound function names for D-Bus the methods - diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index e1b466799..753ceece4 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -27,11 +27,6 @@ Activate a connection using the supplied device. - - - The D-Bus service name of the settings service that provides this connection. - - The connection to activate the devices with. @@ -62,7 +57,6 @@ - Another connection is already activating or the same connection is already active. FIXME: check if the error name is correct. FIXME: split into 2 errors? diff --git a/introspection/nm-vpn-connection.xml b/introspection/nm-vpn-connection.xml index 3a47cdf1b..eaf0fa678 100644 --- a/introspection/nm-vpn-connection.xml +++ b/introspection/nm-vpn-connection.xml @@ -2,9 +2,6 @@ - - The D-Bus service name providing this connection. - The path of the connection. diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index a1f986f49..7de1b6851 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -977,7 +977,6 @@ activate_cb (DBusGProxy *proxy, /** * nm_client_activate_connection: * @client: a #NMClient - * @service_name: the connection's service name * @connection_path: the connection's DBus path * @device: the #NMDevice * @specific_object: the device specific object (currently used only for @@ -989,7 +988,6 @@ activate_cb (DBusGProxy *proxy, **/ void nm_client_activate_connection (NMClient *client, - const char *service_name, const char *connection_path, NMDevice *device, const char *specific_object, @@ -1001,7 +999,6 @@ nm_client_activate_connection (NMClient *client, g_return_if_fail (NM_IS_CLIENT (client)); g_return_if_fail (NM_IS_DEVICE (device)); - g_return_if_fail (service_name != NULL); g_return_if_fail (connection_path != NULL); /* NULL specific object must be translated into "/" because D-Bus does @@ -1015,7 +1012,6 @@ nm_client_activate_connection (NMClient *client, info->user_data = user_data; org_freedesktop_NetworkManager_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->client_proxy, - service_name, connection_path, nm_object_get_path (NM_OBJECT (device)), internal_so, diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index c67e0d8f8..206c55546 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -99,7 +99,6 @@ NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_ typedef void (*NMClientActivateDeviceFn) (gpointer user_data, const char *object_path, GError *error); void nm_client_activate_connection (NMClient *client, - const char *service_name, const char *connection_path, NMDevice *device, const char *specific_object, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index e13d95fee..4d8d0d860 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -83,7 +83,6 @@ typedef struct { enum { PROP_0, - PROP_SERVICE_NAME, PROP_CONNECTION, PROP_SPECIFIC_OBJECT, PROP_DEVICES, @@ -256,10 +255,6 @@ get_property (GObject *object, guint prop_id, GPtrArray *devices; switch (prop_id) { - case PROP_SERVICE_NAME: - /* TODO Remove this propery. */ - g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); - break; case PROP_CONNECTION: g_value_set_boxed (value, nm_connection_get_path (priv->connection)); break; @@ -305,13 +300,6 @@ nm_act_request_class_init (NMActRequestClass *req_class) object_class->finalize = finalize; /* properties */ - g_object_class_install_property - (object_class, PROP_SERVICE_NAME, - g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME, - "Service name", - "Service name", - NULL, - G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_CONNECTION, g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h index 55d27e739..15ae201d4 100644 --- a/src/nm-active-connection.h +++ b/src/nm-active-connection.h @@ -24,7 +24,6 @@ #include #include "nm-connection.h" -#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name" #define NM_ACTIVE_CONNECTION_CONNECTION "connection" #define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" #define NM_ACTIVE_CONNECTION_DEVICES "devices" diff --git a/src/nm-manager.c b/src/nm-manager.c index e00a0ccad..865529c0d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -61,7 +61,6 @@ static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err); static void impl_manager_activate_connection (NMManager *manager, - const char *service_name, const char *connection_path, const char *device_path, const char *specific_object_path, @@ -261,7 +260,6 @@ typedef enum NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0, NM_MANAGER_ERROR_UNKNOWN_DEVICE, NM_MANAGER_ERROR_UNMANAGED_DEVICE, - NM_MANAGER_ERROR_INVALID_SERVICE, NM_MANAGER_ERROR_SYSTEM_CONNECTION, NM_MANAGER_ERROR_PERMISSION_DENIED, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, @@ -297,10 +295,6 @@ nm_manager_error_get_type (void) ENUM_ENTRY (NM_MANAGER_ERROR_UNKNOWN_DEVICE, "UnknownDevice"), /* Unmanaged device. */ ENUM_ENTRY (NM_MANAGER_ERROR_UNMANAGED_DEVICE, "UnmanagedDevice"), - /* Invalid settings service (not a recognized system or user - * settings service name) - */ - ENUM_ENTRY (NM_MANAGER_ERROR_INVALID_SERVICE, "InvalidService"), /* Connection was superceded by a system connection. */ ENUM_ENTRY (NM_MANAGER_ERROR_SYSTEM_CONNECTION, "SystemConnection"), /* User does not have the permission to activate this connection. */ @@ -2172,7 +2166,6 @@ activation_auth_done (PendingActivation *pending, GError *error) static void impl_manager_activate_connection (NMManager *self, - const char *service_name, const char *connection_path, const char *device_path, const char *specific_object_path, @@ -2180,20 +2173,6 @@ impl_manager_activate_connection (NMManager *self, { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); PendingActivation *pending; - GError *error = NULL; - - // TODO user settings services are gone, so service_name is no longer - // meaningful. Remove the parameter and this check. - if (strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_INVALID_SERVICE, - "Invalid settings service name"); - dbus_g_method_return_error (context, error); - nm_log_warn (LOGD_CORE, "connection %s:%s failed to activate: (%d) %s", - service_name, connection_path, error->code, error->message); - g_error_free (error); - return; - } /* Need to check the caller's permissions and stuff before we can * activate the connection. diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 0d618aae8..bda021992 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -97,7 +97,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, - PROP_SERVICE_NAME, PROP_CONNECTION, PROP_SPECIFIC_OBJECT, PROP_DEVICES, @@ -1044,10 +1043,6 @@ get_property (GObject *object, guint prop_id, NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); switch (prop_id) { - case PROP_SERVICE_NAME: - /* TODO remove this property */ - g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); - break; case PROP_CONNECTION: g_value_set_boxed (value, nm_connection_get_path (priv->connection)); break; @@ -1095,13 +1090,6 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) object_class->finalize = finalize; /* properties */ - g_object_class_install_property - (object_class, PROP_SERVICE_NAME, - g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME, - "Service name", - "Service name", - NULL, - G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_CONNECTION, g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, From 67ba32cd299adf5ad58e5badfb00d9a3334cb714 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Wed, 28 Jul 2010 02:40:11 -0400 Subject: [PATCH 008/264] Remove use-user-connections polkit action --- libnm-glib/nm-client.c | 3 --- libnm-glib/nm-client.h | 3 +-- policy/org.freedesktop.NetworkManager.policy.in | 9 --------- src/nm-manager-auth.h | 1 - src/nm-manager.c | 2 -- 5 files changed, 1 insertion(+), 17 deletions(-) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 7de1b6851..8ff15b39b 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -293,7 +293,6 @@ register_for_property_changed (NMClient *client) #define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" -#define NM_AUTH_PERMISSION_USE_USER_CONNECTIONS "org.freedesktop.NetworkManager.use-user-connections" static NMClientPermission nm_permission_to_client (const char *nm) @@ -304,8 +303,6 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI; else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN)) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN; - else if (!strcmp (nm, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS)) - return NM_CLIENT_PERMISSION_USE_USER_CONNECTIONS; return NM_CLIENT_PERMISSION_NONE; } diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 206c55546..e86316116 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -56,9 +56,8 @@ typedef enum { NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK = 1, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, - NM_CLIENT_PERMISSION_USE_USER_CONNECTIONS = 4, - NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_USE_USER_CONNECTIONS + NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN } NMClientPermission; typedef enum { diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index 3e7db0588..67af7838a 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -45,15 +45,6 @@ - - <_description>Allow use of user-specific connections - <_message>System policy prevents use of user-specific connections - - yes - yes - - - <_description>Allow control of network connections <_message>System policy prevents control of network connections diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 6eedb2836..e944d2068 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -31,7 +31,6 @@ #define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" -#define NM_AUTH_PERMISSION_USE_USER_CONNECTIONS "org.freedesktop.NetworkManager.use-user-connections" #define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" diff --git a/src/nm-manager.c b/src/nm-manager.c index 865529c0d..f17389cde 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2716,7 +2716,6 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SLEEP_WAKE); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN); - get_perm_add_result (chain, results, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_NETWORK_CONTROL); dbus_g_method_return (context, results); g_hash_table_destroy (results); @@ -2743,7 +2742,6 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE); } From 215640c59092e772794c98c1a9c8a9f24fe43ef9 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 29 Jul 2010 00:11:21 -0400 Subject: [PATCH 009/264] libnm-glib: remove nm-settings-service Now that we have only one settings service, there is no more need to have common settings service code in libnm-glib. So we can simplify things somewhat my moving everything from nm-settings-service into nm-sysconfig-settings. --- libnm-glib/Makefile.am | 10 +- libnm-glib/libnm-glib.ver | 4 - libnm-glib/nm-settings-service.c | 346 -------------------- libnm-glib/nm-settings-service.h | 81 ----- src/nm-manager.c | 1 - src/system-settings/Makefile.am | 5 + src/system-settings/nm-sysconfig-settings.c | 222 ++++++++++++- src/system-settings/nm-sysconfig-settings.h | 6 +- 8 files changed, 218 insertions(+), 457 deletions(-) delete mode 100644 libnm-glib/nm-settings-service.c delete mode 100644 libnm-glib/nm-settings-service.h diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 008cc6df1..a59e5f346 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -12,7 +12,6 @@ BUILT_SOURCES = \ nm-device-bt-bindings.h \ nm-exported-connection-glue.h \ nm-exported-connection-bindings.h \ - nm-settings-glue.h \ nm-settings-bindings.h \ nm-settings-system-bindings.h \ nm-vpn-connection-bindings.h \ @@ -84,8 +83,7 @@ libnminclude_HEADERS = \ nm-remote-settings.h \ nm-remote-settings-system.h \ nm-settings-connection-interface.h \ - nm-exported-connection.h \ - nm-settings-service.h + nm-exported-connection.h libnm_glib_la_SOURCES = \ nm-object.c \ @@ -119,8 +117,7 @@ libnm_glib_la_SOURCES = \ nm-remote-settings.c \ nm-remote-settings-system.c \ nm-settings-connection-interface.c \ - nm-exported-connection.c \ - nm-settings-service.c + nm-exported-connection.c libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ @@ -166,9 +163,6 @@ nm-device-bt-bindings.h: $(top_srcdir)/introspection/nm-device-bt.xml nm-access-point-bindings.h: $(top_srcdir)/introspection/nm-access-point.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-client --output=$@ $< -nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< - nm-settings-bindings.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-client --output=$@ $< diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index d956e6a26..c4c171c04 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -139,10 +139,6 @@ global: nm_settings_interface_get_connection_by_path; nm_settings_interface_get_type; nm_settings_interface_list_connections; - nm_settings_service_export; - nm_settings_service_export_connection; - nm_settings_service_get_connection_by_path; - nm_settings_service_get_type; nm_settings_system_interface_get_type; nm_settings_system_interface_add_connection; nm_settings_system_interface_get_permissions; diff --git a/libnm-glib/nm-settings-service.c b/libnm-glib/nm-settings-service.c deleted file mode 100644 index 9abce2500..000000000 --- a/libnm-glib/nm-settings-service.c +++ /dev/null @@ -1,346 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2009 Red Hat, Inc. - */ - -#include -#include -#include - -#include "nm-settings-service.h" -#include "nm-settings-interface.h" -#include "nm-exported-connection.h" - -static gboolean impl_settings_list_connections (NMSettingsService *self, - GPtrArray **connections, - GError **error); - -static void impl_settings_add_connection (NMSettingsService *self, - GHashTable *settings, - DBusGMethodInvocation *context); - -#include "nm-settings-glue.h" - -static void settings_interface_init (NMSettingsInterface *class); - -G_DEFINE_TYPE_EXTENDED (NMSettingsService, nm_settings_service, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init)) - -#define NM_SETTINGS_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_SETTINGS_SERVICE, \ - NMSettingsServicePrivate)) - -typedef struct { - DBusGConnection *bus; - gboolean exported; - - gboolean disposed; -} NMSettingsServicePrivate; - -enum { - PROP_0, - PROP_BUS, - - LAST_PROP -}; - - -/**************************************************************/ - -void -nm_settings_service_export (NMSettingsService *self) -{ - NMSettingsServicePrivate *priv; - - g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_SETTINGS_SERVICE (self)); - - priv = NM_SETTINGS_SERVICE_GET_PRIVATE (self); - - g_return_if_fail (priv->bus != NULL); - - /* Don't allow exporting twice */ - g_return_if_fail (priv->exported == FALSE); - - dbus_g_connection_register_g_object (priv->bus, - NM_DBUS_PATH_SETTINGS, - G_OBJECT (self)); - priv->exported = TRUE; -} - -/**************************************************************/ - -static GSList * -list_connections (NMSettingsInterface *settings) -{ - /* Must always be implemented */ - g_assert (NM_SETTINGS_SERVICE_GET_CLASS (settings)->list_connections); - return NM_SETTINGS_SERVICE_GET_CLASS (settings)->list_connections (NM_SETTINGS_SERVICE (settings)); -} - -static gboolean -impl_settings_list_connections (NMSettingsService *self, - GPtrArray **connections, - GError **error) -{ - GSList *list = NULL, *iter; - - list = list_connections (NM_SETTINGS_INTERFACE (self)); - *connections = g_ptr_array_sized_new (g_slist_length (list) + 1); - for (iter = list; iter; iter = g_slist_next (iter)) { - g_ptr_array_add (*connections, - g_strdup (nm_connection_get_path (NM_CONNECTION (iter->data)))); - } - g_slist_free (list); - return TRUE; -} - -static NMSettingsConnectionInterface * -get_connection_by_path (NMSettingsInterface *settings, const char *path) -{ - NMExportedConnection *connection = NULL; - GSList *list = NULL, *iter; - - list = list_connections (settings); - for (iter = list; iter; iter = g_slist_next (iter)) { - if (!strcmp (nm_connection_get_path (NM_CONNECTION (iter->data)), path)) { - connection = NM_EXPORTED_CONNECTION (iter->data); - break; - } - } - g_slist_free (list); - - return (NMSettingsConnectionInterface *) connection; -} - -NMExportedConnection * -nm_settings_service_get_connection_by_path (NMSettingsService *self, - const char *path) -{ - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (NM_IS_SETTINGS_SERVICE (self), NULL); - - return (NMExportedConnection *) get_connection_by_path (NM_SETTINGS_INTERFACE (self), path); -} - -static gboolean -add_connection (NMSettingsInterface *settings, - NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer user_data) -{ - NMSettingsService *self = NM_SETTINGS_SERVICE (settings); - GError *error = NULL; - gboolean success = FALSE; - - if (NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection) { - NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection (NM_SETTINGS_SERVICE (self), - connection, - NULL, - callback, - user_data); - success = TRUE; - } else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, - "%s: %s:%d add_connection() not implemented", - __func__, __FILE__, __LINE__); - callback (settings, error, user_data); - g_error_free (error); - } - - return success; -} - -static void -dbus_add_connection_cb (NMSettingsInterface *settings, - GError *error, - gpointer user_data) -{ - DBusGMethodInvocation *context = user_data; - - if (error) - dbus_g_method_return_error (context, error); - else - dbus_g_method_return (context); -} - -static void -impl_settings_add_connection (NMSettingsService *self, - GHashTable *settings, - DBusGMethodInvocation *context) -{ - NMConnection *tmp; - GError *error = NULL; - - /* Check if the settings are valid first */ - tmp = nm_connection_new_from_hash (settings, &error); - if (!tmp) { - g_assert (error); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - if (NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection) { - NM_SETTINGS_SERVICE_GET_CLASS (self)->add_connection (NM_SETTINGS_SERVICE (self), - tmp, - context, - dbus_add_connection_cb, - context); - } else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, - "%s: %s:%d add_connection() not implemented", - __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } - - g_object_unref (tmp); -} - -void -nm_settings_service_export_connection (NMSettingsService *self, - NMSettingsConnectionInterface *connection) -{ - NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (self); - static guint32 ec_counter = 0; - char *path; - - g_return_if_fail (connection != NULL); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection)); - g_return_if_fail (priv->bus != NULL); - - /* Don't allow exporting twice */ - g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); - - path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); - nm_connection_set_path (NM_CONNECTION (connection), path); - - dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); - g_free (path); -} - -/**************************************************************/ - -static void -settings_interface_init (NMSettingsInterface *iface) -{ - /* interface implementation */ - iface->list_connections = list_connections; - iface->get_connection_by_path = get_connection_by_path; - iface->add_connection = add_connection; - - dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface), - &dbus_glib_nm_settings_object_info); -} - -static GObject * -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - - object = G_OBJECT_CLASS (nm_settings_service_parent_class)->constructor (type, n_construct_params, construct_params); - return object; -} - -static void -nm_settings_service_init (NMSettingsService *self) -{ -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object); - DBusGConnection *bus; - - switch (prop_id) { - case PROP_BUS: - /* Construct only */ - bus = g_value_get_boxed (value); - if (bus) - priv->bus = dbus_g_connection_ref (bus); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_BUS: - g_value_set_boxed (value, priv->bus); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -dispose (GObject *object) -{ - NMSettingsServicePrivate *priv = NM_SETTINGS_SERVICE_GET_PRIVATE (object); - - if (!priv->disposed) { - priv->disposed = TRUE; - if (priv->bus) - dbus_g_connection_unref (priv->bus); - } - - G_OBJECT_CLASS (nm_settings_service_parent_class)->dispose (object); -} - -static void -nm_settings_service_class_init (NMSettingsServiceClass *class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (class); - - g_type_class_add_private (class, sizeof (NMSettingsServicePrivate)); - - /* Virtual methods */ - object_class->dispose = dispose; - object_class->constructor = constructor; - object_class->get_property = get_property; - object_class->set_property = set_property; - - /** - * NMSettingsService:bus: - * - * The %DBusGConnection which this object is exported on - **/ - g_object_class_install_property (object_class, PROP_BUS, - g_param_spec_boxed (NM_SETTINGS_SERVICE_BUS, - "Bus", - "Bus", - DBUS_TYPE_G_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -} diff --git a/libnm-glib/nm-settings-service.h b/libnm-glib/nm-settings-service.h deleted file mode 100644 index 6a55d1ae6..000000000 --- a/libnm-glib/nm-settings-service.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2009 Red Hat, Inc. - */ - -#ifndef NM_SETTINGS_SERVICE_H -#define NM_SETTINGS_SERVICE_H - -#include -#include -#include -#include - -G_BEGIN_DECLS - -#define NM_TYPE_SETTINGS_SERVICE (nm_settings_service_get_type ()) -#define NM_SETTINGS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_SERVICE, NMSettingsService)) -#define NM_SETTINGS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_SERVICE, NMSettingsServiceClass)) -#define NM_IS_SETTINGS_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_SERVICE)) -#define NM_IS_SETTINGS_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTINGS_SERVICE)) -#define NM_SETTINGS_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_SERVICE, NMSettingsServiceClass)) - -#define NM_SETTINGS_SERVICE_BUS "bus" - -typedef struct { - GObject parent; -} NMSettingsService; - -typedef struct { - GObjectClass parent; - - /* Returned list must contain all NMExportedConnection objects exported - * by the settings service. The list (but not the NMExportedConnection - * objects) will be freed by caller. - */ - GSList * (*list_connections) (NMSettingsService *self); - - void (*add_connection) (NMSettingsService *self, - NMConnection *connection, - DBusGMethodInvocation *context, /* Only present for D-Bus calls */ - NMSettingsAddConnectionFunc callback, - gpointer user_data); - - /* Padding for future expansion */ - void (*_reserved1) (void); - void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); -} NMSettingsServiceClass; - -GType nm_settings_service_get_type (void); - -NMExportedConnection *nm_settings_service_get_connection_by_path (NMSettingsService *self, - const char *path); - -void nm_settings_service_export (NMSettingsService *self); - -void nm_settings_service_export_connection (NMSettingsService *self, - NMSettingsConnectionInterface *exported); - -G_END_DECLS - -#endif /* NM_SETTINGS_SERVICE_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index f17389cde..f77d89a8f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -3002,7 +3002,6 @@ nm_manager_get (const char *config_file, g_object_unref (singleton); return NULL; } - nm_settings_service_export (NM_SETTINGS_SERVICE (priv->sys_settings)); priv->config_file = g_strdup (config_file); diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 0b92228f5..005c878cd 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -9,6 +9,7 @@ INCLUDES = -I${top_srcdir} \ noinst_LTLIBRARIES = libsystem-settings.la BUILT_SOURCES = \ + nm-settings-glue.h \ nm-settings-system-glue.h libsystem_settings_la_SOURCES = \ @@ -53,6 +54,10 @@ libsystem_settings_la_LIBADD = \ libsystem_settings_la_LDFLAGS = -rdynamic + +nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< + nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $< diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index c5ff49da1..e3b31cd58 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,14 @@ static void claim_connection (NMSysconfigSettings *self, NMSettingsConnectionInterface *connection, gboolean do_export); +static gboolean impl_settings_list_connections (NMSysconfigSettings *self, + GPtrArray **connections, + GError **error); + +static void impl_settings_add_connection (NMSysconfigSettings *self, + GHashTable *settings, + DBusGMethodInvocation *context); + static void impl_settings_save_hostname (NMSysconfigSettings *self, const char *hostname, DBusGMethodInvocation *context); @@ -86,11 +95,15 @@ static void impl_settings_save_hostname (NMSysconfigSettings *self, static void impl_settings_get_permissions (NMSysconfigSettings *self, DBusGMethodInvocation *context); +#include "nm-settings-glue.h" #include "nm-settings-system-glue.h" static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); typedef struct { + DBusGConnection *bus; + gboolean exported; + PolkitAuthority *authority; guint auth_changed_id; char *config_file; @@ -106,7 +119,11 @@ typedef struct { static void settings_system_interface_init (NMSettingsSystemInterface *klass); -G_DEFINE_TYPE_WITH_CODE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS_SERVICE, +static void settings_interface_init (NMSettingsInterface *klass); + +G_DEFINE_TYPE_WITH_CODE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, + settings_interface_init) G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE, settings_system_interface_init)) @@ -122,6 +139,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, + PROP_BUS, PROP_UNMANAGED_SPECS, LAST_PROP @@ -160,7 +178,7 @@ load_connections (NMSysconfigSettings *self) } static GSList * -list_connections (NMSettingsService *settings) +list_connections (NMSettingsInterface *settings) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); GHashTableIter iter; @@ -175,6 +193,41 @@ list_connections (NMSettingsService *settings) return g_slist_reverse (list); } +static gboolean +impl_settings_list_connections (NMSysconfigSettings *self, + GPtrArray **connections, + GError **error) +{ + GSList *list = NULL, *iter; + + list = list_connections (NM_SETTINGS_INTERFACE (self)); + *connections = g_ptr_array_sized_new (g_slist_length (list) + 1); + for (iter = list; iter; iter = g_slist_next (iter)) { + g_ptr_array_add (*connections, + g_strdup (nm_connection_get_path (NM_CONNECTION (iter->data)))); + } + g_slist_free (list); + return TRUE; +} + +static NMSettingsConnectionInterface * +get_connection_by_path (NMSettingsInterface *settings, const char *path) +{ + NMExportedConnection *connection = NULL; + GSList *list = NULL, *iter; + + list = list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + if (!strcmp (nm_connection_get_path (NM_CONNECTION (iter->data)), path)) { + connection = NM_EXPORTED_CONNECTION (iter->data); + break; + } + } + g_slist_free (list); + + return (NMSettingsConnectionInterface *) connection; +} + static void clear_unmanaged_specs (NMSysconfigSettings *self) { @@ -483,6 +536,28 @@ connection_removed (NMSettingsConnectionInterface *connection, g_hash_table_remove (priv->connections, connection); } +static void +export_connection (NMSysconfigSettings *self, + NMSettingsConnectionInterface *connection) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + static guint32 ec_counter = 0; + char *path; + + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection)); + g_return_if_fail (priv->bus != NULL); + + /* Don't allow exporting twice */ + g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + + path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); + nm_connection_set_path (NM_CONNECTION (connection), path); + + dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); + g_free (path); +} + static void claim_connection (NMSysconfigSettings *self, NMSettingsConnectionInterface *connection, @@ -504,7 +579,7 @@ claim_connection (NMSysconfigSettings *self, self); if (do_export) { - nm_settings_service_export_connection (NM_SETTINGS_SERVICE (self), connection); + export_connection (self, connection); g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_NEW_CONNECTION, connection); } } @@ -684,13 +759,12 @@ out: } static void -add_connection (NMSettingsService *service, - NMConnection *connection, - DBusGMethodInvocation *context, /* Only present for D-Bus calls */ - NMSettingsAddConnectionFunc callback, - gpointer user_data) +internal_add_connection (NMSysconfigSettings *self, + NMConnection *connection, + DBusGMethodInvocation *context, /* Only present for D-Bus calls */ + NMSettingsAddConnectionFunc callback, + gpointer user_data) { - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (service); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); PolkitCall *call; GError *error = NULL; @@ -700,7 +774,7 @@ add_connection (NMSettingsService *service, error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "None of the registered plugins support add."); - callback (NM_SETTINGS_INTERFACE (service), error, user_data); + callback (NM_SETTINGS_INTERFACE (self), error, user_data); g_error_free (error); return; } @@ -718,6 +792,52 @@ add_connection (NMSettingsService *service, priv->pk_calls = g_slist_append (priv->pk_calls, call); } +static void +dbus_add_connection_cb (NMSettingsInterface *settings, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + +static void +impl_settings_add_connection (NMSysconfigSettings *self, + GHashTable *settings, + DBusGMethodInvocation *context) +{ + NMConnection *tmp; + GError *error = NULL; + + /* Check if the settings are valid first */ + tmp = nm_connection_new_from_hash (settings, &error); + if (!tmp) { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + internal_add_connection (self, tmp, context, dbus_add_connection_cb, context); + + g_object_unref (tmp); +} + +static gboolean +settings_interface_add_connection (NMSettingsInterface *settings, + NMConnection *connection, + NMSettingsAddConnectionFunc callback, + gpointer user_data) +{ + NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings); + internal_add_connection (self, connection, NULL, callback, user_data); + return TRUE; +} + static void pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) { @@ -1303,6 +1423,27 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (connection), TRUE); } +static void +export_sysconfig (NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + + priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + + g_return_if_fail (priv->bus != NULL); + + /* Don't allow exporting twice */ + g_return_if_fail (priv->exported == FALSE); + + dbus_g_connection_register_g_object (priv->bus, + NM_DBUS_PATH_SETTINGS, + G_OBJECT (self)); + priv->exported = TRUE; +} + NMSysconfigSettings * nm_sysconfig_settings_new (const char *config_file, const char *plugins, @@ -1313,7 +1454,7 @@ nm_sysconfig_settings_new (const char *config_file, NMSysconfigSettingsPrivate *priv; self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, - NM_SETTINGS_SERVICE_BUS, bus, + NM_SYSCONFIG_SETTINGS_BUS, bus, NULL); if (!self) return NULL; @@ -1331,6 +1472,8 @@ nm_sysconfig_settings_new (const char *config_file, unmanaged_specs_changed (NULL, self); } + export_sysconfig (self); + return self; } @@ -1368,6 +1511,9 @@ dispose (GObject *object) g_slist_free (priv->permissions_calls); priv->permissions_calls = NULL; + if (priv->bus) + dbus_g_connection_unref (priv->bus); + G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); } @@ -1398,15 +1544,51 @@ settings_system_interface_init (NMSettingsSystemInterface *iface) &dbus_glib_nm_settings_system_object_info); } +static void +settings_interface_init (NMSettingsInterface *iface) +{ + iface->add_connection = settings_interface_add_connection; + iface->list_connections = list_connections; + iface->get_connection_by_path = get_connection_by_path; + + dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface), + &dbus_glib_nm_settings_object_info); + +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (object); + DBusGConnection *bus; + + switch (prop_id) { + case PROP_BUS: + /* Construct only */ + bus = g_value_get_boxed (value); + if (bus) + priv->bus = dbus_g_connection_ref (bus); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); const GSList *specs, *iter; GSList *copy = NULL; switch (prop_id) { + case PROP_BUS: + g_value_set_boxed (value, priv->bus); + break; case PROP_UNMANAGED_SPECS: specs = nm_sysconfig_settings_get_unmanaged_specs (self); for (iter = specs; iter; iter = g_slist_next (iter)) @@ -1433,19 +1615,31 @@ static void nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - NMSettingsServiceClass *ss_class = NM_SETTINGS_SERVICE_CLASS (class); g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate)); /* virtual methods */ object_class->notify = notify; + object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; - ss_class->list_connections = list_connections; - ss_class->add_connection = add_connection; /* properties */ + + /** + * NMSysconfigSettings:bus: + * + * The %DBusGConnection which this object is exported on + **/ + g_object_class_install_property + (object_class, PROP_BUS, + g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_BUS, + "Bus", + "Bus", + DBUS_TYPE_G_CONNECTION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_UNMANAGED_SPECS, g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index ae2ba6832..906afff3b 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -27,7 +27,6 @@ #define __NM_SYSCONFIG_SETTINGS_H__ #include -#include #include "nm-sysconfig-connection.h" #include "nm-system-config-interface.h" @@ -40,14 +39,15 @@ #define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) #define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) +#define NM_SYSCONFIG_SETTINGS_BUS "bus" #define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" typedef struct { - NMSettingsService parent_instance; + GObject parent_instance; } NMSysconfigSettings; typedef struct { - NMSettingsServiceClass parent_class; + GObjectClass parent_class; /* Signals */ void (*properties_changed) (NMSysconfigSettings *self, GHashTable *properties); From 4d1681ef09ad881a9e919b071c71ea55ef362b80 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 29 Jul 2010 21:28:49 -0400 Subject: [PATCH 010/264] libnm-glib: merge nm-remote-settings{,-system} Originally, nm-remote-settings was used by the daemon to monitor the user settings service, and its subclass nm-remote-settings-system was used by NM clients to monitor the system settings service. With user settings services gone, this distinction is no longer needed. Simplify things a bit and merge the classes. --- cli/src/connections.c | 3 +- cli/src/nmcli.c | 1 - cli/src/nmcli.h | 3 +- docs/libnm-glib/libnm-glib-docs.sgml | 1 - libnm-glib/Makefile.am | 2 - libnm-glib/libnm-glib.ver | 2 - libnm-glib/nm-remote-settings-system.c | 374 ------------------------- libnm-glib/nm-remote-settings-system.h | 64 ----- libnm-glib/nm-remote-settings.c | 247 +++++++++++++++- 9 files changed, 248 insertions(+), 449 deletions(-) delete mode 100644 libnm-glib/nm-remote-settings-system.c delete mode 100644 libnm-glib/nm-remote-settings-system.h diff --git a/cli/src/connections.c b/cli/src/connections.c index 42fde78aa..67e0c18a9 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -45,7 +45,6 @@ #include //#include #include -#include #include #include #include @@ -1529,7 +1528,7 @@ do_connections (NmCli *nmc, int argc, char **argv) } /* get system settings */ - if (!(nmc->system_settings = nm_remote_settings_system_new (bus))) { + if (!(nmc->system_settings = nm_remote_settings_new (bus))) { g_string_printf (nmc->return_text, _("Error: Could not get system settings.")); nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; return nmc->return_value; diff --git a/cli/src/nmcli.c b/cli/src/nmcli.c index 10b248a28..bbf1f18d0 100644 --- a/cli/src/nmcli.c +++ b/cli/src/nmcli.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/cli/src/nmcli.h b/cli/src/nmcli.h index 50318d5eb..c980f4981 100644 --- a/cli/src/nmcli.h +++ b/cli/src/nmcli.h @@ -24,7 +24,6 @@ #include #include -#include /* nmcli exit codes */ typedef enum { @@ -92,7 +91,7 @@ typedef struct _NmCli { int timeout; /* Operation timeout */ - NMRemoteSettingsSystem *system_settings; /* System settings */ + NMRemoteSettings *system_settings; /* System settings */ gboolean system_settings_running; /* Is system settings service running? */ GSList *system_connections; /* List of system connections */ diff --git a/docs/libnm-glib/libnm-glib-docs.sgml b/docs/libnm-glib/libnm-glib-docs.sgml index b4e5dac25..422c9d3c4 100644 --- a/docs/libnm-glib/libnm-glib-docs.sgml +++ b/docs/libnm-glib/libnm-glib-docs.sgml @@ -31,7 +31,6 @@ - diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index a59e5f346..2e91ecb67 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -81,7 +81,6 @@ libnminclude_HEADERS = \ nm-settings-interface.h \ nm-settings-system-interface.h \ nm-remote-settings.h \ - nm-remote-settings-system.h \ nm-settings-connection-interface.h \ nm-exported-connection.h @@ -115,7 +114,6 @@ libnm_glib_la_SOURCES = \ nm-settings-interface.c \ nm-settings-system-interface.c \ nm-remote-settings.c \ - nm-remote-settings-system.c \ nm-settings-connection-interface.c \ nm-exported-connection.c diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index c4c171c04..0967c9a39 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -123,8 +123,6 @@ global: nm_remote_connection_new; nm_remote_settings_get_type; nm_remote_settings_new; - nm_remote_settings_system_get_type; - nm_remote_settings_system_new; nm_serial_device_get_bytes_received; nm_serial_device_get_bytes_sent; nm_serial_device_get_type; diff --git a/libnm-glib/nm-remote-settings-system.c b/libnm-glib/nm-remote-settings-system.c deleted file mode 100644 index 033aa0124..000000000 --- a/libnm-glib/nm-remote-settings-system.c +++ /dev/null @@ -1,374 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * libnm_glib -- Access network status & information from glib applications - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2009 - 2010 Red Hat, Inc. - */ - -#include -#include -#include - -#include "nm-marshal.h" -#include "nm-dbus-glib-types.h" -#include "nm-remote-settings-system.h" -#include "nm-settings-system-bindings.h" -#include "nm-settings-system-interface.h" - -static void settings_system_interface_init (NMSettingsSystemInterface *klass); - -G_DEFINE_TYPE_EXTENDED (NMRemoteSettingsSystem, nm_remote_settings_system, NM_TYPE_REMOTE_SETTINGS, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE, settings_system_interface_init)) - -#define NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystemPrivate)) - -typedef struct { - DBusGProxy *proxy; - DBusGProxy *props_proxy; - - char *hostname; - gboolean can_modify; - - NMSettingsSystemPermissions permissions; - gboolean have_permissions; - - gboolean disposed; -} NMRemoteSettingsSystemPrivate; - -static void -properties_changed_cb (DBusGProxy *proxy, - GHashTable *properties, - gpointer user_data) -{ - NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (user_data); - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (self); - GHashTableIter iter; - gpointer key, tmp; - - g_hash_table_iter_init (&iter, properties); - while (g_hash_table_iter_next (&iter, &key, &tmp)) { - GValue *value = tmp; - - if (!strcmp ((const char *) key, "Hostname")) { - g_free (priv->hostname); - priv->hostname = g_value_dup_string (value); - g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); - } - - if (!strcmp ((const char *) key, "CanModify")) { - priv->can_modify = g_value_get_boolean (value); - g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); - } - } -} - -static void -get_all_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (user_data); - GHashTable *props = NULL; - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call, &error, - DBUS_TYPE_G_MAP_OF_VARIANT, &props, - G_TYPE_INVALID)) { - /* Don't warn when the call times out because the settings service can't - * be activated or whatever. - */ - if (!(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NO_REPLY)) { - g_warning ("%s: couldn't retrieve system settings properties: (%d) %s.", - __func__, - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); - } - g_clear_error (&error); - return; - } - - properties_changed_cb (NULL, props, self); - g_hash_table_destroy (props); -} - -typedef struct { - NMSettingsSystemInterface *settings; - NMSettingsSystemSaveHostnameFunc callback; - gpointer callback_data; -} SaveHostnameInfo; - -static void -save_hostname_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - SaveHostnameInfo *info = user_data; - GError *error = NULL; - - dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); - info->callback (info->settings, error, info->callback_data); - g_clear_error (&error); -} - -static gboolean -save_hostname (NMSettingsSystemInterface *settings, - const char *hostname, - NMSettingsSystemSaveHostnameFunc callback, - gpointer user_data) -{ - NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (settings); - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (self); - SaveHostnameInfo *info; - - info = g_malloc0 (sizeof (SaveHostnameInfo)); - info->settings = settings; - info->callback = callback; - info->callback_data = user_data; - - dbus_g_proxy_begin_call (priv->proxy, "SaveHostname", - save_hostname_cb, - info, - g_free, - G_TYPE_STRING, hostname ? hostname : "", - G_TYPE_INVALID); - return TRUE; -} - -typedef struct { - NMSettingsSystemInterface *settings; - NMSettingsSystemGetPermissionsFunc callback; - gpointer callback_data; -} GetPermissionsInfo; - -static void -get_permissions_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - GetPermissionsInfo *info = user_data; - NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (info->settings); - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (self); - NMSettingsSystemPermissions permissions = NM_SETTINGS_SYSTEM_PERMISSION_NONE; - GError *error = NULL; - - dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_UINT, &permissions, - G_TYPE_INVALID); - priv->permissions = permissions; - priv->have_permissions = !error; - info->callback (info->settings, permissions, error, info->callback_data); - g_clear_error (&error); -} - -static gboolean -get_permissions (NMSettingsSystemInterface *settings, - NMSettingsSystemGetPermissionsFunc callback, - gpointer user_data) -{ - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (settings); - GetPermissionsInfo *info; - - /* Skip D-Bus if we already have permissions */ - if (priv->have_permissions) { - callback (settings, priv->permissions, NULL, user_data); - return TRUE; - } - - /* Otherwise fetch them from NM */ - info = g_malloc0 (sizeof (GetPermissionsInfo)); - info->settings = settings; - info->callback = callback; - info->callback_data = user_data; - - dbus_g_proxy_begin_call (priv->proxy, "GetPermissions", - get_permissions_cb, - info, - g_free, - G_TYPE_INVALID); - return TRUE; -} - -static void -check_permissions_cb (DBusGProxy *proxy, gpointer user_data) -{ - NMRemoteSettingsSystem *self = NM_REMOTE_SETTINGS_SYSTEM (user_data); - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (self); - - /* Permissions need to be re-fetched */ - priv->have_permissions = FALSE; - g_signal_emit_by_name (self, NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS); -} - -/****************************************************************/ - -static void -settings_system_interface_init (NMSettingsSystemInterface *klass) -{ - /* interface implementation */ - klass->save_hostname = save_hostname; - klass->get_permissions = get_permissions; -} - -/** - * nm_remote_settings_system_new: - * @bus: a valid and connected D-Bus connection - * - * Creates a new object representing the remote system settings service. - * - * Returns: the new remote system settings object on success, or %NULL on failure - **/ -NMRemoteSettingsSystem * -nm_remote_settings_system_new (DBusGConnection *bus) -{ - g_return_val_if_fail (bus != NULL, NULL); - - return (NMRemoteSettingsSystem *) g_object_new (NM_TYPE_REMOTE_SETTINGS_SYSTEM, - NM_REMOTE_SETTINGS_BUS, bus, - NULL); -} - -static void -nm_remote_settings_system_init (NMRemoteSettingsSystem *self) -{ -} - -static GObject * -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - GObject *object; - NMRemoteSettingsSystemPrivate *priv; - DBusGConnection *bus = NULL; - - object = G_OBJECT_CLASS (nm_remote_settings_system_parent_class)->constructor (type, n_construct_params, construct_params); - if (!object) - return NULL; - - priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (object); - - g_object_get (G_OBJECT (object), NM_REMOTE_SETTINGS_BUS, &bus, NULL); - g_assert (bus); - - /* D-Bus properties proxy */ - priv->props_proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, - NM_DBUS_PATH_SETTINGS, - "org.freedesktop.DBus.Properties"); - g_assert (priv->props_proxy); - - /* System settings proxy */ - priv->proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_IFACE_SETTINGS_SYSTEM); - g_assert (priv->proxy); - dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); - - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, - DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->proxy, "PropertiesChanged", - DBUS_TYPE_G_MAP_OF_VARIANT, - G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "PropertiesChanged", - G_CALLBACK (properties_changed_cb), - object, - NULL); - - /* Monitor for permissions changes */ - dbus_g_proxy_add_signal (priv->proxy, "CheckPermissions", G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "CheckPermissions", - G_CALLBACK (check_permissions_cb), - object, - NULL); - - /* Get properties */ - dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", - get_all_cb, - object, - NULL, - G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_SYSTEM, - G_TYPE_INVALID); - - dbus_g_connection_unref (bus); - - return object; -} - -static void -dispose (GObject *object) -{ - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (object); - - if (priv->disposed) - return; - - priv->disposed = TRUE; - - g_free (priv->hostname); - - g_object_unref (priv->props_proxy); - g_object_unref (priv->proxy); - - G_OBJECT_CLASS (nm_remote_settings_system_parent_class)->dispose (object); -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMRemoteSettingsSystemPrivate *priv = NM_REMOTE_SETTINGS_SYSTEM_GET_PRIVATE (object); - - switch (prop_id) { - case NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME: - g_value_set_string (value, priv->hostname); - break; - case NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY: - g_value_set_boolean (value, priv->can_modify); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_remote_settings_system_class_init (NMRemoteSettingsSystemClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (NMRemoteSettingsSystemPrivate)); - - /* Virtual methods */ - object_class->constructor = constructor; - object_class->get_property = get_property; - object_class->dispose = dispose; - - /* Properties */ - g_object_class_override_property (object_class, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME, - NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); - - g_object_class_override_property (object_class, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY, - NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); -} - diff --git a/libnm-glib/nm-remote-settings-system.h b/libnm-glib/nm-remote-settings-system.h deleted file mode 100644 index b51822733..000000000 --- a/libnm-glib/nm-remote-settings-system.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * libnm_glib -- Access network status & information from glib applications - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2009 Red Hat, Inc. - */ - -#ifndef NM_REMOTE_SETTINGS_SYSTEM_H -#define NM_REMOTE_SETTINGS_SYSTEM_H - -#include -#include - -#include "nm-remote-settings.h" -#include "nm-settings-system-interface.h" - -G_BEGIN_DECLS - -#define NM_TYPE_REMOTE_SETTINGS_SYSTEM (nm_remote_settings_system_get_type ()) -#define NM_REMOTE_SETTINGS_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystem)) -#define NM_REMOTE_SETTINGS_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystemClass)) -#define NM_IS_REMOTE_SETTINGS_SYSTEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM)) -#define NM_IS_REMOTE_SETTINGS_SYSTEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM)) -#define NM_REMOTE_SETTINGS_SYSTEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS_SYSTEM, NMRemoteSettingsSystemClass)) - -typedef struct { - NMRemoteSettings parent; -} NMRemoteSettingsSystem; - -typedef struct { - NMRemoteSettingsClass parent; - - /* Padding for future expansion */ - void (*_reserved1) (void); - void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); -} NMRemoteSettingsSystemClass; - -GType nm_remote_settings_system_get_type (void); - -NMRemoteSettingsSystem *nm_remote_settings_system_new (DBusGConnection *bus); - -G_END_DECLS - -#endif /* NM_REMOTE_SETTINGS_SYSTEM_H */ diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 3e7f481d6..0e1a0fd6c 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -26,15 +26,20 @@ #include #include "nm-marshal.h" +#include "nm-dbus-glib-types.h" #include "nm-remote-settings.h" #include "nm-settings-bindings.h" #include "nm-settings-interface.h" +#include "nm-settings-system-bindings.h" +#include "nm-settings-system-interface.h" #include "nm-remote-connection-private.h" static void settings_interface_init (NMSettingsInterface *class); +static void settings_system_interface_init (NMSettingsSystemInterface *class); G_DEFINE_TYPE_EXTENDED (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init)) + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init) + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE, settings_system_interface_init)) #define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate)) @@ -45,6 +50,13 @@ typedef struct { GHashTable *connections; GHashTable *pending; /* Connections we don't have settings for yet */ gboolean service_running; + + DBusGProxy *props_proxy; + DBusGProxy *sys_proxy; + NMSettingsSystemPermissions permissions; + gboolean have_permissions; + char *hostname; + gboolean can_modify; DBusGProxy *dbus_proxy; @@ -283,6 +295,103 @@ remove_connections (gpointer user_data) return FALSE; } +typedef struct { + NMSettingsSystemInterface *settings; + NMSettingsSystemSaveHostnameFunc callback; + gpointer callback_data; +} SaveHostnameInfo; + +static void +save_hostname_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + SaveHostnameInfo *info = user_data; + GError *error = NULL; + + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + info->callback (info->settings, error, info->callback_data); + g_clear_error (&error); +} + +static gboolean +save_hostname (NMSettingsSystemInterface *settings, + const char *hostname, + NMSettingsSystemSaveHostnameFunc callback, + gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (settings); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + SaveHostnameInfo *info; + + info = g_malloc0 (sizeof (SaveHostnameInfo)); + info->settings = settings; + info->callback = callback; + info->callback_data = user_data; + + dbus_g_proxy_begin_call (priv->sys_proxy, "SaveHostname", + save_hostname_cb, + info, + g_free, + G_TYPE_STRING, hostname ? hostname : "", + G_TYPE_INVALID); + return TRUE; +} + +typedef struct { + NMSettingsSystemInterface *settings; + NMSettingsSystemGetPermissionsFunc callback; + gpointer callback_data; +} GetPermissionsInfo; + +static void +get_permissions_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + GetPermissionsInfo *info = user_data; + NMRemoteSettings *self = NM_REMOTE_SETTINGS (info->settings); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + NMSettingsSystemPermissions permissions = NM_SETTINGS_SYSTEM_PERMISSION_NONE; + GError *error = NULL; + + dbus_g_proxy_end_call (proxy, call, &error, + G_TYPE_UINT, &permissions, + G_TYPE_INVALID); + priv->permissions = permissions; + priv->have_permissions = !error; + info->callback (info->settings, permissions, error, info->callback_data); + g_clear_error (&error); +} + +static gboolean +get_permissions (NMSettingsSystemInterface *settings, + NMSettingsSystemGetPermissionsFunc callback, + gpointer user_data) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + GetPermissionsInfo *info; + + /* Skip D-Bus if we already have permissions */ + if (priv->have_permissions) { + callback (settings, priv->permissions, NULL, user_data); + return TRUE; + } + + /* Otherwise fetch them from NM */ + info = g_malloc0 (sizeof (GetPermissionsInfo)); + info->settings = settings; + info->callback = callback; + info->callback_data = user_data; + + dbus_g_proxy_begin_call (priv->sys_proxy, "GetPermissions", + get_permissions_cb, + info, + g_free, + G_TYPE_INVALID); + return TRUE; +} + static void name_owner_changed (DBusGProxy *proxy, const char *name, @@ -309,6 +418,73 @@ name_owner_changed (DBusGProxy *proxy, } } +static void +check_permissions_cb (DBusGProxy *proxy, gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + + /* Permissions need to be re-fetched */ + priv->have_permissions = FALSE; + g_signal_emit_by_name (self, NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS); +} + +static void +properties_changed_cb (DBusGProxy *proxy, + GHashTable *properties, + gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer key, tmp; + + g_hash_table_iter_init (&iter, properties); + while (g_hash_table_iter_next (&iter, &key, &tmp)) { + GValue *value = tmp; + + if (!strcmp ((const char *) key, "Hostname")) { + g_free (priv->hostname); + priv->hostname = g_value_dup_string (value); + g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); + } + + if (!strcmp ((const char *) key, "CanModify")) { + priv->can_modify = g_value_get_boolean (value); + g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); + } + } +} + +static void +get_all_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + GHashTable *props = NULL; + GError *error = NULL; + + if (!dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + /* Don't warn when the call times out because the settings service can't + * be activated or whatever. + */ + if (!(error->domain == DBUS_GERROR && error->code == DBUS_GERROR_NO_REPLY)) { + g_warning ("%s: couldn't retrieve system settings properties: (%d) %s.", + __func__, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + } + g_clear_error (&error); + return; + } + + properties_changed_cb (NULL, props, self); + g_hash_table_destroy (props); +} + /****************************************************************/ static void @@ -320,6 +496,14 @@ settings_interface_init (NMSettingsInterface *iface) iface->add_connection = add_connection; } +static void +settings_system_interface_init (NMSettingsSystemInterface *klass) +{ + /* interface implementation */ + klass->save_hostname = save_hostname; + klass->get_permissions = get_permissions; +} + /** * nm_remote_settings_new: * @bus: a valid and connected D-Bus connection @@ -411,6 +595,49 @@ constructor (GType type, priv->fetch_id = g_idle_add (fetch_connections, object); + + /* D-Bus properties proxy */ + priv->props_proxy = dbus_g_proxy_new_for_name (priv->bus, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_PATH_SETTINGS, + "org.freedesktop.DBus.Properties"); + g_assert (priv->props_proxy); + + /* System settings proxy */ + priv->sys_proxy = dbus_g_proxy_new_for_name (priv->bus, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS_SYSTEM); + g_assert (priv->sys_proxy); + dbus_g_proxy_set_default_timeout (priv->sys_proxy, G_MAXINT); + + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->sys_proxy, "PropertiesChanged", + DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->sys_proxy, "PropertiesChanged", + G_CALLBACK (properties_changed_cb), + object, + NULL); + + /* Monitor for permissions changes */ + dbus_g_proxy_add_signal (priv->sys_proxy, "CheckPermissions", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->sys_proxy, "CheckPermissions", + G_CALLBACK (check_permissions_cb), + object, + NULL); + + /* Get properties */ + dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", + get_all_cb, + object, + NULL, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_SYSTEM, + G_TYPE_INVALID); + return object; } @@ -433,8 +660,11 @@ dispose (GObject *object) if (priv->pending) g_hash_table_destroy (priv->pending); + g_free (priv->hostname); + g_object_unref (priv->dbus_proxy); g_object_unref (priv->proxy); + g_object_unref (priv->props_proxy); dbus_g_connection_unref (priv->bus); G_OBJECT_CLASS (nm_remote_settings_parent_class)->dispose (object); @@ -470,6 +700,12 @@ get_property (GObject *object, guint prop_id, case PROP_SERVICE_RUNNING: g_value_set_boolean (value, priv->service_running); break; + case NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME: + g_value_set_string (value, priv->hostname); + break; + case NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY: + g_value_set_boolean (value, priv->can_modify); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -505,5 +741,14 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) "Is service running", FALSE, G_PARAM_READABLE)); + + g_object_class_override_property (object_class, + NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME, + NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); + + g_object_class_override_property (object_class, + NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY, + NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); + } From da6816a03b0a70c15ec00da58cfdbad97486ff4f Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 29 Jul 2010 21:58:16 -0400 Subject: [PATCH 011/264] nm-glib/DBus: merge nm-settings{,-system} iface Much as with nm-remote-settings and nm-remote-settings-system, the removal of user settings services means there is no more need for separate interfaces for user and system settings services. In libnm-glib, this commit merges everything in nm-settings-system-interface into nm-settings-interface. Alongside with that, we merge everything in the org.freedesktop.NetworkManagerSettings.System DBus interface into org.freedesktop.NetworkManagerSettings. --- docs/libnm-glib/Makefile.am | 1 - docs/libnm-glib/libnm-glib-docs.sgml | 1 - include/NetworkManager.h | 1 - introspection/nm-settings-system.xml | 81 ----------- introspection/nm-settings.xml | 70 +++++++++ libnm-glib/Makefile.am | 6 - libnm-glib/libnm-glib.ver | 6 +- libnm-glib/nm-remote-settings.c | 78 ++++------ libnm-glib/nm-settings-interface.c | 84 +++++++++++ libnm-glib/nm-settings-interface.h | 53 ++++++- libnm-glib/nm-settings-system-interface.c | 150 -------------------- libnm-glib/nm-settings-system-interface.h | 108 -------------- src/nm-manager.c | 3 +- src/system-settings/Makefile.am | 6 +- src/system-settings/nm-sysconfig-settings.c | 66 ++++----- 15 files changed, 265 insertions(+), 449 deletions(-) delete mode 100644 introspection/nm-settings-system.xml delete mode 100644 libnm-glib/nm-settings-system-interface.c delete mode 100644 libnm-glib/nm-settings-system-interface.h diff --git a/docs/libnm-glib/Makefile.am b/docs/libnm-glib/Makefile.am index 96ff66eee..b12e730a4 100644 --- a/docs/libnm-glib/Makefile.am +++ b/docs/libnm-glib/Makefile.am @@ -51,7 +51,6 @@ IGNORE_HFILES= \ nm-ip6-config-bindings.h \ nm-settings-bindings.h \ nm-settings-glue.h \ - nm-settings-system-bindings.h \ nm-vpn-connection-bindings.h \ nm-vpn-plugin-glue.h diff --git a/docs/libnm-glib/libnm-glib-docs.sgml b/docs/libnm-glib/libnm-glib-docs.sgml index 422c9d3c4..87e6b40d0 100644 --- a/docs/libnm-glib/libnm-glib-docs.sgml +++ b/docs/libnm-glib/libnm-glib-docs.sgml @@ -34,7 +34,6 @@ - diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 4001dae03..56fcfa276 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -47,7 +47,6 @@ #define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings" #define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings" -#define NM_DBUS_IFACE_SETTINGS_SYSTEM "org.freedesktop.NetworkManagerSettings.System" #define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings" #define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection" diff --git a/introspection/nm-settings-system.xml b/introspection/nm-settings-system.xml deleted file mode 100644 index 598274c0d..000000000 --- a/introspection/nm-settings-system.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - Implemented by the system settings service to provide additional settings to NetworkManager. - - - - - Save the hostname to persistent configuration. - - - - - - The hostname to save to persistent configuration. If blank, the persistent hostname is cleared. - - - - - - - The machine hostname stored in persistent configuration. - - - - - - If true, adding and modifying connections is supported. - - - - - - - A dictionary mapping property names to variant boxed values - - - - - - - Emitted when system authorization details change, indicating that clients may wish to recheck permissions with GetPermissions. - - - - - - Returns a bitfield indicating certain operations the caller is permitted to perform. Some of these operations may require authorization by the user. - - - - - - A bitfield of permitted operations. Some of these operations may require the user to authorize via password entry or other means. - - - - - - - No permissions. - - - Can modify/add/delete connections. - - - Can share connections via a encrypted user-created WiFi network. - - - Can share connections via a open/unencrypted user-created WiFi network. - - - Can modify the persistent system hostname. - - - - - - diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml index b252c00d5..67e6d2abb 100644 --- a/introspection/nm-settings.xml +++ b/introspection/nm-settings.xml @@ -31,6 +31,58 @@ + + + Save the hostname to persistent configuration. + + + + + + The hostname to save to persistent configuration. If blank, the persistent hostname is cleared. + + + + + + + Returns a bitfield indicating certain operations the caller is permitted to perform. Some of these operations may require authorization by the user. + + + + + + A bitfield of permitted operations. Some of these operations may require the user to authorize via password entry or other means. + + + + + + + The machine hostname stored in persistent configuration. + + + + + + If true, adding and modifying connections is supported. + + + + + + + A dictionary mapping property names to variant boxed values + + + + + + + Emitted when system authorization details change, indicating that clients may wish to recheck permissions with GetPermissions. + + + Emitted when a new connection has been added. @@ -42,6 +94,24 @@ + + + No permissions. + + + Can modify/add/delete connections. + + + Can share connections via a encrypted user-created WiFi network. + + + Can share connections via a open/unencrypted user-created WiFi network. + + + Can modify the persistent system hostname. + + + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 2e91ecb67..388ab5402 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -13,7 +13,6 @@ BUILT_SOURCES = \ nm-exported-connection-glue.h \ nm-exported-connection-bindings.h \ nm-settings-bindings.h \ - nm-settings-system-bindings.h \ nm-vpn-connection-bindings.h \ nm-vpn-plugin-glue.h \ nm-active-connection-bindings.h \ @@ -79,7 +78,6 @@ libnminclude_HEADERS = \ nm-dhcp6-config.h \ nm-remote-connection.h \ nm-settings-interface.h \ - nm-settings-system-interface.h \ nm-remote-settings.h \ nm-settings-connection-interface.h \ nm-exported-connection.h @@ -112,7 +110,6 @@ libnm_glib_la_SOURCES = \ nm-remote-connection.c \ nm-remote-connection-private.h \ nm-settings-interface.c \ - nm-settings-system-interface.c \ nm-remote-settings.c \ nm-settings-connection-interface.c \ nm-exported-connection.c @@ -164,9 +161,6 @@ nm-access-point-bindings.h: $(top_srcdir)/introspection/nm-access-point.xml nm-settings-bindings.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-client --output=$@ $< -nm-settings-system-bindings.h: $(top_srcdir)/introspection/nm-settings-system.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_system --mode=glib-client --output=$@ $< - nm-exported-connection-glue.h: $(top_srcdir)/introspection/nm-exported-connection.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_exported_connection --mode=glib-server --output=$@ $< diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 0967c9a39..2dc9783cc 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -137,10 +137,8 @@ global: nm_settings_interface_get_connection_by_path; nm_settings_interface_get_type; nm_settings_interface_list_connections; - nm_settings_system_interface_get_type; - nm_settings_system_interface_add_connection; - nm_settings_system_interface_get_permissions; - nm_settings_system_interface_save_hostname; + nm_settings_interface_get_permissions; + nm_settings_interface_save_hostname; nm_settings_error_quark; nm_settings_get_type; nm_settings_list_connections; diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 0e1a0fd6c..8b0c4ecad 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -30,16 +30,12 @@ #include "nm-remote-settings.h" #include "nm-settings-bindings.h" #include "nm-settings-interface.h" -#include "nm-settings-system-bindings.h" -#include "nm-settings-system-interface.h" #include "nm-remote-connection-private.h" static void settings_interface_init (NMSettingsInterface *class); -static void settings_system_interface_init (NMSettingsSystemInterface *class); G_DEFINE_TYPE_EXTENDED (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init) - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE, settings_system_interface_init)) + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init)) #define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate)) @@ -52,8 +48,7 @@ typedef struct { gboolean service_running; DBusGProxy *props_proxy; - DBusGProxy *sys_proxy; - NMSettingsSystemPermissions permissions; + NMSettingsPermissions permissions; gboolean have_permissions; char *hostname; gboolean can_modify; @@ -296,8 +291,8 @@ remove_connections (gpointer user_data) } typedef struct { - NMSettingsSystemInterface *settings; - NMSettingsSystemSaveHostnameFunc callback; + NMSettingsInterface *settings; + NMSettingsSaveHostnameFunc callback; gpointer callback_data; } SaveHostnameInfo; @@ -315,9 +310,9 @@ save_hostname_cb (DBusGProxy *proxy, } static gboolean -save_hostname (NMSettingsSystemInterface *settings, +save_hostname (NMSettingsInterface *settings, const char *hostname, - NMSettingsSystemSaveHostnameFunc callback, + NMSettingsSaveHostnameFunc callback, gpointer user_data) { NMRemoteSettings *self = NM_REMOTE_SETTINGS (settings); @@ -329,7 +324,7 @@ save_hostname (NMSettingsSystemInterface *settings, info->callback = callback; info->callback_data = user_data; - dbus_g_proxy_begin_call (priv->sys_proxy, "SaveHostname", + dbus_g_proxy_begin_call (priv->proxy, "SaveHostname", save_hostname_cb, info, g_free, @@ -339,8 +334,8 @@ save_hostname (NMSettingsSystemInterface *settings, } typedef struct { - NMSettingsSystemInterface *settings; - NMSettingsSystemGetPermissionsFunc callback; + NMSettingsInterface *settings; + NMSettingsGetPermissionsFunc callback; gpointer callback_data; } GetPermissionsInfo; @@ -352,7 +347,7 @@ get_permissions_cb (DBusGProxy *proxy, GetPermissionsInfo *info = user_data; NMRemoteSettings *self = NM_REMOTE_SETTINGS (info->settings); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - NMSettingsSystemPermissions permissions = NM_SETTINGS_SYSTEM_PERMISSION_NONE; + NMSettingsPermissions permissions = NM_SETTINGS_PERMISSION_NONE; GError *error = NULL; dbus_g_proxy_end_call (proxy, call, &error, @@ -365,8 +360,8 @@ get_permissions_cb (DBusGProxy *proxy, } static gboolean -get_permissions (NMSettingsSystemInterface *settings, - NMSettingsSystemGetPermissionsFunc callback, +get_permissions (NMSettingsInterface *settings, + NMSettingsGetPermissionsFunc callback, gpointer user_data) { NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); @@ -384,7 +379,7 @@ get_permissions (NMSettingsSystemInterface *settings, info->callback = callback; info->callback_data = user_data; - dbus_g_proxy_begin_call (priv->sys_proxy, "GetPermissions", + dbus_g_proxy_begin_call (priv->proxy, "GetPermissions", get_permissions_cb, info, g_free, @@ -426,7 +421,7 @@ check_permissions_cb (DBusGProxy *proxy, gpointer user_data) /* Permissions need to be re-fetched */ priv->have_permissions = FALSE; - g_signal_emit_by_name (self, NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS); + g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS); } static void @@ -446,12 +441,12 @@ properties_changed_cb (DBusGProxy *proxy, if (!strcmp ((const char *) key, "Hostname")) { g_free (priv->hostname); priv->hostname = g_value_dup_string (value); - g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); + g_object_notify (G_OBJECT (self), NM_SETTINGS_INTERFACE_HOSTNAME); } if (!strcmp ((const char *) key, "CanModify")) { priv->can_modify = g_value_get_boolean (value); - g_object_notify (G_OBJECT (self), NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); + g_object_notify (G_OBJECT (self), NM_SETTINGS_INTERFACE_CAN_MODIFY); } } } @@ -494,14 +489,8 @@ settings_interface_init (NMSettingsInterface *iface) iface->list_connections = list_connections; iface->get_connection_by_path = get_connection_by_path; iface->add_connection = add_connection; -} - -static void -settings_system_interface_init (NMSettingsSystemInterface *klass) -{ - /* interface implementation */ - klass->save_hostname = save_hostname; - klass->get_permissions = get_permissions; + iface->save_hostname = save_hostname; + iface->get_permissions = get_permissions; } /** @@ -603,29 +592,22 @@ constructor (GType type, "org.freedesktop.DBus.Properties"); g_assert (priv->props_proxy); - /* System settings proxy */ - priv->sys_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, - NM_DBUS_PATH_SETTINGS, - NM_DBUS_IFACE_SETTINGS_SYSTEM); - g_assert (priv->sys_proxy); - dbus_g_proxy_set_default_timeout (priv->sys_proxy, G_MAXINT); - + /* Monitor properties */ dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->sys_proxy, "PropertiesChanged", + dbus_g_proxy_add_signal (priv->proxy, "PropertiesChanged", DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->sys_proxy, "PropertiesChanged", + dbus_g_proxy_connect_signal (priv->proxy, "PropertiesChanged", G_CALLBACK (properties_changed_cb), object, NULL); /* Monitor for permissions changes */ - dbus_g_proxy_add_signal (priv->sys_proxy, "CheckPermissions", G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->sys_proxy, "CheckPermissions", + dbus_g_proxy_add_signal (priv->proxy, "CheckPermissions", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->proxy, "CheckPermissions", G_CALLBACK (check_permissions_cb), object, NULL); @@ -635,7 +617,7 @@ constructor (GType type, get_all_cb, object, NULL, - G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS_SYSTEM, + G_TYPE_STRING, NM_DBUS_IFACE_SETTINGS, G_TYPE_INVALID); return object; @@ -700,10 +682,10 @@ get_property (GObject *object, guint prop_id, case PROP_SERVICE_RUNNING: g_value_set_boolean (value, priv->service_running); break; - case NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME: + case NM_SETTINGS_INTERFACE_PROP_HOSTNAME: g_value_set_string (value, priv->hostname); break; - case NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY: + case NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY: g_value_set_boolean (value, priv->can_modify); break; default: @@ -743,12 +725,12 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) G_PARAM_READABLE)); g_object_class_override_property (object_class, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME, - NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); + NM_SETTINGS_INTERFACE_PROP_HOSTNAME, + NM_SETTINGS_INTERFACE_HOSTNAME); g_object_class_override_property (object_class, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY, - NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); + NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY, + NM_SETTINGS_INTERFACE_CAN_MODIFY); } diff --git a/libnm-glib/nm-settings-interface.c b/libnm-glib/nm-settings-interface.c index 3bd4037a1..951c59a24 100644 --- a/libnm-glib/nm-settings-interface.c +++ b/libnm-glib/nm-settings-interface.c @@ -145,6 +145,65 @@ nm_settings_interface_add_connection (NMSettingsInterface *settings, return FALSE; } +/** + * nm_settings_interface_save_hostname: + * @settings: a object implementing %NMSettingsInterface + * @hostname: the new persistent hostname to set, or NULL to clear any existing + * persistent hostname + * @callback: callback to be called when the hostname operation completes + * @user_data: caller-specific data passed to @callback + * + * Requests that the machine's persistent hostname be set to the specified value + * or cleared. + * + * Returns: TRUE if the request was successful, FALSE if it failed + **/ +gboolean +nm_settings_interface_save_hostname (NMSettingsInterface *settings, + const char *hostname, + NMSettingsSaveHostnameFunc callback, + gpointer user_data) +{ + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), FALSE); + g_return_val_if_fail (hostname != NULL, FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->save_hostname) { + return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->save_hostname (settings, + hostname, + callback, + user_data); + } + return FALSE; +} + +/** + * nm_settings_interface_get_permissions: + * @settings: a object implementing %NMSettingsInterface + * @callback: callback to be called when the permissions operation completes + * @user_data: caller-specific data passed to @callback + * + * Requests an indication of the operations the caller is permitted to perform + * including those that may require authorization. + * + * Returns: TRUE if the request was successful, FALSE if it failed + **/ +gboolean +nm_settings_interface_get_permissions (NMSettingsInterface *settings, + NMSettingsGetPermissionsFunc callback, + gpointer user_data) +{ + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_permissions) + return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_permissions (settings, callback, user_data); + return FALSE; +} + + /*****************************************************************/ static void @@ -156,6 +215,23 @@ nm_settings_interface_init (gpointer g_iface) if (initialized) return; + /* Properties */ + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_SETTINGS_INTERFACE_HOSTNAME, + "Hostname", + "Persistent hostname", + NULL, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_boolean (NM_SETTINGS_INTERFACE_CAN_MODIFY, + "CanModify", + "Can modify anything (hostname, connections, etc)", + FALSE, + G_PARAM_READABLE)); + /* Signals */ g_signal_new (NM_SETTINGS_INTERFACE_NEW_CONNECTION, iface_type, @@ -173,6 +249,14 @@ nm_settings_interface_init (gpointer g_iface) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + g_signal_new (NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsInterface, check_permissions), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + initialized = TRUE; } diff --git a/libnm-glib/nm-settings-interface.h b/libnm-glib/nm-settings-interface.h index 5920bd825..6f10c9786 100644 --- a/libnm-glib/nm-settings-interface.h +++ b/libnm-glib/nm-settings-interface.h @@ -47,13 +47,33 @@ GQuark nm_settings_interface_error_quark (void); GType nm_settings_interface_error_get_type (void); +typedef enum { + NM_SETTINGS_PERMISSION_NONE = 0x0, + NM_SETTINGS_PERMISSION_CONNECTION_MODIFY = 0x1, + NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, + NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN = 0x4, + NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY = 0x8 +} NMSettingsPermissions; + + #define NM_TYPE_SETTINGS_INTERFACE (nm_settings_interface_get_type ()) #define NM_SETTINGS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_INTERFACE, NMSettingsInterface)) #define NM_IS_SETTINGS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_INTERFACE)) #define NM_SETTINGS_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_INTERFACE, NMSettingsInterface)) -#define NM_SETTINGS_INTERFACE_NEW_CONNECTION "new-connection" -#define NM_SETTINGS_INTERFACE_CONNECTIONS_READ "connections-read" +#define NM_SETTINGS_INTERFACE_NEW_CONNECTION "new-connection" +#define NM_SETTINGS_INTERFACE_CONNECTIONS_READ "connections-read" +#define NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS "check-permissions" + +#define NM_SETTINGS_INTERFACE_HOSTNAME "hostname" +#define NM_SETTINGS_INTERFACE_CAN_MODIFY "can-modify" + +typedef enum { + NM_SETTINGS_INTERFACE_PROP_FIRST = 0x1000, + + NM_SETTINGS_INTERFACE_PROP_HOSTNAME = NM_SETTINGS_INTERFACE_PROP_FIRST, + NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY +} NMSettingsInterfaceProp; typedef struct _NMSettingsInterface NMSettingsInterface; @@ -61,6 +81,15 @@ typedef void (*NMSettingsAddConnectionFunc) (NMSettingsInterface *settings, GError *error, gpointer user_data); +typedef void (*NMSettingsSaveHostnameFunc) (NMSettingsInterface *settings, + GError *error, + gpointer user_data); + +typedef void (*NMSettingsGetPermissionsFunc) (NMSettingsInterface *settings, + NMSettingsPermissions permissions, + GError *error, + gpointer user_data); + struct _NMSettingsInterface { GTypeInterface g_iface; @@ -75,6 +104,15 @@ struct _NMSettingsInterface { NMConnection *connection, NMSettingsAddConnectionFunc callback, gpointer user_data); + + gboolean (*save_hostname) (NMSettingsInterface *settings, + const char *hostname, + NMSettingsSaveHostnameFunc callback, + gpointer user_data); + + gboolean (*get_permissions) (NMSettingsInterface *settings, + NMSettingsGetPermissionsFunc callback, + gpointer user_data); /* Signals */ void (*new_connection) (NMSettingsInterface *settings, @@ -82,6 +120,8 @@ struct _NMSettingsInterface { void (*connections_read) (NMSettingsInterface *settings); + void (*check_permissions) (NMSettingsInterface *settings); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -104,6 +144,15 @@ gboolean nm_settings_interface_add_connection (NMSettingsInterface *settings, NMSettingsAddConnectionFunc callback, gpointer user_data); +gboolean nm_settings_interface_save_hostname (NMSettingsInterface *settings, + const char *hostname, + NMSettingsSaveHostnameFunc callback, + gpointer user_data); + +gboolean nm_settings_interface_get_permissions (NMSettingsInterface *settings, + NMSettingsGetPermissionsFunc callback, + gpointer user_data); + G_END_DECLS #endif /* NM_SETTINGS_INTERFACE_H */ diff --git a/libnm-glib/nm-settings-system-interface.c b/libnm-glib/nm-settings-system-interface.c deleted file mode 100644 index 0f59377a5..000000000 --- a/libnm-glib/nm-settings-system-interface.c +++ /dev/null @@ -1,150 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. - */ - -#include "nm-settings-interface.h" -#include "nm-settings-system-interface.h" - - -/** - * nm_settings_system_interface_save_hostname: - * @settings: a object implementing %NMSettingsSystemInterface - * @hostname: the new persistent hostname to set, or NULL to clear any existing - * persistent hostname - * @callback: callback to be called when the hostname operation completes - * @user_data: caller-specific data passed to @callback - * - * Requests that the machine's persistent hostname be set to the specified value - * or cleared. - * - * Returns: TRUE if the request was successful, FALSE if it failed - **/ -gboolean -nm_settings_system_interface_save_hostname (NMSettingsSystemInterface *settings, - const char *hostname, - NMSettingsSystemSaveHostnameFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_SYSTEM_INTERFACE (settings), FALSE); - g_return_val_if_fail (hostname != NULL, FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE (settings)->save_hostname) { - return NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE (settings)->save_hostname (settings, - hostname, - callback, - user_data); - } - return FALSE; -} - -/** - * nm_settings_system_interface_get_permissions: - * @settings: a object implementing %NMSettingsSystemInterface - * @callback: callback to be called when the permissions operation completes - * @user_data: caller-specific data passed to @callback - * - * Requests an indication of the operations the caller is permitted to perform - * including those that may require authorization. - * - * Returns: TRUE if the request was successful, FALSE if it failed - **/ -gboolean -nm_settings_system_interface_get_permissions (NMSettingsSystemInterface *settings, - NMSettingsSystemGetPermissionsFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_SYSTEM_INTERFACE (settings), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE (settings)->get_permissions) - return NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE (settings)->get_permissions (settings, callback, user_data); - return FALSE; -} - -static void -nm_settings_system_interface_init (gpointer g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - - /* Properties */ - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME, - "Hostname", - "Persistent hostname", - NULL, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boolean (NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY, - "CanModify", - "Can modify anything (hostname, connections, etc)", - FALSE, - G_PARAM_READABLE)); - - /* Signals */ - g_signal_new (NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS, - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsSystemInterface, check_permissions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - initialized = TRUE; -} - -GType -nm_settings_system_interface_get_type (void) -{ - static GType itype = 0; - - if (!itype) { - const GTypeInfo iinfo = { - sizeof (NMSettingsSystemInterface), /* class_size */ - nm_settings_system_interface_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - itype = g_type_register_static (G_TYPE_INTERFACE, - "NMSettingsSystemInterface", - &iinfo, 0); - - g_type_interface_add_prerequisite (itype, NM_TYPE_SETTINGS_INTERFACE); - } - - return itype; -} - diff --git a/libnm-glib/nm-settings-system-interface.h b/libnm-glib/nm-settings-system-interface.h deleted file mode 100644 index d01655612..000000000 --- a/libnm-glib/nm-settings-system-interface.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2009 Red Hat, Inc. - */ - -#ifndef NM_SETTINGS_SYSTEM_INTERFACE_H -#define NM_SETTINGS_SYSTEM_INTERFACE_H - -#include - -#include "NetworkManager.h" - -G_BEGIN_DECLS - -typedef enum { - NM_SETTINGS_SYSTEM_PERMISSION_NONE = 0x0, - NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY = 0x1, - NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, - NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_OPEN = 0x4, - NM_SETTINGS_SYSTEM_PERMISSION_HOSTNAME_MODIFY = 0x8 -} NMSettingsSystemPermissions; - -#define NM_TYPE_SETTINGS_SYSTEM_INTERFACE (nm_settings_system_interface_get_type ()) -#define NM_SETTINGS_SYSTEM_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_SYSTEM_INTERFACE, NMSettingsSystemInterface)) -#define NM_IS_SETTINGS_SYSTEM_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_SYSTEM_INTERFACE)) -#define NM_SETTINGS_SYSTEM_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_SYSTEM_INTERFACE, NMSettingsSystemInterface)) - -#define NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME "hostname" -#define NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY "can-modify" - -#define NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS "check-permissions" - -typedef enum { - NM_SETTINGS_SYSTEM_INTERFACE_PROP_FIRST = 0x1000, - - NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME = NM_SETTINGS_SYSTEM_INTERFACE_PROP_FIRST, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY -} NMSettingsSystemInterfaceProp; - - -typedef struct _NMSettingsSystemInterface NMSettingsSystemInterface; - - -typedef void (*NMSettingsSystemSaveHostnameFunc) (NMSettingsSystemInterface *settings, - GError *error, - gpointer user_data); - -typedef void (*NMSettingsSystemGetPermissionsFunc) (NMSettingsSystemInterface *settings, - NMSettingsSystemPermissions permissions, - GError *error, - gpointer user_data); - -struct _NMSettingsSystemInterface { - GTypeInterface g_iface; - - /* Methods */ - gboolean (*save_hostname) (NMSettingsSystemInterface *settings, - const char *hostname, - NMSettingsSystemSaveHostnameFunc callback, - gpointer user_data); - - gboolean (*get_permissions) (NMSettingsSystemInterface *settings, - NMSettingsSystemGetPermissionsFunc callback, - gpointer user_data); - - /* Signals */ - void (*check_permissions) (NMSettingsSystemInterface *settings); - - /* Padding for future expansion */ - void (*_reserved1) (void); - void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); -}; - -GType nm_settings_system_interface_get_type (void); - -gboolean nm_settings_system_interface_save_hostname (NMSettingsSystemInterface *settings, - const char *hostname, - NMSettingsSystemSaveHostnameFunc callback, - gpointer user_data); - -gboolean nm_settings_system_interface_get_permissions (NMSettingsSystemInterface *settings, - NMSettingsSystemGetPermissionsFunc callback, - gpointer user_data); - -G_END_DECLS - -#endif /* NM_SETTINGS_SYSTEM_INTERFACE_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index f77d89a8f..6f2191f1f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -53,7 +53,6 @@ #include "nm-sysconfig-settings.h" #include "nm-secrets-provider-interface.h" #include "nm-settings-interface.h" -#include "nm-settings-system-interface.h" #include "nm-manager-auth.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" @@ -3014,7 +3013,7 @@ nm_manager_get (const char *config_file, g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); - g_signal_connect (priv->sys_settings, "notify::" NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME, + g_signal_connect (priv->sys_settings, "notify::" NM_SETTINGS_INTERFACE_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); g_signal_connect (priv->sys_settings, "new-connection", G_CALLBACK (system_new_connection_cb), singleton); diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 005c878cd..0544c6e86 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -9,8 +9,7 @@ INCLUDES = -I${top_srcdir} \ noinst_LTLIBRARIES = libsystem-settings.la BUILT_SOURCES = \ - nm-settings-glue.h \ - nm-settings-system-glue.h + nm-settings-glue.h libsystem_settings_la_SOURCES = \ nm-sysconfig-settings.c \ @@ -58,9 +57,6 @@ libsystem_settings_la_LDFLAGS = -rdynamic nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< -nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=$@ $< - CLEANFILES = \ $(BUILT_SOURCES) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index e3b31cd58..0dff2285a 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -96,7 +95,6 @@ static void impl_settings_get_permissions (NMSysconfigSettings *self, DBusGMethodInvocation *context); #include "nm-settings-glue.h" -#include "nm-settings-system-glue.h" static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); @@ -117,15 +115,11 @@ typedef struct { GSList *unmanaged_specs; } NMSysconfigSettingsPrivate; -static void settings_system_interface_init (NMSettingsSystemInterface *klass); - static void settings_interface_init (NMSettingsInterface *klass); G_DEFINE_TYPE_WITH_CODE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, - settings_interface_init) - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_SYSTEM_INTERFACE, - settings_system_interface_init)) + settings_interface_init)) #define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate)) @@ -391,7 +385,7 @@ hostname_changed (NMSystemConfigInterface *config, GParamSpec *pspec, gpointer user_data) { - g_object_notify (G_OBJECT (user_data), NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); + g_object_notify (G_OBJECT (user_data), NM_SETTINGS_INTERFACE_HOSTNAME); } static void @@ -613,7 +607,7 @@ typedef struct { char *hostname; - NMSettingsSystemPermissions permissions; + NMSettingsPermissions permissions; guint32 permissions_calls; } PolkitCall; @@ -946,14 +940,14 @@ pk_authority_changed_cb (GObject *object, gpointer user_data) { /* Let clients know they should re-check their authorization */ g_signal_emit_by_name (NM_SYSCONFIG_SETTINGS (user_data), - NM_SETTINGS_SYSTEM_INTERFACE_CHECK_PERMISSIONS); + NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS); } typedef struct { PolkitCall *pk_call; const char *pk_action; GCancellable *cancellable; - NMSettingsSystemPermissions permission; + NMSettingsPermissions permission; gboolean disposed; } PermissionsCall; @@ -1025,14 +1019,14 @@ static void start_permission_check (NMSysconfigSettings *self, PolkitCall *pk_call, const char *pk_action, - NMSettingsSystemPermissions permission) + NMSettingsPermissions permission) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); PermissionsCall *call; g_return_if_fail (pk_call != NULL); g_return_if_fail (pk_action != NULL); - g_return_if_fail (permission != NM_SETTINGS_SYSTEM_PERMISSION_NONE); + g_return_if_fail (permission != NM_SETTINGS_PERMISSION_NONE); call = g_malloc0 (sizeof (PermissionsCall)); call->pk_call = pk_call; @@ -1068,32 +1062,32 @@ impl_settings_get_permissions (NMSysconfigSettings *self, if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { start_permission_check (self, call, NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, - NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY); + NM_SETTINGS_PERMISSION_CONNECTION_MODIFY); } /* Only check for hostname-modify if one of our plugins supports it. */ if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { start_permission_check (self, call, NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY, - NM_SETTINGS_SYSTEM_PERMISSION_HOSTNAME_MODIFY); + NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY); } // FIXME: hook these into plugin permissions like the modify permissions */ start_permission_check (self, call, NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN, - NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_OPEN); + NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN); start_permission_check (self, call, NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED, - NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_PROTECTED); + NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED); } static gboolean -get_permissions (NMSettingsSystemInterface *settings, - NMSettingsSystemGetPermissionsFunc callback, +get_permissions (NMSettingsInterface *settings, + NMSettingsGetPermissionsFunc callback, gpointer user_data) { NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings); - NMSettingsSystemPermissions permissions = NM_SETTINGS_SYSTEM_PERMISSION_NONE; + NMSettingsPermissions permissions = NM_SETTINGS_PERMISSION_NONE; /* Local caller (ie, NM) gets full permissions by default because it doesn't * need authorization. However, permissions are still subject to plugin's @@ -1103,15 +1097,15 @@ get_permissions (NMSettingsSystemInterface *settings, /* Only check for connection-modify if one of our plugins supports it. */ if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) - permissions |= NM_SETTINGS_SYSTEM_PERMISSION_CONNECTION_MODIFY; + permissions |= NM_SETTINGS_PERMISSION_CONNECTION_MODIFY; /* Only check for hostname-modify if one of our plugins supports it. */ if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) - permissions |= NM_SETTINGS_SYSTEM_PERMISSION_HOSTNAME_MODIFY; + permissions |= NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY; // FIXME: hook these into plugin permissions like the modify permissions */ - permissions |= NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_OPEN; - permissions |= NM_SETTINGS_SYSTEM_PERMISSION_WIFI_SHARE_PROTECTED; + permissions |= NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN; + permissions |= NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED; callback (settings, permissions, NULL, user_data); return TRUE; @@ -1535,21 +1529,13 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); } -static void -settings_system_interface_init (NMSettingsSystemInterface *iface) -{ - iface->get_permissions = get_permissions; - - dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface), - &dbus_glib_nm_settings_system_object_info); -} - static void settings_interface_init (NMSettingsInterface *iface) { iface->add_connection = settings_interface_add_connection; iface->list_connections = list_connections; iface->get_connection_by_path = get_connection_by_path; + iface->get_permissions = get_permissions; dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface), &dbus_glib_nm_settings_object_info); @@ -1595,14 +1581,14 @@ get_property (GObject *object, guint prop_id, copy = g_slist_append (copy, g_strdup (iter->data)); g_value_take_boxed (value, copy); break; - case NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME: + case NM_SETTINGS_INTERFACE_PROP_HOSTNAME: g_value_take_string (value, nm_sysconfig_settings_get_hostname (self)); /* Don't ever pass NULL through D-Bus */ if (!g_value_get_string (value)) g_value_set_static_string (value, ""); break; - case NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY: + case NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY: g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)); break; default: @@ -1649,12 +1635,12 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) G_PARAM_READABLE)); g_object_class_override_property (object_class, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_HOSTNAME, - NM_SETTINGS_SYSTEM_INTERFACE_HOSTNAME); + NM_SETTINGS_INTERFACE_PROP_HOSTNAME, + NM_SETTINGS_INTERFACE_HOSTNAME); g_object_class_override_property (object_class, - NM_SETTINGS_SYSTEM_INTERFACE_PROP_CAN_MODIFY, - NM_SETTINGS_SYSTEM_INTERFACE_CAN_MODIFY); + NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY, + NM_SETTINGS_INTERFACE_CAN_MODIFY); /* signals */ signals[PROPERTIES_CHANGED] = @@ -1667,7 +1653,7 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, - NM_DBUS_IFACE_SETTINGS_SYSTEM, + NM_DBUS_IFACE_SETTINGS, NM_TYPE_SYSCONFIG_SETTINGS_ERROR); dbus_g_error_domain_register (NM_SETTINGS_INTERFACE_ERROR, From aee48901f42b852f60c73383a4d05b0d0dbb2fdc Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Mon, 2 Aug 2010 20:15:16 -0400 Subject: [PATCH 012/264] Merged NM{Exported,Sysconfig}Connection In continuation of the theme, the removal of user settings services means that the distinction between NMSysconfigConnection and NMExportedConnection is no longer needed. Merge NMExportedConnection into NMSysconfigConnection. --- docs/libnm-glib/Makefile.am | 3 +- docs/libnm-glib/libnm-glib-docs.sgml | 2 +- introspection/Makefile.am | 2 +- introspection/all.xml | 2 +- ...ection.xml => nm-sysconfig-connection.xml} | 8 +- libnm-glib/Makefile.am | 16 +- libnm-glib/libnm-glib.ver | 3 - libnm-glib/nm-exported-connection.c | 277 ------------------ libnm-glib/nm-exported-connection.h | 75 ----- libnm-glib/nm-remote-connection.c | 2 +- src/system-settings/Makefile.am | 6 +- src/system-settings/nm-sysconfig-connection.c | 216 +++++++++++++- src/system-settings/nm-sysconfig-connection.h | 22 +- src/system-settings/nm-sysconfig-settings.c | 6 +- .../plugins/ifupdown/nm-ifupdown-connection.c | 6 +- system-settings/plugins/ifupdown/plugin.c | 2 +- 16 files changed, 251 insertions(+), 397 deletions(-) rename introspection/{nm-exported-connection.xml => nm-sysconfig-connection.xml} (95%) delete mode 100644 libnm-glib/nm-exported-connection.c delete mode 100644 libnm-glib/nm-exported-connection.h diff --git a/docs/libnm-glib/Makefile.am b/docs/libnm-glib/Makefile.am index b12e730a4..f3665f2bc 100644 --- a/docs/libnm-glib/Makefile.am +++ b/docs/libnm-glib/Makefile.am @@ -45,8 +45,7 @@ IGNORE_HFILES= \ nm-device-wifi-bindings.h \ nm-dhcp4-config-bindings.h \ nm-dhcp6-config-bindings.h \ - nm-exported-connection-bindings.h \ - nm-exported-connection-glue.h \ + nm-sysconfig-connection-glue.h \ nm-ip4-config-bindings.h \ nm-ip6-config-bindings.h \ nm-settings-bindings.h \ diff --git a/docs/libnm-glib/libnm-glib-docs.sgml b/docs/libnm-glib/libnm-glib-docs.sgml index 87e6b40d0..c730710ba 100644 --- a/docs/libnm-glib/libnm-glib-docs.sgml +++ b/docs/libnm-glib/libnm-glib-docs.sgml @@ -27,7 +27,7 @@ - + diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 212da3ab9..a2667ca7f 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -18,7 +18,7 @@ EXTRA_DIST = \ nm-manager-client.xml \ nm-settings.xml \ nm-settings-system.xml \ - nm-exported-connection.xml \ + nm-sysconfig-connection.xml \ nm-vpn-plugin.xml \ nm-vpn-connection.xml \ nm-ppp-manager.xml \ diff --git a/introspection/all.xml b/introspection/all.xml index d6b2f2367..1f33708e5 100644 --- a/introspection/all.xml +++ b/introspection/all.xml @@ -40,7 +40,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - + diff --git a/introspection/nm-exported-connection.xml b/introspection/nm-sysconfig-connection.xml similarity index 95% rename from introspection/nm-exported-connection.xml rename to introspection/nm-sysconfig-connection.xml index 46907c05e..aae08e06f 100644 --- a/introspection/nm-exported-connection.xml +++ b/introspection/nm-sysconfig-connection.xml @@ -11,7 +11,7 @@ Update the connection with new settings and properties, replacing all previous settings and properties. - + @@ -24,7 +24,7 @@ Delete the connection. - + @@ -32,7 +32,7 @@ Get the settings maps describing this object. - + The nested settings maps describing this object. @@ -68,7 +68,7 @@ Get the secrets encapsulated in this object. - + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 388ab5402..bff10862c 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -10,8 +10,7 @@ BUILT_SOURCES = \ nm-device-ethernet-bindings.h \ nm-device-wifi-bindings.h \ nm-device-bt-bindings.h \ - nm-exported-connection-glue.h \ - nm-exported-connection-bindings.h \ + nm-sysconfig-connection-bindings.h \ nm-settings-bindings.h \ nm-vpn-connection-bindings.h \ nm-vpn-plugin-glue.h \ @@ -79,8 +78,7 @@ libnminclude_HEADERS = \ nm-remote-connection.h \ nm-settings-interface.h \ nm-remote-settings.h \ - nm-settings-connection-interface.h \ - nm-exported-connection.h + nm-settings-connection-interface.h libnm_glib_la_SOURCES = \ nm-object.c \ @@ -111,8 +109,7 @@ libnm_glib_la_SOURCES = \ nm-remote-connection-private.h \ nm-settings-interface.c \ nm-remote-settings.c \ - nm-settings-connection-interface.c \ - nm-exported-connection.c + nm-settings-connection-interface.c libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ @@ -161,11 +158,8 @@ nm-access-point-bindings.h: $(top_srcdir)/introspection/nm-access-point.xml nm-settings-bindings.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-client --output=$@ $< -nm-exported-connection-glue.h: $(top_srcdir)/introspection/nm-exported-connection.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_exported_connection --mode=glib-server --output=$@ $< - -nm-exported-connection-bindings.h: $(top_srcdir)/introspection/nm-exported-connection.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_exported_connection --mode=glib-client --output=$@ $< +nm-sysconfig-connection-bindings.h: $(top_srcdir)/introspection/nm-sysconfig-connection.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_sysconfig_connection --mode=glib-client --output=$@ $< nm-vpn-connection-bindings.h: $(top_srcdir)/introspection/nm-vpn-connection.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-client --output=$@ $< diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 2dc9783cc..ce10de216 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -93,9 +93,6 @@ global: nm_dhcp4_config_get_options; nm_dhcp4_config_get_type; nm_dhcp4_config_new; - nm_exported_connection_export; - nm_exported_connection_get_type; - nm_exported_connection_new; nm_gsm_device_get_type; nm_gsm_device_new; nm_ip4_config_get_addresses; diff --git a/libnm-glib/nm-exported-connection.c b/libnm-glib/nm-exported-connection.c deleted file mode 100644 index 6fda1b553..000000000 --- a/libnm-glib/nm-exported-connection.c +++ /dev/null @@ -1,277 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2009 Red Hat, Inc. - */ - -#include -#include -#include - -#include "nm-exported-connection.h" -#include "nm-settings-interface.h" -#include "nm-settings-connection-interface.h" - -static gboolean impl_exported_connection_get_settings (NMExportedConnection *connection, - GHashTable **settings, - GError **error); - -static void impl_exported_connection_update (NMExportedConnection *connection, - GHashTable *new_settings, - DBusGMethodInvocation *context); - -static void impl_exported_connection_delete (NMExportedConnection *connection, - DBusGMethodInvocation *context); - -static void impl_exported_connection_get_secrets (NMExportedConnection *connection, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context); - -#include "nm-exported-connection-glue.h" - -static void settings_connection_interface_init (NMSettingsConnectionInterface *class); - -G_DEFINE_TYPE_EXTENDED (NMExportedConnection, nm_exported_connection, NM_TYPE_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) - -#define NM_EXPORTED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_EXPORTED_CONNECTION, \ - NMExportedConnectionPrivate)) - -typedef struct { - gboolean foo; -} NMExportedConnectionPrivate; - - -/**************************************************************/ - -static GHashTable * -real_get_settings (NMExportedConnection *self, GError **error) -{ - NMConnection *no_secrets; - GHashTable *settings; - - /* Secrets should *never* be returned by the GetSettings method, they - * get returned by the GetSecrets method which can be better - * protected against leakage of secrets to unprivileged callers. - */ - no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); - g_assert (no_secrets); - nm_connection_clear_secrets (no_secrets); - settings = nm_connection_to_hash (no_secrets); - g_assert (settings); - g_object_unref (no_secrets); - - return settings; -} - -/**************************************************************/ - -static gboolean -check_writable (NMConnection *connection, GError **error) -{ - NMSettingConnection *s_con; - - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_CONNECTION); - if (!s_con) { - g_set_error_literal (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, - "Connection did not have required 'connection' setting"); - return FALSE; - } - - /* If the connection is read-only, that has to be changed at the source of - * the problem (ex a system settings plugin that can't write connections out) - * instead of over D-Bus. - */ - if (nm_setting_connection_get_read_only (s_con)) { - g_set_error_literal (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION, - "Connection is read-only"); - return FALSE; - } - - return TRUE; -} - -static gboolean -impl_exported_connection_get_settings (NMExportedConnection *self, - GHashTable **settings, - GError **error) -{ - /* Must always be implemented */ - g_assert (NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_settings); - *settings = NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_settings (self, error); - return *settings ? TRUE : FALSE; -} - -static gboolean -update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) -{ - g_object_ref (connection); - nm_settings_connection_interface_emit_updated (connection); - callback (connection, NULL, user_data); - g_object_unref (connection); - return TRUE; -} - -static void -impl_exported_connection_update (NMExportedConnection *self, - GHashTable *new_settings, - DBusGMethodInvocation *context) -{ - NMConnection *tmp; - GError *error = NULL; - - /* If the connection is read-only, that has to be changed at the source of - * the problem (ex a system settings plugin that can't write connections out) - * instead of over D-Bus. - */ - if (!check_writable (NM_CONNECTION (self), &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - /* Check if the settings are valid first */ - tmp = nm_connection_new_from_hash (new_settings, &error); - if (!tmp) { - g_assert (error); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - g_object_unref (tmp); - - if (NM_EXPORTED_CONNECTION_GET_CLASS (self)->update) - NM_EXPORTED_CONNECTION_GET_CLASS (self)->update (self, new_settings, context); - else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, - "%s: %s:%d update() unimplemented", __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -static gboolean -do_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, - gpointer user_data) -{ - g_object_ref (connection); - g_signal_emit_by_name (connection, "removed"); - callback (connection, NULL, user_data); - g_object_unref (connection); - return TRUE; -} - -static void -impl_exported_connection_delete (NMExportedConnection *self, - DBusGMethodInvocation *context) -{ - GError *error = NULL; - - if (!check_writable (NM_CONNECTION (self), &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - if (NM_EXPORTED_CONNECTION_GET_CLASS (self)->delete) - NM_EXPORTED_CONNECTION_GET_CLASS (self)->delete (self, context); - else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, - "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -static void -impl_exported_connection_get_secrets (NMExportedConnection *self, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context) -{ - GError *error = NULL; - - if (NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_secrets) - NM_EXPORTED_CONNECTION_GET_CLASS (self)->get_secrets (self, setting_name, hints, request_new, context); - else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, - "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -/**************************************************************/ - -static void -settings_connection_interface_init (NMSettingsConnectionInterface *iface) -{ - iface->update = update; - iface->delete = do_delete; -} - -/** - * nm_exported_connection_new: - * - * Creates a new object representing the remote connection. - * - * Returns: the new exported connection object on success, or %NULL on failure - **/ -NMExportedConnection * -nm_exported_connection_new () -{ - return (NMExportedConnection *) g_object_new (NM_TYPE_EXPORTED_CONNECTION, - NULL); -} - -static void -nm_exported_connection_init (NMExportedConnection *self) -{ -} - -static void -nm_exported_connection_class_init (NMExportedConnectionClass *class) -{ - g_type_class_add_private (class, sizeof (NMExportedConnectionPrivate)); - - /* Virtual methods */ - class->get_settings = real_get_settings; - - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), - &dbus_glib_nm_exported_connection_object_info); -} diff --git a/libnm-glib/nm-exported-connection.h b/libnm-glib/nm-exported-connection.h deleted file mode 100644 index e2bf649aa..000000000 --- a/libnm-glib/nm-exported-connection.h +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * (C) Copyright 2009 Red Hat, Inc. - */ - -#ifndef NM_EXPORTED_CONNECTION_H -#define NM_EXPORTED_CONNECTION_H - -#include -#include - -G_BEGIN_DECLS - -#define NM_TYPE_EXPORTED_CONNECTION (nm_exported_connection_get_type ()) -#define NM_EXPORTED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnection)) -#define NM_EXPORTED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnectionClass)) -#define NM_IS_EXPORTED_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_EXPORTED_CONNECTION)) -#define NM_IS_EXPORTED_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_EXPORTED_CONNECTION)) -#define NM_EXPORTED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_EXPORTED_CONNECTION, NMExportedConnectionClass)) - -typedef struct { - NMConnection parent; -} NMExportedConnection; - -typedef struct { - NMConnectionClass parent; - - GHashTable * (*get_settings) (NMExportedConnection *self, - GError **error); - - void (*update) (NMExportedConnection *self, - GHashTable *new_settings, - DBusGMethodInvocation *context); - - void (*delete) (NMExportedConnection *self, - DBusGMethodInvocation *context); - - void (*get_secrets) (NMExportedConnection *self, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context); - - /* Padding for future expansion */ - void (*_reserved1) (void); - void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); -} NMExportedConnectionClass; - -GType nm_exported_connection_get_type (void); - -NMExportedConnection *nm_exported_connection_new (void); - -G_END_DECLS - -#endif /* NM_EXPORTED_CONNECTION_H */ diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 2775329f9..8b96b56cb 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -29,7 +29,7 @@ #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" #include "nm-dbus-glib-types.h" -#include "nm-exported-connection-bindings.h" +#include "nm-sysconfig-connection-bindings.h" #include "nm-settings-connection-interface.h" #define NM_REMOTE_CONNECTION_BUS "bus" diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 0544c6e86..67980767c 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -9,7 +9,8 @@ INCLUDES = -I${top_srcdir} \ noinst_LTLIBRARIES = libsystem-settings.la BUILT_SOURCES = \ - nm-settings-glue.h + nm-settings-glue.h \ + nm-sysconfig-connection-glue.h libsystem_settings_la_SOURCES = \ nm-sysconfig-settings.c \ @@ -57,6 +58,9 @@ libsystem_settings_la_LDFLAGS = -rdynamic nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< +nm-sysconfig-connection-glue.h: $(top_srcdir)/introspection/nm-sysconfig-connection.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_sysconfig_connection --mode=glib-server --output=$@ $< + CLEANFILES = \ $(BUILT_SOURCES) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index f46895acc..bc173779c 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -21,6 +21,7 @@ #include #include +#include #include "nm-sysconfig-connection.h" #include "nm-system-config-error.h" @@ -30,10 +31,28 @@ #include "nm-polkit-helpers.h" #include "nm-logging.h" +static gboolean impl_sysconfig_connection_get_settings (NMSysconfigConnection *connection, + GHashTable **settings, + GError **error); + +static void impl_sysconfig_connection_update (NMSysconfigConnection *connection, + GHashTable *new_settings, + DBusGMethodInvocation *context); + +static void impl_sysconfig_connection_delete (NMSysconfigConnection *connection, + DBusGMethodInvocation *context); + +static void impl_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + DBusGMethodInvocation *context); + +#include "nm-sysconfig-connection-glue.h" static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); -G_DEFINE_TYPE_EXTENDED (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_EXPORTED_CONNECTION, 0, +G_DEFINE_TYPE_EXTENDED (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_CONNECTION, 0, G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, settings_connection_interface_init)) @@ -49,6 +68,27 @@ typedef struct { /**************************************************************/ +static GHashTable * +get_settings (NMSysconfigConnection *self, GError **error) +{ + NMConnection *no_secrets; + GHashTable *settings; + + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); + g_assert (no_secrets); + nm_connection_clear_secrets (no_secrets); + settings = nm_connection_to_hash (no_secrets); + g_assert (settings); + g_object_unref (no_secrets); + + return settings; +} + + static void ignore_cb (NMSettingsConnectionInterface *connection, GError *error, @@ -102,6 +142,30 @@ nm_sysconfig_connection_update (NMSysconfigConnection *self, /**************************************************************/ +static gboolean +update (NMSettingsConnectionInterface *connection, + NMSettingsConnectionInterfaceUpdateFunc callback, + gpointer user_data) +{ + g_object_ref (connection); + nm_settings_connection_interface_emit_updated (connection); + callback (connection, NULL, user_data); + g_object_unref (connection); + return TRUE; +} + +static gboolean +do_delete (NMSettingsConnectionInterface *connection, + NMSettingsConnectionInterfaceDeleteFunc callback, + gpointer user_data) +{ + g_object_ref (connection); + g_signal_emit_by_name (connection, "removed"); + callback (connection, NULL, user_data); + g_object_unref (connection); + return TRUE; +} + static GValue * string_to_gvalue (const char *str) { @@ -235,6 +299,134 @@ get_secrets (NMSettingsConnectionInterface *connection, /**************************************************************/ +static gboolean +check_writable (NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, + NM_TYPE_SETTING_CONNECTION); + if (!s_con) { + g_set_error_literal (error, + NM_SETTINGS_INTERFACE_ERROR, + NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, + "Connection did not have required 'connection' setting"); + return FALSE; + } + + /* If the connection is read-only, that has to be changed at the source of + * the problem (ex a system settings plugin that can't write connections out) + * instead of over D-Bus. + */ + if (nm_setting_connection_get_read_only (s_con)) { + g_set_error_literal (error, + NM_SETTINGS_INTERFACE_ERROR, + NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION, + "Connection is read-only"); + return FALSE; + } + + return TRUE; +} + +static gboolean +impl_sysconfig_connection_get_settings (NMSysconfigConnection *self, + GHashTable **settings, + GError **error) +{ + /* Must always be implemented */ + g_assert (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_settings); + *settings = NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_settings (self, error); + return *settings ? TRUE : FALSE; +} + +static void +impl_sysconfig_connection_update (NMSysconfigConnection *self, + GHashTable *new_settings, + DBusGMethodInvocation *context) +{ + NMConnection *tmp; + GError *error = NULL; + + /* If the connection is read-only, that has to be changed at the source of + * the problem (ex a system settings plugin that can't write connections out) + * instead of over D-Bus. + */ + if (!check_writable (NM_CONNECTION (self), &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + /* Check if the settings are valid first */ + tmp = nm_connection_new_from_hash (new_settings, &error); + if (!tmp) { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + g_object_unref (tmp); + + if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->update) + NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->update (self, new_settings, context); + else { + error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, + NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + "%s: %s:%d update() unimplemented", __func__, __FILE__, __LINE__); + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +static void +impl_sysconfig_connection_delete (NMSysconfigConnection *self, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + + if (!check_writable (NM_CONNECTION (self), &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + + if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->delete) + NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->delete (self, context); + else { + error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, + NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +static void +impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + + if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_secrets) + NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_secrets (self, setting_name, hints, request_new, context); + else { + error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, + NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} + +/**************************************************************/ + typedef struct { NMSysconfigConnection *self; DBusGMethodInvocation *context; @@ -379,11 +571,10 @@ out: } static void -dbus_update (NMExportedConnection *exported, +dbus_update (NMSysconfigConnection *self, GHashTable *new_settings, DBusGMethodInvocation *context) { - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported); NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); PolkitCall *call; NMConnection *tmp; @@ -482,10 +673,9 @@ out: } static void -dbus_delete (NMExportedConnection *exported, +dbus_delete (NMSysconfigConnection *self, DBusGMethodInvocation *context) { - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported); NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); PolkitCall *call; @@ -577,7 +767,7 @@ out: } static void -dbus_get_secrets (NMExportedConnection *exported, +dbus_get_secrets (NMSysconfigConnection *exported, const gchar *setting_name, const gchar **hints, gboolean request_new, @@ -605,6 +795,8 @@ dbus_get_secrets (NMExportedConnection *exported, static void settings_connection_interface_init (NMSettingsConnectionInterface *iface) { + iface->update = update; + iface->delete = do_delete; iface->get_secrets = get_secrets; } @@ -646,13 +838,17 @@ static void nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - NMExportedConnectionClass *ec_class = NM_EXPORTED_CONNECTION_CLASS (class); g_type_class_add_private (class, sizeof (NMSysconfigConnectionPrivate)); /* Virtual methods */ object_class->dispose = dispose; - ec_class->update = dbus_update; - ec_class->delete = dbus_delete; - ec_class->get_secrets = dbus_get_secrets; + class->get_settings = get_settings; + class->update = dbus_update; + class->delete = dbus_delete; + class->get_secrets = dbus_get_secrets; + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), + &dbus_glib_nm_sysconfig_connection_object_info); + } diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index 0431dc95c..f8cecce0f 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -22,7 +22,7 @@ #define NM_SYSCONFIG_CONNECTION_H #include -#include +#include G_BEGIN_DECLS @@ -34,11 +34,27 @@ G_BEGIN_DECLS #define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) typedef struct { - NMExportedConnection parent; + NMConnection parent; } NMSysconfigConnection; typedef struct { - NMExportedConnectionClass parent; + NMConnectionClass parent; + + GHashTable * (*get_settings) (NMSysconfigConnection *self, + GError **error); + + void (*update) (NMSysconfigConnection *self, + GHashTable *new_settings, + DBusGMethodInvocation *context); + + void (*delete) (NMSysconfigConnection *self, + DBusGMethodInvocation *context); + + void (*get_secrets) (NMSysconfigConnection *self, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + DBusGMethodInvocation *context); } NMSysconfigConnectionClass; GType nm_sysconfig_connection_get_type (void); diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 0dff2285a..253c2a264 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -183,7 +183,7 @@ list_connections (NMSettingsInterface *settings) g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, &key, NULL)) - list = g_slist_prepend (list, NM_EXPORTED_CONNECTION (key)); + list = g_slist_prepend (list, NM_SYSCONFIG_CONNECTION (key)); return g_slist_reverse (list); } @@ -207,13 +207,13 @@ impl_settings_list_connections (NMSysconfigSettings *self, static NMSettingsConnectionInterface * get_connection_by_path (NMSettingsInterface *settings, const char *path) { - NMExportedConnection *connection = NULL; + NMSysconfigConnection *connection = NULL; GSList *list = NULL, *iter; list = list_connections (settings); for (iter = list; iter; iter = g_slist_next (iter)) { if (!strcmp (nm_connection_get_path (NM_CONNECTION (iter->data)), path)) { - connection = NM_EXPORTED_CONNECTION (iter->data); + connection = NM_SYSCONFIG_CONNECTION (iter->data); break; } } diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c index ad9a479a6..3a7e266ea 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -58,7 +58,7 @@ nm_ifupdown_connection_new (if_block *block) } static void -get_secrets (NMExportedConnection *exported, +get_secrets (NMSysconfigConnection *exported, const gchar *setting_name, const gchar **hints, gboolean request_new, @@ -81,7 +81,7 @@ get_secrets (NMExportedConnection *exported, return; } - NM_EXPORTED_CONNECTION_CLASS (nm_ifupdown_connection_parent_class)->get_secrets (exported, setting_name, hints, request_new, context); + NM_SYSCONFIG_CONNECTION_CLASS (nm_ifupdown_connection_parent_class)->get_secrets (exported, setting_name, hints, request_new, context); } static void @@ -165,7 +165,7 @@ static void nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifupdown_connection_class); - NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (ifupdown_connection_class); + NMSysconfigConnectionClass *connection_class = NM_SYSCONFIG_CONNECTION_CLASS (ifupdown_connection_class); g_type_class_add_private (ifupdown_connection_class, sizeof (NMIfupdownConnectionPrivate)); diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c index e2358b9f5..4a07022c4 100644 --- a/system-settings/plugins/ifupdown/plugin.c +++ b/system-settings/plugins/ifupdown/plugin.c @@ -458,7 +458,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, - NM_EXPORTED_CONNECTION (cl_iter->data)); + NM_SYSCONFIG_CONNECTION (cl_iter->data)); } g_list_free (con_list); } From c2f4b10ab5a0fc4825a2f8d069001c3c1482bd54 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Tue, 3 Aug 2010 13:23:30 -0400 Subject: [PATCH 013/264] libnm-glib: remove NMSettingsInterface NMSettingsInterface was created to allow code to operate on a settings service without caring about what kind of settings service it was. Now that we have just one settings service, this is no longer needed. More work needs to be done in order to handle errors and permission settings in an appropriate manner. --- cli/src/connections.c | 9 +- cli/src/nmcli.c | 1 - docs/libnm-glib/libnm-glib-docs.sgml | 1 - libnm-glib/Makefile.am | 2 - libnm-glib/libnm-glib.ver | 13 +- libnm-glib/nm-remote-settings.c | 235 ++++++++++---- libnm-glib/nm-remote-settings.h | 70 ++++- libnm-glib/nm-settings-interface.c | 290 ------------------ libnm-glib/nm-settings-interface.h | 158 ---------- src/nm-manager.c | 12 +- src/system-settings/nm-sysconfig-connection.c | 29 +- src/system-settings/nm-sysconfig-settings.c | 223 +++++--------- src/system-settings/nm-sysconfig-settings.h | 22 +- src/system-settings/nm-system-config-error.c | 16 + src/system-settings/nm-system-config-error.h | 7 + system-settings/plugins/ifcfg-rh/plugin.c | 23 +- .../plugins/keyfile/io/Makefile.am | 5 +- system-settings/plugins/keyfile/io/writer.c | 10 +- 18 files changed, 417 insertions(+), 709 deletions(-) delete mode 100644 libnm-glib/nm-settings-interface.c delete mode 100644 libnm-glib/nm-settings-interface.h diff --git a/cli/src/connections.c b/cli/src/connections.c index 67e0c18a9..73b79b2ce 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -45,7 +45,6 @@ #include //#include #include -#include #include #include @@ -141,7 +140,7 @@ static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection static const char *active_connection_state_to_string (NMActiveConnectionState state); static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data); static void activate_connection_cb (gpointer user_data, const char *path, GError *error); -static void get_connections_cb (NMSettingsInterface *settings, gpointer user_data); +static void get_connections_cb (NMRemoteSettings *settings, gpointer user_data); static NMCResultCode do_connections_list (NmCli *nmc, int argc, char **argv); static NMCResultCode do_connections_status (NmCli *nmc, int argc, char **argv); static NMCResultCode do_connection_up (NmCli *nmc, int argc, char **argv); @@ -1454,12 +1453,12 @@ error: /* callback called when connections are obtained from the settings service */ static void -get_connections_cb (NMSettingsInterface *settings, gpointer user_data) +get_connections_cb (NMRemoteSettings *settings, gpointer user_data) { ArgsInfo *args = (ArgsInfo *) user_data; GError *error = NULL; - args->nmc->system_connections = nm_settings_interface_list_connections (settings); + args->nmc->system_connections = nm_remote_settings_list_connections (settings); if (args->argc == 0) { if (!nmc_terse_option_check (args->nmc->print_output, args->nmc->required_fields, &error)) @@ -1545,7 +1544,7 @@ do_connections (NmCli *nmc, int argc, char **argv) } /* connect to signal "connections-read" - emitted when connections are fetched and ready */ - g_signal_connect (nmc->system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ, + g_signal_connect (nmc->system_settings, NM_REMOTE_SETTINGS_CONNECTIONS_READ, G_CALLBACK (get_connections_cb), &args_info); diff --git a/cli/src/nmcli.c b/cli/src/nmcli.c index bbf1f18d0..edd2443d3 100644 --- a/cli/src/nmcli.c +++ b/cli/src/nmcli.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "nmcli.h" diff --git a/docs/libnm-glib/libnm-glib-docs.sgml b/docs/libnm-glib/libnm-glib-docs.sgml index c730710ba..84a98d07f 100644 --- a/docs/libnm-glib/libnm-glib-docs.sgml +++ b/docs/libnm-glib/libnm-glib-docs.sgml @@ -32,7 +32,6 @@ - diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index bff10862c..d18a8bae5 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -76,7 +76,6 @@ libnminclude_HEADERS = \ nm-ip6-config.h \ nm-dhcp6-config.h \ nm-remote-connection.h \ - nm-settings-interface.h \ nm-remote-settings.h \ nm-settings-connection-interface.h @@ -107,7 +106,6 @@ libnm_glib_la_SOURCES = \ nm-dhcp6-config.c \ nm-remote-connection.c \ nm-remote-connection-private.h \ - nm-settings-interface.c \ nm-remote-settings.c \ nm-settings-connection-interface.c diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index ce10de216..be8d35753 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -118,6 +118,11 @@ global: nm_object_get_type; nm_remote_connection_get_type; nm_remote_connection_new; + nm_remote_settings_add_connection; + nm_remote_settings_get_connection_by_path; + nm_remote_settings_list_connections; + nm_remote_settings_get_permissions; + nm_remote_settings_save_hostname; nm_remote_settings_get_type; nm_remote_settings_new; nm_serial_device_get_bytes_received; @@ -128,14 +133,6 @@ global: nm_settings_connection_interface_get_secrets; nm_settings_connection_interface_get_type; nm_settings_connection_interface_update; - nm_settings_interface_add_connection; - nm_settings_interface_error_get_type; - nm_settings_interface_error_quark; - nm_settings_interface_get_connection_by_path; - nm_settings_interface_get_type; - nm_settings_interface_list_connections; - nm_settings_interface_get_permissions; - nm_settings_interface_save_hostname; nm_settings_error_quark; nm_settings_get_type; nm_settings_list_connections; diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 8b0c4ecad..6019e3ba6 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -29,13 +29,9 @@ #include "nm-dbus-glib-types.h" #include "nm-remote-settings.h" #include "nm-settings-bindings.h" -#include "nm-settings-interface.h" #include "nm-remote-connection-private.h" -static void settings_interface_init (NMSettingsInterface *class); - -G_DEFINE_TYPE_EXTENDED (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, settings_interface_init)) +G_DEFINE_TYPE (NMRemoteSettings, nm_remote_settings, G_TYPE_OBJECT) #define NM_REMOTE_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsPrivate)) @@ -64,13 +60,39 @@ enum { PROP_0, PROP_BUS, PROP_SERVICE_RUNNING, + PROP_HOSTNAME, + PROP_CAN_MODIFY, LAST_PROP }; -static NMSettingsConnectionInterface * -get_connection_by_path (NMSettingsInterface *settings, const char *path) +/* Signals */ +enum { + NEW_CONNECTION, + CONNECTIONS_READ, + CHECK_PERMISSIONS, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + +/** + * nm_remote_settings_get_connection_by_path: + * @settings: the %NMRemoteSettings + * @path: the D-Bus object path of the remote connection + * + * Returns the %NMRemoteConnection representing the connection at @path. + * + * Returns: the remote connection object on success, or NULL if the object was + * not known + **/ +NMRemoteConnection * +nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path) { + g_return_val_if_fail (settings != NULL, NULL); + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + g_return_val_if_fail (path != NULL, NULL); + return g_hash_table_lookup (NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->connections, path); } @@ -121,7 +143,7 @@ connection_init_result_cb (NMRemoteConnection *remote, /* Finally, let users know of the new connection now that it has all * its settings and is valid. */ - g_signal_emit_by_name (self, "new-connection", remote); + g_signal_emit (self, signals[NEW_CONNECTION], 0, remote); break; case NM_REMOTE_CONNECTION_INIT_RESULT_ERROR: default: @@ -132,7 +154,7 @@ connection_init_result_cb (NMRemoteConnection *remote, /* Let listeners know that all connections have been found */ if (!g_hash_table_size (priv->pending)) - g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_CONNECTIONS_READ); + g_signal_emit (self, signals[CONNECTIONS_READ], 0); } static void @@ -180,7 +202,7 @@ fetch_connections_done (DBusGProxy *proxy, /* Let listeners know we are done getting connections */ if (connections->len == 0) { - g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_CONNECTIONS_READ); + g_signal_emit (self, signals[CONNECTIONS_READ], 0); return; } @@ -207,14 +229,26 @@ fetch_connections (gpointer user_data) return FALSE; } -static GSList * -list_connections (NMSettingsInterface *settings) +/** + * nm_remote_settings_list_connections: + * @settings: the %NMRemoteSettings + * + * Returns: all connections in the remote settings service, represented as + * %NMRemoteConnection instances + **/ +GSList * +nm_remote_settings_list_connections (NMRemoteSettings *settings) { - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + NMRemoteSettingsPrivate *priv; GSList *list = NULL; GHashTableIter iter; gpointer value; + g_return_val_if_fail (settings != NULL, NULL); + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), NULL); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &value)) list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value)); @@ -223,8 +257,8 @@ list_connections (NMSettingsInterface *settings) } typedef struct { - NMSettingsInterface *self; - NMSettingsAddConnectionFunc callback; + NMRemoteSettings *self; + NMRemoteSettingsAddConnectionFunc callback; gpointer callback_data; } AddConnectionInfo; @@ -238,18 +272,37 @@ add_connection_done (DBusGProxy *proxy, info->callback (info->self, error, info->callback_data); g_free (info); } - -static gboolean -add_connection (NMSettingsInterface *settings, - NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer user_data) +/** + * nm_remote_settings_add_connection: + * @settings: the %NMRemoteSettings + * @connection: the connection to add. Note that this object's settings will be + * added, not the object itself + * @callback: callback to be called when the add operation completes + * @user_data: caller-specific data passed to @callback + * + * Requests that the remote settings service add the given settings to a new + * connection. + * + * Returns: TRUE if the request was successful, FALSE if it failed + **/ +gboolean +nm_remote_settings_add_connection (NMRemoteSettings *settings, + NMConnection *connection, + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data) { - NMRemoteSettings *self = NM_REMOTE_SETTINGS (settings); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + NMRemoteSettingsPrivate *priv; AddConnectionInfo *info; GHashTable *new_settings; + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + info = g_malloc0 (sizeof (AddConnectionInfo)); info->self = settings; info->callback = callback; @@ -291,8 +344,8 @@ remove_connections (gpointer user_data) } typedef struct { - NMSettingsInterface *settings; - NMSettingsSaveHostnameFunc callback; + NMRemoteSettings *settings; + NMRemoteSettingsSaveHostnameFunc callback; gpointer callback_data; } SaveHostnameInfo; @@ -309,16 +362,35 @@ save_hostname_cb (DBusGProxy *proxy, g_clear_error (&error); } -static gboolean -save_hostname (NMSettingsInterface *settings, - const char *hostname, - NMSettingsSaveHostnameFunc callback, - gpointer user_data) +/** + * nm_remote_settings_save_hostname: + * @settings: the %NMRemoteSettings + * @hostname: the new persistent hostname to set, or NULL to clear any existing + * persistent hostname + * @callback: callback to be called when the hostname operation completes + * @user_data: caller-specific data passed to @callback + * + * Requests that the machine's persistent hostname be set to the specified value + * or cleared. + * + * Returns: TRUE if the request was successful, FALSE if it failed + **/ +gboolean +nm_remote_settings_save_hostname (NMRemoteSettings *settings, + const char *hostname, + NMRemoteSettingsSaveHostnameFunc callback, + gpointer user_data) { - NMRemoteSettings *self = NM_REMOTE_SETTINGS (settings); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + NMRemoteSettingsPrivate *priv; SaveHostnameInfo *info; + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (hostname != NULL, FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + info = g_malloc0 (sizeof (SaveHostnameInfo)); info->settings = settings; info->callback = callback; @@ -334,8 +406,8 @@ save_hostname (NMSettingsInterface *settings, } typedef struct { - NMSettingsInterface *settings; - NMSettingsGetPermissionsFunc callback; + NMRemoteSettings *settings; + NMRemoteSettingsGetPermissionsFunc callback; gpointer callback_data; } GetPermissionsInfo; @@ -359,14 +431,31 @@ get_permissions_cb (DBusGProxy *proxy, g_clear_error (&error); } -static gboolean -get_permissions (NMSettingsInterface *settings, - NMSettingsGetPermissionsFunc callback, - gpointer user_data) +/** + * nm_remote_settings_get_permissions: + * @settings: the %NMRemoteSettings + * @callback: callback to be called when the permissions operation completes + * @user_data: caller-specific data passed to @callback + * + * Requests an indication of the operations the caller is permitted to perform + * including those that may require authorization. + * + * Returns: TRUE if the request was successful, FALSE if it failed + **/ +gboolean +nm_remote_settings_get_permissions (NMRemoteSettings *settings, + NMRemoteSettingsGetPermissionsFunc callback, + gpointer user_data) { - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + NMRemoteSettingsPrivate *priv; GetPermissionsInfo *info; + g_return_val_if_fail (settings != NULL, FALSE); + g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); + g_return_val_if_fail (callback != NULL, FALSE); + + priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); + /* Skip D-Bus if we already have permissions */ if (priv->have_permissions) { callback (settings, priv->permissions, NULL, user_data); @@ -421,7 +510,7 @@ check_permissions_cb (DBusGProxy *proxy, gpointer user_data) /* Permissions need to be re-fetched */ priv->have_permissions = FALSE; - g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS); + g_signal_emit (self, signals[CHECK_PERMISSIONS], 0); } static void @@ -441,12 +530,12 @@ properties_changed_cb (DBusGProxy *proxy, if (!strcmp ((const char *) key, "Hostname")) { g_free (priv->hostname); priv->hostname = g_value_dup_string (value); - g_object_notify (G_OBJECT (self), NM_SETTINGS_INTERFACE_HOSTNAME); + g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_HOSTNAME); } if (!strcmp ((const char *) key, "CanModify")) { priv->can_modify = g_value_get_boolean (value); - g_object_notify (G_OBJECT (self), NM_SETTINGS_INTERFACE_CAN_MODIFY); + g_object_notify (G_OBJECT (self), NM_REMOTE_SETTINGS_CAN_MODIFY); } } } @@ -482,17 +571,6 @@ get_all_cb (DBusGProxy *proxy, /****************************************************************/ -static void -settings_interface_init (NMSettingsInterface *iface) -{ - /* interface implementation */ - iface->list_connections = list_connections; - iface->get_connection_by_path = get_connection_by_path; - iface->add_connection = add_connection; - iface->save_hostname = save_hostname; - iface->get_permissions = get_permissions; -} - /** * nm_remote_settings_new: * @bus: a valid and connected D-Bus connection @@ -682,10 +760,10 @@ get_property (GObject *object, guint prop_id, case PROP_SERVICE_RUNNING: g_value_set_boolean (value, priv->service_running); break; - case NM_SETTINGS_INTERFACE_PROP_HOSTNAME: + case PROP_HOSTNAME: g_value_set_string (value, priv->hostname); break; - case NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY: + case PROP_CAN_MODIFY: g_value_set_boolean (value, priv->can_modify); break; default: @@ -724,13 +802,48 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) FALSE, G_PARAM_READABLE)); - g_object_class_override_property (object_class, - NM_SETTINGS_INTERFACE_PROP_HOSTNAME, - NM_SETTINGS_INTERFACE_HOSTNAME); + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_REMOTE_SETTINGS_HOSTNAME, + "Hostname", + "Persistent hostname", + NULL, + G_PARAM_READABLE)); - g_object_class_override_property (object_class, - NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY, - NM_SETTINGS_INTERFACE_CAN_MODIFY); + g_object_class_install_property + (object_class, PROP_CAN_MODIFY, + g_param_spec_boolean (NM_REMOTE_SETTINGS_CAN_MODIFY, + "CanModify", + "Can modify anything (hostname, connections, etc)", + FALSE, + G_PARAM_READABLE)); + /* Signals */ + signals[NEW_CONNECTION] = + g_signal_new (NM_REMOTE_SETTINGS_NEW_CONNECTION, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, new_connection), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTIONS_READ] = + g_signal_new (NM_REMOTE_SETTINGS_CONNECTIONS_READ, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, connections_read), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CHECK_PERMISSIONS] = + g_signal_new (NM_REMOTE_SETTINGS_CHECK_PERMISSIONS, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteSettingsClass, check_permissions), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index 6553e3bbf..77b172c12 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -31,6 +31,15 @@ G_BEGIN_DECLS +// FIXME this is temporary, permissions format to be improved +typedef enum { + NM_SETTINGS_PERMISSION_NONE = 0x0, + NM_SETTINGS_PERMISSION_CONNECTION_MODIFY = 0x1, + NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, + NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN = 0x4, + NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY = 0x8 +} NMSettingsPermissions; + #define NM_TYPE_REMOTE_SETTINGS (nm_remote_settings_get_type ()) #define NM_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettings)) #define NM_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) @@ -38,16 +47,48 @@ G_BEGIN_DECLS #define NM_IS_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS)) #define NM_REMOTE_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) -#define NM_REMOTE_SETTINGS_BUS "bus" +#define NM_REMOTE_SETTINGS_BUS "bus" #define NM_REMOTE_SETTINGS_SERVICE_RUNNING "service-running" +#define NM_REMOTE_SETTINGS_HOSTNAME "hostname" +#define NM_REMOTE_SETTINGS_CAN_MODIFY "can-modify" -typedef struct { +#define NM_REMOTE_SETTINGS_NEW_CONNECTION "new-connection" +#define NM_REMOTE_SETTINGS_CONNECTIONS_READ "connections-read" +#define NM_REMOTE_SETTINGS_CHECK_PERMISSIONS "check-permissions" + +typedef struct _NMRemoteSettings NMRemoteSettings; +typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass; + + +typedef void (*NMRemoteSettingsAddConnectionFunc) (NMRemoteSettings *settings, + GError *error, + gpointer user_data); + +typedef void (*NMRemoteSettingsSaveHostnameFunc) (NMRemoteSettings *settings, + GError *error, + gpointer user_data); + +typedef void (*NMRemoteSettingsGetPermissionsFunc) (NMRemoteSettings *settings, + NMSettingsPermissions permissions, + GError *error, + gpointer user_data); + + +struct _NMRemoteSettings { GObject parent; -} NMRemoteSettings; +}; -typedef struct { +struct _NMRemoteSettingsClass { GObjectClass parent; + /* Signals */ + void (*new_connection) (NMRemoteSettings *settings, + NMRemoteConnection *connection); + + void (*connections_read) (NMRemoteSettings *settings); + + void (*check_permissions) (NMRemoteSettings *settings); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -55,12 +96,31 @@ typedef struct { void (*_reserved4) (void); void (*_reserved5) (void); void (*_reserved6) (void); -} NMRemoteSettingsClass; +}; GType nm_remote_settings_get_type (void); NMRemoteSettings *nm_remote_settings_new (DBusGConnection *bus); +GSList * nm_remote_settings_list_connections (NMRemoteSettings *settings); + +NMRemoteConnection * nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, + const char *path); + +gboolean nm_remote_settings_add_connection (NMRemoteSettings *self, + NMConnection *connection, + NMRemoteSettingsAddConnectionFunc callback, + gpointer user_data); + +gboolean nm_remote_settings_save_hostname (NMRemoteSettings *settings, + const char *hostname, + NMRemoteSettingsSaveHostnameFunc callback, + gpointer user_data); + +gboolean nm_remote_settings_get_permissions (NMRemoteSettings *settings, + NMRemoteSettingsGetPermissionsFunc callback, + gpointer user_data); + G_END_DECLS #endif /* NM_REMOTE_SETTINGS_H */ diff --git a/libnm-glib/nm-settings-interface.c b/libnm-glib/nm-settings-interface.c deleted file mode 100644 index 951c59a24..000000000 --- a/libnm-glib/nm-settings-interface.c +++ /dev/null @@ -1,290 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. - */ - -#include "nm-settings-interface.h" - - -/** - * nm_settings_interface_error_quark: - * - * Setting error quark. - * - * Returns: the setting error quark - **/ -GQuark -nm_settings_interface_error_quark (void) -{ - static GQuark quark; - - if (G_UNLIKELY (!quark)) - quark = g_quark_from_static_string ("nm-settings-interface-error-quark"); - return quark; -} - -/* This should really be standard. */ -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_settings_interface_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - /* The connection was invalid. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, "InvalidConnection"), - /* The connection is read-only; modifications are not allowed. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"), - /* A bug in the settings service caused the error. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, "InternalError"), - /* Retrieval or request of secrets failed. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"), - /* The request for secrets was canceled. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"), - /* The request could not be completed because permission was denied. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED, "PermissionDenied"), - /* The requested setting does not existing in this connection. */ - ENUM_ENTRY (NM_SETTINGS_INTERFACE_ERROR_INVALID_SETTING, "InvalidSetting"), - { 0, 0, 0 }, - }; - etype = g_enum_register_static ("NMSettingsInterfaceError", values); - } - return etype; -} - - -/** - * nm_settings_list_connections: - * @settings: a object implementing %NMSettingsInterface - * - * Returns: all connections known to the object. - **/ -GSList * -nm_settings_interface_list_connections (NMSettingsInterface *settings) -{ - g_return_val_if_fail (settings != NULL, NULL); - g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), NULL); - - if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->list_connections) - return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->list_connections (settings); - return NULL; -} - -/** - * nm_settings_get_connection_by_path: - * @settings: a object implementing %NMSettingsInterface - * @path: the D-Bus object path of the remote connection - * - * Returns the object implementing %NMSettingsConnectionInterface at @path. - * - * Returns: the remote connection object on success, or NULL if the object was - * not known - **/ -NMSettingsConnectionInterface * -nm_settings_interface_get_connection_by_path (NMSettingsInterface *settings, - const char *path) -{ - g_return_val_if_fail (settings != NULL, NULL); - g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), NULL); - g_return_val_if_fail (path != NULL, NULL); - - if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_connection_by_path) - return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_connection_by_path (settings, path); - return NULL; -} - -/** - * nm_settings_interface_add_connection: - * @settings: a object implementing %NMSettingsInterface - * @connection: the settings to add; note that this object's settings will be - * added, not the object itself - * @callback: callback to be called when the add operation completes - * @user_data: caller-specific data passed to @callback - * - * Requests that the settings service add the given settings to a new connection. - * - * Returns: TRUE if the request was successful, FALSE if it failed - **/ -gboolean -nm_settings_interface_add_connection (NMSettingsInterface *settings, - NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), FALSE); - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->add_connection) { - return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->add_connection (settings, - connection, - callback, - user_data); - } - return FALSE; -} - -/** - * nm_settings_interface_save_hostname: - * @settings: a object implementing %NMSettingsInterface - * @hostname: the new persistent hostname to set, or NULL to clear any existing - * persistent hostname - * @callback: callback to be called when the hostname operation completes - * @user_data: caller-specific data passed to @callback - * - * Requests that the machine's persistent hostname be set to the specified value - * or cleared. - * - * Returns: TRUE if the request was successful, FALSE if it failed - **/ -gboolean -nm_settings_interface_save_hostname (NMSettingsInterface *settings, - const char *hostname, - NMSettingsSaveHostnameFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), FALSE); - g_return_val_if_fail (hostname != NULL, FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->save_hostname) { - return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->save_hostname (settings, - hostname, - callback, - user_data); - } - return FALSE; -} - -/** - * nm_settings_interface_get_permissions: - * @settings: a object implementing %NMSettingsInterface - * @callback: callback to be called when the permissions operation completes - * @user_data: caller-specific data passed to @callback - * - * Requests an indication of the operations the caller is permitted to perform - * including those that may require authorization. - * - * Returns: TRUE if the request was successful, FALSE if it failed - **/ -gboolean -nm_settings_interface_get_permissions (NMSettingsInterface *settings, - NMSettingsGetPermissionsFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_INTERFACE (settings), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_permissions) - return NM_SETTINGS_INTERFACE_GET_INTERFACE (settings)->get_permissions (settings, callback, user_data); - return FALSE; -} - - -/*****************************************************************/ - -static void -nm_settings_interface_init (gpointer g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - - /* Properties */ - g_object_interface_install_property - (g_iface, - g_param_spec_string (NM_SETTINGS_INTERFACE_HOSTNAME, - "Hostname", - "Persistent hostname", - NULL, - G_PARAM_READABLE)); - - g_object_interface_install_property - (g_iface, - g_param_spec_boolean (NM_SETTINGS_INTERFACE_CAN_MODIFY, - "CanModify", - "Can modify anything (hostname, connections, etc)", - FALSE, - G_PARAM_READABLE)); - - /* Signals */ - g_signal_new (NM_SETTINGS_INTERFACE_NEW_CONNECTION, - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsInterface, new_connection), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - g_signal_new (NM_SETTINGS_INTERFACE_CONNECTIONS_READ, - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsInterface, connections_read), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_signal_new (NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS, - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsInterface, check_permissions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - initialized = TRUE; -} - -GType -nm_settings_interface_get_type (void) -{ - static GType settings_interface_type = 0; - - if (!settings_interface_type) { - const GTypeInfo settings_interface_info = { - sizeof (NMSettingsInterface), /* class_size */ - nm_settings_interface_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - settings_interface_type = g_type_register_static (G_TYPE_INTERFACE, - "NMSettingsInterface", - &settings_interface_info, 0); - - g_type_interface_add_prerequisite (settings_interface_type, G_TYPE_OBJECT); - } - - return settings_interface_type; -} - diff --git a/libnm-glib/nm-settings-interface.h b/libnm-glib/nm-settings-interface.h deleted file mode 100644 index 6f10c9786..000000000 --- a/libnm-glib/nm-settings-interface.h +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. - */ - -#ifndef NM_SETTINGS_INTERFACE_H -#define NM_SETTINGS_INTERFACE_H - -#include - -#include "NetworkManager.h" -#include "nm-settings-connection-interface.h" - -G_BEGIN_DECLS - -typedef enum { - NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION = 0, - NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, - NM_SETTINGS_INTERFACE_ERROR_SECRETS_UNAVAILABLE, - NM_SETTINGS_INTERFACE_ERROR_SECRETS_REQUEST_CANCELED, - NM_SETTINGS_INTERFACE_ERROR_PERMISSION_DENIED, - NM_SETTINGS_INTERFACE_ERROR_INVALID_SETTING, -} NMSettingsInterfaceError; - -#define NM_SETTINGS_INTERFACE_ERROR (nm_settings_interface_error_quark ()) -GQuark nm_settings_interface_error_quark (void); - -#define NM_TYPE_SETTINGS_INTERFACE_ERROR (nm_settings_interface_error_get_type ()) -GType nm_settings_interface_error_get_type (void); - - -typedef enum { - NM_SETTINGS_PERMISSION_NONE = 0x0, - NM_SETTINGS_PERMISSION_CONNECTION_MODIFY = 0x1, - NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, - NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN = 0x4, - NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY = 0x8 -} NMSettingsPermissions; - - -#define NM_TYPE_SETTINGS_INTERFACE (nm_settings_interface_get_type ()) -#define NM_SETTINGS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_INTERFACE, NMSettingsInterface)) -#define NM_IS_SETTINGS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_INTERFACE)) -#define NM_SETTINGS_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_INTERFACE, NMSettingsInterface)) - -#define NM_SETTINGS_INTERFACE_NEW_CONNECTION "new-connection" -#define NM_SETTINGS_INTERFACE_CONNECTIONS_READ "connections-read" -#define NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS "check-permissions" - -#define NM_SETTINGS_INTERFACE_HOSTNAME "hostname" -#define NM_SETTINGS_INTERFACE_CAN_MODIFY "can-modify" - -typedef enum { - NM_SETTINGS_INTERFACE_PROP_FIRST = 0x1000, - - NM_SETTINGS_INTERFACE_PROP_HOSTNAME = NM_SETTINGS_INTERFACE_PROP_FIRST, - NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY -} NMSettingsInterfaceProp; - -typedef struct _NMSettingsInterface NMSettingsInterface; - -typedef void (*NMSettingsAddConnectionFunc) (NMSettingsInterface *settings, - GError *error, - gpointer user_data); - -typedef void (*NMSettingsSaveHostnameFunc) (NMSettingsInterface *settings, - GError *error, - gpointer user_data); - -typedef void (*NMSettingsGetPermissionsFunc) (NMSettingsInterface *settings, - NMSettingsPermissions permissions, - GError *error, - gpointer user_data); - -struct _NMSettingsInterface { - GTypeInterface g_iface; - - /* Methods */ - /* Returns a list of objects implementing NMSettingsConnectionInterface */ - GSList * (*list_connections) (NMSettingsInterface *settings); - - NMSettingsConnectionInterface * (*get_connection_by_path) (NMSettingsInterface *settings, - const char *path); - - gboolean (*add_connection) (NMSettingsInterface *settings, - NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer user_data); - - gboolean (*save_hostname) (NMSettingsInterface *settings, - const char *hostname, - NMSettingsSaveHostnameFunc callback, - gpointer user_data); - - gboolean (*get_permissions) (NMSettingsInterface *settings, - NMSettingsGetPermissionsFunc callback, - gpointer user_data); - - /* Signals */ - void (*new_connection) (NMSettingsInterface *settings, - NMSettingsConnectionInterface *connection); - - void (*connections_read) (NMSettingsInterface *settings); - - void (*check_permissions) (NMSettingsInterface *settings); - - /* Padding for future expansion */ - void (*_reserved1) (void); - void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); -}; - -GType nm_settings_interface_get_type (void); - -/* Returns a list of objects implementing NMSettingsConnectionInterface */ -GSList *nm_settings_interface_list_connections (NMSettingsInterface *settings); - -NMSettingsConnectionInterface *nm_settings_interface_get_connection_by_path (NMSettingsInterface *settings, - const char *path); - -gboolean nm_settings_interface_add_connection (NMSettingsInterface *settings, - NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer user_data); - -gboolean nm_settings_interface_save_hostname (NMSettingsInterface *settings, - const char *hostname, - NMSettingsSaveHostnameFunc callback, - gpointer user_data); - -gboolean nm_settings_interface_get_permissions (NMSettingsInterface *settings, - NMSettingsGetPermissionsFunc callback, - gpointer user_data); - -G_END_DECLS - -#endif /* NM_SETTINGS_INTERFACE_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 6f2191f1f..0f24a4ae3 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -51,8 +51,8 @@ #include "nm-bluez-manager.h" #include "nm-bluez-common.h" #include "nm-sysconfig-settings.h" +#include "nm-sysconfig-connection.h" #include "nm-secrets-provider-interface.h" -#include "nm-settings-interface.h" #include "nm-manager-auth.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" @@ -838,7 +838,7 @@ system_query_connections (NMManager *manager) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); GSList *system_connections, *iter; - system_connections = nm_settings_interface_list_connections (NM_SETTINGS_INTERFACE (priv->sys_settings)); + system_connections = nm_sysconfig_settings_list_connections (priv->sys_settings); for (iter = system_connections; iter; iter = g_slist_next (iter)) system_internal_new_connection (manager, NM_SETTINGS_CONNECTION_INTERFACE (iter->data)); g_slist_free (system_connections); @@ -1862,13 +1862,13 @@ system_get_secrets_idle_cb (gpointer user_data) { GetSecretsInfo *info = user_data; NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); - NMSettingsConnectionInterface *connection; + NMSysconfigConnection *connection; GError *error = NULL; const char *hints[3] = { NULL, NULL, NULL }; info->idle_id = 0; - connection = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (priv->sys_settings), + connection = nm_sysconfig_settings_get_connection_by_path (priv->sys_settings, info->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -1886,7 +1886,7 @@ system_get_secrets_idle_cb (gpointer user_data) hints[0] = info->hint1; hints[1] = info->hint2; - nm_settings_connection_interface_get_secrets (connection, + nm_settings_connection_interface_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (connection), info->setting_name, hints, info->request_new, @@ -3013,7 +3013,7 @@ nm_manager_get (const char *config_file, g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); - g_signal_connect (priv->sys_settings, "notify::" NM_SETTINGS_INTERFACE_HOSTNAME, + g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); g_signal_connect (priv->sys_settings, "new-connection", G_CALLBACK (system_new_connection_cb), singleton); diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index bc173779c..a64de3376 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -27,7 +27,6 @@ #include "nm-system-config-error.h" #include "nm-dbus-glib-types.h" #include "nm-settings-connection-interface.h" -#include "nm-settings-interface.h" #include "nm-polkit-helpers.h" #include "nm-logging.h" @@ -261,8 +260,8 @@ get_secrets (NMSettingsConnectionInterface *connection, * nm_sysconfig_connection_update(). */ if (!priv->secrets) { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, + error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "%s.%d - Internal error; secrets cache invalid.", __FILE__, __LINE__); (*callback) (connection, NULL, error, user_data); @@ -272,8 +271,8 @@ get_secrets (NMSettingsConnectionInterface *connection, setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); if (!setting) { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INVALID_SETTING, + error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_SETTING, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); (*callback) (connection, NULL, error, user_data); @@ -311,8 +310,8 @@ check_writable (NMConnection *connection, GError **error) NM_TYPE_SETTING_CONNECTION); if (!s_con) { g_set_error_literal (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "Connection did not have required 'connection' setting"); return FALSE; } @@ -323,8 +322,8 @@ check_writable (NMConnection *connection, GError **error) */ if (nm_setting_connection_get_read_only (s_con)) { g_set_error_literal (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_READ_ONLY_CONNECTION, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_READ_ONLY_CONNECTION, "Connection is read-only"); return FALSE; } @@ -374,8 +373,8 @@ impl_sysconfig_connection_update (NMSysconfigConnection *self, if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->update) NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->update (self, new_settings, context); else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "%s: %s:%d update() unimplemented", __func__, __FILE__, __LINE__); dbus_g_method_return_error (context, error); g_error_free (error); @@ -397,8 +396,8 @@ impl_sysconfig_connection_delete (NMSysconfigConnection *self, if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->delete) NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->delete (self, context); else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); dbus_g_method_return_error (context, error); g_error_free (error); @@ -417,8 +416,8 @@ impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_secrets) NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_secrets (self, setting_name, hints, request_new, context); else { - error = g_error_new (NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); dbus_g_method_return_error (context, error); g_error_free (error); diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 253c2a264..2084db0c1 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -115,16 +114,14 @@ typedef struct { GSList *unmanaged_specs; } NMSysconfigSettingsPrivate; -static void settings_interface_init (NMSettingsInterface *klass); - -G_DEFINE_TYPE_WITH_CODE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_INTERFACE, - settings_interface_init)) +G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT) #define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate)) enum { PROPERTIES_CHANGED, + NEW_CONNECTION, + CHECK_PERMISSIONS, LAST_SIGNAL }; @@ -135,6 +132,8 @@ enum { PROP_0, PROP_BUS, PROP_UNMANAGED_SPECS, + PROP_HOSTNAME, + PROP_CAN_MODIFY, LAST_PROP }; @@ -171,15 +170,20 @@ load_connections (NMSysconfigSettings *self) unmanaged_specs_changed (NULL, self); } -static GSList * -list_connections (NMSettingsInterface *settings) +GSList * +nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); + NMSysconfigSettingsPrivate *priv; GHashTableIter iter; gpointer key; GSList *list = NULL; - load_connections (NM_SYSCONFIG_SETTINGS (settings)); + g_return_val_if_fail (settings != NULL, NULL); + g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings), NULL); + + priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); + + load_connections (settings); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, &key, NULL)) @@ -194,7 +198,7 @@ impl_settings_list_connections (NMSysconfigSettings *self, { GSList *list = NULL, *iter; - list = list_connections (NM_SETTINGS_INTERFACE (self)); + list = nm_sysconfig_settings_list_connections (self); *connections = g_ptr_array_sized_new (g_slist_length (list) + 1); for (iter = list; iter; iter = g_slist_next (iter)) { g_ptr_array_add (*connections, @@ -204,13 +208,17 @@ impl_settings_list_connections (NMSysconfigSettings *self, return TRUE; } -static NMSettingsConnectionInterface * -get_connection_by_path (NMSettingsInterface *settings, const char *path) +NMSysconfigConnection * +nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, const char *path) { NMSysconfigConnection *connection = NULL; GSList *list = NULL, *iter; - list = list_connections (settings); + g_return_val_if_fail (settings != NULL, NULL); + g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings), NULL); + g_return_val_if_fail (path != NULL, NULL); + + list = nm_sysconfig_settings_list_connections (settings); for (iter = list; iter; iter = g_slist_next (iter)) { if (!strcmp (nm_connection_get_path (NM_CONNECTION (iter->data)), path)) { connection = NM_SYSCONFIG_CONNECTION (iter->data); @@ -219,7 +227,7 @@ get_connection_by_path (NMSettingsInterface *settings, const char *path) } g_slist_free (list); - return (NMSettingsConnectionInterface *) connection; + return connection; } static void @@ -385,7 +393,7 @@ hostname_changed (NMSystemConfigInterface *config, GParamSpec *pspec, gpointer user_data) { - g_object_notify (G_OBJECT (user_data), NM_SETTINGS_INTERFACE_HOSTNAME); + g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME); } static void @@ -574,7 +582,7 @@ claim_connection (NMSysconfigSettings *self, if (do_export) { export_connection (self, connection); - g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_NEW_CONNECTION, connection); + g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } } @@ -602,7 +610,6 @@ typedef struct { gboolean disposed; NMConnection *connection; - NMSettingsAddConnectionFunc callback; gpointer callback_data; char *hostname; @@ -617,8 +624,6 @@ static PolkitCall * polkit_call_new (NMSysconfigSettings *self, DBusGMethodInvocation *context, NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer callback_data, const char *hostname) { PolkitCall *call; @@ -633,10 +638,6 @@ polkit_call_new (NMSysconfigSettings *self, call->context = context; if (connection) call->connection = g_object_ref (connection); - if (callback) { - call->callback = callback; - call->callback_data = callback_data; - } if (hostname) call->hostname = g_strdup (hostname); @@ -720,7 +721,7 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) &error); /* Some random error happened */ if (error) { - call->callback (NM_SETTINGS_INTERFACE (self), error, call->callback_data); + dbus_g_method_return_error (call->context, error); goto out; } @@ -729,12 +730,12 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); - call->callback (NM_SETTINGS_INTERFACE (self), error, call->callback_data); + dbus_g_method_return_error (call->context, error); goto out; } if (add_new_connection (self, call->connection, &add_error)) - call->callback (NM_SETTINGS_INTERFACE (self), NULL, call->callback_data); + dbus_g_method_return (call->context); else { error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, @@ -742,7 +743,7 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) add_error ? add_error->code : -1, (add_error && add_error->message) ? add_error->message : "(unknown)"); g_error_free (add_error); - call->callback (NM_SETTINGS_INTERFACE (self), error, call->callback_data); + dbus_g_method_return_error (call->context, error); } out: @@ -753,27 +754,34 @@ out: } static void -internal_add_connection (NMSysconfigSettings *self, - NMConnection *connection, - DBusGMethodInvocation *context, /* Only present for D-Bus calls */ - NMSettingsAddConnectionFunc callback, - gpointer user_data) +impl_settings_add_connection (NMSysconfigSettings *self, + GHashTable *settings, + DBusGMethodInvocation *context) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); PolkitCall *call; + NMConnection *connection; GError *error = NULL; + connection = nm_connection_new_from_hash (settings, &error); + if (!connection) { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + /* Do any of the plugins support adding? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "None of the registered plugins support add."); - callback (NM_SETTINGS_INTERFACE (self), error, user_data); + dbus_g_method_return_error (context, error); g_error_free (error); return; } - call = polkit_call_new (self, context, connection, callback, user_data, NULL); + call = polkit_call_new (self, context, connection, NULL); g_assert (call); polkit_authority_check_authorization (priv->authority, call->subject, @@ -784,52 +792,8 @@ internal_add_connection (NMSysconfigSettings *self, pk_add_cb, call); priv->pk_calls = g_slist_append (priv->pk_calls, call); -} -static void -dbus_add_connection_cb (NMSettingsInterface *settings, - GError *error, - gpointer user_data) -{ - DBusGMethodInvocation *context = user_data; - - if (error) - dbus_g_method_return_error (context, error); - else - dbus_g_method_return (context); -} - -static void -impl_settings_add_connection (NMSysconfigSettings *self, - GHashTable *settings, - DBusGMethodInvocation *context) -{ - NMConnection *tmp; - GError *error = NULL; - - /* Check if the settings are valid first */ - tmp = nm_connection_new_from_hash (settings, &error); - if (!tmp) { - g_assert (error); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - internal_add_connection (self, tmp, context, dbus_add_connection_cb, context); - - g_object_unref (tmp); -} - -static gboolean -settings_interface_add_connection (NMSettingsInterface *settings, - NMConnection *connection, - NMSettingsAddConnectionFunc callback, - gpointer user_data) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings); - internal_add_connection (self, connection, NULL, callback, user_data); - return TRUE; + g_object_unref (connection); } static void @@ -922,7 +886,7 @@ impl_settings_save_hostname (NMSysconfigSettings *self, return; } - call = polkit_call_new (self, context, NULL, NULL, NULL, hostname); + call = polkit_call_new (self, context, NULL, hostname); g_assert (call); polkit_authority_check_authorization (priv->authority, call->subject, @@ -939,8 +903,7 @@ static void pk_authority_changed_cb (GObject *object, gpointer user_data) { /* Let clients know they should re-check their authorization */ - g_signal_emit_by_name (NM_SYSCONFIG_SETTINGS (user_data), - NM_SETTINGS_INTERFACE_CHECK_PERMISSIONS); + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), signals[CHECK_PERMISSIONS], 0); } typedef struct { @@ -1053,7 +1016,7 @@ impl_settings_get_permissions (NMSysconfigSettings *self, { PolkitCall *call; - call = polkit_call_new (self, context, NULL, NULL, NULL, FALSE); + call = polkit_call_new (self, context, NULL, FALSE); g_assert (call); /* Start checks for the various permissions */ @@ -1081,36 +1044,6 @@ impl_settings_get_permissions (NMSysconfigSettings *self, NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED); } -static gboolean -get_permissions (NMSettingsInterface *settings, - NMSettingsGetPermissionsFunc callback, - gpointer user_data) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings); - NMSettingsPermissions permissions = NM_SETTINGS_PERMISSION_NONE; - - /* Local caller (ie, NM) gets full permissions by default because it doesn't - * need authorization. However, permissions are still subject to plugin's - * restrictions. i.e. if no plugins support connection-modify, then even - * the local caller won't get that permission. - */ - - /* Only check for connection-modify if one of our plugins supports it. */ - if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) - permissions |= NM_SETTINGS_PERMISSION_CONNECTION_MODIFY; - - /* Only check for hostname-modify if one of our plugins supports it. */ - if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) - permissions |= NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY; - - // FIXME: hook these into plugin permissions like the modify permissions */ - permissions |= NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN; - permissions |= NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED; - - callback (settings, permissions, NULL, user_data); - return TRUE; -} - static gboolean have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) { @@ -1529,19 +1462,6 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); } -static void -settings_interface_init (NMSettingsInterface *iface) -{ - iface->add_connection = settings_interface_add_connection; - iface->list_connections = list_connections; - iface->get_connection_by_path = get_connection_by_path; - iface->get_permissions = get_permissions; - - dbus_g_object_type_install_info (G_TYPE_FROM_INTERFACE (iface), - &dbus_glib_nm_settings_object_info); - -} - static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -1581,14 +1501,14 @@ get_property (GObject *object, guint prop_id, copy = g_slist_append (copy, g_strdup (iter->data)); g_value_take_boxed (value, copy); break; - case NM_SETTINGS_INTERFACE_PROP_HOSTNAME: + case PROP_HOSTNAME: g_value_take_string (value, nm_sysconfig_settings_get_hostname (self)); /* Don't ever pass NULL through D-Bus */ if (!g_value_get_string (value)) g_value_set_static_string (value, ""); break; - case NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY: + case PROP_CAN_MODIFY: g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)); break; default: @@ -1634,13 +1554,21 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) DBUS_TYPE_G_LIST_OF_STRING, G_PARAM_READABLE)); - g_object_class_override_property (object_class, - NM_SETTINGS_INTERFACE_PROP_HOSTNAME, - NM_SETTINGS_INTERFACE_HOSTNAME); + g_object_class_install_property + (object_class, PROP_HOSTNAME, + g_param_spec_string (NM_SYSCONFIG_SETTINGS_HOSTNAME, + "Hostname", + "Persistent hostname", + NULL, + G_PARAM_READABLE)); - g_object_class_override_property (object_class, - NM_SETTINGS_INTERFACE_PROP_CAN_MODIFY, - NM_SETTINGS_INTERFACE_CAN_MODIFY); + g_object_class_install_property + (object_class, PROP_CAN_MODIFY, + g_param_spec_boolean (NM_SYSCONFIG_SETTINGS_CAN_MODIFY, + "CanModify", + "Can modify anything (hostname, connections, etc)", + FALSE, + G_PARAM_READABLE)); /* signals */ signals[PROPERTIES_CHANGED] = @@ -1651,15 +1579,28 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); + signals[NEW_CONNECTION] = + g_signal_new (NM_SYSCONFIG_SETTINGS_NEW_CONNECTION, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CHECK_PERMISSIONS] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CHECK_PERMISSIONS, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, NM_TYPE_SYSCONFIG_SETTINGS_ERROR); - dbus_g_error_domain_register (NM_SETTINGS_INTERFACE_ERROR, - NM_DBUS_IFACE_SETTINGS, - NM_TYPE_SETTINGS_INTERFACE_ERROR); - /* And register all the settings errors with D-Bus */ dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR); dbus_g_error_domain_register (NM_SETTING_802_1X_ERROR, NULL, NM_TYPE_SETTING_802_1X_ERROR); @@ -1678,6 +1619,10 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) dbus_g_error_domain_register (NM_SETTING_WIRELESS_SECURITY_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_SECURITY_ERROR); dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR); dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR); + + dbus_g_object_type_install_info (NM_TYPE_SYSCONFIG_SETTINGS, + &dbus_glib_nm_settings_object_info); + } static void diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index 906afff3b..6146ab6dc 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -32,6 +32,15 @@ #include "nm-system-config-interface.h" #include "nm-device.h" +// FIXME this is temporary, permissions format to be improved +typedef enum { + NM_SETTINGS_PERMISSION_NONE = 0x0, + NM_SETTINGS_PERMISSION_CONNECTION_MODIFY = 0x1, + NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, + NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN = 0x4, + NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY = 0x8 +} NMSettingsPermissions; + #define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ()) #define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings)) #define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) @@ -39,8 +48,13 @@ #define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) #define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) -#define NM_SYSCONFIG_SETTINGS_BUS "bus" +#define NM_SYSCONFIG_SETTINGS_BUS "bus" #define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" +#define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" +#define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" + +#define NM_SYSCONFIG_SETTINGS_NEW_CONNECTION "new-connection" +#define NM_SYSCONFIG_SETTINGS_CHECK_PERMISSIONS "check-permissions" typedef struct { GObject parent_instance; @@ -60,6 +74,12 @@ NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file, DBusGConnection *bus, GError **error); +/* Returns a list of NMSysconfigConnections */ +GSList * nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings); + +NMSysconfigConnection * nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, + const char *path); + const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self); char *nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self); diff --git a/src/system-settings/nm-system-config-error.c b/src/system-settings/nm-system-config-error.c index 13d47462f..a4e52a6b6 100644 --- a/src/system-settings/nm-system-config-error.c +++ b/src/system-settings/nm-system-config-error.c @@ -42,6 +42,22 @@ nm_sysconfig_settings_error_get_type (void) if (etype == 0) { static const GEnumValue values[] = { ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "GeneralError"), + + /* The connection was invalid. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"), + /* The connection is read-only; modifications are not allowed. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"), + /* A bug in the settings service caused the error. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"), + /* Retrieval or request of secrets failed. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"), + /* The request for secrets was canceled. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"), + /* The request could not be completed because permission was denied. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"), + /* The requested setting does not existing in this connection. */ + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"), + ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), diff --git a/src/system-settings/nm-system-config-error.h b/src/system-settings/nm-system-config-error.h index 63896fcd0..82753fde0 100644 --- a/src/system-settings/nm-system-config-error.h +++ b/src/system-settings/nm-system-config-error.h @@ -27,6 +27,13 @@ enum { NM_SYSCONFIG_SETTINGS_ERROR_GENERAL = 0, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, + NM_SYSCONFIG_SETTINGS_ERROR_READ_ONLY_CONNECTION, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_UNAVAILABLE, + NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, + NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_SETTING, NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 8a831228c..acfed7652 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -38,12 +38,13 @@ #include #include -#include #include "common.h" #include "nm-dbus-glib-types.h" #include "plugin.h" #include "nm-system-config-interface.h" +#include "nm-system-config-error.h" + #include "nm-ifcfg-connection.h" #include "nm-inotify-helper.h" #include "shvar.h" @@ -537,8 +538,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, if (!g_path_is_absolute (in_ifcfg)) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "ifcfg path '%s' is not absolute", in_ifcfg); return FALSE; } @@ -546,8 +547,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, connection = g_hash_table_lookup (priv->connections, in_ifcfg); if (!connection) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "ifcfg file '%s' unknown", in_ifcfg); return FALSE; } @@ -555,8 +556,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); if (!s_con) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "unable to retrieve the connection setting"); return FALSE; } @@ -564,8 +565,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, uuid = nm_setting_connection_get_uuid (s_con); if (!uuid) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "unable to get the UUID"); return FALSE; } @@ -573,8 +574,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, path = nm_connection_get_path (NM_CONNECTION (connection)); if (!path) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "unable to get the connection D-Bus path"); return FALSE; } diff --git a/system-settings/plugins/keyfile/io/Makefile.am b/system-settings/plugins/keyfile/io/Makefile.am index 9333c5097..c7427fdc3 100644 --- a/system-settings/plugins/keyfile/io/Makefile.am +++ b/system-settings/plugins/keyfile/io/Makefile.am @@ -1,5 +1,6 @@ INCLUDES = \ -I$(top_srcdir)/system-settings/src \ + -I$(top_srcdir)/src/system-settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib @@ -16,5 +17,7 @@ libkeyfile_io_la_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) -libkeyfile_io_la_LIBADD = $(GLIB_LIBS) +libkeyfile_io_la_LIBADD = \ + $(top_builddir)/src/system-settings/libsystem-settings.la \ + $(GLIB_LIBS) diff --git a/system-settings/plugins/keyfile/io/writer.c b/system-settings/plugins/keyfile/io/writer.c index 7bba71e68..6eed7bb77 100644 --- a/system-settings/plugins/keyfile/io/writer.c +++ b/system-settings/plugins/keyfile/io/writer.c @@ -36,9 +36,9 @@ #include #include #include -#include #include "nm-dbus-glib-types.h" +#include "nm-system-config-error.h" #include "writer.h" #include "reader.h" @@ -668,8 +668,8 @@ write_connection (NMConnection *connection, g_file_set_contents (path, data, len, error); if (chown (path, owner_uid, owner_grp) < 0) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "%s.%d: error chowning '%s': %d", __FILE__, __LINE__, path, errno); unlink (path); @@ -677,8 +677,8 @@ write_connection (NMConnection *connection, err = chmod (path, S_IRUSR | S_IWUSR); if (err) { g_set_error (error, - NM_SETTINGS_INTERFACE_ERROR, - NM_SETTINGS_INTERFACE_ERROR_INTERNAL_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "%s.%d: error setting permissions on '%s': %d", __FILE__, __LINE__, path, errno); unlink (path); From a4af7967c955603d4cd009cc118d81ec48f187ef Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 5 Aug 2010 00:54:03 -0400 Subject: [PATCH 014/264] ifupdown: get_secrets: don't override DBus handler ifupdown only supports secrets for wireless connections, so attempts to get non-wireless secrets need to fail. Previously, this was accomplished by overriding NMSysconfigSettingsClass->get_secrets, the handler for DBus GetSecrets() method calls. This had some problems: - It created an information leak. The first thing the NMSysconfigConnection implementation does is verify that the caller is authorized to get secrets information, but nm-ifupdown-connection ends up performing its additional check before authorization happens. Thus, unauthorized users are able to determine that some connections don't have secrets. This will become more significant when secrets handling is revamped. - We'd really like to devirtualize these DBus method call handlers. They were inherited from from NMRemoteConnection, where we needed these functions to be virtual so that user and system settings services could implement them differently. That is no longer needed. ifupdown was the last place were we actually "needed" these functions to be virtual. With this commit, we fix these problems by overriding nm_settings_connection_interface_get_secrets instead. --- .../plugins/ifupdown/nm-ifupdown-connection.c | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c index 3a7e266ea..5eb83ad4b 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -32,7 +32,13 @@ #include "nm-ifupdown-connection.h" #include "parser.h" -G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SYSCONFIG_CONNECTION) +static NMSettingsConnectionInterface *parent_settings_connection_iface; + +static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); + +G_DEFINE_TYPE_EXTENDED (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, + settings_connection_interface_init)) #define NM_IFUPDOWN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionPrivate)) @@ -57,12 +63,13 @@ nm_ifupdown_connection_new (if_block *block) NULL); } -static void -get_secrets (NMSysconfigConnection *exported, +static gboolean +get_secrets (NMSettingsConnectionInterface *connection, const gchar *setting_name, const gchar **hints, gboolean request_new, - DBusGMethodInvocation *context) + NMSettingsConnectionInterfaceGetSecretsFunc callback, + gpointer user_data) { GError *error = NULL; @@ -76,12 +83,24 @@ get_secrets (NMSysconfigConnection *exported, "%s.%d - security setting name not supported '%s'.", __FILE__, __LINE__, setting_name); PLUGIN_PRINT ("SCPlugin-Ifupdown", "%s", error->message); - dbus_g_method_return_error (context, error); + callback (connection, NULL, error, user_data); g_error_free (error); - return; + return FALSE; } - NM_SYSCONFIG_CONNECTION_CLASS (nm_ifupdown_connection_parent_class)->get_secrets (exported, setting_name, hints, request_new, context); + return parent_settings_connection_iface->get_secrets (connection, + setting_name, + hints, + request_new, + callback, + user_data); +} + +static void +settings_connection_interface_init (NMSettingsConnectionInterface *iface) +{ + parent_settings_connection_iface = g_type_interface_peek_parent (iface); + iface->get_secrets = get_secrets; } static void @@ -165,7 +184,6 @@ static void nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifupdown_connection_class); - NMSysconfigConnectionClass *connection_class = NM_SYSCONFIG_CONNECTION_CLASS (ifupdown_connection_class); g_type_class_add_private (ifupdown_connection_class, sizeof (NMIfupdownConnectionPrivate)); @@ -174,8 +192,6 @@ nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connectio object_class->set_property = set_property; object_class->get_property = get_property; - connection_class->get_secrets = get_secrets; - /* Properties */ g_object_class_install_property (object_class, PROP_IFBLOCK, From 5f0b5091b4f86ca885ed7a4bf754b92a7b9c9a3a Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 5 Aug 2010 01:39:13 -0400 Subject: [PATCH 015/264] nm-sysconfig-connection: flatten DBus handlers NMExportedConnection originally implemented its DBus method call handlers as virtual functions, primarily so that system and user settings services could implement them differently. NMIfupdownConnection also depended on GetSecrets being virtual, so this was retained when NMExportedConnection was flattened into NMSysconfigConnection. However, it turns out that NMIfupdownConnection doesn't really need these functions to be virtual; it's more appropriate to override the methods of NMSettingsConnectionInterface (which are used by the DBus handlers). Indeed, we really don't want settings plugins to override the DBus handlers, as we must authorize the caller before doing anything else. So we can save a bunch of code and devirtualize these handlers. --- src/system-settings/nm-sysconfig-connection.c | 178 +++++------------- src/system-settings/nm-sysconfig-connection.h | 16 -- 2 files changed, 47 insertions(+), 147 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index a64de3376..c55ea7012 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -67,27 +67,6 @@ typedef struct { /**************************************************************/ -static GHashTable * -get_settings (NMSysconfigConnection *self, GError **error) -{ - NMConnection *no_secrets; - GHashTable *settings; - - /* Secrets should *never* be returned by the GetSettings method, they - * get returned by the GetSecrets method which can be better - * protected against leakage of secrets to unprivileged callers. - */ - no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); - g_assert (no_secrets); - nm_connection_clear_secrets (no_secrets); - settings = nm_connection_to_hash (no_secrets); - g_assert (settings); - g_object_unref (no_secrets); - - return settings; -} - - static void ignore_cb (NMSettingsConnectionInterface *connection, GError *error, @@ -298,6 +277,26 @@ get_secrets (NMSettingsConnectionInterface *connection, /**************************************************************/ +static gboolean +impl_sysconfig_connection_get_settings (NMSysconfigConnection *self, + GHashTable **settings, + GError **error) +{ + NMConnection *no_secrets; + + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); + g_assert (no_secrets); + nm_connection_clear_secrets (no_secrets); + *settings = nm_connection_to_hash (no_secrets); + g_assert (*settings); + g_object_unref (no_secrets); + return *settings ? TRUE : FALSE; +} + static gboolean check_writable (NMConnection *connection, GError **error) { @@ -331,101 +330,6 @@ check_writable (NMConnection *connection, GError **error) return TRUE; } -static gboolean -impl_sysconfig_connection_get_settings (NMSysconfigConnection *self, - GHashTable **settings, - GError **error) -{ - /* Must always be implemented */ - g_assert (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_settings); - *settings = NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_settings (self, error); - return *settings ? TRUE : FALSE; -} - -static void -impl_sysconfig_connection_update (NMSysconfigConnection *self, - GHashTable *new_settings, - DBusGMethodInvocation *context) -{ - NMConnection *tmp; - GError *error = NULL; - - /* If the connection is read-only, that has to be changed at the source of - * the problem (ex a system settings plugin that can't write connections out) - * instead of over D-Bus. - */ - if (!check_writable (NM_CONNECTION (self), &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - /* Check if the settings are valid first */ - tmp = nm_connection_new_from_hash (new_settings, &error); - if (!tmp) { - g_assert (error); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - g_object_unref (tmp); - - if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->update) - NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->update (self, new_settings, context); - else { - error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, - "%s: %s:%d update() unimplemented", __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -static void -impl_sysconfig_connection_delete (NMSysconfigConnection *self, - DBusGMethodInvocation *context) -{ - GError *error = NULL; - - if (!check_writable (NM_CONNECTION (self), &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } - - if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->delete) - NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->delete (self, context); - else { - error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, - "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -static void -impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context) -{ - GError *error = NULL; - - if (NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_secrets) - NM_SYSCONFIG_CONNECTION_GET_CLASS (self)->get_secrets (self, setting_name, hints, request_new, context); - else { - error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, - "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); - dbus_g_method_return_error (context, error); - g_error_free (error); - } -} - -/**************************************************************/ - typedef struct { NMSysconfigConnection *self; DBusGMethodInvocation *context; @@ -570,15 +474,25 @@ out: } static void -dbus_update (NMSysconfigConnection *self, - GHashTable *new_settings, - DBusGMethodInvocation *context) +impl_sysconfig_connection_update (NMSysconfigConnection *self, + GHashTable *new_settings, + DBusGMethodInvocation *context) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); PolkitCall *call; NMConnection *tmp; GError *error = NULL; + /* If the connection is read-only, that has to be changed at the source of + * the problem (ex a system settings plugin that can't write connections out) + * instead of over D-Bus. + */ + if (!check_writable (NM_CONNECTION (self), &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } + /* Check if the settings are valid first */ tmp = nm_connection_new_from_hash (new_settings, &error); if (!tmp) { @@ -672,11 +586,18 @@ out: } static void -dbus_delete (NMSysconfigConnection *self, - DBusGMethodInvocation *context) +impl_sysconfig_connection_delete (NMSysconfigConnection *self, + DBusGMethodInvocation *context) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); PolkitCall *call; + GError *error = NULL; + + if (!check_writable (NM_CONNECTION (self), &error)) { + dbus_g_method_return_error (context, error); + g_error_free (error); + return; + } call = polkit_call_new (self, context, NULL, NULL, NULL, FALSE); g_assert (call); @@ -766,13 +687,12 @@ out: } static void -dbus_get_secrets (NMSysconfigConnection *exported, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context) +impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + DBusGMethodInvocation *context) { - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (exported); NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); PolkitCall *call; @@ -842,10 +762,6 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) /* Virtual methods */ object_class->dispose = dispose; - class->get_settings = get_settings; - class->update = dbus_update; - class->delete = dbus_delete; - class->get_secrets = dbus_get_secrets; dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_sysconfig_connection_object_info); diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index f8cecce0f..3c43bf914 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -39,22 +39,6 @@ typedef struct { typedef struct { NMConnectionClass parent; - - GHashTable * (*get_settings) (NMSysconfigConnection *self, - GError **error); - - void (*update) (NMSysconfigConnection *self, - GHashTable *new_settings, - DBusGMethodInvocation *context); - - void (*delete) (NMSysconfigConnection *self, - DBusGMethodInvocation *context); - - void (*get_secrets) (NMSysconfigConnection *self, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context); } NMSysconfigConnectionClass; GType nm_sysconfig_connection_get_type (void); From bbd4c232137723d9f241ee33ca40264046f95a4e Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Wed, 4 Aug 2010 04:45:43 -0400 Subject: [PATCH 016/264] split nm_sysconfig_connection_update The various "update" functions implemented by NMSysconfigConnection have become confusing. Depending on how you count, we've wound up with about 4 functions that all share the name "update" but nonetheless do different things. These functions used to be distributed over several interfaces implemented by NMSysconfigConnection, but now that we've removed NMExportedConnection and are about to remove NMSettingsConnectionInterface, they will be all crammed into a single interface and will be even more confusing than before. It's time to give better names to these guys. The renames planned are: - nm_settings_connection_interface_update() --> nm_sysconfig_connection_commit_changes() - nm_sysconfig_connection_update() with signal_update==FALSE --> nm_sysconfig_connection_replace_settings() - nm_sysconfig_connection_update() with signal_update==TRUE --> nm_sysconfig_connection_replace_and_commit() This commit performs the last two renames. The first will be performed when removing NMSettingsConnectionInterface. We also have nm_sysconfig_connection_replace_and_commit() have an async-ish API that accepts a callback. This fits nicely with the async-ish API of nm_settings_connection_interface_update(), and it lets us clean up pk_update_cb() a bit. --- src/system-settings/nm-sysconfig-connection.c | 95 +++++++++++-------- src/system-settings/nm-sysconfig-connection.h | 17 ++-- src/system-settings/nm-sysconfig-settings.c | 3 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 2 +- system-settings/plugins/ifcfg-rh/plugin.c | 22 +++-- .../plugins/keyfile/nm-keyfile-connection.c | 2 +- system-settings/plugins/keyfile/plugin.c | 28 +++--- 7 files changed, 99 insertions(+), 70 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index c55ea7012..8d0c061e8 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -67,18 +67,12 @@ typedef struct { /**************************************************************/ -static void -ignore_cb (NMSettingsConnectionInterface *connection, - GError *error, - gpointer user_data) -{ -} - +/* Update the settings of this connection to match that of 'new', taking care to + * make a private copy of secrets. */ gboolean -nm_sysconfig_connection_update (NMSysconfigConnection *self, - NMConnection *new, - gboolean signal_update, - GError **error) +nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, + NMConnection *new, + GError **error) { NMSysconfigConnectionPrivate *priv; GHashTable *new_settings; @@ -91,12 +85,6 @@ nm_sysconfig_connection_update (NMSysconfigConnection *self, priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - /* Do nothing if there's nothing to update */ - if (nm_connection_compare (NM_CONNECTION (self), - NM_CONNECTION (new), - NM_SETTING_COMPARE_FLAG_EXACT)) - return TRUE; - new_settings = nm_connection_to_hash (new); g_assert (new_settings); if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) { @@ -107,17 +95,57 @@ nm_sysconfig_connection_update (NMSysconfigConnection *self, g_object_unref (priv->secrets); priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); - if (signal_update) { - nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self), - ignore_cb, - NULL); - } success = TRUE; } g_hash_table_destroy (new_settings); return success; } +static void +ignore_cb (NMSettingsConnectionInterface *connection, + GError *error, + gpointer user_data) +{ +} + +/* Replaces the settings in this connection with those in 'new'. If any changes + * are made, commits them to permanent storage and to any other subsystems + * watching this connection. Before returning, 'callback' is run with the given + * 'user_data' along with any errors encountered. + */ +void +nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, + NMConnection *new, + NMSettingsConnectionInterfaceUpdateFunc callback, + gpointer user_data) +{ + GError *error = NULL; + + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (self)); + g_return_if_fail (new != NULL); + g_return_if_fail (NM_IS_CONNECTION (new)); + + if (!callback) + callback = ignore_cb; + + /* Do nothing if there's nothing to update */ + if (nm_connection_compare (NM_CONNECTION (self), + NM_CONNECTION (new), + NM_SETTING_COMPARE_FLAG_EXACT)) { + callback (NM_SETTINGS_CONNECTION_INTERFACE (self), NULL, user_data); + return; + } + + if (nm_sysconfig_connection_replace_settings (self, new, &error)) { + nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self), + callback, user_data); + } else { + callback (NM_SETTINGS_CONNECTION_INTERFACE (self), error, user_data); + g_clear_error (&error); + } +} + /**************************************************************/ static gboolean @@ -236,7 +264,7 @@ get_secrets (NMSettingsConnectionInterface *connection, /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() * will clear secrets on this object's settings. priv->secrets should be * a complete copy of this object and kept in sync by - * nm_sysconfig_connection_update(). + * nm_sysconfig_connection_replace_settings(). */ if (!priv->secrets) { error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, @@ -452,22 +480,11 @@ pk_update_cb (GObject *object, GAsyncResult *result, gpointer user_data) goto out; } - /* Update our settings internally so the update() call will save the new - * ones. We don't let nm_sysconfig_connection_update() handle the update - * signal since we need our own callback after the update is done. - */ - if (!nm_sysconfig_connection_update (self, call->connection, FALSE, &error)) { - /* Shouldn't really happen since we've already validated the settings */ - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - goto out; - } - - /* Caller is authenticated, now we can finally try to commit the update */ - nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self), - con_update_cb, - call); + /* Update and commit our settings. */ + nm_sysconfig_connection_replace_and_commit (self, + call->connection, + con_update_cb, + call); out: g_object_unref (pk_result); diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index 3c43bf914..253c28750 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -22,6 +22,7 @@ #define NM_SYSCONFIG_CONNECTION_H #include +#include #include G_BEGIN_DECLS @@ -43,13 +44,15 @@ typedef struct { GType nm_sysconfig_connection_get_type (void); -/* Called by a system-settings plugin to update a connection is out of sync - * with it's backing storage. - */ -gboolean nm_sysconfig_connection_update (NMSysconfigConnection *self, - NMConnection *new_settings, - gboolean signal_update, - GError **error); +gboolean nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, + NMConnection *new_settings, + GError **error); + +void nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, + NMConnection *new_settings, + NMSettingsConnectionInterfaceUpdateFunc callback, + gpointer user_data); + G_END_DECLS diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 2084db0c1..c6294cbf8 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -71,7 +71,8 @@ EXPORT(nm_inotify_helper_add_watch) EXPORT(nm_inotify_helper_remove_watch) EXPORT(nm_sysconfig_connection_get_type) -EXPORT(nm_sysconfig_connection_update) +EXPORT(nm_sysconfig_connection_replace_settings) +EXPORT(nm_sysconfig_connection_replace_and_commit) /* END LINKER CRACKROCK */ static void claim_connection (NMSysconfigSettings *self, diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 52ce6e152..64f29ecaa 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -133,7 +133,7 @@ nm_ifcfg_connection_new (const char *filename, } /* Update our settings with what was read from the file */ - nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (object), tmp, FALSE, NULL); + nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); g_object_unref (tmp); priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index acfed7652..f6db49572 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -201,6 +201,17 @@ read_connections (SCPluginIfcfg *plugin) /* Monitoring */ +/* Callback for nm_sysconfig_connection_replace_and_commit. Report any errors + * encountered when commiting connection settings updates. */ +static void +commit_cb (NMSettingsConnectionInterface *connection, GError *error, gpointer unused) +{ + if (error) { + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s", + (error && error->message) ? error->message : "(unknown)"); + } +} + static void connection_changed_handler (SCPluginIfcfg *plugin, const char *path, @@ -261,14 +272,9 @@ connection_changed_handler (SCPluginIfcfg *plugin, g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); } - if (!nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (connection), - NM_CONNECTION (new), - TRUE, - &error)) { - PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s", - (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); - } + nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (connection), + NM_CONNECTION (new), + commit_cb, NULL); /* Update unmanaged status */ g_object_set (connection, "unmanaged", new_unmanaged, NULL); diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 1c90961be..b5e5b5c14 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -147,7 +147,7 @@ constructor (GType type, return NULL; } - nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (object), tmp, FALSE, NULL); + nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); g_object_unref (tmp); /* if for some reason the connection didn't have a UUID, add one */ diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 36f47ccdc..5b82b5b6f 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -125,26 +125,28 @@ find_by_uuid (gpointer key, gpointer data, gpointer user_data) } static void -update_connection_settings (NMKeyfileConnection *orig, - NMKeyfileConnection *new) -{ - GError *error = NULL; - - if (!nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (orig), - NM_CONNECTION (new), - TRUE, - &error)) { +update_connection_settings_commit_cb (NMSettingsConnectionInterface *orig, GError *error, gpointer user_data) { + if (error) { g_warning ("%s: '%s' / '%s' invalid: %d", - __func__, - error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)", - (error && error->message) ? error->message : "(none)", - error ? error->code : -1); + __func__, + error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)", + (error && error->message) ? error->message : "(none)", + error ? error->code : -1); g_clear_error (&error); g_signal_emit_by_name (orig, "removed"); } } +static void +update_connection_settings (NMKeyfileConnection *orig, + NMKeyfileConnection *new) +{ + nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (orig), + NM_CONNECTION (new), + update_connection_settings_commit_cb, NULL); +} + /* Monitoring */ static void From 7f8dc06dff95bbc0d1eba70a93e43b310dab858d Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 5 Aug 2010 18:25:15 -0400 Subject: [PATCH 017/264] remove nm-settings-connection-interface NMSettingsConnectionInterface was created to allow the daemon and NM clients to have common code that handled both system and user connections. It's no longer needed now that user settings services are gone. This concludes the flattening of libnm-glib. --- cli/src/connections.c | 1 - cli/src/nmcli.c | 1 - docs/libnm-glib/libnm-glib-docs.sgml | 2 - libnm-glib/Makefile.am | 6 +- libnm-glib/libnm-glib.ver | 8 +- libnm-glib/nm-remote-connection.c | 152 ++++++++----- libnm-glib/nm-remote-connection.h | 37 ++++ libnm-glib/nm-settings-connection-interface.c | 192 ---------------- libnm-glib/nm-settings-connection-interface.h | 116 ---------- src/nm-manager.c | 30 +-- .../nm-default-wired-connection.c | 39 ++-- src/system-settings/nm-sysconfig-connection.c | 205 +++++++++++++----- src/system-settings/nm-sysconfig-connection.h | 62 +++++- src/system-settings/nm-sysconfig-settings.c | 41 ++-- .../nm-system-config-interface.c | 2 +- .../nm-system-config-interface.h | 10 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 40 ++-- system-settings/plugins/ifcfg-rh/plugin.c | 2 +- .../plugins/ifupdown/nm-ifupdown-connection.c | 38 ++-- system-settings/plugins/ifupdown/plugin.c | 20 +- .../plugins/keyfile/nm-keyfile-connection.c | 46 ++-- system-settings/plugins/keyfile/plugin.c | 2 +- 22 files changed, 463 insertions(+), 589 deletions(-) delete mode 100644 libnm-glib/nm-settings-connection-interface.c delete mode 100644 libnm-glib/nm-settings-connection-interface.h diff --git a/cli/src/connections.c b/cli/src/connections.c index 73b79b2ce..20b681b55 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -45,7 +45,6 @@ #include //#include #include -#include #include #include "utils.h" diff --git a/cli/src/nmcli.c b/cli/src/nmcli.c index edd2443d3..bfd90b15a 100644 --- a/cli/src/nmcli.c +++ b/cli/src/nmcli.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "nmcli.h" #include "utils.h" diff --git a/docs/libnm-glib/libnm-glib-docs.sgml b/docs/libnm-glib/libnm-glib-docs.sgml index 84a98d07f..efe379744 100644 --- a/docs/libnm-glib/libnm-glib-docs.sgml +++ b/docs/libnm-glib/libnm-glib-docs.sgml @@ -31,8 +31,6 @@ - - diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index d18a8bae5..feb6c05eb 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -76,8 +76,7 @@ libnminclude_HEADERS = \ nm-ip6-config.h \ nm-dhcp6-config.h \ nm-remote-connection.h \ - nm-remote-settings.h \ - nm-settings-connection-interface.h + nm-remote-settings.h libnm_glib_la_SOURCES = \ nm-object.c \ @@ -106,8 +105,7 @@ libnm_glib_la_SOURCES = \ nm-dhcp6-config.c \ nm-remote-connection.c \ nm-remote-connection-private.h \ - nm-remote-settings.c \ - nm-settings-connection-interface.c + nm-remote-settings.c libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index be8d35753..1ac3bdb5c 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -116,6 +116,9 @@ global: nm_object_get_connection; nm_object_get_path; nm_object_get_type; + nm_remote_connection_delete; + nm_remote_connection_get_secrets; + nm_remote_connection_commit_changes; nm_remote_connection_get_type; nm_remote_connection_new; nm_remote_settings_add_connection; @@ -128,11 +131,6 @@ global: nm_serial_device_get_bytes_received; nm_serial_device_get_bytes_sent; nm_serial_device_get_type; - nm_settings_connection_interface_delete; - nm_settings_connection_interface_emit_updated; - nm_settings_connection_interface_get_secrets; - nm_settings_connection_interface_get_type; - nm_settings_connection_interface_update; nm_settings_error_quark; nm_settings_get_type; nm_settings_list_connections; diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 8b96b56cb..3f716f943 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -30,14 +30,10 @@ #include "nm-remote-connection-private.h" #include "nm-dbus-glib-types.h" #include "nm-sysconfig-connection-bindings.h" -#include "nm-settings-connection-interface.h" #define NM_REMOTE_CONNECTION_BUS "bus" -static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); - -G_DEFINE_TYPE_EXTENDED (NMRemoteConnection, nm_remote_connection, NM_TYPE_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, settings_connection_interface_init)) +G_DEFINE_TYPE (NMRemoteConnection, nm_remote_connection, NM_TYPE_CONNECTION) enum { PROP_0, @@ -47,6 +43,14 @@ enum { LAST_PROP }; +enum { + UPDATED, + REMOVED, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + typedef struct { NMRemoteConnection *self; @@ -88,22 +92,36 @@ static void update_cb (DBusGProxy *proxy, GError *error, gpointer user_data) { RemoteCall *call = user_data; - NMSettingsConnectionInterfaceUpdateFunc func = (NMSettingsConnectionInterfaceUpdateFunc) call->callback; + NMRemoteConnectionCommitFunc func = (NMRemoteConnectionCommitFunc) call->callback; - (*func)(NM_SETTINGS_CONNECTION_INTERFACE (call->self), error, call->user_data); + (*func)(call->self, error, call->user_data); remote_call_complete (call->self, call); } -static gboolean -update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) +/** + * nm_remote_connection_commit_changes: + * @connection: the #NMRemoteConnection + * @callback: a function to be called when the commit completes + * @user_data: caller-specific data to be passed to @callback + * + * Save any local changes to the settings and properties of this connection and + * save them in the settings service. + **/ +void +nm_remote_connection_commit_changes (NMRemoteConnection *self, + NMRemoteConnectionCommitFunc callback, + gpointer user_data) { - NMRemoteConnection *self = NM_REMOTE_CONNECTION (connection); - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + NMRemoteConnectionPrivate *priv; GHashTable *settings = NULL; RemoteCall *call; + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); + g_return_if_fail (callback != NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + call = g_malloc0 (sizeof (RemoteCall)); call->self = self; call->callback = (GFunc) callback; @@ -120,29 +138,40 @@ update (NMSettingsConnectionInterface *connection, priv->calls = g_slist_append (priv->calls, call); g_hash_table_destroy (settings); - - return TRUE; } static void delete_cb (DBusGProxy *proxy, GError *error, gpointer user_data) { RemoteCall *call = user_data; - NMSettingsConnectionInterfaceDeleteFunc func = (NMSettingsConnectionInterfaceDeleteFunc) call->callback; + NMRemoteConnectionDeleteFunc func = (NMRemoteConnectionDeleteFunc) call->callback; - (*func)(NM_SETTINGS_CONNECTION_INTERFACE (call->self), error, call->user_data); + (*func)(call->self, error, call->user_data); remote_call_complete (call->self, call); } -static gboolean -do_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, - gpointer user_data) +/** + * nm_remote_connection_delete: + * @connection: the #NMRemoteConnection + * @callback: a function to be called when the delete completes + * @user_data: caller-specific data to be passed to @callback + * + * Delete the connection. + **/ +void +nm_remote_connection_delete (NMRemoteConnection *self, + NMRemoteConnectionDeleteFunc callback, + gpointer user_data) { - NMRemoteConnection *self = NM_REMOTE_CONNECTION (connection); - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + NMRemoteConnectionPrivate *priv; RemoteCall *call; + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); + g_return_if_fail (callback != NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + call = g_malloc0 (sizeof (RemoteCall)); call->self = self; call->callback = (GFunc) callback; @@ -154,32 +183,47 @@ do_delete (NMSettingsConnectionInterface *connection, call); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); - - return TRUE; } static void get_secrets_cb (DBusGProxy *proxy, GHashTable *secrets, GError *error, gpointer user_data) { RemoteCall *call = user_data; - NMSettingsConnectionInterfaceGetSecretsFunc func = (NMSettingsConnectionInterfaceGetSecretsFunc) call->callback; + NMRemoteConnectionGetSecretsFunc func = (NMRemoteConnectionGetSecretsFunc) call->callback; - (*func)(NM_SETTINGS_CONNECTION_INTERFACE (call->self), error ? NULL : secrets, error, call->user_data); + (*func)(call->self, error ? NULL : secrets, error, call->user_data); remote_call_complete (call->self, call); } -static gboolean -get_secrets (NMSettingsConnectionInterface *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSettingsConnectionInterfaceGetSecretsFunc callback, - gpointer user_data) +/** + * nm_remote_connection_get_secrets: + * @connection: the #NMRemoteConnection + * @setting_name: the #NMSetting object name to get secrets for + * @hints: #NMSetting key names to get secrets for (optional) + * @request_new: hint that new secrets (instead of cached or stored secrets) + * should be returned + * @callback: a function to be called when the update completes + * @user_data: caller-specific data to be passed to @callback + * + * Request the connection's secrets. + **/ +void +nm_remote_connection_get_secrets (NMRemoteConnection *self, + const char *setting_name, + const char **hints, + gboolean request_new, + NMRemoteConnectionGetSecretsFunc callback, + gpointer user_data) { - NMRemoteConnection *self = NM_REMOTE_CONNECTION (connection); - NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + NMRemoteConnectionPrivate *priv; RemoteCall *call; + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_REMOTE_CONNECTION (self)); + g_return_if_fail (callback != NULL); + + priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + call = g_malloc0 (sizeof (RemoteCall)); call->self = self; call->callback = (GFunc) callback; @@ -194,8 +238,6 @@ get_secrets (NMSettingsConnectionInterface *connection, call); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); - - return TRUE; } /****************************************************************/ @@ -218,7 +260,7 @@ replace_settings (NMRemoteConnection *self, GHashTable *new_settings) /* Emit update irregardless to let listeners figure out what to do with * the connection; whether to delete / ignore it or not. */ - nm_settings_connection_interface_emit_updated (NM_SETTINGS_CONNECTION_INTERFACE (self)); + g_signal_emit (self, signals[UPDATED], 0, new_settings); return TRUE; } @@ -257,20 +299,11 @@ updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_data) static void removed_cb (DBusGProxy *proxy, gpointer user_data) { - g_signal_emit_by_name (G_OBJECT (user_data), "removed"); + g_signal_emit (G_OBJECT (user_data), signals[REMOVED], 0); } /****************************************************************/ -static void -settings_connection_interface_init (NMSettingsConnectionInterface *klass) -{ - /* interface implementation */ - klass->update = update; - klass->delete = do_delete; - klass->get_secrets = get_secrets; -} - /** * nm_remote_connection_new: * @bus: a valid and connected D-Bus connection @@ -425,5 +458,24 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) NM_REMOTE_CONNECTION_INIT_RESULT_ERROR, NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN, G_PARAM_READABLE)); -} + /* Signals */ + signals[UPDATED] = + g_signal_new (NM_REMOTE_CONNECTION_UPDATED, + G_TYPE_FROM_CLASS (remote_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteConnectionClass, updated), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + + signals[REMOVED] = + g_signal_new (NM_REMOTE_CONNECTION_REMOVED, + G_TYPE_FROM_CLASS (remote_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMRemoteConnectionClass, removed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + +} diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h index 732ade348..0c627a604 100644 --- a/libnm-glib/nm-remote-connection.h +++ b/libnm-glib/nm-remote-connection.h @@ -38,6 +38,9 @@ G_BEGIN_DECLS #define NM_IS_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_CONNECTION)) #define NM_REMOTE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) +#define NM_REMOTE_CONNECTION_UPDATED "updated" +#define NM_REMOTE_CONNECTION_REMOVED "removed" + typedef struct { NMConnection parent; } NMRemoteConnection; @@ -45,6 +48,12 @@ typedef struct { typedef struct { NMConnectionClass parent_class; + /* Signals */ + void (*updated) (NMRemoteConnection *connection, + GHashTable *new_settings); + + void (*removed) (NMRemoteConnection *connection); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -54,10 +63,38 @@ typedef struct { void (*_reserved6) (void); } NMRemoteConnectionClass; +typedef void (*NMRemoteConnectionCommitFunc) (NMRemoteConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMRemoteConnectionDeleteFunc) (NMRemoteConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMRemoteConnectionGetSecretsFunc) (NMRemoteConnection *connection, + GHashTable *secrets, + GError *error, + gpointer user_data); + GType nm_remote_connection_get_type (void); NMRemoteConnection *nm_remote_connection_new (DBusGConnection *bus, const char *path); + +void nm_remote_connection_commit_changes (NMRemoteConnection *connection, + NMRemoteConnectionCommitFunc callback, + gpointer user_data); + +void nm_remote_connection_delete (NMRemoteConnection *connection, + NMRemoteConnectionDeleteFunc callback, + gpointer user_data); + +void nm_remote_connection_get_secrets (NMRemoteConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + NMRemoteConnectionGetSecretsFunc callback, + gpointer user_data); G_END_DECLS #endif /* __NM_REMOTE_CONNECTION__ */ diff --git a/libnm-glib/nm-settings-connection-interface.c b/libnm-glib/nm-settings-connection-interface.c deleted file mode 100644 index 868ad047a..000000000 --- a/libnm-glib/nm-settings-connection-interface.c +++ /dev/null @@ -1,192 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2009 Red Hat, Inc. - */ - -#include "nm-settings-connection-interface.h" -#include "nm-dbus-glib-types.h" - -/** - * nm_settings_connection_interface_update: - * @connection: an object implementing #NMSettingsConnectionInterface - * @callback: a function to be called when the update completes - * @user_data: caller-specific data to be passed to @callback - * - * Update the connection with current settings and properties. - * - * Returns: TRUE on success, FALSE on failure - **/ -gboolean -nm_settings_connection_interface_update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->update) { - return NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->update (connection, - callback, - user_data); - } - return FALSE; -} - -/** - * nm_settings_connection_interface_delete: - * @connection: a objecting implementing #NMSettingsConnectionInterface - * @callback: a function to be called when the delete completes - * @user_data: caller-specific data to be passed to @callback - * - * Delete the connection. - * - * Returns: TRUE on success, FALSE on failure - **/ -gboolean -nm_settings_connection_interface_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->delete) { - return NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->delete (connection, - callback, - user_data); - } - return FALSE; -} - -/** - * nm_settings_connection_interface_get_secrets: - * @connection: a object implementing #NMSettingsConnectionInterface - * @setting_name: the #NMSetting object name to get secrets for - * @hints: #NMSetting key names to get secrets for (optional) - * @request_new: hint that new secrets (instead of cached or stored secrets) - * should be returned - * @callback: a function to be called when the update completes - * @user_data: caller-specific data to be passed to @callback - * - * Request the connection's secrets. - * - * Returns: TRUE on success, FALSE on failure - **/ -gboolean -nm_settings_connection_interface_get_secrets (NMSettingsConnectionInterface *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSettingsConnectionInterfaceGetSecretsFunc callback, - gpointer user_data) -{ - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->get_secrets) { - return NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->get_secrets (connection, - setting_name, - hints, - request_new, - callback, - user_data); - } - return FALSE; -} - -void -nm_settings_connection_interface_emit_updated (NMSettingsConnectionInterface *connection) -{ - if (NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->emit_updated) - NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE (connection)->emit_updated (connection); - else { - NMConnection *tmp; - GHashTable *settings; - - tmp = nm_connection_duplicate (NM_CONNECTION (connection)); - nm_connection_clear_secrets (tmp); - settings = nm_connection_to_hash (tmp); - g_object_unref (tmp); - - g_signal_emit_by_name (connection, NM_SETTINGS_CONNECTION_INTERFACE_UPDATED, settings); - g_hash_table_destroy (settings); - } -} - -static void -nm_settings_connection_interface_init (gpointer g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - - /* Signals */ - g_signal_new (NM_SETTINGS_CONNECTION_INTERFACE_UPDATED, - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsConnectionInterface, updated), - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); - - g_signal_new (NM_SETTINGS_CONNECTION_INTERFACE_REMOVED, - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsConnectionInterface, removed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - initialized = TRUE; -} - -GType -nm_settings_connection_interface_get_type (void) -{ - static GType itype = 0; - - if (!itype) { - const GTypeInfo iinfo = { - sizeof (NMSettingsConnectionInterface), /* class_size */ - nm_settings_connection_interface_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - itype = g_type_register_static (G_TYPE_INTERFACE, - "NMSettingsConnectionInterface", - &iinfo, 0); - - g_type_interface_add_prerequisite (itype, NM_TYPE_CONNECTION); - } - - return itype; -} - diff --git a/libnm-glib/nm-settings-connection-interface.h b/libnm-glib/nm-settings-connection-interface.h deleted file mode 100644 index 7c7a198c7..000000000 --- a/libnm-glib/nm-settings-connection-interface.h +++ /dev/null @@ -1,116 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* - * libnm_glib -- Access network status & information from glib applications - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2009 Red Hat, Inc. - */ - -#ifndef __NM_SETTINGS_CONNECTION_INTERFACE_H__ -#define __NM_SETTINGS_CONNECTION_INTERFACE_H__ - -#include -#include - -#include - -G_BEGIN_DECLS - -#define NM_TYPE_SETTINGS_CONNECTION_INTERFACE (nm_settings_connection_interface_get_type ()) -#define NM_SETTINGS_CONNECTION_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION_INTERFACE, NMSettingsConnectionInterface)) -#define NM_IS_SETTINGS_CONNECTION_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION_INTERFACE)) -#define NM_SETTINGS_CONNECTION_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_CONNECTION_INTERFACE, NMSettingsConnectionInterface)) - -#define NM_SETTINGS_CONNECTION_INTERFACE_UPDATED "updated" -#define NM_SETTINGS_CONNECTION_INTERFACE_REMOVED "removed" - -typedef struct _NMSettingsConnectionInterface NMSettingsConnectionInterface; - -typedef void (*NMSettingsConnectionInterfaceUpdateFunc) (NMSettingsConnectionInterface *connection, - GError *error, - gpointer user_data); - -typedef void (*NMSettingsConnectionInterfaceDeleteFunc) (NMSettingsConnectionInterface *connection, - GError *error, - gpointer user_data); - -typedef void (*NMSettingsConnectionInterfaceGetSecretsFunc) (NMSettingsConnectionInterface *connection, - GHashTable *secrets, - GError *error, - gpointer user_data); - -struct _NMSettingsConnectionInterface { - GTypeInterface g_iface; - - /* Methods */ - gboolean (*update) (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data); - - gboolean (*delete) (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, - gpointer user_data); - - gboolean (*get_secrets) (NMSettingsConnectionInterface *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSettingsConnectionInterfaceGetSecretsFunc callback, - gpointer user_data); - - void (*emit_updated) (NMSettingsConnectionInterface *connection); - - /* Signals */ - /* 'new_settings' hash should *not* contain secrets */ - void (*updated) (NMSettingsConnectionInterface *connection, - GHashTable *new_settings); - - void (*removed) (NMSettingsConnectionInterface *connection); - - /* Padding for future expansion */ - void (*_reserved1) (void); - void (*_reserved2) (void); - void (*_reserved3) (void); - void (*_reserved4) (void); - void (*_reserved5) (void); - void (*_reserved6) (void); -}; - -GType nm_settings_connection_interface_get_type (void); - -gboolean nm_settings_connection_interface_update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data); - -gboolean nm_settings_connection_interface_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, - gpointer user_data); - -gboolean nm_settings_connection_interface_get_secrets (NMSettingsConnectionInterface *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSettingsConnectionInterfaceGetSecretsFunc callback, - gpointer user_data); - -void nm_settings_connection_interface_emit_updated (NMSettingsConnectionInterface *connection); - -G_END_DECLS - -#endif /* __NM_SETTINGS_CONNECTION_INTERFACE_H__ */ - diff --git a/src/nm-manager.c b/src/nm-manager.c index 0f24a4ae3..fcef95dff 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -757,13 +757,13 @@ remove_connection (NMManager *manager, /*******************************************************************/ static void -system_connection_updated_cb (NMSettingsConnectionInterface *connection, +system_connection_updated_cb (NMSysconfigConnection *connection, gpointer unused, NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); const char *path; - NMSettingsConnectionInterface *existing; + NMSysconfigConnection *existing; GError *error = NULL; path = nm_connection_get_path (NM_CONNECTION (connection)); @@ -792,7 +792,7 @@ system_connection_updated_cb (NMSettingsConnectionInterface *connection, } static void -system_connection_removed_cb (NMSettingsConnectionInterface *connection, +system_connection_removed_cb (NMSysconfigConnection *connection, NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); @@ -807,16 +807,16 @@ system_connection_removed_cb (NMSettingsConnectionInterface *connection, static void system_internal_new_connection (NMManager *manager, - NMSettingsConnectionInterface *connection) + NMSysconfigConnection *connection) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); const char *path; g_return_if_fail (connection != NULL); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_INTERFACE_UPDATED, + g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED, G_CALLBACK (system_connection_updated_cb), manager); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_INTERFACE_REMOVED, + g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, G_CALLBACK (system_connection_removed_cb), manager); path = nm_connection_get_path (NM_CONNECTION (connection)); @@ -826,7 +826,7 @@ system_internal_new_connection (NMManager *manager, static void system_new_connection_cb (NMSysconfigSettings *settings, - NMSettingsConnectionInterface *connection, + NMSysconfigConnection *connection, NMManager *manager) { system_internal_new_connection (manager, connection); @@ -840,7 +840,7 @@ system_query_connections (NMManager *manager) system_connections = nm_sysconfig_settings_list_connections (priv->sys_settings); for (iter = system_connections; iter; iter = g_slist_next (iter)) - system_internal_new_connection (manager, NM_SETTINGS_CONNECTION_INTERFACE (iter->data)); + system_internal_new_connection (manager, NM_SYSCONFIG_CONNECTION (iter->data)); g_slist_free (system_connections); } @@ -1838,7 +1838,7 @@ provider_cancel_secrets (NMSecretsProviderInterface *provider, gpointer user_dat } static void -system_get_secrets_reply_cb (NMSettingsConnectionInterface *connection, +system_get_secrets_reply_cb (NMSysconfigConnection *connection, GHashTable *secrets, GError *error, gpointer user_data) @@ -1886,12 +1886,12 @@ system_get_secrets_idle_cb (gpointer user_data) hints[0] = info->hint1; hints[1] = info->hint2; - nm_settings_connection_interface_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (connection), - info->setting_name, - hints, - info->request_new, - system_get_secrets_reply_cb, - info); + nm_sysconfig_connection_get_secrets (connection, + info->setting_name, + hints, + info->request_new, + system_get_secrets_reply_cb, + info); return FALSE; } diff --git a/src/system-settings/nm-default-wired-connection.c b/src/system-settings/nm-default-wired-connection.c index 54e00d627..365589259 100644 --- a/src/system-settings/nm-default-wired-connection.c +++ b/src/system-settings/nm-default-wired-connection.c @@ -31,15 +31,8 @@ #include "nm-dbus-glib-types.h" #include "nm-marshal.h" #include "nm-default-wired-connection.h" -#include "nm-settings-connection-interface.h" -static NMSettingsConnectionInterface *parent_settings_connection_iface; - -static void settings_connection_interface_init (NMSettingsConnectionInterface *iface); - -G_DEFINE_TYPE_EXTENDED (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) +G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION) #define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate)) @@ -91,10 +84,10 @@ nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired) return NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (wired)->device; } -static gboolean -update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) +static void +commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data) { NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection); @@ -105,31 +98,24 @@ update (NMSettingsConnectionInterface *connection, g_signal_emit (self, signals[TRY_UPDATE], 0); callback (connection, NULL, user_data); g_object_unref (connection); - return TRUE; } -static gboolean -do_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, +static void +do_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, gpointer user_data) { NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection); NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (connection); g_signal_emit (self, signals[DELETED], 0, priv->mac); - return parent_settings_connection_iface->delete (connection, callback, user_data); + NM_SYSCONFIG_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->delete (connection, + callback, + user_data); } /****************************************************************/ -static void -settings_connection_interface_init (NMSettingsConnectionInterface *iface) -{ - parent_settings_connection_iface = g_type_interface_peek_parent (iface); - iface->update = update; - iface->delete = do_delete; -} - static void nm_default_wired_connection_init (NMDefaultWiredConnection *self) { @@ -250,6 +236,7 @@ static void nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (klass); g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate)); @@ -258,6 +245,8 @@ nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; + sysconfig_class->commit_changes = commit_changes; + sysconfig_class->delete = do_delete; /* Properties */ g_object_class_install_property diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 8d0c061e8..7de46866a 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -26,7 +26,6 @@ #include "nm-sysconfig-connection.h" #include "nm-system-config-error.h" #include "nm-dbus-glib-types.h" -#include "nm-settings-connection-interface.h" #include "nm-polkit-helpers.h" #include "nm-logging.h" @@ -49,16 +48,20 @@ static void impl_sysconfig_connection_get_secrets (NMSysconfigConnection *connec #include "nm-sysconfig-connection-glue.h" -static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); - -G_DEFINE_TYPE_EXTENDED (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) +G_DEFINE_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_CONNECTION) #define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_SYSCONFIG_CONNECTION, \ NMSysconfigConnectionPrivate)) +enum { + UPDATED, + REMOVED, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + typedef struct { PolkitAuthority *authority; GSList *pk_calls; @@ -102,7 +105,7 @@ nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, } static void -ignore_cb (NMSettingsConnectionInterface *connection, +ignore_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { @@ -116,7 +119,7 @@ ignore_cb (NMSettingsConnectionInterface *connection, void nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, NMConnection *new, - NMSettingsConnectionInterfaceUpdateFunc callback, + NMSysconfigConnectionCommitFunc callback, gpointer user_data) { GError *error = NULL; @@ -133,43 +136,127 @@ nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, if (nm_connection_compare (NM_CONNECTION (self), NM_CONNECTION (new), NM_SETTING_COMPARE_FLAG_EXACT)) { - callback (NM_SETTINGS_CONNECTION_INTERFACE (self), NULL, user_data); + callback (self, NULL, user_data); return; } if (nm_sysconfig_connection_replace_settings (self, new, &error)) { - nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self), - callback, user_data); + nm_sysconfig_connection_commit_changes (self, callback, user_data); } else { - callback (NM_SETTINGS_CONNECTION_INTERFACE (self), error, user_data); + callback (self, error, user_data); g_clear_error (&error); } } +void +nm_sysconfig_connection_commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data) +{ + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + if (NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->commit_changes) { + NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->commit_changes (connection, + callback, + user_data); + } else { + GError *error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + "%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__); + callback (connection, error, user_data); + g_error_free (error); + } +} + +void +nm_sysconfig_connection_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, + gpointer user_data) +{ + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + if (NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->delete) { + NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->delete (connection, + callback, + user_data); + } else { + GError *error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); + callback (connection, error, user_data); + g_error_free (error); + } +} + +void +nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + NMSysconfigConnectionGetSecretsFunc callback, + gpointer user_data) +{ + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (callback != NULL); + + if (NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->get_secrets) { + NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->get_secrets (connection, + setting_name, + hints, + request_new, + callback, + user_data); + } else { + GError *error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); + callback (connection, NULL, error, user_data); + g_error_free (error); + } +} + /**************************************************************/ -static gboolean -update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) +static void +emit_updated (NMSysconfigConnection *connection) { - g_object_ref (connection); - nm_settings_connection_interface_emit_updated (connection); - callback (connection, NULL, user_data); - g_object_unref (connection); - return TRUE; + NMConnection *tmp; + GHashTable *settings; + + tmp = nm_connection_duplicate (NM_CONNECTION (connection)); + nm_connection_clear_secrets (tmp); + settings = nm_connection_to_hash (tmp); + g_object_unref (tmp); + + g_signal_emit (connection, signals[UPDATED], 0, settings); + g_hash_table_destroy (settings); } -static gboolean -do_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, +static void +commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data) +{ + g_object_ref (connection); + emit_updated (connection); + callback (connection, NULL, user_data); + g_object_unref (connection); +} + +static void +do_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, gpointer user_data) { g_object_ref (connection); - g_signal_emit_by_name (connection, "removed"); + g_signal_emit (connection, signals[REMOVED], 0); callback (connection, NULL, user_data); g_object_unref (connection); - return TRUE; } static GValue * @@ -246,16 +333,15 @@ destroy_gvalue (gpointer data) g_slice_free (GValue, value); } -static gboolean -get_secrets (NMSettingsConnectionInterface *connection, +static void +get_secrets (NMSysconfigConnection *connection, const char *setting_name, const char **hints, gboolean request_new, - NMSettingsConnectionInterfaceGetSecretsFunc callback, + NMSysconfigConnectionGetSecretsFunc callback, gpointer user_data) { - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (connection); - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); GHashTable *settings = NULL; GHashTable *secrets = NULL; NMSetting *setting; @@ -273,7 +359,7 @@ get_secrets (NMSettingsConnectionInterface *connection, __FILE__, __LINE__); (*callback) (connection, NULL, error, user_data); g_error_free (error); - return TRUE; + return; } setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); @@ -284,7 +370,7 @@ get_secrets (NMSettingsConnectionInterface *connection, __FILE__, __LINE__, setting_name); (*callback) (connection, NULL, error, user_data); g_error_free (error); - return TRUE; + return; } /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that @@ -300,7 +386,6 @@ get_secrets (NMSettingsConnectionInterface *connection, g_hash_table_insert (settings, g_strdup (setting_name), secrets); callback (connection, settings, NULL, user_data); g_hash_table_destroy (settings); - return TRUE; } /**************************************************************/ @@ -420,7 +505,7 @@ polkit_call_free (PolkitCall *call) } static void -con_update_cb (NMSettingsConnectionInterface *connection, +con_update_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { @@ -533,7 +618,7 @@ impl_sysconfig_connection_update (NMSysconfigConnection *self, } static void -con_delete_cb (NMSettingsConnectionInterface *connection, +con_delete_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { @@ -594,9 +679,7 @@ pk_delete_cb (GObject *object, GAsyncResult *result, gpointer user_data) } /* Caller is authenticated, now we can finally try to delete */ - nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (self), - con_delete_cb, - call); + nm_sysconfig_connection_delete (self, con_delete_cb, call); out: g_object_unref (pk_result); @@ -630,7 +713,7 @@ impl_sysconfig_connection_delete (NMSysconfigConnection *self, } static void -con_secrets_cb (NMSettingsConnectionInterface *connection, +con_secrets_cb (NMSysconfigConnection *connection, GHashTable *secrets, GError *error, gpointer user_data) @@ -692,12 +775,12 @@ pk_secrets_cb (GObject *object, GAsyncResult *result, gpointer user_data) } /* Caller is authenticated, now we can finally try to update */ - nm_settings_connection_interface_get_secrets (NM_SETTINGS_CONNECTION_INTERFACE (self), - call->setting_name, - (const char **) call->hints, - call->request_new, - con_secrets_cb, - call); + nm_sysconfig_connection_get_secrets (self, + call->setting_name, + (const char **) call->hints, + call->request_new, + con_secrets_cb, + call); out: g_object_unref (pk_result); @@ -728,14 +811,6 @@ impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, /**************************************************************/ -static void -settings_connection_interface_init (NMSettingsConnectionInterface *iface) -{ - iface->update = update; - iface->delete = do_delete; - iface->get_secrets = get_secrets; -} - static void nm_sysconfig_connection_init (NMSysconfigConnection *self) { @@ -779,6 +854,28 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) /* Virtual methods */ object_class->dispose = dispose; + class->commit_changes = commit_changes; + class->delete = do_delete; + class->get_secrets = get_secrets; + + /* Signals */ + signals[UPDATED] = + g_signal_new (NM_SYSCONFIG_CONNECTION_UPDATED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + + signals[REMOVED] = + g_signal_new (NM_SYSCONFIG_CONNECTION_REMOVED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_sysconfig_connection_object_info); diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index 253c28750..f2510d288 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -22,7 +22,6 @@ #define NM_SYSCONFIG_CONNECTION_H #include -#include #include G_BEGIN_DECLS @@ -34,25 +33,74 @@ G_BEGIN_DECLS #define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) #define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) -typedef struct { - NMConnection parent; -} NMSysconfigConnection; +#define NM_SYSCONFIG_CONNECTION_UPDATED "updated" +#define NM_SYSCONFIG_CONNECTION_REMOVED "removed" -typedef struct { +typedef struct _NMSysconfigConnection NMSysconfigConnection; + +typedef struct _NMSysconfigConnectionClass NMSysconfigConnectionClass; + +typedef void (*NMSysconfigConnectionCommitFunc) (NMSysconfigConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMSysconfigConnectionDeleteFunc) (NMSysconfigConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMSysconfigConnectionGetSecretsFunc) (NMSysconfigConnection *connection, + GHashTable *secrets, + GError *error, + gpointer user_data); + +struct _NMSysconfigConnection { + NMConnection parent; +}; + +struct _NMSysconfigConnectionClass { NMConnectionClass parent; -} NMSysconfigConnectionClass; + + void (*commit_changes) (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data); + + void (*delete) (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, + gpointer user_data); + + void (*get_secrets) (NMSysconfigConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + NMSysconfigConnectionGetSecretsFunc callback, + gpointer user_data); +}; GType nm_sysconfig_connection_get_type (void); +void nm_sysconfig_connection_commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data); + gboolean nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, NMConnection *new_settings, GError **error); void nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, NMConnection *new_settings, - NMSettingsConnectionInterfaceUpdateFunc callback, + NMSysconfigConnectionCommitFunc callback, gpointer user_data); +void nm_sysconfig_connection_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, + gpointer user_data); + +void nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + NMSysconfigConnectionGetSecretsFunc callback, + gpointer user_data); G_END_DECLS diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index c6294cbf8..bc89b777c 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -76,7 +76,7 @@ EXPORT(nm_sysconfig_connection_replace_and_commit) /* END LINKER CRACKROCK */ static void claim_connection (NMSysconfigSettings *self, - NMSettingsConnectionInterface *connection, + NMSysconfigConnection *connection, gboolean do_export); static gboolean impl_settings_list_connections (NMSysconfigSettings *self, @@ -160,7 +160,7 @@ load_connections (NMSysconfigSettings *self) // priority plugin. for (elt = plugin_connections; elt; elt = g_slist_next (elt)) - claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (elt->data), TRUE); + claim_connection (self, NM_SYSCONFIG_CONNECTION (elt->data), TRUE); g_slist_free (plugin_connections); } @@ -342,7 +342,7 @@ nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self) static void plugin_connection_added (NMSystemConfigInterface *config, - NMSettingsConnectionInterface *connection, + NMSysconfigConnection *connection, gpointer user_data) { claim_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE); @@ -531,7 +531,7 @@ load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) } static void -connection_removed (NMSettingsConnectionInterface *connection, +connection_removed (NMSysconfigConnection *connection, gpointer user_data) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); @@ -541,14 +541,14 @@ connection_removed (NMSettingsConnectionInterface *connection, static void export_connection (NMSysconfigSettings *self, - NMSettingsConnectionInterface *connection) + NMSysconfigConnection *connection) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); static guint32 ec_counter = 0; char *path; g_return_if_fail (connection != NULL); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection)); + g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); g_return_if_fail (priv->bus != NULL); /* Don't allow exporting twice */ @@ -563,13 +563,13 @@ export_connection (NMSysconfigSettings *self, static void claim_connection (NMSysconfigSettings *self, - NMSettingsConnectionInterface *connection, + NMSysconfigConnection *connection, gboolean do_export) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection)); + g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); if (g_hash_table_lookup (priv->connections, connection)) /* A plugin is lying to us. */ @@ -577,7 +577,7 @@ claim_connection (NMSysconfigSettings *self, g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); g_signal_connect (connection, - NM_SETTINGS_CONNECTION_INTERFACE_REMOVED, + NM_SYSCONFIG_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); @@ -589,16 +589,13 @@ claim_connection (NMSysconfigSettings *self, static void remove_connection (NMSysconfigSettings *self, - NMSettingsConnectionInterface *connection, + NMSysconfigConnection *connection, gboolean do_signal) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection)); - if (g_hash_table_lookup (priv->connections, connection)) { - g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_CONNECTION_INTERFACE_REMOVED); + g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_REMOVED); g_hash_table_remove (priv->connections, connection); } } @@ -1234,7 +1231,7 @@ cleanup: } static void -delete_cb (NMSettingsConnectionInterface *connection, GError *error, gpointer user_data) +delete_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { } @@ -1256,11 +1253,11 @@ default_wired_try_update (NMDefaultWiredConnection *wired, id = nm_setting_connection_get_id (s_con); g_assert (id); - remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), FALSE); + remove_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); if (add_new_connection (self, NM_CONNECTION (wired), &error)) { - nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (wired), - delete_cb, - NULL); + nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (wired), + delete_cb, + NULL); g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), DEFAULT_WIRED_TAG, @@ -1278,7 +1275,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, * but add it back to the system settings service. Connection is already * exported on the bus, don't export it again, thus do_export == FALSE. */ - claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), FALSE); + claim_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); return TRUE; } @@ -1329,7 +1326,7 @@ nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device) g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self); g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self); - claim_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (wired), TRUE); + claim_connection (self, NM_SYSCONFIG_CONNECTION (wired), TRUE); g_object_unref (wired); g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired); @@ -1348,7 +1345,7 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG); if (connection) - remove_connection (self, NM_SETTINGS_CONNECTION_INTERFACE (connection), TRUE); + remove_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); } static void diff --git a/src/system-settings/nm-system-config-interface.c b/src/system-settings/nm-system-config-interface.c index 90fd93ba3..f522a9b44 100644 --- a/src/system-settings/nm-system-config-interface.c +++ b/src/system-settings/nm-system-config-interface.c @@ -73,7 +73,7 @@ interface_init (gpointer g_iface) NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - NM_TYPE_SETTINGS_CONNECTION_INTERFACE); + NM_TYPE_SYSCONFIG_CONNECTION); g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED, iface_type, diff --git a/src/system-settings/nm-system-config-interface.h b/src/system-settings/nm-system-config-interface.h index 3daceb89b..439586a40 100644 --- a/src/system-settings/nm-system-config-interface.h +++ b/src/system-settings/nm-system-config-interface.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include G_BEGIN_DECLS @@ -90,9 +90,9 @@ struct _NMSystemConfigInterface { /* Called when the plugin is loaded to initialize it */ void (*init) (NMSystemConfigInterface *config); - /* Returns a GSList of objects that implement NMSettingsConnectionInterface - * that represent connections the plugin knows about. The returned list - * is freed by the system settings service. + /* Returns a GSList of NMSysconfigConnection objects that represent + * connections the plugin knows about. The returned list is freed by the + * system settings service. */ GSList * (*get_connections) (NMSystemConfigInterface *config); @@ -127,7 +127,7 @@ struct _NMSystemConfigInterface { /* Emitted when a new connection has been found by the plugin */ void (*connection_added) (NMSystemConfigInterface *config, - NMSettingsConnectionInterface *connection); + NMSysconfigConnection *connection); /* Emitted when the list of unmanaged device specifications changes */ void (*unmanaged_specs_changed) (NMSystemConfigInterface *config); diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 64f29ecaa..e8df1b376 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "common.h" #include "nm-ifcfg-connection.h" @@ -41,13 +40,7 @@ #include "writer.h" #include "nm-inotify-helper.h" -static NMSettingsConnectionInterface *parent_settings_connection_iface; - -static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); - -G_DEFINE_TYPE_EXTENDED (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) +G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECTION) #define NM_IFCFG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionPrivate)) @@ -171,10 +164,10 @@ nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self) return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged; } -static gboolean -update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) +static void +commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); GError *error = NULL; @@ -205,18 +198,18 @@ update (NMSettingsConnectionInterface *connection, &error)) { callback (connection, error, user_data); g_error_free (error); - return FALSE; + return; } out: if (reread) g_object_unref (reread); - return parent_settings_connection_iface->update (connection, callback, user_data); + NM_SYSCONFIG_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data); } -static gboolean -do_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, +static void +do_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, gpointer user_data) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); @@ -230,19 +223,11 @@ do_delete (NMSettingsConnectionInterface *connection, if (priv->route6file) g_unlink (priv->route6file); - return parent_settings_connection_iface->delete (connection, callback, user_data); + NM_SYSCONFIG_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data); } /* GObject */ -static void -settings_connection_interface_init (NMSettingsConnectionInterface *iface) -{ - parent_settings_connection_iface = g_type_interface_peek_parent (iface); - iface->update = update; - iface->delete = do_delete; -} - static void nm_ifcfg_connection_init (NMIfcfgConnection *connection) { @@ -331,6 +316,7 @@ static void nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class); + NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (ifcfg_connection_class); g_type_class_add_private (ifcfg_connection_class, sizeof (NMIfcfgConnectionPrivate)); @@ -338,6 +324,8 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; + sysconfig_class->delete = do_delete; + sysconfig_class->commit_changes = commit_changes; /* Properties */ g_object_class_install_property diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index f6db49572..c328a3336 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -204,7 +204,7 @@ read_connections (SCPluginIfcfg *plugin) /* Callback for nm_sysconfig_connection_replace_and_commit. Report any errors * encountered when commiting connection settings updates. */ static void -commit_cb (NMSettingsConnectionInterface *connection, GError *error, gpointer unused) +commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused) { if (error) { PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s", diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c index 5eb83ad4b..3c584cc3f 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -32,13 +32,7 @@ #include "nm-ifupdown-connection.h" #include "parser.h" -static NMSettingsConnectionInterface *parent_settings_connection_iface; - -static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); - -G_DEFINE_TYPE_EXTENDED (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) +G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SYSCONFIG_CONNECTION) #define NM_IFUPDOWN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionPrivate)) @@ -63,12 +57,12 @@ nm_ifupdown_connection_new (if_block *block) NULL); } -static gboolean -get_secrets (NMSettingsConnectionInterface *connection, +static void +get_secrets (NMSysconfigConnection *connection, const gchar *setting_name, const gchar **hints, gboolean request_new, - NMSettingsConnectionInterfaceGetSecretsFunc callback, + NMSysconfigConnectionGetSecretsFunc callback, gpointer user_data) { GError *error = NULL; @@ -85,22 +79,15 @@ get_secrets (NMSettingsConnectionInterface *connection, PLUGIN_PRINT ("SCPlugin-Ifupdown", "%s", error->message); callback (connection, NULL, error, user_data); g_error_free (error); - return FALSE; + return; } - return parent_settings_connection_iface->get_secrets (connection, - setting_name, - hints, - request_new, - callback, - user_data); -} - -static void -settings_connection_interface_init (NMSettingsConnectionInterface *iface) -{ - parent_settings_connection_iface = g_type_interface_peek_parent (iface); - iface->get_secrets = get_secrets; + NM_SYSCONFIG_CONNECTION_CLASS (nm_ifupdown_connection_parent_class)->get_secrets (connection, + setting_name, + hints, + request_new, + callback, + user_data); } static void @@ -184,6 +171,7 @@ static void nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifupdown_connection_class); + NMSysconfigConnectionClass *connection_class = NM_SYSCONFIG_CONNECTION_CLASS (ifupdown_connection_class); g_type_class_add_private (ifupdown_connection_class, sizeof (NMIfupdownConnectionPrivate)); @@ -192,6 +180,8 @@ nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connectio object_class->set_property = set_property; object_class->get_property = get_property; + connection_class->get_secrets = get_secrets; + /* Properties */ g_object_class_install_property (object_class, PROP_IFBLOCK, diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c index 4a07022c4..34f724cca 100644 --- a/system-settings/plugins/ifupdown/plugin.c +++ b/system-settings/plugins/ifupdown/plugin.c @@ -177,7 +177,7 @@ sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class) } static void -ignore_cb (NMSettingsConnectionInterface *connection, +ignore_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { @@ -227,9 +227,9 @@ bind_device_to_connection (SCPluginIfupdown *self, } g_byte_array_free (mac_address, TRUE); - nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (exported), - ignore_cb, - NULL); + nm_sysconfig_connection_commit_changes (NM_SYSCONFIG_CONNECTION (exported), + ignore_cb, + NULL); } static void @@ -366,9 +366,9 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) /* Remove any connection for this block that was previously found */ exported = g_hash_table_lookup (priv->iface_connections, block->name); if (exported) { - nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (exported), - ignore_cb, - NULL); + nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (exported), + ignore_cb, + NULL); g_hash_table_remove (priv->iface_connections, block->name); } @@ -397,9 +397,9 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); - nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (exported), - ignore_cb, - NULL); + nm_sysconfig_connection_commit_changes (NM_SYSCONFIG_CONNECTION (exported), + ignore_cb, + NULL); PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); } diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index b5e5b5c14..9594d64f8 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -24,20 +24,13 @@ #include #include #include -#include #include "nm-dbus-glib-types.h" #include "nm-keyfile-connection.h" #include "reader.h" #include "writer.h" -static NMSettingsConnectionInterface *parent_settings_connection_iface; - -static void settings_connection_interface_init (NMSettingsConnectionInterface *klass); - -G_DEFINE_TYPE_EXTENDED (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CONNECTION, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) +G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CONNECTION) #define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate)) @@ -70,10 +63,10 @@ nm_keyfile_connection_get_filename (NMKeyfileConnection *self) return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->filename; } -static gboolean -update (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceUpdateFunc callback, - gpointer user_data) +static void +commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data) { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); char *filename = NULL; @@ -82,7 +75,7 @@ update (NMSettingsConnectionInterface *connection, if (!write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &filename, &error)) { callback (connection, error, user_data); g_clear_error (&error); - return FALSE; + return; } if (g_strcmp0 (priv->filename, filename)) { @@ -92,31 +85,27 @@ update (NMSettingsConnectionInterface *connection, } else g_free (filename); - return parent_settings_connection_iface->update (connection, callback, user_data); + NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, + callback, + user_data); } -static gboolean -do_delete (NMSettingsConnectionInterface *connection, - NMSettingsConnectionInterfaceDeleteFunc callback, - gpointer user_data) +static void +do_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, + gpointer user_data) { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); g_unlink (priv->filename); - return parent_settings_connection_iface->delete (connection, callback, user_data); + NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, + callback, + user_data); } /* GObject */ -static void -settings_connection_interface_init (NMSettingsConnectionInterface *iface) -{ - parent_settings_connection_iface = g_type_interface_peek_parent (iface); - iface->update = update; - iface->delete = do_delete; -} - static void nm_keyfile_connection_init (NMKeyfileConnection *connection) { @@ -221,6 +210,7 @@ static void nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class); + NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (keyfile_connection_class); g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); @@ -229,6 +219,8 @@ nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_c object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; + sysconfig_class->commit_changes = commit_changes; + sysconfig_class->delete = do_delete; /* Properties */ g_object_class_install_property diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 5b82b5b6f..19cadc48d 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -125,7 +125,7 @@ find_by_uuid (gpointer key, gpointer data, gpointer user_data) } static void -update_connection_settings_commit_cb (NMSettingsConnectionInterface *orig, GError *error, gpointer user_data) { +update_connection_settings_commit_cb (NMSysconfigConnection *orig, GError *error, gpointer user_data) { if (error) { g_warning ("%s: '%s' / '%s' invalid: %d", __func__, From f8a92d44cbec14c855f5c2b813b0940851889833 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Fri, 6 Aug 2010 15:47:36 -0400 Subject: [PATCH 018/264] nm-sysconfig-settings: remove "bus" property NMSysconfigSettings inherited the "bus" property from NMSettingsService. The property was originally created to allow us to specify what DBus connection to use, which was important in the days of user settings services. Now, however, the daemon is the only thing that has a settings service, and so we can trim a bit of clutter by removing this property and using NMDBusManager directly. --- src/nm-manager.c | 6 +- src/system-settings/nm-sysconfig-settings.c | 62 +++------------------ src/system-settings/nm-sysconfig-settings.h | 2 - 3 files changed, 10 insertions(+), 60 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index fcef95dff..5a4d3cd25 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2983,7 +2983,6 @@ nm_manager_get (const char *config_file, { static NMManager *singleton = NULL; NMManagerPrivate *priv; - DBusGConnection *bus; if (singleton) return g_object_ref (singleton); @@ -2993,10 +2992,7 @@ nm_manager_get (const char *config_file, priv = NM_MANAGER_GET_PRIVATE (singleton); - bus = nm_dbus_manager_get_connection (priv->dbus_mgr); - g_assert (bus); - - priv->sys_settings = nm_sysconfig_settings_new (config_file, plugins, bus, error); + priv->sys_settings = nm_sysconfig_settings_new (config_file, plugins, error); if (!priv->sys_settings) { g_object_unref (singleton); return NULL; diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index bc89b777c..7e1e3f530 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -58,6 +58,7 @@ #include "nm-system-config-error.h" #include "nm-default-wired-connection.h" #include "nm-logging.h" +#include "nm-dbus-manager.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -131,7 +132,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, - PROP_BUS, PROP_UNMANAGED_SPECS, PROP_HOSTNAME, PROP_CAN_MODIFY, @@ -540,16 +540,14 @@ connection_removed (NMSysconfigConnection *connection, } static void -export_connection (NMSysconfigSettings *self, - NMSysconfigConnection *connection) +export_connection (NMSysconfigConnection *connection) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + DBusGConnection *bus; static guint32 ec_counter = 0; char *path; g_return_if_fail (connection != NULL); g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); - g_return_if_fail (priv->bus != NULL); /* Don't allow exporting twice */ g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); @@ -557,7 +555,8 @@ export_connection (NMSysconfigSettings *self, path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); nm_connection_set_path (NM_CONNECTION (connection), path); - dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); + bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); + dbus_g_connection_register_g_object (bus, path, G_OBJECT (connection)); g_free (path); } @@ -582,7 +581,7 @@ claim_connection (NMSysconfigSettings *self, self); if (do_export) { - export_connection (self, connection); + export_connection (connection); g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } } @@ -1352,18 +1351,18 @@ static void export_sysconfig (NMSysconfigSettings *self) { NMSysconfigSettingsPrivate *priv; + DBusGConnection *bus; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - g_return_if_fail (priv->bus != NULL); - /* Don't allow exporting twice */ g_return_if_fail (priv->exported == FALSE); - dbus_g_connection_register_g_object (priv->bus, + bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); + dbus_g_connection_register_g_object (bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); priv->exported = TRUE; @@ -1372,14 +1371,12 @@ export_sysconfig (NMSysconfigSettings *self) NMSysconfigSettings * nm_sysconfig_settings_new (const char *config_file, const char *plugins, - DBusGConnection *bus, GError **error) { NMSysconfigSettings *self; NMSysconfigSettingsPrivate *priv; self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, - NM_SYSCONFIG_SETTINGS_BUS, bus, NULL); if (!self) return NULL; @@ -1436,9 +1433,6 @@ dispose (GObject *object) g_slist_free (priv->permissions_calls); priv->permissions_calls = NULL; - if (priv->bus) - dbus_g_connection_unref (priv->bus); - G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); } @@ -1460,39 +1454,15 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); } -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (object); - DBusGConnection *bus; - - switch (prop_id) { - case PROP_BUS: - /* Construct only */ - bus = g_value_get_boxed (value); - if (bus) - priv->bus = dbus_g_connection_ref (bus); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); const GSList *specs, *iter; GSList *copy = NULL; switch (prop_id) { - case PROP_BUS: - g_value_set_boxed (value, priv->bus); - break; case PROP_UNMANAGED_SPECS: specs = nm_sysconfig_settings_get_unmanaged_specs (self); for (iter = specs; iter; iter = g_slist_next (iter)) @@ -1524,26 +1494,12 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) /* virtual methods */ object_class->notify = notify; - object_class->set_property = set_property; object_class->get_property = get_property; object_class->dispose = dispose; object_class->finalize = finalize; /* properties */ - /** - * NMSysconfigSettings:bus: - * - * The %DBusGConnection which this object is exported on - **/ - g_object_class_install_property - (object_class, PROP_BUS, - g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_BUS, - "Bus", - "Bus", - DBUS_TYPE_G_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_UNMANAGED_SPECS, g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index 6146ab6dc..7a7f7db50 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -48,7 +48,6 @@ typedef enum { #define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) #define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) -#define NM_SYSCONFIG_SETTINGS_BUS "bus" #define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" #define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" #define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" @@ -71,7 +70,6 @@ GType nm_sysconfig_settings_get_type (void); NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file, const char *plugins, - DBusGConnection *bus, GError **error); /* Returns a list of NMSysconfigConnections */ From 8b1cac703cfd1e21d3e85cc9cd9ab0837ffd3d67 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Fri, 6 Aug 2010 21:02:50 -0400 Subject: [PATCH 019/264] examples: update for user settings removal Some of the example code broke when we removed user settings services. Oops! --- examples/python/list-connections.py | 9 +++------ examples/python/nm-state.py | 5 +---- examples/python/vpn.py | 10 +++++----- 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/examples/python/list-connections.py b/examples/python/list-connections.py index ad8d9047c..de2ca1872 100644 --- a/examples/python/list-connections.py +++ b/examples/python/list-connections.py @@ -70,14 +70,13 @@ def connection_to_string(config): print "" -def print_one_services_connections(service_name, desc): +def print_connections(): # Ask the settings service for the list of connections it provides + service_name = "org.freedesktop.NetworkManager" proxy = bus.get_object(service_name, "/org/freedesktop/NetworkManagerSettings") settings = dbus.Interface(proxy, "org.freedesktop.NetworkManagerSettings") connection_paths = settings.ListConnections() - print "%s connections --------------------------------------------\n" % desc - # List each connection's name, UUID, and type for path in connection_paths: con_proxy = bus.get_object(service_name, path) @@ -106,7 +105,5 @@ def print_one_services_connections(service_name, desc): print "" -# Print out connection information for all connections -print_one_services_connections("org.freedesktop.NetworkManagerSystemSettings", "System") -print_one_services_connections("org.freedesktop.NetworkManagerUserSettings", "User") +print_connections() diff --git a/examples/python/nm-state.py b/examples/python/nm-state.py index fddd2da62..1ee475281 100644 --- a/examples/python/nm-state.py +++ b/examples/python/nm-state.py @@ -53,10 +53,7 @@ for a in active: # needed to connect to a specific network. Lets get those details so we # can find the user-readable name of the connection. con_path = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "Connection") - con_service = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "ServiceName") - - # ask the provider of the connection for its details - service_proxy = bus.get_object(con_service, con_path) + service_proxy = bus.get_object("org.freedesktop.NetworkManagerSystemSettings", con_path) con_iface = dbus.Interface(service_proxy, "org.freedesktop.NetworkManagerSettings.Connection") con_details = con_iface.GetSettings() con_name = con_details['connection']['id'] diff --git a/examples/python/vpn.py b/examples/python/vpn.py index 4b4057fc2..7e53f4bd9 100644 --- a/examples/python/vpn.py +++ b/examples/python/vpn.py @@ -37,7 +37,7 @@ DBusGMainLoop(set_as_default=True) def get_connections(): bus = dbus.SystemBus() - proxy = bus.get_object('org.freedesktop.NetworkManagerUserSettings', '/org/freedesktop/NetworkManagerSettings') + proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', '/org/freedesktop/NetworkManagerSettings') iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings') return iface.ListConnections() @@ -45,7 +45,7 @@ def get_connections(): def get_connection_by_uuid(uuid): bus = dbus.SystemBus() for c in get_connections(): - proxy = bus.get_object('org.freedesktop.NetworkManagerUserSettings', c) + proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', c) iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') settings = iface.GetSettings() if settings['connection']['uuid'] == uuid: @@ -57,7 +57,7 @@ def get_connection_by_uuid(uuid): def list_uuids(): bus = dbus.SystemBus() for c in get_connections(): - proxy = bus.get_object('org.freedesktop.NetworkManagerUserSettings', c) + proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', c) iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') settings = iface.GetSettings() conn = settings['connection'] @@ -76,7 +76,7 @@ def get_active_connection_path(uuid): iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties') path = iface.Get('org.freedesktop.NetworkManager.Connection.Active', 'Connection') - proxy = bus.get_object('org.freedesktop.NetworkManagerUserSettings', path) + proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', path) iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') settings = iface.GetSettings() @@ -112,7 +112,7 @@ def activate_connection(connection_path, device_path): bus = dbus.SystemBus() proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManager') - iface.ActivateConnection('org.freedesktop.NetworkManagerUserSettings', + iface.ActivateConnection('org.freedesktop.NetworkManagerSystemSettings', connection_path, device_path, "/", From fb96309899a5ca853e206f52905df540719c7c5b Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Fri, 6 Aug 2010 21:21:24 -0400 Subject: [PATCH 020/264] DBus: merge NetworkManger{,SystemSettings} Remove the org.freedesktop.NetworkManagerSystemSettings bus name and have everybody talk to org.freedesktop.NetworkManager. Now that we have a single settings service that's embedded in the main daemon, we don't need separate names anymore. --- callouts/nm-dispatcher-action.h | 1 - examples/python/add-system-connection.py | 2 +- examples/python/nm-state.py | 2 +- examples/python/vpn.py | 10 +++++----- include/NetworkManager.h | 1 - libnm-glib/nm-remote-connection.c | 4 ++-- libnm-glib/nm-remote-settings.c | 8 ++++---- src/NetworkManager.conf | 14 +++++++++----- src/NetworkManagerUtils.c | 7 ------- src/nm-dbus-manager.c | 18 ------------------ test/nm-tool.c | 4 ++-- 11 files changed, 24 insertions(+), 47 deletions(-) diff --git a/callouts/nm-dispatcher-action.h b/callouts/nm-dispatcher-action.h index 39aefd8f8..e4f2fab2f 100644 --- a/callouts/nm-dispatcher-action.h +++ b/callouts/nm-dispatcher-action.h @@ -22,7 +22,6 @@ #define NM_DISPATCHER_DBUS_IFACE "org.freedesktop.nm_dispatcher" #define NM_DISPATCHER_DBUS_PATH "/org/freedesktop/nm_dispatcher" -#define NMD_CONNECTION_PROPS_SERVICE_NAME "service-name" #define NMD_CONNECTION_PROPS_PATH "path" #define NMD_DEVICE_PROPS_INTERFACE "interface" diff --git a/examples/python/add-system-connection.py b/examples/python/add-system-connection.py index 39eaabee0..447ffd829 100755 --- a/examples/python/add-system-connection.py +++ b/examples/python/add-system-connection.py @@ -41,7 +41,7 @@ con = dbus.Dictionary({ bus = dbus.SystemBus() -proxy = bus.get_object("org.freedesktop.NetworkManagerSystemSettings", "/org/freedesktop/NetworkManagerSettings") +proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManagerSettings") settings = dbus.Interface(proxy, "org.freedesktop.NetworkManagerSettings") settings.AddConnection(con) diff --git a/examples/python/nm-state.py b/examples/python/nm-state.py index 1ee475281..179143c2f 100644 --- a/examples/python/nm-state.py +++ b/examples/python/nm-state.py @@ -53,7 +53,7 @@ for a in active: # needed to connect to a specific network. Lets get those details so we # can find the user-readable name of the connection. con_path = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "Connection") - service_proxy = bus.get_object("org.freedesktop.NetworkManagerSystemSettings", con_path) + service_proxy = bus.get_object("org.freedesktop.NetworkManager", con_path) con_iface = dbus.Interface(service_proxy, "org.freedesktop.NetworkManagerSettings.Connection") con_details = con_iface.GetSettings() con_name = con_details['connection']['id'] diff --git a/examples/python/vpn.py b/examples/python/vpn.py index 7e53f4bd9..892d4bd55 100644 --- a/examples/python/vpn.py +++ b/examples/python/vpn.py @@ -37,7 +37,7 @@ DBusGMainLoop(set_as_default=True) def get_connections(): bus = dbus.SystemBus() - proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', '/org/freedesktop/NetworkManagerSettings') + proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManagerSettings') iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings') return iface.ListConnections() @@ -45,7 +45,7 @@ def get_connections(): def get_connection_by_uuid(uuid): bus = dbus.SystemBus() for c in get_connections(): - proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', c) + proxy = bus.get_object('org.freedesktop.NetworkManager', c) iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') settings = iface.GetSettings() if settings['connection']['uuid'] == uuid: @@ -57,7 +57,7 @@ def get_connection_by_uuid(uuid): def list_uuids(): bus = dbus.SystemBus() for c in get_connections(): - proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', c) + proxy = bus.get_object('org.freedesktop.NetworkManager', c) iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') settings = iface.GetSettings() conn = settings['connection'] @@ -76,7 +76,7 @@ def get_active_connection_path(uuid): iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.DBus.Properties') path = iface.Get('org.freedesktop.NetworkManager.Connection.Active', 'Connection') - proxy = bus.get_object('org.freedesktop.NetworkManagerSystemSettings', path) + proxy = bus.get_object('org.freedesktop.NetworkManager', path) iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') settings = iface.GetSettings() @@ -112,7 +112,7 @@ def activate_connection(connection_path, device_path): bus = dbus.SystemBus() proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager') iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManager') - iface.ActivateConnection('org.freedesktop.NetworkManagerSystemSettings', + iface.ActivateConnection('org.freedesktop.NetworkManager', connection_path, device_path, "/", diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 56fcfa276..81b610491 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -45,7 +45,6 @@ #define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config" -#define NM_DBUS_SERVICE_SYSTEM_SETTINGS "org.freedesktop.NetworkManagerSystemSettings" #define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings" #define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings" diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 3f716f943..030761869 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -343,14 +343,14 @@ constructor (GType type, g_assert (nm_connection_get_path (NM_CONNECTION (object))); priv->proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_SERVICE, nm_connection_get_path (NM_CONNECTION (object)), NM_DBUS_IFACE_SETTINGS_CONNECTION); g_assert (priv->proxy); dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); priv->secrets_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_SERVICE, nm_connection_get_path (NM_CONNECTION (object)), NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS); g_assert (priv->secrets_proxy); diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 6019e3ba6..fcf28605e 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -485,7 +485,7 @@ name_owner_changed (DBusGProxy *proxy, { NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - const char *sname = NM_DBUS_SERVICE_SYSTEM_SETTINGS; + const char *sname = NM_DBUS_SERVICE; if (!strcmp (name, sname)) { if (priv->fetch_id) @@ -633,7 +633,7 @@ constructor (GType type, object, NULL); if (!dbus_g_proxy_call (priv->dbus_proxy, "NameHasOwner", &error, - G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS, + G_TYPE_STRING, NM_DBUS_SERVICE, G_TYPE_INVALID, G_TYPE_BOOLEAN, &priv->service_running, G_TYPE_INVALID)) { @@ -646,7 +646,7 @@ constructor (GType type, } priv->proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_SERVICE, NM_DBUS_PATH_SETTINGS, NM_DBUS_IFACE_SETTINGS); g_assert (priv->proxy); @@ -665,7 +665,7 @@ constructor (GType type, /* D-Bus properties proxy */ priv->props_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_SERVICE, NM_DBUS_PATH_SETTINGS, "org.freedesktop.DBus.Properties"); g_assert (priv->props_proxy); diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf index 8d0831400..8a581cb9b 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -4,10 +4,7 @@ - - - @@ -63,10 +60,17 @@ - - + + + + + + proxy, "RequestName", &err, - G_TYPE_STRING, NM_DBUS_SERVICE_SYSTEM_SETTINGS, - G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE, - G_TYPE_INVALID, - G_TYPE_UINT, &result, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_CORE, "Could not acquire the NetworkManagerSystemSettings service.\n" - " Message: '%s'", err->message); - g_error_free (err); - return FALSE; - } - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - nm_log_warn (LOGD_CORE, "Could not acquire the NetworkManagerSystemSettings service " - "as it is already taken."); - return FALSE; - } - priv->started = TRUE; return priv->started; } diff --git a/test/nm-tool.c b/test/nm-tool.c index 6682558ff..922bb63b1 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -568,7 +568,7 @@ get_one_connection (DBusGConnection *bus, g_return_if_fail (path != NULL); g_return_if_fail (table != NULL); - proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE_SYSTEM_SETTINGS, + proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE, path, NM_DBUS_IFACE_SETTINGS_CONNECTION); if (!proxy) return; @@ -619,7 +619,7 @@ get_all_connections (void) } proxy = dbus_g_proxy_new_for_name (bus, - NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_SERVICE, NM_DBUS_PATH_SETTINGS, NM_DBUS_IFACE_SETTINGS); if (!proxy) { From f98e2528a6f6524857d569a0d1b41e5323a3217d Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Sat, 7 Aug 2010 01:07:44 -0400 Subject: [PATCH 021/264] NetworkMangerSettings -> NetworkManager.Settings Just for consistency, make settings related stuff live under the org.freedesktop.NetworkManager namespace, rather than its own org.freedesktop.NetworkManagerSettings namespace. Renames are done for DBus interface names, DBus object paths, and polkit actions. --- examples/python/add-system-connection.py | 4 +- examples/python/list-connections.py | 8 ++-- examples/python/nm-state.py | 2 +- examples/python/vpn.py | 10 ++-- include/NetworkManager.h | 10 ++-- introspection/nm-settings.xml | 4 +- introspection/nm-sysconfig-connection.xml | 4 +- libnm-glib/nm-remote-connection.c | 32 ++++++------- libnm-glib/nm-remote-settings.c | 14 +++--- po/POTFILES.in | 1 - policy/Makefile.am | 1 - .../org.freedesktop.NetworkManager.policy.in | 36 ++++++++++++++ ....network-manager-settings.system.policy.in | 48 ------------------- src/NetworkManager.conf | 8 ++-- src/system-settings/nm-polkit-helpers.h | 8 ++-- 15 files changed, 88 insertions(+), 102 deletions(-) delete mode 100644 policy/org.freedesktop.network-manager-settings.system.policy.in diff --git a/examples/python/add-system-connection.py b/examples/python/add-system-connection.py index 447ffd829..d508e8c6e 100755 --- a/examples/python/add-system-connection.py +++ b/examples/python/add-system-connection.py @@ -41,8 +41,8 @@ con = dbus.Dictionary({ bus = dbus.SystemBus() -proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManagerSettings") -settings = dbus.Interface(proxy, "org.freedesktop.NetworkManagerSettings") +proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Settings") +settings = dbus.Interface(proxy, "org.freedesktop.NetworkManager.Settings") settings.AddConnection(con) diff --git a/examples/python/list-connections.py b/examples/python/list-connections.py index de2ca1872..9c3e1771c 100644 --- a/examples/python/list-connections.py +++ b/examples/python/list-connections.py @@ -73,21 +73,21 @@ def connection_to_string(config): def print_connections(): # Ask the settings service for the list of connections it provides service_name = "org.freedesktop.NetworkManager" - proxy = bus.get_object(service_name, "/org/freedesktop/NetworkManagerSettings") - settings = dbus.Interface(proxy, "org.freedesktop.NetworkManagerSettings") + proxy = bus.get_object(service_name, "/org/freedesktop/NetworkManager/Settings") + settings = dbus.Interface(proxy, "org.freedesktop.NetworkManager.Settings") connection_paths = settings.ListConnections() # List each connection's name, UUID, and type for path in connection_paths: con_proxy = bus.get_object(service_name, path) - connection = dbus.Interface(con_proxy, "org.freedesktop.NetworkManagerSettings.Connection") + connection = dbus.Interface(con_proxy, "org.freedesktop.NetworkManager.Settings.Connection") config = connection.GetSettings() # Now get secrets too; we grab the secrets for each type of connection # (since there isn't a "get all secrets" call because most of the time # you only need 'wifi' secrets or '802.1x' secrets, not everything) and # merge that into the configuration data - connection_secrets = dbus.Interface(con_proxy, "org.freedesktop.NetworkManagerSettings.Connection.Secrets") + connection_secrets = dbus.Interface(con_proxy, "org.freedesktop.NetworkManager.Settings.Connection.Secrets") merge_secrets(connection_secrets, config, '802-11-wireless') merge_secrets(connection_secrets, config, '802-11-wireless-security') merge_secrets(connection_secrets, config, '802-1x') diff --git a/examples/python/nm-state.py b/examples/python/nm-state.py index 179143c2f..42c96bf56 100644 --- a/examples/python/nm-state.py +++ b/examples/python/nm-state.py @@ -54,7 +54,7 @@ for a in active: # can find the user-readable name of the connection. con_path = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "Connection") service_proxy = bus.get_object("org.freedesktop.NetworkManager", con_path) - con_iface = dbus.Interface(service_proxy, "org.freedesktop.NetworkManagerSettings.Connection") + con_iface = dbus.Interface(service_proxy, "org.freedesktop.NetworkManager.Settings.Connection") con_details = con_iface.GetSettings() con_name = con_details['connection']['id'] diff --git a/examples/python/vpn.py b/examples/python/vpn.py index 892d4bd55..7e3e19f37 100644 --- a/examples/python/vpn.py +++ b/examples/python/vpn.py @@ -37,8 +37,8 @@ DBusGMainLoop(set_as_default=True) def get_connections(): bus = dbus.SystemBus() - proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManagerSettings') - iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings') + proxy = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager/Settings') + iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManager.Settings') return iface.ListConnections() @@ -46,7 +46,7 @@ def get_connection_by_uuid(uuid): bus = dbus.SystemBus() for c in get_connections(): proxy = bus.get_object('org.freedesktop.NetworkManager', c) - iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') + iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManager.Settings.Connection') settings = iface.GetSettings() if settings['connection']['uuid'] == uuid: return c @@ -58,7 +58,7 @@ def list_uuids(): bus = dbus.SystemBus() for c in get_connections(): proxy = bus.get_object('org.freedesktop.NetworkManager', c) - iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') + iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManager.Settings.Connection') settings = iface.GetSettings() conn = settings['connection'] print "%s - %s (%s)" % (conn['uuid'], conn['id'], conn['type']) @@ -77,7 +77,7 @@ def get_active_connection_path(uuid): path = iface.Get('org.freedesktop.NetworkManager.Connection.Active', 'Connection') proxy = bus.get_object('org.freedesktop.NetworkManager', path) - iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManagerSettings.Connection') + iface = dbus.Interface(proxy, dbus_interface='org.freedesktop.NetworkManager.Settings.Connection') settings = iface.GetSettings() if settings['connection']['uuid'] == uuid: diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 81b610491..98aad2d11 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -45,12 +45,12 @@ #define NM_DBUS_INTERFACE_DHCP6_CONFIG NM_DBUS_INTERFACE ".DHCP6Config" -#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManagerSettings" -#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManagerSettings" +#define NM_DBUS_IFACE_SETTINGS "org.freedesktop.NetworkManager.Settings" +#define NM_DBUS_PATH_SETTINGS "/org/freedesktop/NetworkManager/Settings" -#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManagerSettings.Connection" -#define NM_DBUS_PATH_SETTINGS_CONNECTION "/org/freedesktop/NetworkManagerSettings/Connection" -#define NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS "org.freedesktop.NetworkManagerSettings.Connection.Secrets" +#define NM_DBUS_IFACE_SETTINGS_CONNECTION "org.freedesktop.NetworkManager.Settings.Connection" +#define NM_DBUS_PATH_SETTINGS_CONNECTION "/org/freedesktop/NetworkManager/Settings/Connection" +#define NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS "org.freedesktop.NetworkManager.Settings.Connection.Secrets" /* diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml index 67e6d2abb..d907cf7bc 100644 --- a/introspection/nm-settings.xml +++ b/introspection/nm-settings.xml @@ -1,9 +1,9 @@ - + - The NetworkManagerSettings interface is provided by the service which provides connections to NetworkManager. + The Settings interface allows clients to view and administrate the connections stored and used by NetworkManager. diff --git a/introspection/nm-sysconfig-connection.xml b/introspection/nm-sysconfig-connection.xml index aae08e06f..9df94af49 100644 --- a/introspection/nm-sysconfig-connection.xml +++ b/introspection/nm-sysconfig-connection.xml @@ -2,7 +2,7 @@ - + Represents a single network connection configuration. @@ -59,7 +59,7 @@ - + Secrets have a separate interface so that they can be locked down. diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 030761869..9f52570cb 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -130,10 +130,10 @@ nm_remote_connection_commit_changes (NMRemoteConnection *self, settings = nm_connection_to_hash (NM_CONNECTION (self)); - call->call = org_freedesktop_NetworkManagerSettings_Connection_update_async (priv->proxy, - settings, - update_cb, - call); + call->call = org_freedesktop_NetworkManager_Settings_Connection_update_async (priv->proxy, + settings, + update_cb, + call); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); @@ -178,9 +178,9 @@ nm_remote_connection_delete (NMRemoteConnection *self, call->user_data = user_data; call->proxy = priv->proxy; - call->call = org_freedesktop_NetworkManagerSettings_Connection_delete_async (priv->proxy, - delete_cb, - call); + call->call = org_freedesktop_NetworkManager_Settings_Connection_delete_async (priv->proxy, + delete_cb, + call); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); } @@ -230,12 +230,12 @@ nm_remote_connection_get_secrets (NMRemoteConnection *self, call->user_data = user_data; call->proxy = priv->secrets_proxy; - call->call = org_freedesktop_NetworkManagerSettings_Connection_Secrets_get_secrets_async (priv->secrets_proxy, - setting_name, - hints, - request_new, - get_secrets_cb, - call); + call->call = org_freedesktop_NetworkManager_Settings_Connection_Secrets_get_secrets_async (priv->secrets_proxy, + setting_name, + hints, + request_new, + get_secrets_cb, + call); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); } @@ -362,9 +362,9 @@ constructor (GType type, dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "Removed", G_CALLBACK (removed_cb), object, NULL); - org_freedesktop_NetworkManagerSettings_Connection_get_settings_async (priv->proxy, - get_settings_cb, - object); + org_freedesktop_NetworkManager_Settings_Connection_get_settings_async (priv->proxy, + get_settings_cb, + object); return object; } diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index fcf28605e..62ae13d2b 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -223,9 +223,9 @@ fetch_connections (gpointer user_data) priv->fetch_id = 0; - org_freedesktop_NetworkManagerSettings_list_connections_async (priv->proxy, - fetch_connections_done, - self); + org_freedesktop_NetworkManager_Settings_list_connections_async (priv->proxy, + fetch_connections_done, + self); return FALSE; } @@ -309,10 +309,10 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, info->callback_data = user_data; new_settings = nm_connection_to_hash (connection); - org_freedesktop_NetworkManagerSettings_add_connection_async (priv->proxy, - new_settings, - add_connection_done, - info); + org_freedesktop_NetworkManager_Settings_add_connection_async (priv->proxy, + new_settings, + add_connection_done, + info); g_hash_table_destroy (new_settings); return TRUE; } diff --git a/po/POTFILES.in b/po/POTFILES.in index 22e8cf382..509ec67bb 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -11,7 +11,6 @@ libnm-util/crypto.c libnm-util/crypto_gnutls.c libnm-util/crypto_nss.c libnm-util/nm-utils.c -policy/org.freedesktop.network-manager-settings.system.policy.in policy/org.freedesktop.NetworkManager.policy.in src/nm-netlink-monitor.c src/main.c diff --git a/policy/Makefile.am b/policy/Makefile.am index 4778ce230..289d220bd 100644 --- a/policy/Makefile.am +++ b/policy/Makefile.am @@ -1,7 +1,6 @@ polkit_policydir = $(datadir)/polkit-1/actions dist_polkit_policy_in_files = \ - org.freedesktop.network-manager-settings.system.policy.in \ org.freedesktop.NetworkManager.policy.in dist_polkit_policy_DATA = $(dist_polkit_policy_in_files:.policy.in=.policy) diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index 67af7838a..32b8ab00b 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -54,5 +54,41 @@ + + <_description>Modify system connections + <_message>System policy prevents modification of system settings + + no + auth_admin_keep + + + + + <_description>Modify persistent system hostname + <_message>System policy prevents modification of the persistent system hostname + + no + auth_admin_keep + + + + + <_description>Connection sharing via a protected WiFi network + <_message>System policy prevents sharing connections via a protected WiFi network + + no + yes + + + + + <_description>Connection sharing via an open WiFi network + <_message>System policy prevents sharing connections via an open WiFi network + + no + yes + + + diff --git a/policy/org.freedesktop.network-manager-settings.system.policy.in b/policy/org.freedesktop.network-manager-settings.system.policy.in deleted file mode 100644 index 620e3a6a5..000000000 --- a/policy/org.freedesktop.network-manager-settings.system.policy.in +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - NetworkManager - http://www.gnome.org/projects/NetworkManager - nm-icon - - - <_description>Modify system connections - <_message>System policy prevents modification of system settings - - no - auth_admin_keep - - - - - <_description>Modify persistent system hostname - <_message>System policy prevents modification of the persistent system hostname - - no - auth_admin_keep - - - - - <_description>Connection sharing via a protected WiFi network - <_message>System policy prevents sharing connections via a protected WiFi network - - no - yes - - - - - <_description>Connection sharing via an open WiFi network - <_message>System policy prevents sharing connections via an open WiFi network - - no - yes - - - - diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf index 8a581cb9b..afaef2179 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -64,19 +64,19 @@ + send_interface="org.freedesktop.NetworkManager.Settings"/> + send_interface="org.freedesktop.NetworkManager.Settings.Connection"/> + send_interface="org.freedesktop.NetworkManager.Settings.Secrets"/> - diff --git a/src/system-settings/nm-polkit-helpers.h b/src/system-settings/nm-polkit-helpers.h index c26fcc2c9..0ca3ca0f8 100644 --- a/src/system-settings/nm-polkit-helpers.h +++ b/src/system-settings/nm-polkit-helpers.h @@ -24,9 +24,9 @@ #include -#define NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY "org.freedesktop.network-manager-settings.system.modify" -#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED "org.freedesktop.network-manager-settings.system.wifi.share.protected" -#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN "org.freedesktop.network-manager-settings.system.wifi.share.open" -#define NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY "org.freedesktop.network-manager-settings.system.hostname.modify" +#define NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY "org.freedesktop.NetworkManager.settings.modify" +#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.settings.wifi.share.protected" +#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.settings.wifi.share.open" +#define NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" #endif /* NM_POLKIT_HELPERS_H */ From 94d26709cc77c8708a968f9f4d2cc54be4444ace Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Mon, 9 Aug 2010 20:01:19 -0400 Subject: [PATCH 022/264] WIP: libnm-util: added "permissions" property --- libnm-util/nm-setting-connection.c | 131 +++++++++++++++++++++++++++++ libnm-util/nm-setting-connection.h | 20 +++-- 2 files changed, 144 insertions(+), 7 deletions(-) diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 65f613eba..40c9ac14c 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -25,6 +25,9 @@ #include #include +#include "nm-utils.h" +#include "nm-dbus-glib-types.h" +#include "nm-param-spec-specialized.h" #include "nm-setting-connection.h" /** @@ -85,6 +88,7 @@ typedef struct { char *id; char *uuid; char *type; + GSList *permissions; gboolean autoconnect; guint64 timestamp; gboolean read_only; @@ -95,6 +99,7 @@ enum { PROP_ID, PROP_UUID, PROP_TYPE, + PROP_PERMISSIONS, PROP_AUTOCONNECT, PROP_TIMESTAMP, PROP_READ_ONLY, @@ -162,6 +167,42 @@ nm_setting_connection_get_connection_type (NMSettingConnection *setting) return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->type; } + +/** + * nm_setting_connection_get_num_permissions: + * @setting: the #NMSettingConnection + * + * Returns the number of entires in the #NMSettingConnection:permissions + * property of this setting. + * + * Returns: the number of permissions entires + */ +guint32 +nm_setting_connection_get_num_permissions (NMSettingConnection *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0); + + return g_slist_length (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions); +} + +/** + * nm_setting_connection_get_permission_entry: + * @setting: the #NMSettingConnection + * @index: the zero-based index of the permissions entry + * + * Retrieve one of the entries of the #NMSettingConnection:permissions property + * of this setting. + * + * Returns: the entry at the specified index + */ +const char * +nm_setting_connection_get_permission_entry (NMSettingConnection *setting, guint32 i) +{ + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + + return (const char *) g_slist_nth_data (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions, i); +} + /** * nm_setting_connection_get_autoconnect: * @setting: the #NMSettingConnection @@ -235,6 +276,49 @@ validate_uuid (const char *uuid) return TRUE; } +/* Check that every entry in the given permissions array is of proper form. + * Report a descriptive error if it's not. */ +static gboolean +validate_permissions (GSList *permissions, GError **error) +{ + GSList *iter; + for (iter = permissions; iter; iter = iter->next) { + char *entry = (char *) iter->data; + char *usr_start = NULL; + char *ext_start = NULL; + int prefix_len; + + if (g_str_has_prefix (entry, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER)) { + prefix_len = strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER); + } else if (g_str_has_prefix (entry, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_GROUP)) { + prefix_len = strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_GROUP); + } else { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + "permissions: entry '%s': invalid prefix", entry); + return FALSE; + } + + usr_start = entry + prefix_len; + + ext_start = strchr(usr_start, ':'); + if (!ext_start) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + "permissions: entry '%s': two few ':'s", entry); + return FALSE; + } + ext_start++; + + /* We don't (yet) care about what comes afterwards. */ + + } + + return TRUE; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -291,6 +375,14 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (priv->permissions) { + GError *perm_error = NULL; + if (!validate_permissions (priv->permissions, &perm_error)) { + g_propagate_error (error, perm_error); + return FALSE; + } + } + return TRUE; } @@ -308,6 +400,7 @@ finalize (GObject *object) g_free (priv->id); g_free (priv->uuid); g_free (priv->type); + nm_utils_slist_free (priv->permissions, g_free); G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object); } @@ -331,6 +424,10 @@ set_property (GObject *object, guint prop_id, g_free (priv->type); priv->type = g_value_dup_string (value); break; + case PROP_PERMISSIONS: + nm_utils_slist_free (priv->permissions, g_free); + priv->permissions = g_value_dup_boxed (value); + break; case PROP_AUTOCONNECT: priv->autoconnect = g_value_get_boolean (value); break; @@ -362,6 +459,9 @@ get_property (GObject *object, guint prop_id, case PROP_TYPE: g_value_set_string (value, nm_setting_connection_get_connection_type (setting)); break; + case PROP_PERMISSIONS: + g_value_set_boxed (value, NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions); + break; case PROP_AUTOCONNECT: g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting)); break; @@ -464,6 +564,37 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** + * NMSettingConnection:permissions: + * + * An array of strings defining what access a given user has to this + * connection. If this is NULL or empty, all users are allowed to access + * this connection. Otherwise, each entry in this array specifies a user or + * unix group, and a user is allowed to access this connection if and only + * if they are in this list or if they are included in at least one of any + * listed unix groups . Each entry is of the form "user:: + * or "group::. Any present must be ignored; it is + * reserved for future versions of NM. + */ + g_object_class_install_property + (object_class, PROP_PERMISSIONS, + _nm_param_spec_specialized (NM_SETTING_CONNECTION_PERMISSIONS, + "Permissions", + "An array of strings defining what access a given " + "user has to this connection. If this is NULL or " + "empty, all users are allowed to access this " + "connection. Otherwise, each entry in this array " + "specifies a user or unix group, and a user is " + "allowed to access this connection if and only if " + "they are in this list or if they are included in at " + "least one of any listed unix groups. Each entry is " + "of the form \"user::\" or " + "\"group::\". Any present " + "must be ignored; it is reserved for future versions " + "of NM.", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingConnection:autoconnect: * diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 6dedca220..22e0deb6a 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -74,6 +74,10 @@ GQuark nm_setting_connection_error_quark (void); #define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" #define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" #define NM_SETTING_CONNECTION_READ_ONLY "read-only" +#define NM_SETTING_CONNECTION_PERMISSIONS "permissions" + +#define NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER "user:" +#define NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_GROUP "group:" /** * NMSettingConnection: @@ -97,13 +101,15 @@ typedef struct { GType nm_setting_connection_get_type (void); -NMSetting * nm_setting_connection_new (void); -const char *nm_setting_connection_get_id (NMSettingConnection *setting); -const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); -const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); -gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); -guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); -gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); +NMSetting * nm_setting_connection_new (void); +const char *nm_setting_connection_get_id (NMSettingConnection *setting); +const char *nm_setting_connection_get_uuid (NMSettingConnection *setting); +const char *nm_setting_connection_get_connection_type (NMSettingConnection *setting); +gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); +guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); +gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); +guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); +const char *nm_setting_connection_get_permission_entry (NMSettingConnection *setting, guint32 index); G_END_DECLS From b0fb908e187ab6ea254d6d2c9666563c37885884 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Thu, 12 Aug 2010 17:10:26 -0400 Subject: [PATCH 023/264] WIP: Adding ConsoleKit session tracking framework --- src/system-settings/Makefile.am | 6 +- src/system-settings/nm-session-info.c | 220 +++++++ src/system-settings/nm-session-info.h | 60 ++ src/system-settings/nm-session-manager.c | 781 +++++++++++++++++++++++ src/system-settings/nm-session-manager.h | 81 +++ 5 files changed, 1147 insertions(+), 1 deletion(-) create mode 100644 src/system-settings/nm-session-info.c create mode 100644 src/system-settings/nm-session-info.h create mode 100644 src/system-settings/nm-session-manager.c create mode 100644 src/system-settings/nm-session-manager.h diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 67980767c..5f18623ce 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -25,7 +25,11 @@ libsystem_settings_la_SOURCES = \ nm-sysconfig-connection.c \ nm-sysconfig-connection.h \ nm-default-wired-connection.c \ - nm-default-wired-connection.h + nm-default-wired-connection.h \ + nm-session-info.c \ + nm-session-info.h \ + nm-session-manager.c \ + nm-session-manager.h libsystem_settings_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/system-settings/nm-session-info.c b/src/system-settings/nm-session-info.c new file mode 100644 index 000000000..28421ce14 --- /dev/null +++ b/src/system-settings/nm-session-info.c @@ -0,0 +1,220 @@ +/* NetworkManager user session tracker -- per-session data + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Daniel Gnoutcheff + */ + +#include "nm-session-info.h" +#include "nm-dbus-glib-types.h" +#include "nm-utils.h" + +G_DEFINE_TYPE (NMSessionInfo, nm_session_info, G_TYPE_OBJECT); + +typedef struct { + char *id; + char *user; + GSList *groups; + gboolean is_default; +} NMSessionInfoPrivate; + +#define NM_SESSION_INFO_GET_PRIVATE(self) (G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SESSION_INFO, NMSessionInfoPrivate)) + +enum { + PROP_0, + PROP_ID, + PROP_USER, + PROP_GROUPS, + PROP_IS_DEFAULT +}; + +char * +nm_session_info_get_id (NMSessionInfo *self) +{ + g_return_val_if_fail (NM_IS_SESSION_INFO (self), NULL); + + return NM_SESSION_INFO_GET_PRIVATE (self)->id; +} + +char * +nm_session_info_get_unix_user (NMSessionInfo *self) +{ + g_return_val_if_fail (NM_IS_SESSION_INFO (self), NULL); + + return NM_SESSION_INFO_GET_PRIVATE (self)->user; +} + +GSList * +nm_session_info_get_unix_groups (NMSessionInfo *self) +{ + g_return_val_if_fail (NM_IS_SESSION_INFO (self), NULL); + + return NM_SESSION_INFO_GET_PRIVATE (self)->groups; +} + +gboolean +nm_session_info_is_default_session (NMSessionInfo *self) +{ + g_return_val_if_fail (NM_IS_SESSION_INFO (self), FALSE); + + return NM_SESSION_INFO_GET_PRIVATE (self)->is_default; +} + +static void +set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { + NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); + + switch (property_id) { + case PROP_ID: + g_free (priv->id); + priv->id = g_value_dup_string (value); + break; + case PROP_USER: + g_free (priv->user); + priv->user = g_value_dup_string (value); + break; + case PROP_GROUPS: + nm_utils_slist_free (priv->groups, g_free); + priv->groups = g_value_dup_boxed (value); + break; + case PROP_IS_DEFAULT: + priv->is_default = g_value_get_boolean (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { + NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); + + switch (property_id) { + case PROP_ID: + g_value_set_string (value, priv->id); + break; + case PROP_USER: + g_value_set_string (value, priv->user); + break; + case PROP_GROUPS: + g_value_set_boxed (value, priv->groups); + break; + case PROP_IS_DEFAULT: + g_value_set_boolean (value, priv->is_default); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +nm_session_info_init (NMSessionInfo *self) { +} + +static void +dispose (GObject *object) +{ + NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); + + if (priv->id) { + g_free (priv->id); + priv->id = NULL; + } + + if (priv->user) { + g_free (priv->user); + priv->user = NULL; + } + + if (priv->groups) { + nm_utils_slist_free (priv->groups, g_free); + priv->groups = NULL; + } + + G_OBJECT_CLASS (nm_session_info_parent_class)->dispose (object); +} + +static void +nm_session_info_class_init (NMSessionInfoClass *info_class) { + GObjectClass *g_class = G_OBJECT_CLASS (info_class); + + g_type_class_add_private (g_class, sizeof(NMSessionInfoPrivate)); + g_class->set_property = set_property; + g_class->get_property = get_property; + g_class->dispose = dispose; + + g_object_class_install_property + (g_class, PROP_ID, + g_param_spec_string ( + NM_SESSION_INFO_ID, + "ConsoleKitSID", + "ConsoleKit session ID, or \"[none]\" if this is the \"default\" " + "session.", + NM_SESSION_INFO_DEFAULT_ID, + G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (g_class, PROP_USER, + g_param_spec_string ( + NM_SESSION_INFO_UNIX_USER, + "UnixUser", + "String name of the unix user who owns this session, or NULL if " + "this is the default session.", + NULL, + G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (g_class, PROP_GROUPS, + g_param_spec_boxed ( + NM_SESSION_INFO_UNIX_GROUPS, + "UnixGroups", + "List of strings representing the groups that this session's user " + "belonged to at login time. This represents our best guess as to " + "what groups the session's processes belong to. If this is the " + "default session, this is NULL.", + DBUS_TYPE_G_LIST_OF_STRING, + G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property + (g_class, PROP_IS_DEFAULT, + g_param_spec_boolean ( + NM_SESSION_INFO_IS_DEFAULT, + "IsDefaultSession", + "Indicates if this NMSessionInfo instance represents the " + "\"default\" session, the session containing all processes that " + "do not belong to a ConsoleKit-recognized session.", + TRUE, + G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_signal_new ( + NM_SESSION_INFO_REMOVED, + NM_TYPE_SESSION_INFO, + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} diff --git a/src/system-settings/nm-session-info.h b/src/system-settings/nm-session-info.h new file mode 100644 index 000000000..5dc1ab484 --- /dev/null +++ b/src/system-settings/nm-session-info.h @@ -0,0 +1,60 @@ +/* NetworkManager user session tracker -- per-session data + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Daniel Gnoutcheff + */ + +#ifndef NM_SESSION_INFO_H +#define NM_SESSION_INFO_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SESSION_INFO (nm_session_info_get_type ()) +#define NM_SESSION_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SESSION_INFO, NMSessionInfo)) +#define NM_SESSION_INFO_CLASS(class_struct) (G_TYPE_CHECK_CLASS_CAST ((class_struct), NM_TYPE_SESSION_INFO, NMSessionInfoClass)) +#define NM_IS_SESSION_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SESSION_INFO)) +#define NM_IS_SESSION_INFO_CLASS(class_struct) (G_TYPE_CHECK_CLASS_TYPE ((class_struct), NM_TYPE_SESSION_INFO)) +#define NM_SESSION_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SESSION_INFO, NMSessionInfoClass)) + +#define NM_SESSION_INFO_ID "session-id" +#define NM_SESSION_INFO_UNIX_USER "unix-user" +#define NM_SESSION_INFO_UNIX_GROUPS "unix-groups" +#define NM_SESSION_INFO_IS_DEFAULT "is-default" + +#define NM_SESSION_INFO_REMOVED "removed" + +#define NM_SESSION_INFO_DEFAULT_ID "[none]" + +typedef struct { + GObject parent; +} NMSessionInfo; + +typedef struct { + GObjectClass parent_class; +} NMSessionInfoClass; + +GType nm_session_info_get_type (void); + +char * nm_session_info_get_id (NMSessionInfo *self); +char * nm_session_info_get_unix_user (NMSessionInfo *self); +GSList * nm_session_info_get_unix_groups (NMSessionInfo *self); +gboolean nm_session_info_is_default_session (NMSessionInfo *self); + +G_END_DECLS + +#endif diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c new file mode 100644 index 000000000..e089cf6a0 --- /dev/null +++ b/src/system-settings/nm-session-manager.c @@ -0,0 +1,781 @@ +/* NetworkManager user session tracker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Daniel Gnoutcheff + */ + +#include +#include +#include +#include +#include +#include +#include "nm-dbus-manager.h" +#include "nm-session-manager.h" + +G_DEFINE_TYPE (NMSessionManager, nm_session_manager, G_TYPE_OBJECT); + +/* NMSessionManager data */ +typedef struct { + gboolean disposed; + gboolean initalized; + + /* The master table of NMSessionInfo instances, keyed by session id. */ + GHashTable *sessions; + + /* DBus proxy of the ConsoleKit manager */ + DBusGProxy *ck_manager; + + /* Table of PendingSessionInfo structs, representing sessions for which we + * are waiting for information on. Keyed by session id. */ + GHashTable *pending_sessions; + + /* List of PendingCallerInfo structs, representing ongoing + * get_session_of_caller calls. */ + GSList *pending_callers; +} NMSessionManagerPrivate; + +#define NM_SESSION_MANAGER_GET_PRIVATE(self) (G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SESSION_MANAGER, NMSessionManagerPrivate)) + + +enum { + ADDED, + INIT_DONE, + + LAST_SIGNAL +}; +static guint signals[LAST_SIGNAL] = { 0 }; + + +/**** general utilities for managing callbacks *******************************/ + +typedef struct { + NMSessionFunc callback; + gpointer user_data; +} CallbackInfo; + +/* Allocate a new CallbackInfo for the given callback & data */ +static CallbackInfo * +callback_info_new (NMSessionFunc callback, gpointer user_data) +{ + CallbackInfo *info = g_slice_new (CallbackInfo); + info->callback = callback; + info->user_data = user_data; + return info; +} + +/* Run the callback represented by cb_info and free it. */ +static void +callback_info_run (CallbackInfo *cb_info, NMSessionInfo *session, GError *error) +{ + if (cb_info->callback) { + (cb_info->callback) (session, error, cb_info->user_data); + } + g_slice_free (CallbackInfo, cb_info); +} + +/* Run the callback with an error message indicating that we've been disposed. */ +static void +callback_info_fail_disposed (CallbackInfo *cb_info) +{ + GError *error = g_error_new (NM_SESSION_MANAGER_ERROR, + NM_SESSION_MANAGER_ERROR_DISPOSED, + "NMSessionManager was disposed before operation completed."); + callback_info_run (cb_info, NULL, error); + g_error_free (error); +} + + +/**** get_session stuff ******************************************************/ + +typedef struct { + NMSessionManager *manager; + DBusGProxy *session_proxy; + DBusGProxyCall *session_call; + char *session_id; + + GSList *callbacks; /* List of CallbackInfo structs */ +} PendingSessionInfo; + +/* Called by the pending_sessions GHashTable when removing a PendingSession */ +static void +pending_session_destroy (gpointer data) +{ + PendingSessionInfo *pending = (PendingSessionInfo *) data; + + // FIXME this is ugly copy-and-paste + // If any callbacks remain, send failure messages to them. + while (pending->callbacks) { + CallbackInfo *cb_info = (CallbackInfo *) pending->callbacks->data; + callback_info_fail_disposed (cb_info); + pending->callbacks = g_slist_remove (pending->callbacks, cb_info); + } + + g_free (pending->session_id); + g_object_unref (pending->session_proxy); + g_object_unref (pending->session_call); + g_slice_free (PendingSessionInfo, pending); +} + +static void +pending_session_finish (PendingSessionInfo *pending, + NMSessionInfo *session, + GError *error) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (pending->manager); + + while (pending->callbacks) { + CallbackInfo *cb_info = (CallbackInfo *) pending->callbacks->data; + callback_info_run (cb_info, session, error); + pending->callbacks = g_slist_remove (pending->callbacks, cb_info); + } + + g_hash_table_remove (priv->pending_sessions, pending->session_id); + // pending_session_destroy() will be called by GHashTable +} + +static void +pending_session_cancel (PendingSessionInfo *pending, GError *error) +{ + dbus_g_proxy_cancel_call (pending->session_proxy, pending->session_call); + pending_session_finish (pending, NULL, error); +} + +static void +get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + PendingSessionInfo *pending = (PendingSessionInfo *) user_data; + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (pending->manager); + guint user_id; + struct passwd *pw_info = NULL; + int ngroups; + guint group_ids_size; + gid_t *group_ids = NULL; + GSList *group_names = NULL; + NMSessionInfo *session = NULL; + GError *error = NULL; + int i; + + if (!dbus_g_proxy_end_call (proxy, call_id, NULL, + G_TYPE_UINT, &user_id, G_TYPE_NONE)) { + error = g_error_new (NM_SESSION_MANAGER_ERROR, + NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, + "session %s: failed to get uid", + pending->session_id); + goto out; + } + + pw_info = getpwuid (user_id); + if (!pw_info) { + error = g_error_new (NM_SESSION_MANAGER_ERROR, + NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, + "session %s: failed to get username for uid %u", + pending->session_id, user_id); + goto out; + } + + // Figure out how many groups the user is in + group_ids = g_slice_alloc (0); + ngroups = 0; + getgrouplist (pw_info->pw_name, pw_info->pw_gid, group_ids, &ngroups); + g_slice_free1 (0, group_ids); + + // Get the list of group IDs + // FIXME what happens if the group list changes in the window between the + // two getgrouplist calls? + group_ids_size = ngroups * sizeof(gid_t); + group_ids = g_slice_alloc (group_ids_size); + if (getgrouplist (pw_info->pw_name, pw_info->pw_gid, group_ids, &ngroups) == -1) { + error = g_error_new (NM_SESSION_MANAGER_ERROR, + NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, + "session %s: failed to get groups for user %s", + pending->session_id, pw_info->pw_name); + goto out; + } + + for (i = 0; i < ngroups; i++) { + struct group *gr_info = getgrgid (group_ids[i]); + group_names = g_slist_prepend (group_names, g_strdup (gr_info->gr_name)); + } + + session = g_object_new (NM_TYPE_SESSION_INFO, + NM_SESSION_INFO_ID, pending->session_id, + NM_SESSION_INFO_UNIX_USER, pw_info->pw_name, + NM_SESSION_INFO_UNIX_GROUPS, group_names, + NULL); + g_assert (session); + + g_hash_table_insert (priv->sessions, nm_session_info_get_id (session), session); + g_signal_emit (pending->manager, signals[ADDED], 0, session); + +out: + if (group_names) + nm_utils_slist_free (group_names, g_free); + if (group_ids) + g_slice_free1 (group_ids_size, group_ids); + + pending_session_finish (pending, session, error); + + g_clear_error (&error); +} + +/* Start the process of loading information about the given session, and return + * the PendingSessionInfo struct that represents it. + */ +static PendingSessionInfo * +pending_session_start (NMSessionManager *self, char *session_id) +{ + PendingSessionInfo *pending = g_slice_new (PendingSessionInfo); + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); + DBusGConnection *connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); + + pending->session_id = g_strdup (session_id); + pending->manager = self; + pending->callbacks = NULL; + + pending->session_proxy = dbus_g_proxy_new_for_name (connection, + "org.freedesktop.ConsoleKit", + pending->session_id, + "org.freedesktop.ConsoleKit.Session"); + + pending->session_call = dbus_g_proxy_begin_call (pending->session_proxy, + "GetUnixUser", + get_unix_user_cb, + pending, + NULL, + G_TYPE_INVALID); + + g_hash_table_insert (priv->pending_sessions, pending->session_id, pending); + + return pending; +} + +static PendingSessionInfo * +pending_session_find (NMSessionManager *self, char *session_id) { + GHashTable *pending_sessions = NM_SESSION_MANAGER_GET_PRIVATE (self)->pending_sessions; + return g_hash_table_lookup (pending_sessions, session_id); +} + +static void +pending_session_add_callback (PendingSessionInfo *pending, CallbackInfo *cb_info) +{ + pending->callbacks = g_slist_prepend (pending->callbacks, cb_info); +} + +static void +get_session_internal (NMSessionManager *self, + char *session_id, + CallbackInfo *cb_info) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); + NMSessionInfo *session; + + if (priv->disposed) { + callback_info_fail_disposed (cb_info); + return; + } + + session = g_hash_table_lookup (priv->sessions, session_id); + if (session) { + callback_info_run (cb_info, session, NULL); + } else { + PendingSessionInfo *pending = pending_session_find (self, session_id); + if (!pending) { + pending = pending_session_start (self, session_id); + } + pending_session_add_callback (pending, cb_info); + } +} + +void +nm_session_manager_get_session (NMSessionManager *self, + char *session_id, + NMSessionFunc callback, + gpointer user_data) +{ + CallbackInfo *cb_info; + + g_return_if_fail (NM_IS_SESSION_MANAGER (self)); + g_return_if_fail (session_id != NULL); + g_return_if_fail (callback != NULL); + + cb_info = callback_info_new (callback, user_data); + + get_session_internal (self, session_id, cb_info); +} + +/**** get_sessions stuff *****************************************************/ + +static void +prepend_slist (gpointer key, gpointer value, gpointer user_data) +{ + GSList **sessions = (GSList **) user_data; + + *sessions = g_slist_prepend (*sessions, value); +} + +GSList * +nm_session_manager_get_sessions (NMSessionManager *self) +{ + NMSessionManagerPrivate *priv; + GSList *sessions; + + g_return_val_if_fail (NM_IS_SESSION_MANAGER (self), NULL); + + priv = NM_SESSION_MANAGER_GET_PRIVATE (self); + g_hash_table_foreach (priv->sessions, prepend_slist, &sessions); + + return sessions; +} + +/**** ConsoleKit signal handling *********************************************/ + +/* ConsoleKit reports a new session. Pull it into our cache. */ +static void +session_added (NMSessionManager *self, char *new_session) +{ + nm_session_manager_get_session (self, new_session, NULL, NULL); +} + +/* ConsoleKit reports that a session has been removed. */ +static void +session_removed (NMSessionManager *self, char *removed_id) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); + NMSessionInfo *removed = g_hash_table_lookup (priv->sessions, removed_id); + + if (removed) { + g_signal_emit_by_name (removed, NM_SESSION_INFO_REMOVED); + g_hash_table_remove (priv->sessions, removed_id); + } else { + PendingSessionInfo *removed_pending = pending_session_find (self, removed_id); + if (removed_pending) { + GError *error = g_error_new (NM_SESSION_MANAGER_ERROR, + NM_SESSION_MANAGER_ERROR_NOT_FOUND, + "session %s removed moments ago", + removed_id); + pending_session_cancel (removed_pending, error); + g_error_free (error); + } + } +} + +/* A DBus signal filter for picking up ConsoleKit signals indicating that + * sessions have been added or removed. We use this custom message filter as + * we'd otherwise have to keep track of all the seats and register signal + * handlers in every one. */ +static DBusHandlerResult +ck_session_signal_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + NMSessionManager *self = NM_SESSION_MANAGER (user_data); + char *session_id; + + // TODO: filter by sender? + + if (dbus_message_is_signal (message, + "org.freedesktop.ConsoleKit.Seat", + "SessionAdded")) { + if (dbus_message_get_args (message, NULL, + DBUS_TYPE_OBJECT_PATH, &session_id, + DBUS_TYPE_INVALID)) { + session_added (self, session_id); + } + } + else + if (dbus_message_is_signal (message, + "org.freedesktop.ConsoleKit.Seat", + "SessionRemoved")) { + if (dbus_message_get_args (message, NULL, + DBUS_TYPE_OBJECT_PATH, &session_id, + DBUS_TYPE_INVALID)) { + session_removed (self, session_id); + } + } + + // If anything else registers message filters for these signals for some + // reason, we want to be sure not to step on them. + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +/**** get_session_of_caller stuff ********************************************/ + +typedef struct { + NMSessionManager *manager; + CallbackInfo *cb_info; + DBusGProxy *bus_proxy; + DBusGProxy *current_call_proxy; + DBusGProxyCall *current_call; + char *caller_bus_name; + char *session_id; +} PendingCallerInfo; + +static void +pending_caller_free (PendingCallerInfo *info) +{ + if (info->bus_proxy) + g_object_unref (info->bus_proxy); + + if (info->caller_bus_name) + g_free (info->caller_bus_name); + + if (info->session_id) + g_free (info->session_id); + + // cb_info gets freed when the callback it wraps is run + + g_slice_free (PendingCallerInfo, info); +} + +static void +pending_caller_dispose (gpointer data) +{ + PendingCallerInfo *info = (PendingCallerInfo *) data; + + if (info->current_call) + dbus_g_proxy_cancel_call (info->current_call_proxy, info->current_call); + + callback_info_fail_disposed (info->cb_info); + pending_caller_free (info); +} + +static void +pending_caller_cb (NMSessionInfo *session, GError *error, gpointer user_data) +{ + PendingCallerInfo *info = (PendingCallerInfo *) user_data; + + if (!session) { + get_session_internal (info->manager, NM_SESSION_INFO_DEFAULT_ID, info->cb_info); + } else { + callback_info_run (info->cb_info, session, error); + } + + pending_caller_free (info); +} + +static void +pending_caller_abort (PendingCallerInfo *info, GError *error) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (info->manager); + + priv->pending_callers = g_slist_remove (priv->pending_callers, info); + pending_caller_cb (NULL, error, info); +} + +static void +dbus_name_has_owner_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + PendingCallerInfo *info = (PendingCallerInfo *) user_data; + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (info->manager); + gboolean has_owner; + + if (!dbus_g_proxy_end_call (proxy, call_id, NULL, + G_TYPE_BOOLEAN, &has_owner, G_TYPE_INVALID) + || !has_owner) { + pending_caller_abort (info, NULL); + return; + } + + info->current_call = NULL; + info->current_call_proxy = NULL; + priv->pending_callers = g_slist_remove (priv->pending_callers, info); + + nm_session_manager_get_session (info->manager, info->session_id, + pending_caller_cb, info); +} + +static void +ck_get_session_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + PendingCallerInfo *info = (PendingCallerInfo *) user_data; + + if (!dbus_g_proxy_end_call (proxy, call_id, NULL, + G_TYPE_STRING, &(info->session_id), + G_TYPE_INVALID)) { + pending_caller_abort (info, NULL); + return; + } + + // Finally, ensure that the calling process is still there, so we are sure + // that the process we've just examined is indeed the calling process. + info->current_call = dbus_g_proxy_begin_call (info->bus_proxy, + "NameHasOwner", + dbus_name_has_owner_cb, + info, + NULL, + G_TYPE_STRING, info->caller_bus_name, + G_TYPE_INVALID); + info->current_call_proxy = info->bus_proxy; +} + +static void +dbus_get_pid_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + PendingCallerInfo *info = (PendingCallerInfo *) user_data; + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (info->manager); + guint pid; + + if (!dbus_g_proxy_end_call (proxy, call_id, NULL, + G_TYPE_UINT, &pid, G_TYPE_INVALID)) { + pending_caller_abort (info, NULL); + return; + } + + info->current_call = dbus_g_proxy_begin_call (priv->ck_manager, + "GetSessionForUnixProcess", + ck_get_session_cb, + info, + NULL, + G_TYPE_UINT, pid, + G_TYPE_INVALID); + info->current_call_proxy = priv->ck_manager; +} + +static void +get_session_of_caller_internal (NMSessionManager *manager, + DBusGMethodInvocation *method_call, + CallbackInfo *cb_info) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (manager); + DBusGConnection *connection; + PendingCallerInfo *info; + + if (priv->disposed) { + callback_info_fail_disposed (cb_info); + return; + } + connection = nm_dbus_manager_get_connection (nm_dbus_manager_get()); + + info = g_slice_new (PendingCallerInfo); + info->manager = manager; + info->cb_info = cb_info; + info->caller_bus_name = dbus_g_method_get_sender (method_call); + info->bus_proxy = dbus_g_proxy_new_for_name (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + + info->current_call = dbus_g_proxy_begin_call (info->bus_proxy, + "GetConnectionUnixProcessID", + dbus_get_pid_cb, + info, + NULL, + G_TYPE_STRING, info->caller_bus_name, + G_TYPE_INVALID); + info->current_call_proxy = info->bus_proxy; + + priv->pending_callers = g_slist_prepend (priv->pending_callers, info); + + g_object_unref (connection); +} + +void +nm_session_manager_get_session_of_caller (NMSessionManager *manager, + DBusGMethodInvocation *method_call, + NMSessionFunc callback, + gpointer user_data) +{ + CallbackInfo *cb_info; + + g_return_if_fail (NM_IS_SESSION_MANAGER (manager)); + g_return_if_fail (method_call != NULL); + + cb_info = callback_info_new (callback, user_data); + + get_session_of_caller_internal (manager, method_call, cb_info); +} + + +/**** Initialization & disposal **********************************************/ + +gboolean +nm_session_manager_is_initalized (NMSessionManager *self) +{ + g_return_val_if_fail (NM_IS_SESSION_MANAGER (self), FALSE); + + return NM_SESSION_MANAGER_GET_PRIVATE (self)->initalized; +} + +typedef struct { + NMSessionManager *manager; + guint sessions_left; +} InitInfo; + +/* Callback run for sessions loaded during initialization. Emits the + * "initialized" signal when all sessions are loaded. */ +static void +init_session_load_cb (NMSessionInfo *session, GError *error, gpointer user_data) +{ + InitInfo *info = (InitInfo *) user_data; + info->sessions_left--; + + if (info->sessions_left == 0) { + NM_SESSION_MANAGER_GET_PRIVATE (info->manager)->initalized = TRUE; + g_signal_emit (info->manager, signals[INIT_DONE], 0); + g_slice_free (InitInfo, info); + } +} + +static void +ck_get_sessions_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSessionManager *manager = NM_SESSION_MANAGER (user_data); + GPtrArray *session_ids; + InitInfo *info; + int i; + + if (!dbus_g_proxy_end_call (proxy, call_id, NULL, + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &session_ids, + G_TYPE_INVALID)) { + g_warning ("NMSessionManager: error getting sessions list!"); + return; + } + + info = g_slice_new (InitInfo); + info->manager = manager; + info->sessions_left = session_ids->len; + + for (i = 0; i < session_ids->len; i++) { + char *session_id = g_ptr_array_index (session_ids, i); + nm_session_manager_get_session (manager, session_id, init_session_load_cb, info); + g_free (session_id); + } + g_ptr_array_free (session_ids, TRUE); +} + +static void +nm_session_manager_init (NMSessionManager *self) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); + NMSessionInfo *default_session; + DBusGConnection *g_connection = nm_dbus_manager_get_connection (nm_dbus_manager_get()); + DBusConnection *connection = dbus_g_connection_get_connection (g_connection); + + priv->disposed = FALSE; + priv->initalized = FALSE; + priv->sessions = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, g_object_unref); + priv->pending_sessions = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, pending_session_destroy); + priv->pending_callers = NULL; + + default_session = NM_SESSION_INFO (g_object_new (NM_TYPE_SESSION_INFO, + NM_SESSION_INFO_IS_DEFAULT, TRUE, + NM_SESSION_INFO_ID, NM_SESSION_INFO_DEFAULT_ID, + NULL)); + g_hash_table_insert (priv->sessions, + NM_SESSION_INFO_DEFAULT_ID, default_session); + + + priv->ck_manager = dbus_g_proxy_new_for_name (g_connection, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager"); + + // Setup a signal handler to catch SessionAdded/Removed signals for *all* + // seats, all in one shot. + dbus_connection_add_filter (connection, + ck_session_signal_filter, + self, + NULL); + dbus_bus_add_match (connection, + "type='signal',sender='org.freedesktop.ConsoleKit'," + "interface='org.freedesktop.ConsoleKit.Seat',member='SessionAdded'", + NULL); + dbus_bus_add_match (connection, + "type='signal',sender='org.freedesktop.ConsoleKit'," + "interface='org.freedesktop.ConsoleKit.Seat',member='SessionRemoved'", + NULL); + + dbus_g_proxy_begin_call (priv->ck_manager, + "GetSessions", + ck_get_sessions_cb, + self, + NULL, + G_TYPE_INVALID); +} + +static void +dispose (GObject *object) +{ + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (object); + DBusConnection *connection = nm_dbus_manager_get_dbus_connection (nm_dbus_manager_get ()); + + if (priv->disposed) + return; + + priv->disposed = TRUE; + + dbus_connection_remove_filter (connection, ck_session_signal_filter, object); + nm_utils_slist_free (priv->pending_callers, pending_caller_dispose); + g_hash_table_unref (priv->pending_sessions); + g_hash_table_unref (priv->sessions); + g_object_unref(priv->ck_manager); + + G_OBJECT_CLASS (nm_session_manager_parent_class)->dispose (object); +} + +static void +nm_session_manager_class_init (NMSessionManagerClass *manager_class) { + GObjectClass *g_class = G_OBJECT_CLASS (manager_class); + g_type_class_add_private (g_class, sizeof(NMSessionManagerPrivate)); + g_class->dispose = dispose; + + signals[ADDED] = + g_signal_new (NM_SESSION_MANAGER_SESSION_ADDED, + NM_TYPE_SESSION_MANAGER, + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, NM_TYPE_SESSION_INFO); + + signals[INIT_DONE] = + g_signal_new (NM_SESSION_MANAGER_INIT_DONE, + NM_TYPE_SESSION_MANAGER, + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +NMSessionManager * +nm_session_manager_get (void) +{ + static NMSessionManager *singleton = NULL; + + if (!singleton) { + singleton = NM_SESSION_MANAGER (g_object_new (NM_TYPE_SESSION_MANAGER, NULL)); + } + + return singleton; +} + +GQuark +nm_session_manager_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) { + ret = g_quark_from_string ("nm-session-manager-error"); + } + + return ret; +} diff --git a/src/system-settings/nm-session-manager.h b/src/system-settings/nm-session-manager.h new file mode 100644 index 000000000..da4ddc006 --- /dev/null +++ b/src/system-settings/nm-session-manager.h @@ -0,0 +1,81 @@ +/* NetworkManager user session tracker + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Daniel Gnoutcheff + */ + +#ifndef NM_SESSION_MANAGER_H +#define NM_SESSION_MANAGER_H + +#include +#include +#include "nm-session-info.h" + +G_BEGIN_DECLS + +#define NM_SESSION_MANAGER_ERROR (nm_session_manager_error_quark()) + +enum { + NM_SESSION_MANAGER_ERROR_NOT_FOUND, + NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, + NM_SESSION_MANAGER_ERROR_DISPOSED +} NMSessionManagerError; + +#define NM_TYPE_SESSION_MANAGER (nm_session_manager_get_type ()) +#define NM_SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SESSION_MANAGER, NMSessionManager)) +#define NM_SESSION_MANAGER_CLASS(class_struct) (G_TYPE_CHECK_CLASS_CAST ((class_struct), NM_TYPE_SESSION_MANAGER, NMSessionManagerClass)) +#define NM_IS_SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SESSION_MANAGER)) +#define NM_IS_SESSION_MANAGER_CLASS(class_struct) (G_TYPE_CHECK_CLASS_TYPE ((class_struct), NM_TYPE_SESSION_MANAGER)) +#define NM_SESSION_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SESSION_MANAGER, NMSessionManagerClass)) + +#define NM_SESSION_MANAGER_SESSION_ADDED "session-added" +#define NM_SESSION_MANAGER_INIT_DONE "init-done" + +typedef struct { + GObject parent; +} NMSessionManager; + +typedef struct { + GObjectClass parent_class; +} NMSessionManagerClass; + +typedef void (*NMSessionFunc) (NMSessionInfo *session, + GError *error, + gpointer user_data); + +NMSessionManager * nm_session_manager_get (void); + +gboolean nm_session_manager_is_initalized (NMSessionManager *manager); + +GSList * nm_session_manager_get_sessions (NMSessionManager *manager); + +void nm_session_manager_get_session (NMSessionManager *manager, + char *session_id, + NMSessionFunc callback, + gpointer user_data); + +void nm_session_manager_get_session_of_caller (NMSessionManager *manager, + DBusGMethodInvocation *method_call, + NMSessionFunc callback, + gpointer user_data); + +GType nm_session_manager_get_type (void); + +GQuark nm_session_manager_error_quark (void); + +G_END_DECLS + +#endif From 6ebc201636769cbdecffceab613d3f91f426be09 Mon Sep 17 00:00:00 2001 From: Daniel Gnoutcheff Date: Sun, 15 Aug 2010 03:25:58 -0400 Subject: [PATCH 024/264] WIP: NMSysconfig: enforce access controls --- introspection/nm-sysconfig-connection.xml | 9 +- src/system-settings/nm-sysconfig-connection.c | 762 ++++++++++++------ src/system-settings/nm-sysconfig-connection.h | 11 + src/system-settings/nm-sysconfig-settings.c | 71 +- 4 files changed, 562 insertions(+), 291 deletions(-) diff --git a/introspection/nm-sysconfig-connection.xml b/introspection/nm-sysconfig-connection.xml index 9df94af49..427213269 100644 --- a/introspection/nm-sysconfig-connection.xml +++ b/introspection/nm-sysconfig-connection.xml @@ -33,6 +33,7 @@ Get the settings maps describing this object. + The nested settings maps describing this object. @@ -53,7 +54,13 @@ - Emitted when this connection has been deleted/removed. After receipt of this signal, the object no longer exists. + Emitted when this connection is no longer available. This happens when the connection is deleted or if it is no longer accessable by any of the system's logged in users. After receipt of this signal, the object no longer exists. + + + + + + Emitted when a client's permission to access this connection may have changed. Generally, clients should re-test their ability to access this connecton whenever this signal is emmited. diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 7de46866a..e5fa90fe9 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -22,16 +22,18 @@ #include #include #include +#include #include "nm-sysconfig-connection.h" +#include "nm-session-manager.h" +#include "nm-dbus-manager.h" #include "nm-system-config-error.h" #include "nm-dbus-glib-types.h" #include "nm-polkit-helpers.h" #include "nm-logging.h" -static gboolean impl_sysconfig_connection_get_settings (NMSysconfigConnection *connection, - GHashTable **settings, - GError **error); +static void impl_sysconfig_connection_get_settings (NMSysconfigConnection *connection, + DBusGMethodInvocation *context); static void impl_sysconfig_connection_update (NMSysconfigConnection *connection, GHashTable *new_settings, @@ -56,7 +58,10 @@ G_DEFINE_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_CONNECTIO enum { UPDATED, + CHECK_PERMISSIONS, REMOVED, + PURGED, + UNHIDDEN, LAST_SIGNAL }; @@ -64,12 +69,220 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { PolkitAuthority *authority; - GSList *pk_calls; + GSList *pending_auths; /* List of PendingAuth structs*/ NMConnection *secrets; + gboolean visible; /* Is this connection is visible by some session? */ + GHashTable *access_list; /* Sessions that may access this connection. */ } NMSysconfigConnectionPrivate; /**************************************************************/ +/* Returns true iff the given session should be permitted to access this + * connection. Used to update the access list */ +static gboolean +session_allowed (NMSysconfigConnection *connection, + NMSessionInfo *session) +{ + NMSettingConnection *setting_connection = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + GSList *permissions_entries; + char *session_user; + GSList *session_groups; + GSList *p_iter; + gboolean allowed = FALSE; + + g_object_get (setting_connection, NM_SETTING_CONNECTION_PERMISSIONS, &permissions_entries, NULL); + + /* If permissions list is empty, the connection is world-accessible. */ + if (permissions_entries == NULL) { + allowed = TRUE; + goto out; + } + + /* The "default session" can only access world-accessible connections. */ + if (nm_session_info_is_default_session (session)) { + allowed = FALSE; + goto out; + } + + session_user = nm_session_info_get_unix_user (session); + session_groups = nm_session_info_get_unix_groups (session); + + for (p_iter = permissions_entries; p_iter != NULL; p_iter = p_iter->next) { + char **p_comps = g_strsplit ((char *)p_iter->data, ":", 3); + char *type = p_comps[0]; + char *name = p_comps[1]; + + if (g_str_equal (type, "user")) { + if (g_str_equal (session_user, name)) { + allowed = TRUE; + goto out; + } + } + else if (g_str_equal (type, "group")) { + GSList *g_iter; + + for (g_iter = session_groups; g_iter != NULL; g_iter = g_iter->next ) { + char *group_name = (char *) g_iter->data; + if (g_str_equal (group_name, name)) { + allowed = TRUE; + goto out; + } + } + } + else { + nm_log_err (LOGD_SYS_SET, + "connection %s: failed to parse permissions entry '%s'", + nm_setting_connection_get_id (setting_connection), + (char *) p_iter->data); + } + } + +out: + nm_utils_slist_free (permissions_entries, g_free); + return allowed; +} + +static void +set_visibility (NMSysconfigConnection *self, gboolean new_visibility) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + DBusGConnection *connection = nm_dbus_manager_get_connection (nm_dbus_manager_get()); + const char *dbus_path = nm_connection_get_path (NM_CONNECTION (self)); + + if (new_visibility && !priv->visible) { + priv->visible = TRUE; + + dbus_g_connection_register_g_object (connection, dbus_path, G_OBJECT (self)); + g_signal_emit (self, signals[UNHIDDEN], 0); + } + else + if (!new_visibility && priv->visible) { + priv->visible = FALSE; + + g_signal_emit (self, signals[REMOVED], 0); + dbus_g_connection_unregister_g_object (connection, G_OBJECT (self)); + } +} + +/* One of the sessions on our access list has been removed. */ +static void +session_removed_cb (NMSessionInfo *removed_session, + gpointer user_data) +{ + NMSysconfigConnection *connection = NM_SYSCONFIG_CONNECTION (user_data); + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + char *removed_session_id = nm_session_info_get_id (removed_session); + + g_hash_table_remove (priv->access_list, removed_session_id); + + if (g_hash_table_size (priv->access_list) == 0) { + set_visibility (connection, FALSE); + } else { + g_signal_emit (connection, signals[CHECK_PERMISSIONS], 0); + } +} + +/* The session manager reports that a new session has been added. */ +static void +session_added_cb (NMSessionManager *mananager, + NMSessionInfo *session, + gpointer user_data) +{ + NMSysconfigConnection *connection = NM_SYSCONFIG_CONNECTION (user_data); + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + + if (session_allowed (connection, session)) { + g_object_ref (session); + g_signal_connect (session, NM_SESSION_INFO_REMOVED, + G_CALLBACK(session_removed_cb), connection); + g_hash_table_insert (priv->access_list, nm_session_info_get_id (session), session); + g_signal_emit (connection, signals[CHECK_PERMISSIONS], 0); + set_visibility (connection, TRUE); + } +} + +/* Our permissions property may have been changed. Update the access list. */ +static void +update_access_list (NMSysconfigConnection *connection) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + NMSessionManager *session_manager = nm_session_manager_get(); + GSList *sessions = nm_session_manager_get_sessions (session_manager); + GSList *iter; + + if (!priv->access_list) + return; + + g_hash_table_remove_all (priv->access_list); + for (iter = sessions; iter != NULL; iter = iter->next) { + NMSessionInfo *session = (NMSessionInfo *) iter->data; + if (session_allowed (connection, iter->data)) { + g_object_ref (session); + g_signal_connect (session, NM_SESSION_INFO_REMOVED, + G_CALLBACK(session_removed_cb), connection); + g_hash_table_insert (priv->access_list, nm_session_info_get_id (session), session); + } + } + + if (g_hash_table_size (priv->access_list) == 0) { + set_visibility (connection, FALSE); + } else { + g_signal_emit (connection, signals[CHECK_PERMISSIONS], 0); + } +} + +gboolean +nm_sysconfig_connection_is_visible (NMSysconfigConnection *connection) +{ + g_return_val_if_fail (NM_SYSCONFIG_CONNECTION (connection), FALSE); + + return NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection)->visible; +} + +static void +prepend_slist (gpointer key, gpointer value, gpointer user_data) +{ + GSList **sessions = (GSList **) user_data; + + *sessions = g_slist_prepend (*sessions, value); +} + +GSList * +nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *connection) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + GSList *sessions = NULL; + + if (priv->access_list) + g_hash_table_foreach (priv->access_list, prepend_slist, &sessions); + + return sessions; +} + +gboolean +nm_sysconfig_connection_is_accessible_by_session (NMSysconfigConnection *connection, + NMSessionInfo *session) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + NMSessionInfo *stored_session = NULL; + + g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), FALSE); + g_return_val_if_fail (NM_IS_SESSION_INFO (session), FALSE); + + if (!priv->access_list) + return FALSE; + + stored_session = g_hash_table_lookup (priv->access_list, + nm_session_info_get_id (session)); + + if (stored_session == session) + return TRUE; + + return FALSE; +} + +/**************************************************************/ + /* Update the settings of this connection to match that of 'new', taking care to * make a private copy of secrets. */ gboolean @@ -98,6 +311,8 @@ nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, g_object_unref (priv->secrets); priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + update_access_list (self); + success = TRUE; } g_hash_table_destroy (new_settings); @@ -254,7 +469,8 @@ do_delete (NMSysconfigConnection *connection, gpointer user_data) { g_object_ref (connection); - g_signal_emit (connection, signals[REMOVED], 0); + set_visibility (connection, FALSE); + g_signal_emit (connection, signals[PURGED], 0); callback (connection, NULL, user_data); g_object_unref (connection); } @@ -388,28 +604,158 @@ get_secrets (NMSysconfigConnection *connection, g_hash_table_destroy (settings); } -/**************************************************************/ +/**** User authorization **************************************/ -static gboolean -impl_sysconfig_connection_get_settings (NMSysconfigConnection *self, - GHashTable **settings, - GError **error) +typedef void (*AuthCallback) (NMSysconfigConnection *connection, + DBusGMethodInvocation *context, + GError *error, + gpointer data); + +typedef struct { + NMSysconfigConnection *self; + DBusGMethodInvocation *context; + PolkitSubject *subject; + GCancellable *cancellable; + gboolean check_modify; + gboolean disposed; + + AuthCallback callback; + gpointer callback_data; +} PendingAuth; + +static void +auth_finish (PendingAuth *info, GError *error) { - NMConnection *no_secrets; + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); + priv->pending_auths = g_slist_remove (priv->pending_auths, info); - /* Secrets should *never* be returned by the GetSettings method, they - * get returned by the GetSecrets method which can be better - * protected against leakage of secrets to unprivileged callers. - */ - no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); - g_assert (no_secrets); - nm_connection_clear_secrets (no_secrets); - *settings = nm_connection_to_hash (no_secrets); - g_assert (*settings); - g_object_unref (no_secrets); - return *settings ? TRUE : FALSE; + info->callback (info->self, info->context, error, info->callback_data); + + if (info->subject) + g_object_unref (info->subject); + if (info->cancellable) + g_object_unref (info->cancellable); + + g_slice_free (PendingAuth, info); } +static void +auth_pk_cb (GObject *object, GAsyncResult *result, gpointer user_data) +{ + PendingAuth *info = user_data; + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); + PolkitAuthorizationResult *pk_result; + GError *error = NULL; + + if (info->disposed) { + error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "Request was canceled."); + auth_finish (info, error); + g_error_free (error); + return; + } + + pk_result = polkit_authority_check_authorization_finish (priv->authority, + result, + &error); + + if (error) { + auth_finish (info, error); + g_error_free (error); + return; + } + + if (!polkit_authorization_result_get_is_authorized (pk_result)) { + error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + "Insufficient privileges."); + auth_finish (info, error); + g_error_free (error); + goto out; + } + + auth_finish (info, NULL); + +out: + g_object_unref (pk_result); +} + +static void +auth_get_session_cb (NMSessionInfo *session, + GError *session_error, + gpointer user_data) +{ + PendingAuth *info = user_data; + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); + GError *error = NULL; + + if (info->disposed || !session) { + error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "Request was canceled."); + auth_finish (info, error); + g_error_free (error); + return; + } + + if (!nm_sysconfig_connection_is_accessible_by_session (info->self, session)) { + error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + "Caller's session is not authorized to access connection."); + auth_finish (info, error); + g_error_free (error); + return; + } + + if (!info->check_modify) { + auth_finish (info, NULL); + } else { + char *sender = dbus_g_method_get_sender (info->context); + info->subject = polkit_system_bus_name_new (sender); + info->cancellable = g_cancellable_new(); + g_free (sender); + + polkit_authority_check_authorization (priv->authority, + info->subject, + NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, + NULL, + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, + info->cancellable, + auth_pk_cb, + info); + } + +} + +static void +auth_start (NMSysconfigConnection *self, + DBusGMethodInvocation *context, + gboolean check_modify, + AuthCallback callback, + gpointer callback_data) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + PendingAuth *info = g_slice_new (PendingAuth); + info->self = self; + info->context = context; + info->subject = NULL; + info->cancellable = NULL; + info->check_modify = check_modify; + info->disposed = FALSE; + info->callback_data = callback_data; + + priv->pending_auths = g_slist_prepend (priv->pending_auths, info); + + nm_session_manager_get_session_of_caller (nm_session_manager_get(), + context, + auth_get_session_cb, + info); + +} + +/**** DBus method handlers ************************************/ + static gboolean check_writable (NMConnection *connection, GError **error) { @@ -443,65 +789,41 @@ check_writable (NMConnection *connection, GError **error) return TRUE; } -typedef struct { - NMSysconfigConnection *self; - DBusGMethodInvocation *context; - PolkitSubject *subject; - GCancellable *cancellable; - gboolean disposed; - - /* Update */ - NMConnection *connection; - - /* Secrets */ - char *setting_name; - char **hints; - gboolean request_new; -} PolkitCall; - -static PolkitCall * -polkit_call_new (NMSysconfigConnection *self, - DBusGMethodInvocation *context, - NMConnection *connection, - const char *setting_name, - const char **hints, - gboolean request_new) +static void +get_settings_auth_cb (NMSysconfigConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer data) { - PolkitCall *call; - char *sender; + NMConnection *no_secrets; + GHashTable *settings; - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (context != NULL, NULL); + if (error) { + dbus_g_method_return_error (context, error); + return; + } - call = g_malloc0 (sizeof (PolkitCall)); - call->self = self; - call->context = context; - call->cancellable = g_cancellable_new (); - call->connection = connection; - call->setting_name = g_strdup (setting_name); - if (hints) - call->hints = g_strdupv ((char **) hints); - call->request_new = request_new; + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); + g_assert (no_secrets); + nm_connection_clear_secrets (no_secrets); + settings = nm_connection_to_hash (no_secrets); + g_assert (settings); - sender = dbus_g_method_get_sender (context); - call->subject = polkit_system_bus_name_new (sender); - g_free (sender); - - return call; + dbus_g_method_return (context, settings); + + g_object_unref (no_secrets); + g_object_unref (settings); } static void -polkit_call_free (PolkitCall *call) +impl_sysconfig_connection_get_settings (NMSysconfigConnection *self, + DBusGMethodInvocation *context) { - if (call->connection) - g_object_unref (call->connection); - g_free (call->setting_name); - if (call->hints) - g_strfreev (call->hints); - - g_object_unref (call->subject); - g_object_unref (call->cancellable); - g_free (call); + auth_start (self, context, FALSE, get_settings_auth_cb, NULL); } static void @@ -509,70 +831,35 @@ con_update_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { - PolkitCall *call = user_data; + DBusGMethodInvocation *context = user_data; if (error) - dbus_g_method_return_error (call->context, error); + dbus_g_method_return_error (context, error); else - dbus_g_method_return (call->context); - - polkit_call_free (call); + dbus_g_method_return (context); } static void -pk_update_cb (GObject *object, GAsyncResult *result, gpointer user_data) +update_auth_cb (NMSysconfigConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer data) { - PolkitCall *call = user_data; - NMSysconfigConnection *self = call->self; - NMSysconfigConnectionPrivate *priv; - PolkitAuthorizationResult *pk_result; - GError *error = NULL; + NMConnection *new_settings = data; - /* If our NMSysconfigConnection is already gone, do nothing */ - if (call->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; - } - - priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - - priv->pk_calls = g_slist_remove (priv->pk_calls, call); - - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - /* Some random error happened */ if (error) { - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; - } - - /* Caller didn't successfully authenticate */ - if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - "Insufficient privileges."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); + dbus_g_method_return_error (context, error); goto out; } /* Update and commit our settings. */ nm_sysconfig_connection_replace_and_commit (self, - call->connection, + new_settings, con_update_cb, - call); + context); out: - g_object_unref (pk_result); + g_object_unref (new_settings); } static void @@ -580,8 +867,6 @@ impl_sysconfig_connection_update (NMSysconfigConnection *self, GHashTable *new_settings, DBusGMethodInvocation *context) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - PolkitCall *call; NMConnection *tmp; GError *error = NULL; @@ -604,17 +889,7 @@ impl_sysconfig_connection_update (NMSysconfigConnection *self, return; } - call = polkit_call_new (self, context, tmp, NULL, NULL, FALSE); - g_assert (call); - polkit_authority_check_authorization (priv->authority, - call->subject, - NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - call->cancellable, - pk_update_cb, - call); - priv->pk_calls = g_slist_prepend (priv->pk_calls, call); + auth_start (self, context, TRUE, update_auth_cb, tmp); } static void @@ -622,75 +897,32 @@ con_delete_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { - PolkitCall *call = user_data; + DBusGMethodInvocation *context = user_data; if (error) - dbus_g_method_return_error (call->context, error); + dbus_g_method_return_error (context, error); else - dbus_g_method_return (call->context); - - polkit_call_free (call); + dbus_g_method_return (context); } static void -pk_delete_cb (GObject *object, GAsyncResult *result, gpointer user_data) +delete_auth_cb (NMSysconfigConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer data) { - PolkitCall *call = user_data; - NMSysconfigConnection *self = call->self; - NMSysconfigConnectionPrivate *priv; - PolkitAuthorizationResult *pk_result; - GError *error = NULL; - - /* If our NMSysconfigConnection is already gone, do nothing */ - if (call->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; - } - - priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - - priv->pk_calls = g_slist_remove (priv->pk_calls, call); - - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - /* Some random error happened */ if (error) { - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); + dbus_g_method_return_error (context, error); return; } - /* Caller didn't successfully authenticate */ - if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - "Insufficient privileges."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - goto out; - } - - /* Caller is authenticated, now we can finally try to delete */ - nm_sysconfig_connection_delete (self, con_delete_cb, call); - -out: - g_object_unref (pk_result); + nm_sysconfig_connection_delete (self, con_delete_cb, context); } static void impl_sysconfig_connection_delete (NMSysconfigConnection *self, DBusGMethodInvocation *context) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - PolkitCall *call; GError *error = NULL; if (!check_writable (NM_CONNECTION (self), &error)) { @@ -699,91 +931,53 @@ impl_sysconfig_connection_delete (NMSysconfigConnection *self, return; } - call = polkit_call_new (self, context, NULL, NULL, NULL, FALSE); - g_assert (call); - polkit_authority_check_authorization (priv->authority, - call->subject, - NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - call->cancellable, - pk_delete_cb, - call); - priv->pk_calls = g_slist_prepend (priv->pk_calls, call); + auth_start (self, context, TRUE, delete_auth_cb, NULL); } +typedef struct { + char *setting_name; + char **hints; + gboolean request_new; +} GetSecretsInfo; + static void con_secrets_cb (NMSysconfigConnection *connection, GHashTable *secrets, GError *error, gpointer user_data) { - PolkitCall *call = user_data; + DBusGMethodInvocation *context = user_data; if (error) - dbus_g_method_return_error (call->context, error); + dbus_g_method_return_error (context, error); else - dbus_g_method_return (call->context, secrets); - - polkit_call_free (call); + dbus_g_method_return (context, secrets); } static void -pk_secrets_cb (GObject *object, GAsyncResult *result, gpointer user_data) +secrets_auth_cb (NMSysconfigConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer data) { - PolkitCall *call = user_data; - NMSysconfigConnection *self = call->self; - NMSysconfigConnectionPrivate *priv; - PolkitAuthorizationResult *pk_result; - GError *error = NULL; + GetSecretsInfo *info = data; - /* If our NMSysconfigConnection is already gone, do nothing */ - if (call->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; - } - - priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - - priv->pk_calls = g_slist_remove (priv->pk_calls, call); - - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - /* Some random error happened */ if (error) { - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; - } - - /* Caller didn't successfully authenticate */ - if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - "Insufficient privileges."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); + dbus_g_method_return_error (context, error); goto out; } - /* Caller is authenticated, now we can finally try to update */ nm_sysconfig_connection_get_secrets (self, - call->setting_name, - (const char **) call->hints, - call->request_new, + info->setting_name, + (const char **) info->hints, + info->request_new, con_secrets_cb, - call); + context); out: - g_object_unref (pk_result); + g_free (info->setting_name); + g_strfreev (info->hints); + g_slice_free (GetSecretsInfo, info); } static void @@ -793,20 +987,12 @@ impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, gboolean request_new, DBusGMethodInvocation *context) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - PolkitCall *call; + GetSecretsInfo *info = g_slice_new (GetSecretsInfo); + info->setting_name = g_strdup (setting_name); + info->hints = g_strdupv ((char **) hints); + info->request_new = request_new; - call = polkit_call_new (self, context, NULL, setting_name, hints, request_new); - g_assert (call); - polkit_authority_check_authorization (priv->authority, - call->subject, - NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - call->cancellable, - pk_secrets_cb, - call); - priv->pk_calls = g_slist_prepend (priv->pk_calls, call); + auth_start (self, context, TRUE, secrets_auth_cb, info); } /**************************************************************/ @@ -815,11 +1001,34 @@ static void nm_sysconfig_connection_init (NMSysconfigConnection *self) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSessionManager *session_manager; + static guint32 dbus_counter = 0; + char *dbus_path; priv->authority = polkit_authority_get (); if (!priv->authority) { - nm_log_err (LOGD_SYS_SET, "%s: error creating PolicyKit authority"); + nm_log_err (LOGD_SYS_SET, "%s:error creating PolicyKit authority"); } + + dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++); + nm_connection_set_path (NM_CONNECTION (self), dbus_path); + g_free (dbus_path); + priv->visible = FALSE; + + priv->access_list = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + session_manager = nm_session_manager_get(); + g_signal_connect (session_manager, NM_SESSION_MANAGER_SESSION_ADDED, + G_CALLBACK (session_added_cb), self); + +} + +static void +access_list_dispose (gpointer key, gpointer value, gpointer user_data) +{ + NMSysconfigConnection *connection = (NMSysconfigConnection *) user_data; + NMSessionInfo *session = (NMSessionInfo *) value; + + g_signal_handlers_disconnect_by_func (session, session_removed_cb, connection); } static void @@ -827,20 +1036,27 @@ dispose (GObject *object) { NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (object); NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSessionManager *session_manager = nm_session_manager_get (); GSList *iter; if (priv->secrets) g_object_unref (priv->secrets); /* Cancel PolicyKit requests */ - for (iter = priv->pk_calls; iter; iter = g_slist_next (iter)) { - PolkitCall *call = iter->data; + for (iter = priv->pending_auths; iter; iter = g_slist_next (iter)) { + PendingAuth *call = iter->data; call->disposed = TRUE; g_cancellable_cancel (call->cancellable); } - g_slist_free (priv->pk_calls); - priv->pk_calls = NULL; + g_slist_free (priv->pending_auths); + priv->pending_auths = NULL; + + set_visibility (self, FALSE); + g_signal_handlers_disconnect_by_func (session_manager, session_added_cb, self); + g_hash_table_foreach (priv->access_list, access_list_dispose, self); + g_hash_table_unref (priv->access_list); + priv->access_list = NULL; G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object); } @@ -877,6 +1093,24 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[PURGED] = + g_signal_new (NM_SYSCONFIG_CONNECTION_PURGED, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[UNHIDDEN] = + g_signal_new (NM_SYSCONFIG_CONNECTION_UNHIDDEN, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_sysconfig_connection_object_info); diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index f2510d288..80e074367 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -23,6 +23,7 @@ #include #include +#include "nm-session-info.h" G_BEGIN_DECLS @@ -35,6 +36,8 @@ G_BEGIN_DECLS #define NM_SYSCONFIG_CONNECTION_UPDATED "updated" #define NM_SYSCONFIG_CONNECTION_REMOVED "removed" +#define NM_SYSCONFIG_CONNECTION_PURGED "purged" +#define NM_SYSCONFIG_CONNECTION_UNHIDDEN "unhidden" typedef struct _NMSysconfigConnection NMSysconfigConnection; @@ -102,6 +105,14 @@ void nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, NMSysconfigConnectionGetSecretsFunc callback, gpointer user_data); +gboolean nm_sysconfig_connection_is_visible (NMSysconfigConnection *connection); + +gboolean nm_sysconfig_connection_is_accessible_by_session (NMSysconfigConnection *connection, + NMSessionInfo *session); + +GSList * nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *connection); + + G_END_DECLS #endif /* NM_SYSCONFIG_CONNECTION_H */ diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 7e1e3f530..7b8ec9057 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -112,7 +112,8 @@ typedef struct { GSList *plugins; gboolean connections_loaded; - GHashTable *connections; + GHashTable *visible_connections; + GHashTable *all_connections; GSList *unmanaged_specs; } NMSysconfigSettingsPrivate; @@ -186,7 +187,7 @@ nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings) load_connections (settings); - g_hash_table_iter_init (&iter, priv->connections); + g_hash_table_iter_init (&iter, priv->visible_connections); while (g_hash_table_iter_next (&iter, &key, NULL)) list = g_slist_prepend (list, NM_SYSCONFIG_CONNECTION (key)); return g_slist_reverse (list); @@ -536,28 +537,28 @@ connection_removed (NMSysconfigConnection *connection, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); - g_hash_table_remove (priv->connections, connection); + g_hash_table_remove (priv->visible_connections, connection); } static void -export_connection (NMSysconfigConnection *connection) +connection_unhidden (NMSysconfigConnection *connection, + gpointer user_data) { - DBusGConnection *bus; - static guint32 ec_counter = 0; - char *path; + NMSysconfigSettings *settings = user_data; + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); - g_return_if_fail (connection != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_hash_table_insert (priv->visible_connections, + connection, GINT_TO_POINTER (1)); + g_signal_emit (settings, signals[NEW_CONNECTION], 0, connection); +} - /* Don't allow exporting twice */ - g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); +static void +connection_purged (NMSysconfigConnection *connection, + gpointer user_data) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); - path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); - nm_connection_set_path (NM_CONNECTION (connection), path); - - bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - dbus_g_connection_register_g_object (bus, path, G_OBJECT (connection)); - g_free (path); + g_hash_table_remove (priv->all_connections, connection); } static void @@ -570,22 +571,33 @@ claim_connection (NMSysconfigSettings *self, g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); - if (g_hash_table_lookup (priv->connections, connection)) + if (g_hash_table_lookup (priv->all_connections, connection)) /* A plugin is lying to us. */ return; - g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); + g_hash_table_insert (priv->all_connections, g_object_ref (connection), GINT_TO_POINTER (1)); g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); + g_signal_connect (connection, + NM_SYSCONFIG_CONNECTION_PURGED, + G_CALLBACK (connection_purged), + self); + g_signal_connect (connection, + NM_SYSCONFIG_CONNECTION_UNHIDDEN, + G_CALLBACK (connection_unhidden), + self); - if (do_export) { - export_connection (connection); + if (nm_sysconfig_connection_is_visible (connection)) { + g_hash_table_insert (priv->visible_connections, connection, GINT_TO_POINTER (1)); g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } } +// TODO it seems that this is only ever used to remove a +// NMDefaultWiredConnection, and it probably needs to stay that way. So this +// *needs* a better name! static void remove_connection (NMSysconfigSettings *self, NMSysconfigConnection *connection, @@ -593,9 +605,14 @@ remove_connection (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - if (g_hash_table_lookup (priv->connections, connection)) { + if (g_hash_table_lookup (priv->visible_connections, connection)) { g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_REMOVED); - g_hash_table_remove (priv->connections, connection); + g_hash_table_remove (priv->visible_connections, connection); + } + + if (g_hash_table_lookup (priv->all_connections, connection)) { + g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_PURGED); + g_hash_table_remove (priv->all_connections, connection); } } @@ -1056,7 +1073,7 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) g_return_val_if_fail (mac != NULL, FALSE); /* Find a wired connection locked to the given MAC address, if any */ - g_hash_table_iter_init (&iter, priv->connections); + g_hash_table_iter_init (&iter, priv->visible_connections); while (g_hash_table_iter_next (&iter, &key, NULL)) { NMConnection *connection = NM_CONNECTION (key); const char *connection_type; @@ -1442,7 +1459,8 @@ finalize (GObject *object) NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - g_hash_table_destroy (priv->connections); + g_hash_table_destroy (priv->visible_connections); + g_hash_table_destroy (priv->all_connections); clear_unmanaged_specs (self); @@ -1584,7 +1602,8 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + priv->visible_connections = g_hash_table_new (g_direct_hash, g_direct_equal); + priv->all_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->authority = polkit_authority_get (); if (priv->authority) { From 3945f75bda13961519f038be47b94f12e23cffc4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 26 Aug 2010 14:26:12 -0500 Subject: [PATCH 025/264] core: consolidate all permissions checking into main D-Bus interface Moves the system settings permissions checking into the core service's permissions checking, which at the same time enables 3-way permission reporting (yes, no, auth) instead of the old yes/no that we had for system settings permissions before. This allows UI to show a lock icon or such when the user could authenticate to gain the permission. It also moves the wifi-create permissions' namespace to the main namespace (not .settings) since they really should be checked before starting a shared wifi connection, rather than having anything to do with the settings service. --- introspection/nm-settings.xml | 37 ---- libnm-glib/nm-client.c | 31 ++- libnm-glib/nm-client.h | 8 +- libnm-glib/nm-remote-settings.c | 101 ---------- libnm-glib/nm-remote-settings.h | 21 -- .../org.freedesktop.NetworkManager.policy.in | 36 ++-- src/nm-manager-auth.h | 14 +- src/nm-manager.c | 8 + src/system-settings/nm-polkit-helpers.h | 5 - src/system-settings/nm-sysconfig-connection.c | 15 +- src/system-settings/nm-sysconfig-settings.c | 184 +----------------- src/system-settings/nm-sysconfig-settings.h | 10 - 12 files changed, 79 insertions(+), 391 deletions(-) diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml index d907cf7bc..f10a6e1c6 100644 --- a/introspection/nm-settings.xml +++ b/introspection/nm-settings.xml @@ -44,19 +44,6 @@ - - - Returns a bitfield indicating certain operations the caller is permitted to perform. Some of these operations may require authorization by the user. - - - - - - A bitfield of permitted operations. Some of these operations may require the user to authorize via password entry or other means. - - - - The machine hostname stored in persistent configuration. @@ -77,12 +64,6 @@ - - - Emitted when system authorization details change, indicating that clients may wish to recheck permissions with GetPermissions. - - - Emitted when a new connection has been added. @@ -94,24 +75,6 @@ - - - No permissions. - - - Can modify/add/delete connections. - - - Can share connections via a encrypted user-created WiFi network. - - - Can share connections via a open/unencrypted user-created WiFi network. - - - Can modify the persistent system hostname. - - - diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 88f71af2a..e7770df64 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -290,9 +290,15 @@ register_for_property_changed (NMClient *client) property_changed_info); } -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" +#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" +#define NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY "org.freedesktop.NetworkManager.settings.modify" +#define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" static NMClientPermission nm_permission_to_client (const char *nm) @@ -303,6 +309,19 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI; else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN)) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SLEEP_WAKE)) + return NM_CLIENT_PERMISSION_SLEEP_WAKE; + else if (!strcmp (nm, NM_AUTH_PERMISSION_NETWORK_CONTROL)) + return NM_CLIENT_PERMISSION_NETWORK_CONTROL; + else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED)) + return NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED; + else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN)) + return NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY)) + return NM_CLIENT_PERMISSION_SETTINGS_CONNECTION_MODIFY; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY)) + return NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY; + return NM_CLIENT_PERMISSION_NONE; } @@ -461,9 +480,9 @@ constructor (GType type, get_permissions_sync (NM_CLIENT (object)); priv->bus_proxy = dbus_g_proxy_new_for_name (connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); dbus_g_proxy_add_signal (priv->bus_proxy, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index e86316116..69847fdcc 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -56,8 +56,14 @@ typedef enum { NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK = 1, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, + NM_CLIENT_PERMISSION_SLEEP_WAKE = 4, + NM_CLIENT_PERMISSION_NETWORK_CONTROL = 5, + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 6, + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 7, + NM_CLIENT_PERMISSION_SETTINGS_CONNECTION_MODIFY = 8, + NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY = 9, - NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN + NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY } NMClientPermission; typedef enum { diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index eb3288d11..f263df29f 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -44,8 +44,6 @@ typedef struct { gboolean service_running; DBusGProxy *props_proxy; - NMSettingsPermissions permissions; - gboolean have_permissions; char *hostname; gboolean can_modify; @@ -70,7 +68,6 @@ enum { enum { NEW_CONNECTION, CONNECTIONS_READ, - CHECK_PERMISSIONS, LAST_SIGNAL }; @@ -412,77 +409,6 @@ nm_remote_settings_save_hostname (NMRemoteSettings *settings, return TRUE; } -typedef struct { - NMRemoteSettings *settings; - NMRemoteSettingsGetPermissionsFunc callback; - gpointer callback_data; -} GetPermissionsInfo; - -static void -get_permissions_cb (DBusGProxy *proxy, - DBusGProxyCall *call, - gpointer user_data) -{ - GetPermissionsInfo *info = user_data; - NMRemoteSettings *self = NM_REMOTE_SETTINGS (info->settings); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - NMSettingsPermissions permissions = NM_SETTINGS_PERMISSION_NONE; - GError *error = NULL; - - dbus_g_proxy_end_call (proxy, call, &error, - G_TYPE_UINT, &permissions, - G_TYPE_INVALID); - priv->permissions = permissions; - priv->have_permissions = !error; - info->callback (info->settings, permissions, error, info->callback_data); - g_clear_error (&error); -} - -/** - * nm_remote_settings_get_permissions: - * @settings: the %NMRemoteSettings - * @callback: callback to be called when the permissions operation completes - * @user_data: caller-specific data passed to @callback - * - * Requests an indication of the operations the caller is permitted to perform - * including those that may require authorization. - * - * Returns: TRUE if the request was successful, FALSE if it failed - **/ -gboolean -nm_remote_settings_get_permissions (NMRemoteSettings *settings, - NMRemoteSettingsGetPermissionsFunc callback, - gpointer user_data) -{ - NMRemoteSettingsPrivate *priv; - GetPermissionsInfo *info; - - g_return_val_if_fail (settings != NULL, FALSE); - g_return_val_if_fail (NM_IS_REMOTE_SETTINGS (settings), FALSE); - g_return_val_if_fail (callback != NULL, FALSE); - - priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings); - - /* Skip D-Bus if we already have permissions */ - if (priv->have_permissions) { - callback (settings, priv->permissions, NULL, user_data); - return TRUE; - } - - /* Otherwise fetch them from NM */ - info = g_malloc0 (sizeof (GetPermissionsInfo)); - info->settings = settings; - info->callback = callback; - info->callback_data = user_data; - - dbus_g_proxy_begin_call (priv->proxy, "GetPermissions", - get_permissions_cb, - info, - g_free, - G_TYPE_INVALID); - return TRUE; -} - static void name_owner_changed (DBusGProxy *proxy, const char *name, @@ -509,17 +435,6 @@ name_owner_changed (DBusGProxy *proxy, } } -static void -check_permissions_cb (DBusGProxy *proxy, gpointer user_data) -{ - NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - - /* Permissions need to be re-fetched */ - priv->have_permissions = FALSE; - g_signal_emit (self, signals[CHECK_PERMISSIONS], 0); -} - static void properties_changed_cb (DBusGProxy *proxy, GHashTable *properties, @@ -690,13 +605,6 @@ constructor (GType type, object, NULL); - /* Monitor for permissions changes */ - dbus_g_proxy_add_signal (priv->proxy, "CheckPermissions", G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->proxy, "CheckPermissions", - G_CALLBACK (check_permissions_cb), - object, - NULL); - /* Get properties */ dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", get_all_cb, @@ -843,14 +751,5 @@ nm_remote_settings_class_init (NMRemoteSettingsClass *class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - - signals[CHECK_PERMISSIONS] = - g_signal_new (NM_REMOTE_SETTINGS_CHECK_PERMISSIONS, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMRemoteSettingsClass, check_permissions), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); } diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index 77b172c12..a1d3cee83 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -31,15 +31,6 @@ G_BEGIN_DECLS -// FIXME this is temporary, permissions format to be improved -typedef enum { - NM_SETTINGS_PERMISSION_NONE = 0x0, - NM_SETTINGS_PERMISSION_CONNECTION_MODIFY = 0x1, - NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, - NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN = 0x4, - NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY = 0x8 -} NMSettingsPermissions; - #define NM_TYPE_REMOTE_SETTINGS (nm_remote_settings_get_type ()) #define NM_REMOTE_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettings)) #define NM_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) @@ -54,7 +45,6 @@ typedef enum { #define NM_REMOTE_SETTINGS_NEW_CONNECTION "new-connection" #define NM_REMOTE_SETTINGS_CONNECTIONS_READ "connections-read" -#define NM_REMOTE_SETTINGS_CHECK_PERMISSIONS "check-permissions" typedef struct _NMRemoteSettings NMRemoteSettings; typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass; @@ -68,11 +58,6 @@ typedef void (*NMRemoteSettingsSaveHostnameFunc) (NMRemoteSettings *settings, GError *error, gpointer user_data); -typedef void (*NMRemoteSettingsGetPermissionsFunc) (NMRemoteSettings *settings, - NMSettingsPermissions permissions, - GError *error, - gpointer user_data); - struct _NMRemoteSettings { GObject parent; @@ -87,8 +72,6 @@ struct _NMRemoteSettingsClass { void (*connections_read) (NMRemoteSettings *settings); - void (*check_permissions) (NMRemoteSettings *settings); - /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -117,10 +100,6 @@ gboolean nm_remote_settings_save_hostname (NMRemoteSettings *settings, NMRemoteSettingsSaveHostnameFunc callback, gpointer user_data); -gboolean nm_remote_settings_get_permissions (NMRemoteSettings *settings, - NMRemoteSettingsGetPermissionsFunc callback, - gpointer user_data); - G_END_DECLS #endif /* NM_REMOTE_SETTINGS_H */ diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index 32b8ab00b..af4b9a15b 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -54,6 +54,24 @@ + + <_description>Connection sharing via a protected WiFi network + <_message>System policy prevents sharing connections via a protected WiFi network + + no + yes + + + + + <_description>Connection sharing via an open WiFi network + <_message>System policy prevents sharing connections via an open WiFi network + + no + yes + + + <_description>Modify system connections <_message>System policy prevents modification of system settings @@ -72,23 +90,5 @@ - - <_description>Connection sharing via a protected WiFi network - <_message>System policy prevents sharing connections via a protected WiFi network - - no - yes - - - - - <_description>Connection sharing via an open WiFi network - <_message>System policy prevents sharing connections via an open WiFi network - - no - yes - - - diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 13489f39d..9fae64c5f 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -27,11 +27,15 @@ #include "nm-dbus-manager.h" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" -#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" -#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" -#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" +#define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" +#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" +#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" +#define NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY "org.freedesktop.NetworkManager.settings.modify" +#define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" typedef struct NMAuthChain NMAuthChain; diff --git a/src/nm-manager.c b/src/nm-manager.c index 5cef1fe6f..2368eeef0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2735,6 +2735,10 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_NETWORK_CONTROL); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); dbus_g_method_return (context, results); g_hash_table_destroy (results); } @@ -2761,6 +2765,10 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, FALSE); } /* Legacy 0.6 compatibility interface */ diff --git a/src/system-settings/nm-polkit-helpers.h b/src/system-settings/nm-polkit-helpers.h index 48841486c..dfe9ecefc 100644 --- a/src/system-settings/nm-polkit-helpers.h +++ b/src/system-settings/nm-polkit-helpers.h @@ -25,11 +25,6 @@ #include #include -#define NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY "org.freedesktop.NetworkManager.settings.modify" -#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.settings.wifi.share.protected" -#define NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.settings.wifi.share.open" -#define NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" - /* Fix for polkit 0.97 and later */ #if !HAVE_POLKIT_AUTHORITY_GET_SYNC static inline PolkitAuthority * diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 62e776ee1..b42c8e3ec 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -31,6 +31,7 @@ #include "nm-dbus-glib-types.h" #include "nm-polkit-helpers.h" #include "nm-logging.h" +#include "nm-manager-auth.h" static void impl_sysconfig_connection_get_settings (NMSysconfigConnection *connection, DBusGMethodInvocation *context); @@ -717,13 +718,13 @@ auth_get_session_cb (NMSessionInfo *session, g_free (sender); polkit_authority_check_authorization (priv->authority, - info->subject, - NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - info->cancellable, - auth_pk_cb, - info); + info->subject, + NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, + NULL, + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, + info->cancellable, + auth_pk_cb, + info); } } diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 67355258d..197c01584 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -59,6 +59,7 @@ #include "nm-default-wired-connection.h" #include "nm-logging.h" #include "nm-dbus-manager.h" +#include "nm-manager-auth.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -92,9 +93,6 @@ static void impl_settings_save_hostname (NMSysconfigSettings *self, const char *hostname, DBusGMethodInvocation *context); -static void impl_settings_get_permissions (NMSysconfigSettings *self, - DBusGMethodInvocation *context); - #include "nm-settings-glue.h" static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); @@ -108,7 +106,6 @@ typedef struct { char *config_file; GSList *pk_calls; - GSList *permissions_calls; GSList *plugins; gboolean connections_loaded; @@ -124,7 +121,6 @@ G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT) enum { PROPERTIES_CHANGED, NEW_CONNECTION, - CHECK_PERMISSIONS, LAST_SIGNAL }; @@ -627,9 +623,6 @@ typedef struct { gpointer callback_data; char *hostname; - - NMSettingsPermissions permissions; - guint32 permissions_calls; } PolkitCall; #include "nm-dbus-manager.h" @@ -799,7 +792,7 @@ impl_settings_add_connection (NMSysconfigSettings *self, g_assert (call); polkit_authority_check_authorization (priv->authority, call->subject, - NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, + NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, call->cancellable, @@ -904,7 +897,7 @@ impl_settings_save_hostname (NMSysconfigSettings *self, g_assert (call); polkit_authority_check_authorization (priv->authority, call->subject, - NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY, + NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, NULL, POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, call->cancellable, @@ -913,151 +906,6 @@ impl_settings_save_hostname (NMSysconfigSettings *self, priv->pk_calls = g_slist_append (priv->pk_calls, call); } -static void -pk_authority_changed_cb (GObject *object, gpointer user_data) -{ - /* Let clients know they should re-check their authorization */ - g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), signals[CHECK_PERMISSIONS], 0); -} - -typedef struct { - PolkitCall *pk_call; - const char *pk_action; - GCancellable *cancellable; - NMSettingsPermissions permission; - gboolean disposed; -} PermissionsCall; - -static void -permission_call_done (GObject *object, GAsyncResult *result, gpointer user_data) -{ - PermissionsCall *call = user_data; - PolkitCall *pk_call = call->pk_call; - NMSysconfigSettings *self = pk_call->self; - NMSysconfigSettingsPrivate *priv; - PolkitAuthorizationResult *pk_result; - GError *error = NULL; - - /* If NMSysconfigSettings is gone, just skip to the end */ - if (call->disposed) - goto done; - - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - priv->permissions_calls = g_slist_remove (priv->permissions_calls, call); - - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - /* Some random error happened */ - if (error) { - nm_log_err (LOGD_SYS_SET, "error checking '%s' permission: (%d) %s", - __FILE__, __LINE__, __func__, - call->pk_action, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - if (error) - g_error_free (error); - } else { - /* If the caller is authorized, or the caller could authorize via a - * challenge, then authorization is possible. Otherwise, caller is out of - * luck. - */ - if ( polkit_authorization_result_get_is_authorized (pk_result) - || polkit_authorization_result_get_is_challenge (pk_result)) - pk_call->permissions |= call->permission; - } - - g_object_unref (pk_result); - -done: - pk_call->permissions_calls--; - if (pk_call->permissions_calls == 0) { - if (call->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - dbus_g_method_return_error (pk_call->context, error); - g_error_free (error); - } else { - /* All the permissions calls are done, return the full permissions - * bitfield back to the user. - */ - dbus_g_method_return (pk_call->context, pk_call->permissions); - } - - polkit_call_free (pk_call); - } - memset (call, 0, sizeof (PermissionsCall)); - g_free (call); -} - -static void -start_permission_check (NMSysconfigSettings *self, - PolkitCall *pk_call, - const char *pk_action, - NMSettingsPermissions permission) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - PermissionsCall *call; - - g_return_if_fail (pk_call != NULL); - g_return_if_fail (pk_action != NULL); - g_return_if_fail (permission != NM_SETTINGS_PERMISSION_NONE); - - call = g_malloc0 (sizeof (PermissionsCall)); - call->pk_call = pk_call; - call->pk_action = pk_action; - call->permission = permission; - call->cancellable = g_cancellable_new (); - - pk_call->permissions_calls++; - - polkit_authority_check_authorization (priv->authority, - pk_call->subject, - pk_action, - NULL, - 0, - call->cancellable, - permission_call_done, - call); - priv->permissions_calls = g_slist_append (priv->permissions_calls, call); -} - -static void -impl_settings_get_permissions (NMSysconfigSettings *self, - DBusGMethodInvocation *context) -{ - PolkitCall *call; - - call = polkit_call_new (self, context, NULL, FALSE); - g_assert (call); - - /* Start checks for the various permissions */ - - /* Only check for connection-modify if one of our plugins supports it. */ - if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { - start_permission_check (self, call, - NM_SYSCONFIG_POLICY_ACTION_CONNECTION_MODIFY, - NM_SETTINGS_PERMISSION_CONNECTION_MODIFY); - } - - /* Only check for hostname-modify if one of our plugins supports it. */ - if (get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { - start_permission_check (self, call, - NM_SYSCONFIG_POLICY_ACTION_HOSTNAME_MODIFY, - NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY); - } - - // FIXME: hook these into plugin permissions like the modify permissions */ - start_permission_check (self, call, - NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_OPEN, - NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN); - start_permission_check (self, call, - NM_SYSCONFIG_POLICY_ACTION_WIFI_SHARE_PROTECTED, - NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED); -} - static gboolean have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) { @@ -1440,16 +1288,6 @@ dispose (GObject *object) g_slist_free (priv->pk_calls); priv->pk_calls = NULL; - /* Cancel PolicyKit permissions requests */ - for (iter = priv->permissions_calls; iter; iter = g_slist_next (iter)) { - PermissionsCall *call = iter->data; - - call->disposed = TRUE; - g_cancellable_cancel (call->cancellable); - } - g_slist_free (priv->permissions_calls); - priv->permissions_calls = NULL; - G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); } @@ -1560,15 +1398,6 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); - signals[CHECK_PERMISSIONS] = - g_signal_new (NM_SYSCONFIG_SETTINGS_CHECK_PERMISSIONS, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, NM_TYPE_SYSCONFIG_SETTINGS_ERROR); @@ -1607,12 +1436,7 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) priv->all_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->authority = polkit_authority_get_sync (NULL, &error); - if (priv->authority) { - priv->auth_changed_id = g_signal_connect (priv->authority, - "changed", - G_CALLBACK (pk_authority_changed_cb), - self); - } else { + if (!priv->authority) { nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index 7a7f7db50..d4e58a696 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -32,15 +32,6 @@ #include "nm-system-config-interface.h" #include "nm-device.h" -// FIXME this is temporary, permissions format to be improved -typedef enum { - NM_SETTINGS_PERMISSION_NONE = 0x0, - NM_SETTINGS_PERMISSION_CONNECTION_MODIFY = 0x1, - NM_SETTINGS_PERMISSION_WIFI_SHARE_PROTECTED = 0x2, - NM_SETTINGS_PERMISSION_WIFI_SHARE_OPEN = 0x4, - NM_SETTINGS_PERMISSION_HOSTNAME_MODIFY = 0x8 -} NMSettingsPermissions; - #define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ()) #define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings)) #define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) @@ -53,7 +44,6 @@ typedef enum { #define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" #define NM_SYSCONFIG_SETTINGS_NEW_CONNECTION "new-connection" -#define NM_SYSCONFIG_SETTINGS_CHECK_PERMISSIONS "check-permissions" typedef struct { GObject parent_instance; From f58f2d7f39233604385bdd48f39a08de9b4c2b19 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 26 Aug 2010 15:10:29 -0500 Subject: [PATCH 026/264] ifnet: update for settings rework --- .../plugins/ifnet/nm-ifnet-connection.c | 89 ++++++++----------- system-settings/plugins/ifnet/plugin.c | 41 +++++---- 2 files changed, 60 insertions(+), 70 deletions(-) diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.c b/system-settings/plugins/ifnet/nm-ifnet-connection.c index e47495cfb..bfcb7202b 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.c +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.c @@ -34,18 +34,8 @@ #include "wpa_parser.h" #include "plugin.h" -static NMSettingsConnectionInterface *parent_settings_connection_iface; +G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SYSCONFIG_CONNECTION) -static void settings_connection_interface_init (NMSettingsConnectionInterface * - klass); - -G_DEFINE_TYPE_EXTENDED (NMIfnetConnection, nm_ifnet_connection, - NM_TYPE_SYSCONFIG_CONNECTION, 0, - G_IMPLEMENT_INTERFACE - (NM_TYPE_SETTINGS_CONNECTION_INTERFACE, - settings_connection_interface_init)) -// G_DEFINE_TYPE(NMIfnetConnection, nm_ifnet_connection, -// NM_TYPE_SYSCONFIG_CONNECTION) #define NM_IFNET_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionPrivate)) enum { PROP_ZERO, @@ -84,8 +74,7 @@ nm_ifnet_connection_new (gchar * conn_name) g_object_unref (tmp); return NULL; } - nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (object), tmp, - FALSE, NULL); + nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); g_object_unref (tmp); return NM_IFNET_CONNECTION (object); } @@ -95,50 +84,49 @@ nm_ifnet_connection_init (NMIfnetConnection * connection) { } -static gboolean -update (NMSettingsConnectionInterface * connection, - NMSettingsConnectionInterfaceUpdateFunc callback, gpointer user_data) +static void +commit_changes (NMSysconfigConnection *connection, + NMSysconfigConnectionCommitFunc callback, + gpointer user_data) { GError *error = NULL; gchar *new_conn_name = NULL; - gboolean result; - NMIfnetConnectionPrivate *priv = - NM_IFNET_CONNECTION_GET_PRIVATE (connection); + NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection); + g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); - if (!ifnet_update_parsers_by_connection - (NM_CONNECTION (connection), priv->conn_name, &new_conn_name, - CONF_NET_FILE, WPA_SUPPLICANT_CONF, &error)) { + if (!ifnet_update_parsers_by_connection (NM_CONNECTION (connection), + priv->conn_name, + &new_conn_name, + CONF_NET_FILE, + WPA_SUPPLICANT_CONF, + &error)) { if (new_conn_name) g_free (new_conn_name); - PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to update %s", - priv->conn_name); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to update %s", priv->conn_name); reload_parsers (); callback (connection, error, user_data); g_error_free (error); g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); - return FALSE; + return; } g_free (priv->conn_name); priv->conn_name = new_conn_name; - result = - parent_settings_connection_iface->update (connection, callback, - user_data); - if (result) - PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s", - priv->conn_name); + + NM_SYSCONFIG_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, callback, user_data); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s", priv->conn_name); + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); - return result; } -static gboolean -do_delete (NMSettingsConnectionInterface * connection, - NMSettingsConnectionInterfaceDeleteFunc callback, gpointer user_data) +static void +do_delete (NMSysconfigConnection *connection, + NMSysconfigConnectionDeleteFunc callback, + gpointer user_data) { GError *error = NULL; - gboolean result; - NMIfnetConnectionPrivate *priv = - NM_IFNET_CONNECTION_GET_PRIVATE (connection); + NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection); + g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); if (!ifnet_delete_connection_in_parsers (priv->conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF)) { @@ -148,24 +136,14 @@ do_delete (NMSettingsConnectionInterface * connection, callback (connection, error, user_data); g_error_free (error); g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); - return FALSE; + return; } - result = - parent_settings_connection_iface->delete (connection, callback, - user_data); - if (result) - PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully deleted %s", - priv->conn_name); - g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); - return result; -} -static void -settings_connection_interface_init (NMSettingsConnectionInterface * iface) -{ - parent_settings_connection_iface = g_type_interface_peek_parent (iface); - iface->update = update; - iface->delete = do_delete; + NM_SYSCONFIG_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data); + + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully deleted %s", + priv->conn_name); + g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); } static void @@ -222,6 +200,7 @@ static void nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class); + NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (ifnet_connection_class); g_type_class_add_private (ifnet_connection_class, sizeof (NMIfnetConnectionPrivate)); @@ -229,6 +208,8 @@ nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; + sysconfig_class->delete = do_delete; + sysconfig_class->commit_changes = commit_changes; /* Properties */ g_object_class_install_property diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index 51d560246..0bc333615 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -194,23 +194,34 @@ monitor_file_changes (const char *filename, return monitor; } +/* Callback for nm_sysconfig_connection_replace_and_commit. Report any errors + * encountered when commiting connection settings updates. */ +static void +commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused) +{ + if (error) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, " error updating: %s", + (error && error->message) ? error->message : "(unknown)"); + } else { + NMSettingConnection *s_con; + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), + NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated", + nm_setting_connection_get_id (s_con)); + } +} + static void update_old_connection (gchar * conn_name, NMIfnetConnection * old_conn, NMIfnetConnection * new_conn, SCPluginIfnetPrivate * priv) { - GError **error = NULL; - - if (!nm_sysconfig_connection_update (NM_SYSCONFIG_CONNECTION (old_conn), - NM_CONNECTION (new_conn), TRUE, - error)) { - PLUGIN_WARN (IFNET_PLUGIN_NAME, "error updating: %s", - (error - && (*error)) ? (*error)->message : "(unknown)"); - } else - PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection %s updated", - conn_name); + nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (old_conn), + NM_CONNECTION (new_conn), + commit_cb, NULL); g_object_unref (new_conn); } @@ -302,8 +313,7 @@ reload_connections (gpointer config) PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name); - g_signal_emit_by_name (old, - NM_SETTINGS_CONNECTION_INTERFACE_REMOVED); + g_signal_emit_by_name (old, "removed"); g_hash_table_remove (priv->config_connections, conn_name); @@ -334,8 +344,7 @@ reload_connections (gpointer config) g_hash_table_iter_init (&iter, priv->config_connections); while (g_hash_table_iter_next (&iter, &key, &value)) { if (!g_hash_table_lookup (new_conn_names, key)) { - g_signal_emit_by_name (value, - NM_SETTINGS_CONNECTION_INTERFACE_REMOVED); + g_signal_emit_by_name (value, "removed"); g_hash_table_remove (priv->config_connections, key); } } @@ -423,7 +432,7 @@ SCPluginIfnet_init (NMSystemConfigInterface * config) g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, - NM_EXPORTED_CONNECTION (value)); + NM_CONNECTION (value)); } } /* Read hostname */ From e5c562262632b88b87be8aaf13f4b961273d3e96 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 26 Aug 2010 18:05:33 -0500 Subject: [PATCH 027/264] core: flatten connection listing from the settings service While it may not reduce the LOC it saves a few memory allocations and is somewhat less error prone since callers don't need to free the returned lists. --- src/nm-manager.c | 36 +++++------- src/system-settings/nm-sysconfig-settings.c | 65 +++++++++++---------- src/system-settings/nm-sysconfig-settings.h | 9 ++- 3 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 2368eeef0..04931b9d7 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -822,43 +822,33 @@ system_connection_removed_cb (NMSysconfigConnection *connection, } static void -system_internal_new_connection (NMManager *manager, - NMSysconfigConnection *connection) +_new_connection (NMSysconfigSettings *settings, + NMSysconfigConnection *connection, + gpointer user_data) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); const char *path; g_return_if_fail (connection != NULL); g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED, - G_CALLBACK (system_connection_updated_cb), manager); + G_CALLBACK (system_connection_updated_cb), self); g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, - G_CALLBACK (system_connection_removed_cb), manager); + G_CALLBACK (system_connection_removed_cb), self); path = nm_connection_get_path (NM_CONNECTION (connection)); g_hash_table_insert (priv->system_connections, g_strdup (path), g_object_ref (connection)); - g_signal_emit (manager, signals[CONNECTION_ADDED], 0, connection); + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); } static void system_new_connection_cb (NMSysconfigSettings *settings, NMSysconfigConnection *connection, - NMManager *manager) + NMManager *self) { - system_internal_new_connection (manager, connection); -} - -static void -system_query_connections (NMManager *manager) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - GSList *system_connections, *iter; - - system_connections = nm_sysconfig_settings_list_connections (priv->sys_settings); - for (iter = system_connections; iter; iter = g_slist_next (iter)) - system_internal_new_connection (manager, NM_SYSCONFIG_CONNECTION (iter->data)); - g_slist_free (system_connections); + _new_connection (settings, connection, self); } static void @@ -2932,7 +2922,11 @@ nm_manager_start (NMManager *self) system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self); system_hostname_changed_cb (priv->sys_settings, NULL, self); - system_query_connections (self); + + /* Get all connections */ + nm_sysconfig_settings_for_each_connection (NM_MANAGER_GET_PRIVATE (self)->sys_settings, + _new_connection, + self); nm_udev_manager_query_devices (priv->udev_mgr); bluez_manager_resync_devices (self); diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 197c01584..5841e625a 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -168,25 +168,26 @@ load_connections (NMSysconfigSettings *self) unmanaged_specs_changed (NULL, self); } -GSList * -nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings) +void +nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, + NMSysconfigSettingsForEachFunc for_each_func, + gpointer user_data) { NMSysconfigSettingsPrivate *priv; GHashTableIter iter; gpointer key; - GSList *list = NULL; - g_return_val_if_fail (settings != NULL, NULL); - g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings), NULL); + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + g_return_if_fail (for_each_func != NULL); - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); + priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - load_connections (settings); + load_connections (self); g_hash_table_iter_init (&iter, priv->visible_connections); while (g_hash_table_iter_next (&iter, &key, NULL)) - list = g_slist_prepend (list, NM_SYSCONFIG_CONNECTION (key)); - return g_slist_reverse (list); + for_each_func (self, NM_SYSCONFIG_CONNECTION (key), user_data); } static gboolean @@ -194,38 +195,40 @@ impl_settings_list_connections (NMSysconfigSettings *self, GPtrArray **connections, GError **error) { - GSList *list = NULL, *iter; + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer key; - list = nm_sysconfig_settings_list_connections (self); - *connections = g_ptr_array_sized_new (g_slist_length (list) + 1); - for (iter = list; iter; iter = g_slist_next (iter)) { - g_ptr_array_add (*connections, - g_strdup (nm_connection_get_path (NM_CONNECTION (iter->data)))); - } - g_slist_free (list); + load_connections (self); + + *connections = g_ptr_array_sized_new (g_hash_table_size (priv->visible_connections) + 1); + g_hash_table_iter_init (&iter, priv->visible_connections); + while (g_hash_table_iter_next (&iter, &key, NULL)) + g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (key)))); return TRUE; } NMSysconfigConnection * -nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, const char *path) +nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const char *path) { - NMSysconfigConnection *connection = NULL; - GSList *list = NULL, *iter; + NMSysconfigSettingsPrivate *priv; + GHashTableIter iter; + gpointer key; - g_return_val_if_fail (settings != NULL, NULL); - g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings), NULL); + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); g_return_val_if_fail (path != NULL, NULL); - list = nm_sysconfig_settings_list_connections (settings); - for (iter = list; iter; iter = g_slist_next (iter)) { - if (!strcmp (nm_connection_get_path (NM_CONNECTION (iter->data)), path)) { - connection = NM_SYSCONFIG_CONNECTION (iter->data); - break; - } - } - g_slist_free (list); + priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - return connection; + load_connections (self); + + g_hash_table_iter_init (&iter, priv->visible_connections); + while (g_hash_table_iter_next (&iter, &key, NULL)) { + if (!strcmp (nm_connection_get_path (NM_CONNECTION (key)), path)) + return NM_SYSCONFIG_CONNECTION (key); + } + return NULL; } static void diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index d4e58a696..948349820 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -62,7 +62,14 @@ NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file, const char *plugins, GError **error); -/* Returns a list of NMSysconfigConnections */ +typedef void (*NMSysconfigSettingsForEachFunc) (NMSysconfigSettings *settings, + NMSysconfigConnection *connection, + gpointer user_data); + +void nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *settings, + NMSysconfigSettingsForEachFunc for_each_func, + gpointer user_data); + GSList * nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings); NMSysconfigConnection * nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, From 26327e7646c3a1121e8a4fa09cd9bcde0524cec4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 26 Aug 2010 18:11:46 -0500 Subject: [PATCH 028/264] settings: simplify settings object registration And fix a leak of the D-Bus manager too. --- src/system-settings/nm-sysconfig-settings.c | 28 +++++---------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 5841e625a..edb41f8e9 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -1215,27 +1215,6 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic remove_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); } -static void -export_sysconfig (NMSysconfigSettings *self) -{ - NMSysconfigSettingsPrivate *priv; - DBusGConnection *bus; - - g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); - - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - - /* Don't allow exporting twice */ - g_return_if_fail (priv->exported == FALSE); - - bus = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - dbus_g_connection_register_g_object (bus, - NM_DBUS_PATH_SETTINGS, - G_OBJECT (self)); - priv->exported = TRUE; -} - NMSysconfigSettings * nm_sysconfig_settings_new (const char *config_file, const char *plugins, @@ -1243,6 +1222,8 @@ nm_sysconfig_settings_new (const char *config_file, { NMSysconfigSettings *self; NMSysconfigSettingsPrivate *priv; + NMDBusManager *dbus_mgr; + DBusGConnection *bus; self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL); @@ -1262,7 +1243,10 @@ nm_sysconfig_settings_new (const char *config_file, unmanaged_specs_changed (NULL, self); } - export_sysconfig (self); + dbus_mgr = nm_dbus_manager_get (); + bus = nm_dbus_manager_get_connection (dbus_mgr); + dbus_g_connection_register_g_object (bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); + g_object_unref (dbus_mgr); return self; } From 3697aa7d7522d88e381afc3563ca24e73064d4de Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 11:51:19 -0500 Subject: [PATCH 029/264] trivial: whitespace cleanup --- src/system-settings/nm-session-manager.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c index 3b36a08c0..e30742fe5 100644 --- a/src/system-settings/nm-session-manager.c +++ b/src/system-settings/nm-session-manager.c @@ -730,8 +730,10 @@ dispose (GObject *object) } static void -nm_session_manager_class_init (NMSessionManagerClass *manager_class) { +nm_session_manager_class_init (NMSessionManagerClass *manager_class) +{ GObjectClass *g_class = G_OBJECT_CLASS (manager_class); + g_type_class_add_private (g_class, sizeof(NMSessionManagerPrivate)); g_class->dispose = dispose; From cdcf74da8984370d6110157d1fa75b58c1568c65 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:13:41 -0500 Subject: [PATCH 030/264] settings: simplify initial CK session retrieval Get rid of the InitInfo struct since it's so small and just store that information in the main object's private data; less complicated. Also fix an edge-case where the init-done signal would not get emitted if CK wasn't tracking any sessions at the time. --- src/system-settings/nm-session-manager.c | 54 ++++++++++++------------ src/system-settings/nm-session-manager.h | 2 +- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c index e30742fe5..d67f61902 100644 --- a/src/system-settings/nm-session-manager.c +++ b/src/system-settings/nm-session-manager.c @@ -25,13 +25,15 @@ #include #include "nm-dbus-manager.h" #include "nm-session-manager.h" +#include "nm-logging.h" G_DEFINE_TYPE (NMSessionManager, nm_session_manager, G_TYPE_OBJECT); /* NMSessionManager data */ typedef struct { gboolean disposed; - gboolean initalized; + gboolean initialized; + guint init_sessions_left; /* The master table of NMSessionInfo instances, keyed by session id. */ GHashTable *sessions; @@ -603,56 +605,56 @@ nm_session_manager_get_session_of_caller (NMSessionManager *manager, /**** Initialization & disposal **********************************************/ gboolean -nm_session_manager_is_initalized (NMSessionManager *self) +nm_session_manager_is_initialized (NMSessionManager *self) { g_return_val_if_fail (NM_IS_SESSION_MANAGER (self), FALSE); - return NM_SESSION_MANAGER_GET_PRIVATE (self)->initalized; + return NM_SESSION_MANAGER_GET_PRIVATE (self)->initialized; } -typedef struct { - NMSessionManager *manager; - guint sessions_left; -} InitInfo; - /* Callback run for sessions loaded during initialization. Emits the * "initialized" signal when all sessions are loaded. */ static void init_session_load_cb (NMSessionInfo *session, GError *error, gpointer user_data) { - InitInfo *info = (InitInfo *) user_data; - info->sessions_left--; + NMSessionManager *self = NM_SESSION_MANAGER (user_data); + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - if (info->sessions_left == 0) { - NM_SESSION_MANAGER_GET_PRIVATE (info->manager)->initalized = TRUE; - g_signal_emit (info->manager, signals[INIT_DONE], 0); - g_slice_free (InitInfo, info); + priv->init_sessions_left--; + if (priv->init_sessions_left == 0) { + priv->initialized = TRUE; + g_signal_emit (self, signals[INIT_DONE], 0); } } static void ck_get_sessions_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - NMSessionManager *manager = NM_SESSION_MANAGER (user_data); + NMSessionManager *self = NM_SESSION_MANAGER (user_data); + NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); GPtrArray *session_ids; - InitInfo *info; int i; + + g_assert (priv->initialized == FALSE); if (!dbus_g_proxy_end_call (proxy, call_id, NULL, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &session_ids, G_TYPE_INVALID)) { - g_warning ("NMSessionManager: error getting sessions list!"); + nm_log_err (LOGD_SYS_SET, "failed to get initial ConsoleKit session list"); return; } - info = g_slice_new (InitInfo); - info->manager = manager; - info->sessions_left = session_ids->len; - - for (i = 0; i < session_ids->len; i++) { - char *session_id = g_ptr_array_index (session_ids, i); - nm_session_manager_get_session (manager, session_id, init_session_load_cb, info); - g_free (session_id); + priv->init_sessions_left = session_ids->len; + if (priv->init_sessions_left > 0) { + for (i = 0; i < session_ids->len; i++) { + char *session_id = g_ptr_array_index (session_ids, i); + nm_session_manager_get_session (self, session_id, init_session_load_cb, self); + g_free (session_id); + } + } else { + /* Make sure we send the init-done signal if there aren't any sessions */ + priv->initialized = TRUE; + g_signal_emit (self, signals[INIT_DONE], 0); } g_ptr_array_free (session_ids, TRUE); } @@ -666,7 +668,7 @@ nm_session_manager_init (NMSessionManager *self) DBusConnection *connection = dbus_g_connection_get_connection (g_connection); priv->disposed = FALSE; - priv->initalized = FALSE; + priv->initialized = FALSE; priv->sessions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); priv->pending_sessions = g_hash_table_new_full (g_str_hash, g_str_equal, diff --git a/src/system-settings/nm-session-manager.h b/src/system-settings/nm-session-manager.h index da4ddc006..1f1d9668a 100644 --- a/src/system-settings/nm-session-manager.h +++ b/src/system-settings/nm-session-manager.h @@ -58,7 +58,7 @@ typedef void (*NMSessionFunc) (NMSessionInfo *session, NMSessionManager * nm_session_manager_get (void); -gboolean nm_session_manager_is_initalized (NMSessionManager *manager); +gboolean nm_session_manager_is_initialized (NMSessionManager *manager); GSList * nm_session_manager_get_sessions (NMSessionManager *manager); From b2fdf36d8d6c222c94abdfdd691816165199f130 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:16:03 -0500 Subject: [PATCH 031/264] trivial: add modelines to session tracker files --- src/system-settings/nm-session-info.c | 1 + src/system-settings/nm-session-info.h | 1 + src/system-settings/nm-session-manager.c | 1 + src/system-settings/nm-session-manager.h | 1 + 4 files changed, 4 insertions(+) diff --git a/src/system-settings/nm-session-info.c b/src/system-settings/nm-session-info.c index 28421ce14..07e482056 100644 --- a/src/system-settings/nm-session-info.c +++ b/src/system-settings/nm-session-info.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager user session tracker -- per-session data * * This program is free software; you can redistribute it and/or modify diff --git a/src/system-settings/nm-session-info.h b/src/system-settings/nm-session-info.h index 5dc1ab484..f44aeaf24 100644 --- a/src/system-settings/nm-session-info.h +++ b/src/system-settings/nm-session-info.h @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager user session tracker -- per-session data * * This program is free software; you can redistribute it and/or modify diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c index d67f61902..931610e81 100644 --- a/src/system-settings/nm-session-manager.c +++ b/src/system-settings/nm-session-manager.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager user session tracker * * This program is free software; you can redistribute it and/or modify diff --git a/src/system-settings/nm-session-manager.h b/src/system-settings/nm-session-manager.h index 1f1d9668a..a7f8642ca 100644 --- a/src/system-settings/nm-session-manager.h +++ b/src/system-settings/nm-session-manager.h @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager user session tracker * * This program is free software; you can redistribute it and/or modify From e40511d2e9096844be595f4d05c1547e2de16179 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:17:31 -0500 Subject: [PATCH 032/264] trivial: style fix --- src/system-settings/nm-session-manager.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c index 931610e81..d30727576 100644 --- a/src/system-settings/nm-session-manager.c +++ b/src/system-settings/nm-session-manager.c @@ -267,7 +267,8 @@ pending_session_start (NMSessionManager *self, char *session_id) } static PendingSessionInfo * -pending_session_find (NMSessionManager *self, char *session_id) { +pending_session_find (NMSessionManager *self, char *session_id) +{ GHashTable *pending_sessions = NM_SESSION_MANAGER_GET_PRIVATE (self)->pending_sessions; return g_hash_table_lookup (pending_sessions, session_id); } From 423a319af0eaf215f9bd4478d3b16323b8a2a05f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:20:04 -0500 Subject: [PATCH 033/264] trivial: whitespace & style fixes --- src/system-settings/nm-session-info.c | 86 ++++++++++++------------ src/system-settings/nm-session-manager.c | 12 ++-- 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/system-settings/nm-session-info.c b/src/system-settings/nm-session-info.c index 07e482056..3e05eafde 100644 --- a/src/system-settings/nm-session-info.c +++ b/src/system-settings/nm-session-info.c @@ -74,60 +74,62 @@ nm_session_info_is_default_session (NMSessionInfo *self) } static void -set_property (GObject *object, +set_property (GObject *object, guint property_id, const GValue *value, - GParamSpec *pspec) { - NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); + GParamSpec *pspec) +{ + NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); - switch (property_id) { - case PROP_ID: - g_free (priv->id); - priv->id = g_value_dup_string (value); - break; - case PROP_USER: - g_free (priv->user); - priv->user = g_value_dup_string (value); - break; - case PROP_GROUPS: - nm_utils_slist_free (priv->groups, g_free); - priv->groups = g_value_dup_boxed (value); - break; - case PROP_IS_DEFAULT: - priv->is_default = g_value_get_boolean (value); - break; + switch (property_id) { + case PROP_ID: + g_free (priv->id); + priv->id = g_value_dup_string (value); + break; + case PROP_USER: + g_free (priv->user); + priv->user = g_value_dup_string (value); + break; + case PROP_GROUPS: + nm_utils_slist_free (priv->groups, g_free); + priv->groups = g_value_dup_boxed (value); + break; + case PROP_IS_DEFAULT: + priv->is_default = g_value_get_boolean (value); + break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } } static void -get_property (GObject *object, +get_property (GObject *object, guint property_id, GValue *value, - GParamSpec *pspec) { + GParamSpec *pspec) +{ NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); - switch (property_id) { - case PROP_ID: - g_value_set_string (value, priv->id); - break; - case PROP_USER: - g_value_set_string (value, priv->user); - break; - case PROP_GROUPS: - g_value_set_boxed (value, priv->groups); - break; - case PROP_IS_DEFAULT: - g_value_set_boolean (value, priv->is_default); - break; + switch (property_id) { + case PROP_ID: + g_value_set_string (value, priv->id); + break; + case PROP_USER: + g_value_set_string (value, priv->user); + break; + case PROP_GROUPS: + g_value_set_boxed (value, priv->groups); + break; + case PROP_IS_DEFAULT: + g_value_set_boolean (value, priv->is_default); + break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } } static void diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c index d30727576..17cc0bb5d 100644 --- a/src/system-settings/nm-session-manager.c +++ b/src/system-settings/nm-session-manager.c @@ -490,8 +490,8 @@ dbus_name_has_owner_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer use if (!dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_BOOLEAN, &has_owner, G_TYPE_INVALID) || !has_owner) { - pending_caller_abort (info, NULL); - return; + pending_caller_abort (info, NULL); + return; } info->current_call = NULL; @@ -511,7 +511,7 @@ ck_get_session_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat G_TYPE_STRING, &(info->session_id), G_TYPE_INVALID)) { pending_caller_abort (info, NULL); - return; + return; } // Finally, ensure that the calling process is still there, so we are sure @@ -536,7 +536,7 @@ dbus_get_pid_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) if (!dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_UINT, &pid, G_TYPE_INVALID)) { pending_caller_abort (info, NULL); - return; + return; } info->current_call = dbus_g_proxy_begin_call (priv->ck_manager, @@ -642,8 +642,8 @@ ck_get_sessions_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_da if (!dbus_g_proxy_end_call (proxy, call_id, NULL, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &session_ids, G_TYPE_INVALID)) { - nm_log_err (LOGD_SYS_SET, "failed to get initial ConsoleKit session list"); - return; + nm_log_err (LOGD_SYS_SET, "failed to get initial ConsoleKit session list"); + return; } priv->init_sessions_left = session_ids->len; From c5e06c16ceb1905743f9dd1b50ad44ac87ec4552 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:36:35 -0500 Subject: [PATCH 034/264] settings: fix memory leak The GSList returned by nm_session_manager_get_sessions() must be freed by the caller. s/connection/self to make it clear what object is actually being handled here too. --- src/system-settings/nm-sysconfig-connection.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index b42c8e3ec..0eeb81f52 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -204,31 +204,33 @@ session_added_cb (NMSessionManager *mananager, /* Our permissions property may have been changed. Update the access list. */ static void -update_access_list (NMSysconfigConnection *connection) +update_access_list (NMSysconfigConnection *self) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); - NMSessionManager *session_manager = nm_session_manager_get(); - GSList *sessions = nm_session_manager_get_sessions (session_manager); - GSList *iter; + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSessionManager *session_manager = nm_session_manager_get (); + GSList *sessions, *iter; if (!priv->access_list) return; g_hash_table_remove_all (priv->access_list); + sessions = nm_session_manager_get_sessions (session_manager); for (iter = sessions; iter != NULL; iter = iter->next) { - NMSessionInfo *session = (NMSessionInfo *) iter->data; - if (session_allowed (connection, iter->data)) { + NMSessionInfo *session = NM_SESSION_INFO (iter->data); + + if (session_allowed (self, session)) { g_object_ref (session); g_signal_connect (session, NM_SESSION_INFO_REMOVED, - G_CALLBACK(session_removed_cb), connection); + G_CALLBACK (session_removed_cb), self); g_hash_table_insert (priv->access_list, nm_session_info_get_id (session), session); } } + g_slist_free (sessions); if (g_hash_table_size (priv->access_list) == 0) { - set_visibility (connection, FALSE); + set_visibility (self, FALSE); } else { - g_signal_emit (connection, signals[CHECK_PERMISSIONS], 0); + g_signal_emit (self, signals[CHECK_PERMISSIONS], 0); } } From 4c23ac3c6c3f7f8339a3e93ab3c62e33ccbd5bdf Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:39:47 -0500 Subject: [PATCH 035/264] settings: remove some unused code priv->access_list is allocated during object initialization and only destroyed when the object is destroyed, so it will always be valid over the lifetime of the object. Thus no need to check if it exists or not. --- src/system-settings/nm-sysconfig-connection.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 0eeb81f52..87798c29d 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -210,9 +210,6 @@ update_access_list (NMSysconfigConnection *self) NMSessionManager *session_manager = nm_session_manager_get (); GSList *sessions, *iter; - if (!priv->access_list) - return; - g_hash_table_remove_all (priv->access_list); sessions = nm_session_manager_get_sessions (session_manager); for (iter = sessions; iter != NULL; iter = iter->next) { @@ -256,9 +253,7 @@ nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *connecti NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); GSList *sessions = NULL; - if (priv->access_list) - g_hash_table_foreach (priv->access_list, prepend_slist, &sessions); - + g_hash_table_foreach (priv->access_list, prepend_slist, &sessions); return sessions; } @@ -272,9 +267,6 @@ nm_sysconfig_connection_is_accessible_by_session (NMSysconfigConnection *connect g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), FALSE); g_return_val_if_fail (NM_IS_SESSION_INFO (session), FALSE); - if (!priv->access_list) - return FALSE; - stored_session = g_hash_table_lookup (priv->access_list, nm_session_info_get_id (session)); From 25a59910b9e0c325bf286bd97179078a793477c8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:44:57 -0500 Subject: [PATCH 036/264] settings: simplify nm_sysconfig_connection_get_session_access_list() Clearer and fewer LOC to use GHashTableIter here. --- src/system-settings/nm-sysconfig-connection.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 87798c29d..962a6db72 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -239,21 +239,16 @@ nm_sysconfig_connection_is_visible (NMSysconfigConnection *connection) return NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection)->visible; } -static void -prepend_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **sessions = (GSList **) user_data; - - *sessions = g_slist_prepend (*sessions, value); -} - GSList * -nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *connection) +nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *self) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + GHashTableIter iter; + gpointer value; GSList *sessions = NULL; - g_hash_table_foreach (priv->access_list, prepend_slist, &sessions); + g_hash_table_iter_init (&iter, NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self)->access_list); + while (g_hash_table_iter_next (&iter, NULL, &value)) + sessions = g_slist_prepend (sessions, value); return sessions; } From 4f2266de64c673f4754f6f09f565030c9c4428b5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 27 Aug 2010 12:49:01 -0500 Subject: [PATCH 037/264] settings: simplify NMSysconfigConnection disposal Use GHashTableIters again. --- src/system-settings/nm-sysconfig-connection.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 962a6db72..5bfe15f7c 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -1016,15 +1016,6 @@ nm_sysconfig_connection_init (NMSysconfigConnection *self) } -static void -access_list_dispose (gpointer key, gpointer value, gpointer user_data) -{ - NMSysconfigConnection *connection = (NMSysconfigConnection *) user_data; - NMSessionInfo *session = (NMSessionInfo *) value; - - g_signal_handlers_disconnect_by_func (session, session_removed_cb, connection); -} - static void dispose (GObject *object) { @@ -1032,6 +1023,8 @@ dispose (GObject *object) NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); NMSessionManager *session_manager = nm_session_manager_get (); GSList *iter; + GHashTableIter hiter; + gpointer value; if (priv->secrets) g_object_unref (priv->secrets); @@ -1048,8 +1041,11 @@ dispose (GObject *object) set_visibility (self, FALSE); g_signal_handlers_disconnect_by_func (session_manager, session_added_cb, self); - g_hash_table_foreach (priv->access_list, access_list_dispose, self); - g_hash_table_unref (priv->access_list); + + g_hash_table_iter_init (&hiter, priv->access_list); + while (g_hash_table_iter_next (&hiter, NULL, &value)) + g_signal_handlers_disconnect_by_func (NM_SESSION_INFO (value), session_removed_cb, self); + g_hash_table_destroy (priv->access_list); priv->access_list = NULL; G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object); From 82772191a993fc9836ffeec5d23589abbe53a9d2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 12 Oct 2010 17:55:08 -0500 Subject: [PATCH 038/264] libnm-util: simplify permissions somewhat; remove groups Groups may come later, but they are also quite a bit more complicated because getting the groups a user is in may require network access if that user is backed by LDAP. And it gets worse because you have no idea that the glibc calls like getgrouplist(3) are backed by the network and may take an arbitrary amount of time to complete. Punt that. --- libnm-util/libnm-util.ver | 2 + libnm-util/nm-setting-connection.c | 87 ++++++++++++++---------------- libnm-util/nm-setting-connection.h | 9 ++-- 3 files changed, 47 insertions(+), 51 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index cf3d801fb..8f5ddbe74 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -113,6 +113,8 @@ global: nm_setting_connection_get_autoconnect; nm_setting_connection_get_timestamp; nm_setting_connection_get_read_only; + nm_setting_connection_get_num_permissions; + nm_setting_connection_get_permission; nm_setting_duplicate; nm_setting_enumerate_values; nm_setting_error_get_type; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 40c9ac14c..644ed59ca 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -30,6 +30,8 @@ #include "nm-param-spec-specialized.h" #include "nm-setting-connection.h" +#define NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER "user:" + /** * SECTION:nm-setting-connection * @short_description: Describes general connection properties @@ -186,7 +188,7 @@ nm_setting_connection_get_num_permissions (NMSettingConnection *setting) } /** - * nm_setting_connection_get_permission_entry: + * nm_setting_connection_get_permission: * @setting: the #NMSettingConnection * @index: the zero-based index of the permissions entry * @@ -196,11 +198,17 @@ nm_setting_connection_get_num_permissions (NMSettingConnection *setting) * Returns: the entry at the specified index */ const char * -nm_setting_connection_get_permission_entry (NMSettingConnection *setting, guint32 i) +nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 i) { + NMSettingConnectionPrivate *priv; + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); - return (const char *) g_slist_nth_data (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions, i); + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + g_return_val_if_fail (i < g_slist_length (priv->permissions), NULL); + + return (const char *) g_slist_nth_data (priv->permissions, i); } /** @@ -282,38 +290,23 @@ static gboolean validate_permissions (GSList *permissions, GError **error) { GSList *iter; + for (iter = permissions; iter; iter = iter->next) { - char *entry = (char *) iter->data; - char *usr_start = NULL; - char *ext_start = NULL; - int prefix_len; + const char *entry = iter->data; + const char *usr_start = NULL; - if (g_str_has_prefix (entry, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER)) { - prefix_len = strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER); - } else if (g_str_has_prefix (entry, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_GROUP)) { - prefix_len = strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_GROUP); - } else { - g_set_error (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, - "permissions: entry '%s': invalid prefix", entry); - return FALSE; - } + if (!g_str_has_prefix (entry, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER)) + continue; - usr_start = entry + prefix_len; - - ext_start = strchr(usr_start, ':'); - if (!ext_start) { + usr_start = entry + strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER); + if (!strchr (usr_start, ':')) { g_set_error (error, NM_SETTING_CONNECTION_ERROR, NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, - "permissions: entry '%s': two few ':'s", entry); + "permissions: entry '%s': two few ':' characters", entry); return FALSE; } - ext_start++; - /* We don't (yet) care about what comes afterwards. */ - } return TRUE; @@ -376,11 +369,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } if (priv->permissions) { - GError *perm_error = NULL; - if (!validate_permissions (priv->permissions, &perm_error)) { - g_propagate_error (error, perm_error); + if (!validate_permissions (priv->permissions, error)) return FALSE; - } } return TRUE; @@ -569,12 +559,16 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * * An array of strings defining what access a given user has to this * connection. If this is NULL or empty, all users are allowed to access - * this connection. Otherwise, each entry in this array specifies a user or - * unix group, and a user is allowed to access this connection if and only - * if they are in this list or if they are included in at least one of any - * listed unix groups . Each entry is of the form "user:: - * or "group::. Any present must be ignored; it is - * reserved for future versions of NM. + * this connection. Otherwise a user is allowed to access this connection + * if and only if they are in this list. Each entry is of the form + * "[type]:[id]:[reserved]", for example: + * + * user:dcbw:blah + * + * At this time only the 'user' [type] is allowed. Any other values are + * ignored and reserved for future use. [id] is the username that this + * permission refers to. Any [reserved] information present must be + * ignored and is reserved for future use. */ g_object_class_install_property (object_class, PROP_PERMISSIONS, @@ -583,15 +577,16 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) "An array of strings defining what access a given " "user has to this connection. If this is NULL or " "empty, all users are allowed to access this " - "connection. Otherwise, each entry in this array " - "specifies a user or unix group, and a user is " - "allowed to access this connection if and only if " - "they are in this list or if they are included in at " - "least one of any listed unix groups. Each entry is " - "of the form \"user::\" or " - "\"group::\". Any present " - "must be ignored; it is reserved for future versions " - "of NM.", + "connection. Otherwise a user is allowed to access " + "this connection if and only if they are in this " + "array. Each entry is of the form " + "\"[type]:[id]:[reserved]\", for example: " + "\"user:dcbw:blah\" At this time only the 'user' " + "[type] is allowed. Any other values are ignored and " + "reserved for future use. [id] is the username that " + "this permission refers to. Any [reserved] " + "information (if present) must be ignored and is " + "reserved for future use.", DBUS_TYPE_G_LIST_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 22e0deb6a..49dacb0b3 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2010 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -76,9 +76,6 @@ GQuark nm_setting_connection_error_quark (void); #define NM_SETTING_CONNECTION_READ_ONLY "read-only" #define NM_SETTING_CONNECTION_PERMISSIONS "permissions" -#define NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER "user:" -#define NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_GROUP "group:" - /** * NMSettingConnection: * @@ -109,7 +106,9 @@ gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *set guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); -const char *nm_setting_connection_get_permission_entry (NMSettingConnection *setting, guint32 index); +const char *nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 index); + +/* FIXME: need add/remove calls for permissions */ G_END_DECLS From fee318abdb0950fc2b58ff02948ceba3a1a56a39 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 12 Oct 2010 18:01:11 -0500 Subject: [PATCH 039/264] settings: remove groups checking See "libnm-util: simplify permissions somewhat; remove groups" for more rationale. Might come back later. --- src/system-settings/nm-session-info.c | 34 ------------------ src/system-settings/nm-session-info.h | 2 -- src/system-settings/nm-session-manager.c | 35 ------------------- src/system-settings/nm-sysconfig-connection.c | 16 +-------- 4 files changed, 1 insertion(+), 86 deletions(-) diff --git a/src/system-settings/nm-session-info.c b/src/system-settings/nm-session-info.c index 3e05eafde..3faf407dd 100644 --- a/src/system-settings/nm-session-info.c +++ b/src/system-settings/nm-session-info.c @@ -27,7 +27,6 @@ G_DEFINE_TYPE (NMSessionInfo, nm_session_info, G_TYPE_OBJECT); typedef struct { char *id; char *user; - GSList *groups; gboolean is_default; } NMSessionInfoPrivate; @@ -37,7 +36,6 @@ enum { PROP_0, PROP_ID, PROP_USER, - PROP_GROUPS, PROP_IS_DEFAULT }; @@ -57,14 +55,6 @@ nm_session_info_get_unix_user (NMSessionInfo *self) return NM_SESSION_INFO_GET_PRIVATE (self)->user; } -GSList * -nm_session_info_get_unix_groups (NMSessionInfo *self) -{ - g_return_val_if_fail (NM_IS_SESSION_INFO (self), NULL); - - return NM_SESSION_INFO_GET_PRIVATE (self)->groups; -} - gboolean nm_session_info_is_default_session (NMSessionInfo *self) { @@ -90,10 +80,6 @@ set_property (GObject *object, g_free (priv->user); priv->user = g_value_dup_string (value); break; - case PROP_GROUPS: - nm_utils_slist_free (priv->groups, g_free); - priv->groups = g_value_dup_boxed (value); - break; case PROP_IS_DEFAULT: priv->is_default = g_value_get_boolean (value); break; @@ -119,9 +105,6 @@ get_property (GObject *object, case PROP_USER: g_value_set_string (value, priv->user); break; - case PROP_GROUPS: - g_value_set_boxed (value, priv->groups); - break; case PROP_IS_DEFAULT: g_value_set_boolean (value, priv->is_default); break; @@ -151,11 +134,6 @@ dispose (GObject *object) priv->user = NULL; } - if (priv->groups) { - nm_utils_slist_free (priv->groups, g_free); - priv->groups = NULL; - } - G_OBJECT_CLASS (nm_session_info_parent_class)->dispose (object); } @@ -188,18 +166,6 @@ nm_session_info_class_init (NMSessionInfoClass *info_class) { NULL, G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property - (g_class, PROP_GROUPS, - g_param_spec_boxed ( - NM_SESSION_INFO_UNIX_GROUPS, - "UnixGroups", - "List of strings representing the groups that this session's user " - "belonged to at login time. This represents our best guess as to " - "what groups the session's processes belong to. If this is the " - "default session, this is NULL.", - DBUS_TYPE_G_LIST_OF_STRING, - G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (g_class, PROP_IS_DEFAULT, g_param_spec_boolean ( diff --git a/src/system-settings/nm-session-info.h b/src/system-settings/nm-session-info.h index f44aeaf24..aebe4f59b 100644 --- a/src/system-settings/nm-session-info.h +++ b/src/system-settings/nm-session-info.h @@ -34,7 +34,6 @@ G_BEGIN_DECLS #define NM_SESSION_INFO_ID "session-id" #define NM_SESSION_INFO_UNIX_USER "unix-user" -#define NM_SESSION_INFO_UNIX_GROUPS "unix-groups" #define NM_SESSION_INFO_IS_DEFAULT "is-default" #define NM_SESSION_INFO_REMOVED "removed" @@ -53,7 +52,6 @@ GType nm_session_info_get_type (void); char * nm_session_info_get_id (NMSessionInfo *self); char * nm_session_info_get_unix_user (NMSessionInfo *self); -GSList * nm_session_info_get_unix_groups (NMSessionInfo *self); gboolean nm_session_info_is_default_session (NMSessionInfo *self); G_END_DECLS diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c index 17cc0bb5d..80c4ab60e 100644 --- a/src/system-settings/nm-session-manager.c +++ b/src/system-settings/nm-session-manager.c @@ -164,13 +164,8 @@ get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (pending->manager); guint user_id; struct passwd *pw_info = NULL; - int ngroups; - guint group_ids_size = 0; - gid_t *group_ids = NULL; - GSList *group_names = NULL; NMSessionInfo *session = NULL; GError *error = NULL; - int i; if (!dbus_g_proxy_end_call (proxy, call_id, NULL, G_TYPE_UINT, &user_id, G_TYPE_NONE)) { @@ -190,34 +185,9 @@ get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data goto out; } - // Figure out how many groups the user is in - group_ids = g_slice_alloc (0); - ngroups = 0; - getgrouplist (pw_info->pw_name, pw_info->pw_gid, group_ids, &ngroups); - g_slice_free1 (0, group_ids); - - // Get the list of group IDs - // FIXME what happens if the group list changes in the window between the - // two getgrouplist calls? - group_ids_size = ngroups * sizeof (gid_t); - group_ids = g_slice_alloc (group_ids_size); - if (getgrouplist (pw_info->pw_name, pw_info->pw_gid, group_ids, &ngroups) == -1) { - error = g_error_new (NM_SESSION_MANAGER_ERROR, - NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, - "session %s: failed to get groups for user %s", - pending->session_id, pw_info->pw_name); - goto out; - } - - for (i = 0; i < ngroups; i++) { - struct group *gr_info = getgrgid (group_ids[i]); - group_names = g_slist_prepend (group_names, g_strdup (gr_info->gr_name)); - } - session = g_object_new (NM_TYPE_SESSION_INFO, NM_SESSION_INFO_ID, pending->session_id, NM_SESSION_INFO_UNIX_USER, pw_info->pw_name, - NM_SESSION_INFO_UNIX_GROUPS, group_names, NULL); g_assert (session); @@ -225,11 +195,6 @@ get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data g_signal_emit (pending->manager, signals[ADDED], 0, session); out: - if (group_names) - nm_utils_slist_free (group_names, g_free); - if (group_ids) - g_slice_free1 (group_ids_size, group_ids); - pending_session_finish (pending, session, error); g_clear_error (&error); diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 5bfe15f7c..66548d569 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -87,7 +87,6 @@ session_allowed (NMSysconfigConnection *connection, NMSettingConnection *setting_connection = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); GSList *permissions_entries; char *session_user; - GSList *session_groups; GSList *p_iter; gboolean allowed = FALSE; @@ -106,7 +105,6 @@ session_allowed (NMSysconfigConnection *connection, } session_user = nm_session_info_get_unix_user (session); - session_groups = nm_session_info_get_unix_groups (session); for (p_iter = permissions_entries; p_iter != NULL; p_iter = p_iter->next) { char **p_comps = g_strsplit ((char *)p_iter->data, ":", 3); @@ -118,19 +116,7 @@ session_allowed (NMSysconfigConnection *connection, allowed = TRUE; goto out; } - } - else if (g_str_equal (type, "group")) { - GSList *g_iter; - - for (g_iter = session_groups; g_iter != NULL; g_iter = g_iter->next ) { - char *group_name = (char *) g_iter->data; - if (g_str_equal (group_name, name)) { - allowed = TRUE; - goto out; - } - } - } - else { + } else { nm_log_err (LOGD_SYS_SET, "connection %s: failed to parse permissions entry '%s'", nm_setting_connection_get_id (setting_connection), From 0c409d75ea24fea5d7e7a21e77cde5f3d74f6b75 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 25 Oct 2010 23:24:44 -0500 Subject: [PATCH 040/264] settings: add a simpler session monitor Heavily modified from polkitbackendsessionmonitor.c, thanks davidz! --- src/system-settings/Makefile.am | 4 +- src/system-settings/nm-session-monitor.c | 478 +++++++++++++++++++++++ src/system-settings/nm-session-monitor.h | 60 +++ 3 files changed, 541 insertions(+), 1 deletion(-) create mode 100644 src/system-settings/nm-session-monitor.c create mode 100644 src/system-settings/nm-session-monitor.h diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 5f18623ce..5d2d3cf9b 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -29,7 +29,9 @@ libsystem_settings_la_SOURCES = \ nm-session-info.c \ nm-session-info.h \ nm-session-manager.c \ - nm-session-manager.h + nm-session-manager.h \ + nm-session-monitor.c \ + nm-session-monitor.h libsystem_settings_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/system-settings/nm-session-monitor.c b/src/system-settings/nm-session-monitor.c new file mode 100644 index 000000000..3fcb70bb7 --- /dev/null +++ b/src/system-settings/nm-session-monitor.c @@ -0,0 +1,478 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + * Author: David Zeuthen + * Author: Dan Williams + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include "nm-logging.h" +#include "nm-system-config-error.h" + +#include "nm-session-monitor.h" + +#define CKDB_PATH "/var/run/ConsoleKit/database" + +/* + * SECTION:nm-session-monitor + * @title: NMSessionMonitor + * @short_description: Monitor sessions + * + * The #NMSessionMonitor class is a utility class to track and monitor sessions. + */ + +struct _NMSessionMonitor { + GObject parent_instance; + + GKeyFile *database; + GFileMonitor *database_monitor; + time_t database_mtime; + GHashTable *sessions_by_uid; + GHashTable *sessions_by_user; +}; + +struct _NMSessionMonitorClass { + GObjectClass parent_class; + + void (*changed) (NMSessionMonitor *monitor); +}; + + +enum { + CHANGED, + LAST_SIGNAL, +}; +static guint signals[LAST_SIGNAL] = {0}; + +G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); + +/********************************************************************/ + +typedef struct { + char *user; + uid_t uid; + gboolean local; + gboolean active; +} Session; + +static void +session_free (Session *s) +{ + g_free (s->user); + memset (s, 0, sizeof (Session)); + g_free (s); +} + +static gboolean +check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error) +{ + if (g_key_file_has_key (keyfile, group, key, error)) + return TRUE; + + if (!error) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key", + group, key); + } + return FALSE; +} + +static Session * +session_new (GKeyFile *keyfile, const char *group, GError **error) +{ + Session *s; + struct passwd *pw; + + s = g_new0 (Session, 1); + g_assert (s); + + if (!check_key (keyfile, group, "uid", error)) + return FALSE; + s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", error); + if (error) + goto error; + + if (!check_key (keyfile, group, "is_active", error)) + return FALSE; + s->active = g_key_file_get_boolean (keyfile, group, "is_active", error); + if (error) + goto error; + + if (!check_key (keyfile, group, "is_local", error)) + return FALSE; + s->local = g_key_file_get_boolean (keyfile, group, "is_local", error); + if (error) + goto error; + + pw = getpwuid (s->uid); + if (!pw) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "Could not get username for UID %d", + s->uid); + goto error; + } + s->user = g_strdup (pw->pw_name); + + return s; + +error: + session_free (s); + return NULL; +} + +/********************************************************************/ + +static void +free_database (NMSessionMonitor *self) +{ + if (self->database != NULL) { + g_key_file_free (self->database); + self->database = NULL; + } + + g_hash_table_remove_all (self->sessions_by_uid); + g_hash_table_remove_all (self->sessions_by_user); +} + +static gboolean +reload_database (NMSessionMonitor *self, GError **error) +{ + struct stat statbuf; + char **groups; + gsize len = 0, i; + Session *s; + + free_database (self); + + if (stat (CKDB_PATH, &statbuf) != 0) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "Error statting file " CKDB_PATH ": %s", + strerror (errno)); + goto error; + } + self->database_mtime = statbuf.st_mtime; + + self->database = g_key_file_new (); + if (!g_key_file_load_from_file (self->database, CKDB_PATH, G_KEY_FILE_NONE, error)) + goto error; + + groups = g_key_file_get_groups (self->database, &len); + if (!groups) { + g_set_error_literal (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "Could not load groups from " CKDB_PATH ""); + goto error; + } + + for (i = 0; i < len; i++) { + if (!g_str_has_prefix (groups[i], "Session ")) + continue; + + s = session_new (self->database, groups[i], error); + if (!s) + goto error; + g_hash_table_insert (self->sessions_by_user, (gpointer) s->user, s); + g_hash_table_insert (self->sessions_by_uid, GUINT_TO_POINTER (s->uid), s); + } + + g_strfreev (groups); + return TRUE; + +error: + if (groups) + g_strfreev (groups); + free_database (self); + return FALSE; +} + +static gboolean +ensure_database (NMSessionMonitor *self, GError **error) +{ + gboolean ret = FALSE; + + if (self->database != NULL) { + struct stat statbuf; + + if (stat (CKDB_PATH, &statbuf) != 0) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "Error statting file " CKDB_PATH " to check timestamp: %s", + strerror (errno)); + goto out; + } + + if (statbuf.st_mtime == self->database_mtime) { + ret = TRUE; + goto out; + } + } + + ret = reload_database (self, error); + +out: + return ret; +} + +static void +on_file_monitor_changed (GFileMonitor * file_monitor, + GFile * file, + GFile * other_file, + GFileMonitorEvent event_type, + gpointer user_data) +{ + NMSessionMonitor *self = NM_SESSION_MONITOR (user_data); + + /* throw away cache */ + free_database (self); + + g_signal_emit (self, signals[CHANGED], 0); +} + +static void +nm_session_monitor_init (NMSessionMonitor *self) +{ + GError *error = NULL; + GFile *file; + + /* Sessions-by-user is responsible for destroying the Session objects */ + self->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal, + NULL, (GDestroyNotify) session_free); + self->sessions_by_uid = g_hash_table_new (g_direct_hash, g_direct_equal); + + + error = NULL; + if (!ensure_database (self, &error)) { + nm_log_err (LOGD_SYS_SET, "Error loading " CKDB_PATH ": %s", error->message); + g_error_free (error); + } + + error = NULL; + file = g_file_new_for_path (CKDB_PATH); + self->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error); + g_object_unref (file); + if (self->database_monitor == NULL) { + nm_log_err (LOGD_SYS_SET, "Error monitoring " CKDB_PATH ": %s", error->message); + g_error_free (error); + } else { + g_signal_connect (self->database_monitor, + "changed", + G_CALLBACK (on_file_monitor_changed), + self); + } +} + +static void +finalize (GObject *object) +{ + NMSessionMonitor *self = NM_SESSION_MONITOR (object); + + if (self->database_monitor != NULL) + g_object_unref (self->database_monitor); + + free_database (self); + + if (G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize != NULL) + G_OBJECT_CLASS (nm_session_monitor_parent_class)->finalize (object); +} + +static void +nm_session_monitor_class_init (NMSessionMonitorClass *klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = finalize; + + /** + * NMSessionMonitor::changed: + * @monitor: A #NMSessionMonitor + * + * Emitted when something changes. + */ + signals[CHANGED] = g_signal_new ("changed", + NM_TYPE_SESSION_MONITOR, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NMSessionMonitorClass, changed), + NULL, /* accumulator */ + NULL, /* accumulator data */ + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +NMSessionMonitor * +nm_session_monitor_get (void) +{ + static NMSessionMonitor *singleton = NULL; + + if (singleton) + return NM_SESSION_MONITOR (g_object_ref (singleton)); + + return NM_SESSION_MONITOR (g_object_new (NM_TYPE_SESSION_MONITOR, NULL)); +} + +/* ---------------------------------------------------------------------------------------------------- */ + +/** + * nm_session_monitor_user_has_session: + * @monitor: A #NMSessionMonitor. + * @username: A username. + * @error: Return location for error. + * + * Checks whether the given @username is logged into a session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is + * currently logged into a session. + */ +gboolean +nm_session_monitor_user_has_session (NMSessionMonitor *monitor, + const char *username, + GError **error) +{ + Session *s; + + if (!ensure_database (monitor, error)) + return FALSE; + + s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); + if (!s) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "No session found for user '%s'", + username); + return FALSE; + } + + return TRUE; +} + +/** + * nm_session_monitor_uid_has_session: + * @monitor: A #NMSessionMonitor. + * @uid: A user ID. + * @error: Return location for error. + * + * Checks whether the given @uid is logged into a session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is + * currently logged into a session. + */ +gboolean +nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, + uid_t uid, + GError **error) +{ + Session *s; + + if (!ensure_database (monitor, error)) + return FALSE; + + s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); + if (!s) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "No session found for uid %d", + uid); + return FALSE; + } + + return TRUE; +} + +/** + * nm_session_monitor_user_active: + * @monitor: A #NMSessionMonitor. + * @username: A username. + * @error: Return location for error. + * + * Checks whether the given @username is logged into a active session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @username is + * logged into an active session. + */ +gboolean +nm_session_monitor_user_active (NMSessionMonitor *monitor, + const char *username, + GError **error) +{ + Session *s; + + if (!ensure_database (monitor, error)) + return FALSE; + + s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); + if (!s) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "No session found for user '%s'", + username); + return FALSE; + } + + return s->active; +} + +/** + * nm_session_monitor_uid_active: + * @monitor: A #NMSessionMonitor. + * @uid: A user ID. + * @error: Return location for error. + * + * Checks whether the given @uid is logged into a active session or not. + * + * Returns: %FALSE if @error is set otherwise %TRUE if the given @uid is + * logged into an active session. + */ +gboolean +nm_session_monitor_uid_active (NMSessionMonitor *monitor, + uid_t uid, + GError **error) +{ + Session *s; + + if (!ensure_database (monitor, error)) + return FALSE; + + s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); + if (!s) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + "No session found for uid '%d'", + uid); + return FALSE; + } + + return s->active; +} + diff --git a/src/system-settings/nm-session-monitor.h b/src/system-settings/nm-session-monitor.h new file mode 100644 index 000000000..f318bbb98 --- /dev/null +++ b/src/system-settings/nm-session-monitor.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 - 2010 Red Hat, Inc. + * Author: David Zeuthen + * Author: Dan Williams + */ + +#ifndef NM_SESSION_MONITOR_H +#define NM_SESSION_MONITOR_H + +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SESSION_MONITOR (nm_session_monitor_get_type ()) +#define NM_SESSION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_SESSION_MONITOR, NMSessionMonitor)) +#define NM_SESSION_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), NM_TYPE_SESSION_MONITOR, NMSessionMonitorClass)) +#define NM_SESSION_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_SESSION_MONITOR, NMSessionMonitorClass)) +#define NM_IS_SESSION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NM_TYPE_SESSION_MONITOR)) +#define NM_IS_SESSION_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_SESSION_MONITOR)) + +typedef struct _NMSessionMonitor NMSessionMonitor; +typedef struct _NMSessionMonitorClass NMSessionMonitorClass; + +GType nm_session_monitor_get_type (void) G_GNUC_CONST; +NMSessionMonitor *nm_session_monitor_get (void); + +gboolean nm_session_monitor_user_has_session (NMSessionMonitor *monitor, + const char *username, + GError **error); + +gboolean nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, + uid_t uid, + GError **error); + +gboolean nm_session_monitor_user_active (NMSessionMonitor *monitor, + const char *username, + GError **error); + +gboolean nm_session_monitor_uid_active (NMSessionMonitor *monitor, + uid_t uid, + GError **error); + +G_END_DECLS + +#endif /* NM_SESSION_MONITOR_H */ + From 1b21949380a546f140dc4e122eb75fa47844cf3d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 25 Oct 2010 23:43:04 -0500 Subject: [PATCH 041/264] core: move session monitor to core We'll need it for agent authentication too, so move it out of system settings specific code. --- src/Makefile.am | 4 +- .../nm-session-monitor.c | 81 ++++++++++++++----- .../nm-session-monitor.h | 0 src/system-settings/Makefile.am | 4 +- 4 files changed, 66 insertions(+), 23 deletions(-) rename src/{system-settings => }/nm-session-monitor.c (84%) rename src/{system-settings => }/nm-session-monitor.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 8c01df0fb..5f42b7ab0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -147,7 +147,9 @@ NetworkManager_SOURCES = \ nm-dhcp4-config.h \ nm-dhcp6-config.c \ nm-dhcp6-config.h \ - nm-rfkill.h + nm-rfkill.h \ + nm-session-monitor.c \ + nm-session-monitor.h nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $< diff --git a/src/system-settings/nm-session-monitor.c b/src/nm-session-monitor.c similarity index 84% rename from src/system-settings/nm-session-monitor.c rename to src/nm-session-monitor.c index 3fcb70bb7..3bbdb9ed3 100644 --- a/src/system-settings/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -26,7 +26,6 @@ #include #include #include "nm-logging.h" -#include "nm-system-config-error.h" #include "nm-session-monitor.h" @@ -67,6 +66,50 @@ G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); /********************************************************************/ +#define NM_SESSION_MONITOR_ERROR (nm_session_monitor_error_quark ()) +GQuark nm_session_monitor_error_quark (void) G_GNUC_CONST; +GType nm_session_monitor_error_get_type (void) G_GNUC_CONST; + +typedef enum { + NM_SESSION_MONITOR_ERROR_IO_ERROR = 0, + NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, +} NMSessionMonitorError; + +GQuark +nm_session_monitor_error_quark (void) +{ + static GQuark ret = 0; + + if (G_UNLIKELY (ret == 0)) + ret = g_quark_from_static_string ("nm-session-monitor-error"); + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_session_monitor_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Some I/O operation on the CK database failed */ + ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_IO_ERROR, "IOError"), + /* Error parsing the CK database */ + ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "MalformedDatabase"), + /* Username or UID could could not be found */ + ENUM_ENTRY (NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "UnknownUser"), + { 0, 0, 0 } + }; + + etype = g_enum_register_static ("NMSessionMonitorError", values); + } + return etype; +} +/********************************************************************/ + typedef struct { char *user; uid_t uid; @@ -90,8 +133,8 @@ check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error if (!error) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_MALFORMED_DATABASE, "ConsoleKit database " CKDB_PATH " group '%s' had no '%s' key", group, key); } @@ -128,8 +171,8 @@ session_new (GKeyFile *keyfile, const char *group, GError **error) pw = getpwuid (s->uid); if (!pw) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "Could not get username for UID %d", s->uid); goto error; @@ -169,8 +212,8 @@ reload_database (NMSessionMonitor *self, GError **error) if (stat (CKDB_PATH, &statbuf) != 0) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_IO_ERROR, "Error statting file " CKDB_PATH ": %s", strerror (errno)); goto error; @@ -184,8 +227,8 @@ reload_database (NMSessionMonitor *self, GError **error) groups = g_key_file_get_groups (self->database, &len); if (!groups) { g_set_error_literal (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_IO_ERROR, "Could not load groups from " CKDB_PATH ""); goto error; } @@ -221,8 +264,8 @@ ensure_database (NMSessionMonitor *self, GError **error) if (stat (CKDB_PATH, &statbuf) != 0) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_IO_ERROR, "Error statting file " CKDB_PATH " to check timestamp: %s", strerror (errno)); goto out; @@ -364,8 +407,8 @@ nm_session_monitor_user_has_session (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); if (!s) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "No session found for user '%s'", username); return FALSE; @@ -398,8 +441,8 @@ nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); if (!s) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "No session found for uid %d", uid); return FALSE; @@ -432,8 +475,8 @@ nm_session_monitor_user_active (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_user, (gpointer) username); if (!s) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "No session found for user '%s'", username); return FALSE; @@ -466,8 +509,8 @@ nm_session_monitor_uid_active (NMSessionMonitor *monitor, s = g_hash_table_lookup (monitor->sessions_by_uid, GUINT_TO_POINTER (uid)); if (!s) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "No session found for uid '%d'", uid); return FALSE; diff --git a/src/system-settings/nm-session-monitor.h b/src/nm-session-monitor.h similarity index 100% rename from src/system-settings/nm-session-monitor.h rename to src/nm-session-monitor.h diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 5d2d3cf9b..5f18623ce 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -29,9 +29,7 @@ libsystem_settings_la_SOURCES = \ nm-session-info.c \ nm-session-info.h \ nm-session-manager.c \ - nm-session-manager.h \ - nm-session-monitor.c \ - nm-session-monitor.h + nm-session-manager.h libsystem_settings_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ From 39ed9c29568f2c5d22a5946d43af05d8da3c668e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 11:00:30 -0500 Subject: [PATCH 042/264] core: get D-Bus manager during auth if not provided --- src/nm-manager-auth.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index 566fc80a6..e6d4778a4 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -20,6 +20,7 @@ #include "nm-manager-auth.h" #include "nm-logging.h" +#include "nm-dbus-manager.h" #include #include @@ -325,9 +326,14 @@ nm_auth_get_caller_uid (DBusGMethodInvocation *context, DBusError dbus_error; g_return_val_if_fail (context != NULL, FALSE); - g_return_val_if_fail (dbus_mgr != NULL, FALSE); g_return_val_if_fail (out_uid != NULL, FALSE); + if (!dbus_mgr) { + dbus_mgr = nm_dbus_manager_get (); + g_assert (dbus_mgr); + } else + g_object_ref (dbus_mgr); + *out_uid = G_MAXULONG; sender = dbus_g_method_get_sender (context); @@ -356,6 +362,7 @@ nm_auth_get_caller_uid (DBusGMethodInvocation *context, success = TRUE; out: + g_object_unref (dbus_mgr); g_free (sender); return success; } From 925d69c6d189fa70fa3dc45c903dd7d267ef92f2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 11:15:19 -0500 Subject: [PATCH 043/264] core: use new session monitor in system connection class --- src/nm-session-monitor.c | 7 + src/nm-session-monitor.h | 2 + src/system-settings/nm-sysconfig-connection.c | 510 +++++++++--------- src/system-settings/nm-sysconfig-connection.h | 18 +- src/system-settings/nm-sysconfig-settings.c | 47 +- 5 files changed, 290 insertions(+), 294 deletions(-) diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index 3bbdb9ed3..61d647901 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -150,6 +150,7 @@ session_new (GKeyFile *keyfile, const char *group, GError **error) s = g_new0 (Session, 1); g_assert (s); + s->uid = G_MAXUINT; /* paranoia */ if (!check_key (keyfile, group, "uid", error)) return FALSE; s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", error); @@ -397,6 +398,7 @@ nm_session_monitor_get (void) gboolean nm_session_monitor_user_has_session (NMSessionMonitor *monitor, const char *username, + uid_t *out_uid, GError **error) { Session *s; @@ -414,6 +416,8 @@ nm_session_monitor_user_has_session (NMSessionMonitor *monitor, return FALSE; } + if (out_uid) + *out_uid = s->uid; return TRUE; } @@ -431,6 +435,7 @@ nm_session_monitor_user_has_session (NMSessionMonitor *monitor, gboolean nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, uid_t uid, + const char **out_user, GError **error) { Session *s; @@ -448,6 +453,8 @@ nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, return FALSE; } + if (out_user) + *out_user = s->user; return TRUE; } diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h index f318bbb98..fe99fa4d6 100644 --- a/src/nm-session-monitor.h +++ b/src/nm-session-monitor.h @@ -40,10 +40,12 @@ NMSessionMonitor *nm_session_monitor_get (void); gboolean nm_session_monitor_user_has_session (NMSessionMonitor *monitor, const char *username, + uid_t *out_uid, GError **error); gboolean nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, uid_t uid, + const char **out_user, GError **error); gboolean nm_session_monitor_user_active (NMSessionMonitor *monitor, diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 66548d569..947052ec5 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -19,13 +19,15 @@ * (C) Copyright 2008 - 2010 Red Hat, Inc. */ +#include + #include #include #include #include #include "nm-sysconfig-connection.h" -#include "nm-session-manager.h" +#include "nm-session-monitor.h" #include "nm-dbus-manager.h" #include "nm-system-config-error.h" #include "nm-dbus-glib-types.h" @@ -57,12 +59,16 @@ G_DEFINE_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_CONNECTIO NM_TYPE_SYSCONFIG_CONNECTION, \ NMSysconfigConnectionPrivate)) +enum { + PROP_0 = 0, + PROP_VISIBLE, +}; + enum { UPDATED, CHECK_PERMISSIONS, REMOVED, PURGED, - UNHIDDEN, LAST_SIGNAL }; @@ -73,192 +79,168 @@ typedef struct { GSList *pending_auths; /* List of PendingAuth structs*/ NMConnection *secrets; gboolean visible; /* Is this connection is visible by some session? */ - GHashTable *access_list; /* Sessions that may access this connection. */ + NMSessionMonitor *session_monitor; } NMSysconfigConnectionPrivate; /**************************************************************/ -/* Returns true iff the given session should be permitted to access this - * connection. Used to update the access list */ +#define USER_TAG "user:" + +/* Extract the username from the permission string and dump to a buffer */ static gboolean -session_allowed (NMSysconfigConnection *connection, - NMSessionInfo *session) +perm_to_user (const char *perm, char *out_user, gsize out_user_size) { - NMSettingConnection *setting_connection = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); - GSList *permissions_entries; - char *session_user; - GSList *p_iter; - gboolean allowed = FALSE; + const char *end; + gsize userlen; - g_object_get (setting_connection, NM_SETTING_CONNECTION_PERMISSIONS, &permissions_entries, NULL); + g_return_val_if_fail (perm != NULL, FALSE); + g_return_val_if_fail (out_user != NULL, FALSE); - /* If permissions list is empty, the connection is world-accessible. */ - if (permissions_entries == NULL) { - allowed = TRUE; - goto out; + if (!g_str_has_prefix (perm, USER_TAG)) + return FALSE; + perm += strlen (USER_TAG); + + /* Look for trailing ':' */ + end = strchr (perm, ':'); + if (!end) + end = perm + strlen (perm); + + userlen = end - perm; + if (userlen > (out_user_size + 1)) + return FALSE; + memcpy (out_user, perm, userlen); + out_user[userlen] = '\0'; + return TRUE; +} + +static gboolean +uid_in_acl (NMConnection *self, + NMSessionMonitor *smon, + const uid_t uid, + GError **error) +{ + NMSettingConnection *s_con; + guint32 num, i; + const char *user = NULL; + GError *local = NULL; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (smon != NULL, FALSE); + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (self, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + /* Reject the request if the request comes from no session at all */ + if (nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + "No session found for uid %d (%s)", + uid, + local && local->message ? local->message : "unknown"); + g_clear_error (&local); + return FALSE; } - /* The "default session" can only access world-accessible connections. */ - if (nm_session_info_is_default_session (session)) { - allowed = FALSE; - goto out; + if (!user) { + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + "Could not determine username for uid %d", + uid); + return FALSE; } - session_user = nm_session_info_get_unix_user (session); + /* Match the username returned by the session check to a user in the ACL */ + num = nm_setting_connection_get_num_permissions (s_con); + if (num == 0) + return TRUE; /* visible to all */ - for (p_iter = permissions_entries; p_iter != NULL; p_iter = p_iter->next) { - char **p_comps = g_strsplit ((char *)p_iter->data, ":", 3); - char *type = p_comps[0]; - char *name = p_comps[1]; + for (i = 0; i < num; i++) { + const char *perm; + char buf[75]; - if (g_str_equal (type, "user")) { - if (g_str_equal (session_user, name)) { - allowed = TRUE; - goto out; + perm = nm_setting_connection_get_permission (s_con, i); + g_assert (perm); + if (perm_to_user (perm, buf, sizeof (buf))) { + if (strcmp (buf, user) == 0) { + /* Yay, permitted */ + return TRUE; } - } else { - nm_log_err (LOGD_SYS_SET, - "connection %s: failed to parse permissions entry '%s'", - nm_setting_connection_get_id (setting_connection), - (char *) p_iter->data); } } -out: - nm_utils_slist_free (permissions_entries, g_free); - return allowed; -} - -static void -set_visibility (NMSysconfigConnection *self, gboolean new_visibility) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - DBusGConnection *connection = nm_dbus_manager_get_connection (nm_dbus_manager_get()); - const char *dbus_path = nm_connection_get_path (NM_CONNECTION (self)); - - if (new_visibility && !priv->visible) { - priv->visible = TRUE; - - dbus_g_connection_register_g_object (connection, dbus_path, G_OBJECT (self)); - g_signal_emit (self, signals[UNHIDDEN], 0); - } - else - if (!new_visibility && priv->visible) { - priv->visible = FALSE; - - g_signal_emit (self, signals[REMOVED], 0); - dbus_g_connection_unregister_g_object (connection, G_OBJECT (self)); - } -} - -/* One of the sessions on our access list has been removed. */ -static void -session_removed_cb (NMSessionInfo *removed_session, - gpointer user_data) -{ - NMSysconfigConnection *connection = NM_SYSCONFIG_CONNECTION (user_data); - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); - char *removed_session_id = nm_session_info_get_id (removed_session); - - g_hash_table_remove (priv->access_list, removed_session_id); - - if (g_hash_table_size (priv->access_list) == 0) { - set_visibility (connection, FALSE); - } else { - g_signal_emit (connection, signals[CHECK_PERMISSIONS], 0); - } -} - -/* The session manager reports that a new session has been added. */ -static void -session_added_cb (NMSessionManager *mananager, - NMSessionInfo *session, - gpointer user_data) -{ - NMSysconfigConnection *connection = NM_SYSCONFIG_CONNECTION (user_data); - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); - - if (session_allowed (connection, session)) { - g_object_ref (session); - g_signal_connect (session, NM_SESSION_INFO_REMOVED, - G_CALLBACK(session_removed_cb), connection); - g_hash_table_insert (priv->access_list, nm_session_info_get_id (session), session); - g_signal_emit (connection, signals[CHECK_PERMISSIONS], 0); - set_visibility (connection, TRUE); - } -} - -/* Our permissions property may have been changed. Update the access list. */ -static void -update_access_list (NMSysconfigConnection *self) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - NMSessionManager *session_manager = nm_session_manager_get (); - GSList *sessions, *iter; - - g_hash_table_remove_all (priv->access_list); - sessions = nm_session_manager_get_sessions (session_manager); - for (iter = sessions; iter != NULL; iter = iter->next) { - NMSessionInfo *session = NM_SESSION_INFO (iter->data); - - if (session_allowed (self, session)) { - g_object_ref (session); - g_signal_connect (session, NM_SESSION_INFO_REMOVED, - G_CALLBACK (session_removed_cb), self); - g_hash_table_insert (priv->access_list, nm_session_info_get_id (session), session); - } - } - g_slist_free (sessions); - - if (g_hash_table_size (priv->access_list) == 0) { - set_visibility (self, FALSE); - } else { - g_signal_emit (self, signals[CHECK_PERMISSIONS], 0); - } -} - -gboolean -nm_sysconfig_connection_is_visible (NMSysconfigConnection *connection) -{ - g_return_val_if_fail (NM_SYSCONFIG_CONNECTION (connection), FALSE); - - return NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection)->visible; -} - -GSList * -nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *self) -{ - GHashTableIter iter; - gpointer value; - GSList *sessions = NULL; - - g_hash_table_iter_init (&iter, NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self)->access_list); - while (g_hash_table_iter_next (&iter, NULL, &value)) - sessions = g_slist_prepend (sessions, value); - return sessions; -} - -gboolean -nm_sysconfig_connection_is_accessible_by_session (NMSysconfigConnection *connection, - NMSessionInfo *session) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); - NMSessionInfo *stored_session = NULL; - - g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), FALSE); - g_return_val_if_fail (NM_IS_SESSION_INFO (session), FALSE); - - stored_session = g_hash_table_lookup (priv->access_list, - nm_session_info_get_id (session)); - - if (stored_session == session) - return TRUE; - + g_set_error (error, + NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + "uid %d has no permission to perform this operation", + uid); return FALSE; } /**************************************************************/ +static void +set_visible (NMSysconfigConnection *self, gboolean new_visible) +{ + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + + if (new_visible == priv->visible) + return; + priv->visible = new_visible; + g_object_notify (G_OBJECT (self), NM_SYSCONFIG_CONNECTION_VISIBLE); +} + +gboolean +nm_sysconfig_connection_is_visible (NMSysconfigConnection *self) +{ + g_return_val_if_fail (NM_SYSCONFIG_CONNECTION (self), FALSE); + + return NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self)->visible; +} + +void +nm_sysconfig_connection_recheck_visibility (NMSysconfigConnection *self) +{ + NMSysconfigConnectionPrivate *priv; + NMSettingConnection *s_con; + guint32 num, i; + + g_return_if_fail (NM_SYSCONFIG_CONNECTION (self)); + + priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (self), + NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + /* Check every user in the ACL for a session */ + num = nm_setting_connection_get_num_permissions (s_con); + if (num == 0) { + /* Visible to all */ + set_visible (self, TRUE); + return; + } + + for (i = 0; i < num; i++) { + const char *perm; + char buf[75]; + + perm = nm_setting_connection_get_permission (s_con, i); + g_assert (perm); + if (perm_to_user (perm, buf, sizeof (buf))) { + if (nm_session_monitor_user_has_session (priv->session_monitor, buf, NULL, NULL)) { + set_visible (self, TRUE); + return; + } + } + } + + set_visible (self, FALSE); +} + +/**************************************************************/ + /* Update the settings of this connection to match that of 'new', taking care to * make a private copy of secrets. */ gboolean @@ -287,8 +269,7 @@ nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, g_object_unref (priv->secrets); priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); - update_access_list (self); - + nm_sysconfig_connection_recheck_visibility (self); success = TRUE; } g_hash_table_destroy (new_settings); @@ -445,7 +426,7 @@ do_delete (NMSysconfigConnection *connection, gpointer user_data) { g_object_ref (connection); - set_visibility (connection, FALSE); + set_visible (connection, FALSE); g_signal_emit (connection, signals[PURGED], 0); callback (connection, NULL, user_data); g_object_unref (connection); @@ -590,9 +571,7 @@ typedef void (*AuthCallback) (NMSysconfigConnection *connection, typedef struct { NMSysconfigConnection *self; DBusGMethodInvocation *context; - PolkitSubject *subject; GCancellable *cancellable; - gboolean check_modify; gboolean disposed; AuthCallback callback; @@ -607,11 +586,8 @@ auth_finish (PendingAuth *info, GError *error) info->callback (info->self, info->context, error, info->callback_data); - if (info->subject) - g_object_unref (info->subject); - if (info->cancellable) - g_object_unref (info->cancellable); - + g_object_unref (info->cancellable); + memset (info, 0, sizeof (PendingAuth)); g_slice_free (PendingAuth, info); } @@ -620,88 +596,36 @@ auth_pk_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PendingAuth *info = user_data; NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); - PolkitAuthorizationResult *pk_result; + PolkitAuthorizationResult *pk_result = NULL; GError *error = NULL; if (info->disposed) { error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "Request was canceled."); - auth_finish (info, error); - g_error_free (error); - return; + goto out; } pk_result = polkit_authority_check_authorization_finish (priv->authority, result, &error); - - if (error) { - auth_finish (info, error); - g_error_free (error); - return; - } + if (error) + goto out; if (!polkit_authorization_result_get_is_authorized (pk_result)) { error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); - auth_finish (info, error); - g_error_free (error); goto out; } - auth_finish (info, NULL); - out: - g_object_unref (pk_result); -} + auth_finish (info, error); -static void -auth_get_session_cb (NMSessionInfo *session, - GError *session_error, - gpointer user_data) -{ - PendingAuth *info = user_data; - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); - GError *error = NULL; - - if (info->disposed || !session) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - auth_finish (info, error); + if (error) g_error_free (error); - return; - } - - if (!nm_sysconfig_connection_is_accessible_by_session (info->self, session)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, - "Caller's session is not authorized to access connection."); - auth_finish (info, error); - g_error_free (error); - return; - } - - if (!info->check_modify) { - auth_finish (info, NULL); - } else { - char *sender = dbus_g_method_get_sender (info->context); - info->subject = polkit_system_bus_name_new (sender); - info->cancellable = g_cancellable_new(); - g_free (sender); - - polkit_authority_check_authorization (priv->authority, - info->subject, - NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - info->cancellable, - auth_pk_cb, - info); - } - + if (pk_result) + g_object_unref (pk_result); } static void @@ -712,22 +636,63 @@ auth_start (NMSysconfigConnection *self, gpointer callback_data) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - PendingAuth *info = g_slice_new (PendingAuth); + PendingAuth *info; + gulong sender_uid = G_MAXULONG; + GError *error = NULL; + char *sender; + const char *error_desc = NULL; + PolkitSubject *subject; + + /* Get the caller's UID */ + if (!nm_auth_get_caller_uid (context, NULL, &sender_uid, &error_desc)) { + error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, + NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + goto error; + } + + /* Make sure the UID can view this connection */ + if (0 != sender_uid) { + if (!uid_in_acl (NM_CONNECTION (self), priv->session_monitor, sender_uid, &error)) { + g_assert (error); + goto error; + } + } + + if (!check_modify) { + callback (self, context, NULL, callback_data); + return; + } + + info = g_slice_new (PendingAuth); info->self = self; info->context = context; - info->subject = NULL; info->cancellable = NULL; - info->check_modify = check_modify; info->disposed = FALSE; info->callback_data = callback_data; + info->cancellable = g_cancellable_new(); + + sender = dbus_g_method_get_sender (info->context); + subject = polkit_system_bus_name_new (sender); + g_free (sender); priv->pending_auths = g_slist_prepend (priv->pending_auths, info); - nm_session_manager_get_session_of_caller (nm_session_manager_get(), - context, - auth_get_session_cb, - info); + /* Kick off the PolicyKit request */ + polkit_authority_check_authorization (priv->authority, + subject, + NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, + NULL, + POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, + info->cancellable, + auth_pk_cb, + info); + g_object_unref (subject); + return; +error: + callback (self, context, error, callback_data); + g_error_free (error); } /**** DBus method handlers ************************************/ @@ -977,7 +942,6 @@ static void nm_sysconfig_connection_init (NMSysconfigConnection *self) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - NMSessionManager *session_manager; static guint32 dbus_counter = 0; char *dbus_path; GError *error = NULL; @@ -995,11 +959,7 @@ nm_sysconfig_connection_init (NMSysconfigConnection *self) g_free (dbus_path); priv->visible = FALSE; - priv->access_list = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - session_manager = nm_session_manager_get(); - g_signal_connect (session_manager, NM_SESSION_MANAGER_SESSION_ADDED, - G_CALLBACK (session_added_cb), self); - + priv->session_monitor = nm_session_monitor_get (); } static void @@ -1007,10 +967,7 @@ dispose (GObject *object) { NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (object); NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - NMSessionManager *session_manager = nm_session_manager_get (); GSList *iter; - GHashTableIter hiter; - gpointer value; if (priv->secrets) g_object_unref (priv->secrets); @@ -1025,18 +982,34 @@ dispose (GObject *object) g_slist_free (priv->pending_auths); priv->pending_auths = NULL; - set_visibility (self, FALSE); - g_signal_handlers_disconnect_by_func (session_manager, session_added_cb, self); + set_visible (self, FALSE); - g_hash_table_iter_init (&hiter, priv->access_list); - while (g_hash_table_iter_next (&hiter, NULL, &value)) - g_signal_handlers_disconnect_by_func (NM_SESSION_INFO (value), session_removed_cb, self); - g_hash_table_destroy (priv->access_list); - priv->access_list = NULL; + g_object_unref (priv->session_monitor); G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object); } +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + case PROP_VISIBLE: + g_value_set_boolean (value, NM_SYSCONFIG_CONNECTION_GET_PRIVATE (object)->visible); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + static void nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) { @@ -1046,10 +1019,22 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) /* Virtual methods */ object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + class->commit_changes = commit_changes; class->delete = do_delete; class->get_secrets = get_secrets; + /* Properties */ + g_object_class_install_property + (object_class, PROP_VISIBLE, + g_param_spec_boolean (NM_SYSCONFIG_CONNECTION_VISIBLE, + "Visible", + "Visible", + FALSE, + G_PARAM_READABLE)); + /* Signals */ signals[UPDATED] = g_signal_new (NM_SYSCONFIG_CONNECTION_UPDATED, @@ -1078,15 +1063,6 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - signals[UNHIDDEN] = - g_signal_new (NM_SYSCONFIG_CONNECTION_UNHIDDEN, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_sysconfig_connection_object_info); diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index 80e074367..19962c00e 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -16,6 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 - 2010 Red Hat, Inc. */ #ifndef NM_SYSCONFIG_CONNECTION_H @@ -23,7 +24,6 @@ #include #include -#include "nm-session-info.h" G_BEGIN_DECLS @@ -34,10 +34,10 @@ G_BEGIN_DECLS #define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) #define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) -#define NM_SYSCONFIG_CONNECTION_UPDATED "updated" -#define NM_SYSCONFIG_CONNECTION_REMOVED "removed" -#define NM_SYSCONFIG_CONNECTION_PURGED "purged" -#define NM_SYSCONFIG_CONNECTION_UNHIDDEN "unhidden" +#define NM_SYSCONFIG_CONNECTION_UPDATED "updated" +#define NM_SYSCONFIG_CONNECTION_REMOVED "removed" +#define NM_SYSCONFIG_CONNECTION_PURGED "purged" +#define NM_SYSCONFIG_CONNECTION_VISIBLE "visible" typedef struct _NMSysconfigConnection NMSysconfigConnection; @@ -105,13 +105,9 @@ void nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, NMSysconfigConnectionGetSecretsFunc callback, gpointer user_data); -gboolean nm_sysconfig_connection_is_visible (NMSysconfigConnection *connection); - -gboolean nm_sysconfig_connection_is_accessible_by_session (NMSysconfigConnection *connection, - NMSessionInfo *session); - -GSList * nm_sysconfig_connection_get_session_access_list (NMSysconfigConnection *connection); +gboolean nm_sysconfig_connection_is_visible (NMSysconfigConnection *self); +void nm_sysconfig_connection_recheck_visibility (NMSysconfigConnection *self); G_END_DECLS diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 8ac048fda..6045d9a51 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -60,6 +60,7 @@ #include "nm-logging.h" #include "nm-dbus-manager.h" #include "nm-manager-auth.h" +#include "nm-session-monitor.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -101,6 +102,9 @@ typedef struct { DBusGConnection *bus; gboolean exported; + NMSessionMonitor *session_monitor; + guint session_monitor_id; + PolkitAuthority *authority; guint auth_changed_id; char *config_file; @@ -531,6 +535,20 @@ load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) return success; } +static void +session_monitor_changed_cb (NMSessionMonitor *monitor, gpointer user_data) +{ + NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data); + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data; + + /* Update visibility on all connections */ + g_hash_table_iter_init (&iter, priv->all_connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + } +} + static void connection_removed (NMSysconfigConnection *connection, gpointer user_data) @@ -540,18 +558,6 @@ connection_removed (NMSysconfigConnection *connection, g_hash_table_remove (priv->visible_connections, connection); } -static void -connection_unhidden (NMSysconfigConnection *connection, - gpointer user_data) -{ - NMSysconfigSettings *settings = user_data; - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (settings); - - g_hash_table_insert (priv->visible_connections, - connection, GINT_TO_POINTER (1)); - g_signal_emit (settings, signals[NEW_CONNECTION], 0, connection); -} - static void connection_purged (NMSysconfigConnection *connection, gpointer user_data) @@ -584,10 +590,6 @@ claim_connection (NMSysconfigSettings *self, NM_SYSCONFIG_CONNECTION_PURGED, G_CALLBACK (connection_purged), self); - g_signal_connect (connection, - NM_SYSCONFIG_CONNECTION_UNHIDDEN, - G_CALLBACK (connection_unhidden), - self); if (nm_sysconfig_connection_is_visible (connection)) { g_hash_table_insert (priv->visible_connections, connection, GINT_TO_POINTER (1)); @@ -1287,6 +1289,12 @@ dispose (GObject *object) g_slist_free (priv->pk_calls); priv->pk_calls = NULL; + if (priv->session_monitor) { + g_signal_handler_disconnect (priv->session_monitor, priv->session_monitor_id); + g_object_unref (priv->session_monitor); + priv->session_monitor = NULL; + } + G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); } @@ -1441,5 +1449,12 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) error && error->message ? error->message : "(unknown)"); g_clear_error (&error); } + + priv->session_monitor = nm_session_monitor_get (); + g_assert (priv->session_monitor); + priv->session_monitor_id = g_signal_connect (priv->session_monitor, + "changed", + G_CALLBACK (session_monitor_changed_cb), + self); } From d2d48676fcc200a8c7f91414d8c55ba8f48ef19f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 11:19:29 -0500 Subject: [PATCH 044/264] settings: remove older session monitor code --- src/system-settings/Makefile.am | 6 +- src/system-settings/nm-session-info.c | 189 ------ src/system-settings/nm-session-info.h | 59 -- src/system-settings/nm-session-manager.c | 752 ----------------------- src/system-settings/nm-session-manager.h | 82 --- 5 files changed, 1 insertion(+), 1087 deletions(-) delete mode 100644 src/system-settings/nm-session-info.c delete mode 100644 src/system-settings/nm-session-info.h delete mode 100644 src/system-settings/nm-session-manager.c delete mode 100644 src/system-settings/nm-session-manager.h diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 5f18623ce..67980767c 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -25,11 +25,7 @@ libsystem_settings_la_SOURCES = \ nm-sysconfig-connection.c \ nm-sysconfig-connection.h \ nm-default-wired-connection.c \ - nm-default-wired-connection.h \ - nm-session-info.c \ - nm-session-info.h \ - nm-session-manager.c \ - nm-session-manager.h + nm-default-wired-connection.h libsystem_settings_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/system-settings/nm-session-info.c b/src/system-settings/nm-session-info.c deleted file mode 100644 index 3faf407dd..000000000 --- a/src/system-settings/nm-session-info.c +++ /dev/null @@ -1,189 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager user session tracker -- per-session data - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2010 Daniel Gnoutcheff - */ - -#include "nm-session-info.h" -#include "nm-dbus-glib-types.h" -#include "nm-utils.h" - -G_DEFINE_TYPE (NMSessionInfo, nm_session_info, G_TYPE_OBJECT); - -typedef struct { - char *id; - char *user; - gboolean is_default; -} NMSessionInfoPrivate; - -#define NM_SESSION_INFO_GET_PRIVATE(self) (G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SESSION_INFO, NMSessionInfoPrivate)) - -enum { - PROP_0, - PROP_ID, - PROP_USER, - PROP_IS_DEFAULT -}; - -char * -nm_session_info_get_id (NMSessionInfo *self) -{ - g_return_val_if_fail (NM_IS_SESSION_INFO (self), NULL); - - return NM_SESSION_INFO_GET_PRIVATE (self)->id; -} - -char * -nm_session_info_get_unix_user (NMSessionInfo *self) -{ - g_return_val_if_fail (NM_IS_SESSION_INFO (self), NULL); - - return NM_SESSION_INFO_GET_PRIVATE (self)->user; -} - -gboolean -nm_session_info_is_default_session (NMSessionInfo *self) -{ - g_return_val_if_fail (NM_IS_SESSION_INFO (self), FALSE); - - return NM_SESSION_INFO_GET_PRIVATE (self)->is_default; -} - -static void -set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); - - switch (property_id) { - case PROP_ID: - g_free (priv->id); - priv->id = g_value_dup_string (value); - break; - case PROP_USER: - g_free (priv->user); - priv->user = g_value_dup_string (value); - break; - case PROP_IS_DEFAULT: - priv->is_default = g_value_get_boolean (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); - - switch (property_id) { - case PROP_ID: - g_value_set_string (value, priv->id); - break; - case PROP_USER: - g_value_set_string (value, priv->user); - break; - case PROP_IS_DEFAULT: - g_value_set_boolean (value, priv->is_default); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -nm_session_info_init (NMSessionInfo *self) { -} - -static void -dispose (GObject *object) -{ - NMSessionInfoPrivate *priv = NM_SESSION_INFO_GET_PRIVATE (object); - - if (priv->id) { - g_free (priv->id); - priv->id = NULL; - } - - if (priv->user) { - g_free (priv->user); - priv->user = NULL; - } - - G_OBJECT_CLASS (nm_session_info_parent_class)->dispose (object); -} - -static void -nm_session_info_class_init (NMSessionInfoClass *info_class) { - GObjectClass *g_class = G_OBJECT_CLASS (info_class); - - g_type_class_add_private (g_class, sizeof(NMSessionInfoPrivate)); - g_class->set_property = set_property; - g_class->get_property = get_property; - g_class->dispose = dispose; - - g_object_class_install_property - (g_class, PROP_ID, - g_param_spec_string ( - NM_SESSION_INFO_ID, - "ConsoleKitSID", - "ConsoleKit session ID, or \"[none]\" if this is the \"default\" " - "session.", - NM_SESSION_INFO_DEFAULT_ID, - G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (g_class, PROP_USER, - g_param_spec_string ( - NM_SESSION_INFO_UNIX_USER, - "UnixUser", - "String name of the unix user who owns this session, or NULL if " - "this is the default session.", - NULL, - G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property - (g_class, PROP_IS_DEFAULT, - g_param_spec_boolean ( - NM_SESSION_INFO_IS_DEFAULT, - "IsDefaultSession", - "Indicates if this NMSessionInfo instance represents the " - "\"default\" session, the session containing all processes that " - "do not belong to a ConsoleKit-recognized session.", - TRUE, - G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); - - g_signal_new ( - NM_SESSION_INFO_REMOVED, - NM_TYPE_SESSION_INFO, - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} diff --git a/src/system-settings/nm-session-info.h b/src/system-settings/nm-session-info.h deleted file mode 100644 index aebe4f59b..000000000 --- a/src/system-settings/nm-session-info.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager user session tracker -- per-session data - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2010 Daniel Gnoutcheff - */ - -#ifndef NM_SESSION_INFO_H -#define NM_SESSION_INFO_H - -#include - -G_BEGIN_DECLS - -#define NM_TYPE_SESSION_INFO (nm_session_info_get_type ()) -#define NM_SESSION_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SESSION_INFO, NMSessionInfo)) -#define NM_SESSION_INFO_CLASS(class_struct) (G_TYPE_CHECK_CLASS_CAST ((class_struct), NM_TYPE_SESSION_INFO, NMSessionInfoClass)) -#define NM_IS_SESSION_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SESSION_INFO)) -#define NM_IS_SESSION_INFO_CLASS(class_struct) (G_TYPE_CHECK_CLASS_TYPE ((class_struct), NM_TYPE_SESSION_INFO)) -#define NM_SESSION_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SESSION_INFO, NMSessionInfoClass)) - -#define NM_SESSION_INFO_ID "session-id" -#define NM_SESSION_INFO_UNIX_USER "unix-user" -#define NM_SESSION_INFO_IS_DEFAULT "is-default" - -#define NM_SESSION_INFO_REMOVED "removed" - -#define NM_SESSION_INFO_DEFAULT_ID "[none]" - -typedef struct { - GObject parent; -} NMSessionInfo; - -typedef struct { - GObjectClass parent_class; -} NMSessionInfoClass; - -GType nm_session_info_get_type (void); - -char * nm_session_info_get_id (NMSessionInfo *self); -char * nm_session_info_get_unix_user (NMSessionInfo *self); -gboolean nm_session_info_is_default_session (NMSessionInfo *self); - -G_END_DECLS - -#endif diff --git a/src/system-settings/nm-session-manager.c b/src/system-settings/nm-session-manager.c deleted file mode 100644 index 80c4ab60e..000000000 --- a/src/system-settings/nm-session-manager.c +++ /dev/null @@ -1,752 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager user session tracker - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2010 Daniel Gnoutcheff - */ - -#include -#include -#include -#include -#include -#include -#include "nm-dbus-manager.h" -#include "nm-session-manager.h" -#include "nm-logging.h" - -G_DEFINE_TYPE (NMSessionManager, nm_session_manager, G_TYPE_OBJECT); - -/* NMSessionManager data */ -typedef struct { - gboolean disposed; - gboolean initialized; - guint init_sessions_left; - - /* The master table of NMSessionInfo instances, keyed by session id. */ - GHashTable *sessions; - - /* DBus proxy of the ConsoleKit manager */ - DBusGProxy *ck_manager; - - /* Table of PendingSessionInfo structs, representing sessions for which we - * are waiting for information on. Keyed by session id. */ - GHashTable *pending_sessions; - - /* List of PendingCallerInfo structs, representing ongoing - * get_session_of_caller calls. */ - GSList *pending_callers; -} NMSessionManagerPrivate; - -#define NM_SESSION_MANAGER_GET_PRIVATE(self) (G_TYPE_INSTANCE_GET_PRIVATE (self, NM_TYPE_SESSION_MANAGER, NMSessionManagerPrivate)) - - -enum { - ADDED, - INIT_DONE, - - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL] = { 0 }; - - -/**** general utilities for managing callbacks *******************************/ - -typedef struct { - NMSessionFunc callback; - gpointer user_data; -} CallbackInfo; - -/* Allocate a new CallbackInfo for the given callback & data */ -static CallbackInfo * -callback_info_new (NMSessionFunc callback, gpointer user_data) -{ - CallbackInfo *info = g_slice_new (CallbackInfo); - info->callback = callback; - info->user_data = user_data; - return info; -} - -/* Run the callback represented by cb_info and free it. */ -static void -callback_info_run (CallbackInfo *cb_info, NMSessionInfo *session, GError *error) -{ - if (cb_info->callback) { - (cb_info->callback) (session, error, cb_info->user_data); - } - g_slice_free (CallbackInfo, cb_info); -} - -/* Run the callback with an error message indicating that we've been disposed. */ -static void -callback_info_fail_disposed (CallbackInfo *cb_info) -{ - GError *error = g_error_new (NM_SESSION_MANAGER_ERROR, - NM_SESSION_MANAGER_ERROR_DISPOSED, - "NMSessionManager was disposed before operation completed."); - callback_info_run (cb_info, NULL, error); - g_error_free (error); -} - - -/**** get_session stuff ******************************************************/ - -typedef struct { - NMSessionManager *manager; - DBusGProxy *session_proxy; - DBusGProxyCall *session_call; - char *session_id; - - GSList *callbacks; /* List of CallbackInfo structs */ -} PendingSessionInfo; - -/* Called by the pending_sessions GHashTable when removing a PendingSession */ -static void -pending_session_destroy (gpointer data) -{ - PendingSessionInfo *pending = (PendingSessionInfo *) data; - - // FIXME this is ugly copy-and-paste - // If any callbacks remain, send failure messages to them. - while (pending->callbacks) { - CallbackInfo *cb_info = (CallbackInfo *) pending->callbacks->data; - callback_info_fail_disposed (cb_info); - pending->callbacks = g_slist_remove (pending->callbacks, cb_info); - } - - g_free (pending->session_id); - g_object_unref (pending->session_proxy); - g_object_unref (pending->session_call); - g_slice_free (PendingSessionInfo, pending); -} - -static void -pending_session_finish (PendingSessionInfo *pending, - NMSessionInfo *session, - GError *error) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (pending->manager); - - while (pending->callbacks) { - CallbackInfo *cb_info = (CallbackInfo *) pending->callbacks->data; - callback_info_run (cb_info, session, error); - pending->callbacks = g_slist_remove (pending->callbacks, cb_info); - } - - g_hash_table_remove (priv->pending_sessions, pending->session_id); - // pending_session_destroy() will be called by GHashTable -} - -static void -pending_session_cancel (PendingSessionInfo *pending, GError *error) -{ - dbus_g_proxy_cancel_call (pending->session_proxy, pending->session_call); - pending_session_finish (pending, NULL, error); -} - -static void -get_unix_user_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - PendingSessionInfo *pending = (PendingSessionInfo *) user_data; - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (pending->manager); - guint user_id; - struct passwd *pw_info = NULL; - NMSessionInfo *session = NULL; - GError *error = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, NULL, - G_TYPE_UINT, &user_id, G_TYPE_NONE)) { - error = g_error_new (NM_SESSION_MANAGER_ERROR, - NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, - "session %s: failed to get uid", - pending->session_id); - goto out; - } - - pw_info = getpwuid (user_id); - if (!pw_info) { - error = g_error_new (NM_SESSION_MANAGER_ERROR, - NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, - "session %s: failed to get username for uid %u", - pending->session_id, user_id); - goto out; - } - - session = g_object_new (NM_TYPE_SESSION_INFO, - NM_SESSION_INFO_ID, pending->session_id, - NM_SESSION_INFO_UNIX_USER, pw_info->pw_name, - NULL); - g_assert (session); - - g_hash_table_insert (priv->sessions, nm_session_info_get_id (session), session); - g_signal_emit (pending->manager, signals[ADDED], 0, session); - -out: - pending_session_finish (pending, session, error); - - g_clear_error (&error); -} - -/* Start the process of loading information about the given session, and return - * the PendingSessionInfo struct that represents it. - */ -static PendingSessionInfo * -pending_session_start (NMSessionManager *self, char *session_id) -{ - PendingSessionInfo *pending = g_slice_new (PendingSessionInfo); - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - DBusGConnection *connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - - pending->session_id = g_strdup (session_id); - pending->manager = self; - pending->callbacks = NULL; - - pending->session_proxy = dbus_g_proxy_new_for_name (connection, - "org.freedesktop.ConsoleKit", - pending->session_id, - "org.freedesktop.ConsoleKit.Session"); - - pending->session_call = dbus_g_proxy_begin_call (pending->session_proxy, - "GetUnixUser", - get_unix_user_cb, - pending, - NULL, - G_TYPE_INVALID); - - g_hash_table_insert (priv->pending_sessions, pending->session_id, pending); - - return pending; -} - -static PendingSessionInfo * -pending_session_find (NMSessionManager *self, char *session_id) -{ - GHashTable *pending_sessions = NM_SESSION_MANAGER_GET_PRIVATE (self)->pending_sessions; - return g_hash_table_lookup (pending_sessions, session_id); -} - -static void -pending_session_add_callback (PendingSessionInfo *pending, CallbackInfo *cb_info) -{ - pending->callbacks = g_slist_prepend (pending->callbacks, cb_info); -} - -static void -get_session_internal (NMSessionManager *self, - char *session_id, - CallbackInfo *cb_info) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - NMSessionInfo *session; - - if (priv->disposed) { - callback_info_fail_disposed (cb_info); - return; - } - - session = g_hash_table_lookup (priv->sessions, session_id); - if (session) { - callback_info_run (cb_info, session, NULL); - } else { - PendingSessionInfo *pending = pending_session_find (self, session_id); - if (!pending) { - pending = pending_session_start (self, session_id); - } - pending_session_add_callback (pending, cb_info); - } -} - -void -nm_session_manager_get_session (NMSessionManager *self, - char *session_id, - NMSessionFunc callback, - gpointer user_data) -{ - CallbackInfo *cb_info; - - g_return_if_fail (NM_IS_SESSION_MANAGER (self)); - g_return_if_fail (session_id != NULL); - g_return_if_fail (callback != NULL); - - cb_info = callback_info_new (callback, user_data); - - get_session_internal (self, session_id, cb_info); -} - -/**** get_sessions stuff *****************************************************/ - -static void -prepend_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **sessions = (GSList **) user_data; - - *sessions = g_slist_prepend (*sessions, value); -} - -GSList * -nm_session_manager_get_sessions (NMSessionManager *self) -{ - NMSessionManagerPrivate *priv; - GSList *sessions; - - g_return_val_if_fail (NM_IS_SESSION_MANAGER (self), NULL); - - priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - g_hash_table_foreach (priv->sessions, prepend_slist, &sessions); - - return sessions; -} - -/**** ConsoleKit signal handling *********************************************/ - -/* ConsoleKit reports a new session. Pull it into our cache. */ -static void -session_added (NMSessionManager *self, char *new_session) -{ - nm_session_manager_get_session (self, new_session, NULL, NULL); -} - -/* ConsoleKit reports that a session has been removed. */ -static void -session_removed (NMSessionManager *self, char *removed_id) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - NMSessionInfo *removed = g_hash_table_lookup (priv->sessions, removed_id); - - if (removed) { - g_signal_emit_by_name (removed, NM_SESSION_INFO_REMOVED); - g_hash_table_remove (priv->sessions, removed_id); - } else { - PendingSessionInfo *removed_pending = pending_session_find (self, removed_id); - if (removed_pending) { - GError *error = g_error_new (NM_SESSION_MANAGER_ERROR, - NM_SESSION_MANAGER_ERROR_NOT_FOUND, - "session %s removed moments ago", - removed_id); - pending_session_cancel (removed_pending, error); - g_error_free (error); - } - } -} - -/* A DBus signal filter for picking up ConsoleKit signals indicating that - * sessions have been added or removed. We use this custom message filter as - * we'd otherwise have to keep track of all the seats and register signal - * handlers in every one. */ -static DBusHandlerResult -ck_session_signal_filter (DBusConnection *connection, - DBusMessage *message, - void *user_data) -{ - NMSessionManager *self = NM_SESSION_MANAGER (user_data); - char *session_id; - - // TODO: filter by sender? - - if (dbus_message_is_signal (message, - "org.freedesktop.ConsoleKit.Seat", - "SessionAdded")) { - if (dbus_message_get_args (message, NULL, - DBUS_TYPE_OBJECT_PATH, &session_id, - DBUS_TYPE_INVALID)) { - session_added (self, session_id); - } - } - else - if (dbus_message_is_signal (message, - "org.freedesktop.ConsoleKit.Seat", - "SessionRemoved")) { - if (dbus_message_get_args (message, NULL, - DBUS_TYPE_OBJECT_PATH, &session_id, - DBUS_TYPE_INVALID)) { - session_removed (self, session_id); - } - } - - // If anything else registers message filters for these signals for some - // reason, we want to be sure not to step on them. - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - -/**** get_session_of_caller stuff ********************************************/ - -typedef struct { - NMSessionManager *manager; - CallbackInfo *cb_info; - DBusGProxy *bus_proxy; - DBusGProxy *current_call_proxy; - DBusGProxyCall *current_call; - char *caller_bus_name; - char *session_id; -} PendingCallerInfo; - -static void -pending_caller_free (PendingCallerInfo *info) -{ - if (info->bus_proxy) - g_object_unref (info->bus_proxy); - - if (info->caller_bus_name) - g_free (info->caller_bus_name); - - if (info->session_id) - g_free (info->session_id); - - // cb_info gets freed when the callback it wraps is run - - g_slice_free (PendingCallerInfo, info); -} - -static void -pending_caller_dispose (gpointer data) -{ - PendingCallerInfo *info = (PendingCallerInfo *) data; - - if (info->current_call) - dbus_g_proxy_cancel_call (info->current_call_proxy, info->current_call); - - callback_info_fail_disposed (info->cb_info); - pending_caller_free (info); -} - -static void -pending_caller_cb (NMSessionInfo *session, GError *error, gpointer user_data) -{ - PendingCallerInfo *info = (PendingCallerInfo *) user_data; - - if (!session) { - get_session_internal (info->manager, NM_SESSION_INFO_DEFAULT_ID, info->cb_info); - } else { - callback_info_run (info->cb_info, session, error); - } - - pending_caller_free (info); -} - -static void -pending_caller_abort (PendingCallerInfo *info, GError *error) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (info->manager); - - priv->pending_callers = g_slist_remove (priv->pending_callers, info); - pending_caller_cb (NULL, error, info); -} - -static void -dbus_name_has_owner_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - PendingCallerInfo *info = (PendingCallerInfo *) user_data; - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (info->manager); - gboolean has_owner; - - if (!dbus_g_proxy_end_call (proxy, call_id, NULL, - G_TYPE_BOOLEAN, &has_owner, G_TYPE_INVALID) - || !has_owner) { - pending_caller_abort (info, NULL); - return; - } - - info->current_call = NULL; - info->current_call_proxy = NULL; - priv->pending_callers = g_slist_remove (priv->pending_callers, info); - - nm_session_manager_get_session (info->manager, info->session_id, - pending_caller_cb, info); -} - -static void -ck_get_session_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - PendingCallerInfo *info = (PendingCallerInfo *) user_data; - - if (!dbus_g_proxy_end_call (proxy, call_id, NULL, - G_TYPE_STRING, &(info->session_id), - G_TYPE_INVALID)) { - pending_caller_abort (info, NULL); - return; - } - - // Finally, ensure that the calling process is still there, so we are sure - // that the process we've just examined is indeed the calling process. - info->current_call = dbus_g_proxy_begin_call (info->bus_proxy, - "NameHasOwner", - dbus_name_has_owner_cb, - info, - NULL, - G_TYPE_STRING, info->caller_bus_name, - G_TYPE_INVALID); - info->current_call_proxy = info->bus_proxy; -} - -static void -dbus_get_pid_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - PendingCallerInfo *info = (PendingCallerInfo *) user_data; - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (info->manager); - guint pid; - - if (!dbus_g_proxy_end_call (proxy, call_id, NULL, - G_TYPE_UINT, &pid, G_TYPE_INVALID)) { - pending_caller_abort (info, NULL); - return; - } - - info->current_call = dbus_g_proxy_begin_call (priv->ck_manager, - "GetSessionForUnixProcess", - ck_get_session_cb, - info, - NULL, - G_TYPE_UINT, pid, - G_TYPE_INVALID); - info->current_call_proxy = priv->ck_manager; -} - -static void -get_session_of_caller_internal (NMSessionManager *manager, - DBusGMethodInvocation *method_call, - CallbackInfo *cb_info) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (manager); - DBusGConnection *connection; - PendingCallerInfo *info; - - if (priv->disposed) { - callback_info_fail_disposed (cb_info); - return; - } - connection = nm_dbus_manager_get_connection (nm_dbus_manager_get()); - - info = g_slice_new (PendingCallerInfo); - info->manager = manager; - info->cb_info = cb_info; - info->caller_bus_name = dbus_g_method_get_sender (method_call); - info->bus_proxy = dbus_g_proxy_new_for_name (connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); - - info->current_call = dbus_g_proxy_begin_call (info->bus_proxy, - "GetConnectionUnixProcessID", - dbus_get_pid_cb, - info, - NULL, - G_TYPE_STRING, info->caller_bus_name, - G_TYPE_INVALID); - info->current_call_proxy = info->bus_proxy; - - priv->pending_callers = g_slist_prepend (priv->pending_callers, info); - - g_object_unref (connection); -} - -void -nm_session_manager_get_session_of_caller (NMSessionManager *manager, - DBusGMethodInvocation *method_call, - NMSessionFunc callback, - gpointer user_data) -{ - CallbackInfo *cb_info; - - g_return_if_fail (NM_IS_SESSION_MANAGER (manager)); - g_return_if_fail (method_call != NULL); - - cb_info = callback_info_new (callback, user_data); - - get_session_of_caller_internal (manager, method_call, cb_info); -} - - -/**** Initialization & disposal **********************************************/ - -gboolean -nm_session_manager_is_initialized (NMSessionManager *self) -{ - g_return_val_if_fail (NM_IS_SESSION_MANAGER (self), FALSE); - - return NM_SESSION_MANAGER_GET_PRIVATE (self)->initialized; -} - -/* Callback run for sessions loaded during initialization. Emits the - * "initialized" signal when all sessions are loaded. */ -static void -init_session_load_cb (NMSessionInfo *session, GError *error, gpointer user_data) -{ - NMSessionManager *self = NM_SESSION_MANAGER (user_data); - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - - priv->init_sessions_left--; - if (priv->init_sessions_left == 0) { - priv->initialized = TRUE; - g_signal_emit (self, signals[INIT_DONE], 0); - } -} - -static void -ck_get_sessions_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMSessionManager *self = NM_SESSION_MANAGER (user_data); - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - GPtrArray *session_ids; - int i; - - g_assert (priv->initialized == FALSE); - - if (!dbus_g_proxy_end_call (proxy, call_id, NULL, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &session_ids, - G_TYPE_INVALID)) { - nm_log_err (LOGD_SYS_SET, "failed to get initial ConsoleKit session list"); - return; - } - - priv->init_sessions_left = session_ids->len; - if (priv->init_sessions_left > 0) { - for (i = 0; i < session_ids->len; i++) { - char *session_id = g_ptr_array_index (session_ids, i); - nm_session_manager_get_session (self, session_id, init_session_load_cb, self); - g_free (session_id); - } - } else { - /* Make sure we send the init-done signal if there aren't any sessions */ - priv->initialized = TRUE; - g_signal_emit (self, signals[INIT_DONE], 0); - } - g_ptr_array_free (session_ids, TRUE); -} - -static void -nm_session_manager_init (NMSessionManager *self) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (self); - NMSessionInfo *default_session; - DBusGConnection *g_connection = nm_dbus_manager_get_connection (nm_dbus_manager_get()); - DBusConnection *connection = dbus_g_connection_get_connection (g_connection); - - priv->disposed = FALSE; - priv->initialized = FALSE; - priv->sessions = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, g_object_unref); - priv->pending_sessions = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, pending_session_destroy); - priv->pending_callers = NULL; - - default_session = NM_SESSION_INFO (g_object_new (NM_TYPE_SESSION_INFO, - NM_SESSION_INFO_IS_DEFAULT, TRUE, - NM_SESSION_INFO_ID, NM_SESSION_INFO_DEFAULT_ID, - NULL)); - g_hash_table_insert (priv->sessions, - NM_SESSION_INFO_DEFAULT_ID, default_session); - - - priv->ck_manager = dbus_g_proxy_new_for_name (g_connection, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager"); - - // Setup a signal handler to catch SessionAdded/Removed signals for *all* - // seats, all in one shot. - dbus_connection_add_filter (connection, - ck_session_signal_filter, - self, - NULL); - dbus_bus_add_match (connection, - "type='signal',sender='org.freedesktop.ConsoleKit'," - "interface='org.freedesktop.ConsoleKit.Seat',member='SessionAdded'", - NULL); - dbus_bus_add_match (connection, - "type='signal',sender='org.freedesktop.ConsoleKit'," - "interface='org.freedesktop.ConsoleKit.Seat',member='SessionRemoved'", - NULL); - - dbus_g_proxy_begin_call (priv->ck_manager, - "GetSessions", - ck_get_sessions_cb, - self, - NULL, - G_TYPE_INVALID); -} - -static void -dispose (GObject *object) -{ - NMSessionManagerPrivate *priv = NM_SESSION_MANAGER_GET_PRIVATE (object); - DBusConnection *connection = nm_dbus_manager_get_dbus_connection (nm_dbus_manager_get ()); - - if (priv->disposed) - return; - - priv->disposed = TRUE; - - dbus_connection_remove_filter (connection, ck_session_signal_filter, object); - nm_utils_slist_free (priv->pending_callers, pending_caller_dispose); - g_hash_table_unref (priv->pending_sessions); - g_hash_table_unref (priv->sessions); - g_object_unref(priv->ck_manager); - - G_OBJECT_CLASS (nm_session_manager_parent_class)->dispose (object); -} - -static void -nm_session_manager_class_init (NMSessionManagerClass *manager_class) -{ - GObjectClass *g_class = G_OBJECT_CLASS (manager_class); - - g_type_class_add_private (g_class, sizeof(NMSessionManagerPrivate)); - g_class->dispose = dispose; - - signals[ADDED] = - g_signal_new (NM_SESSION_MANAGER_SESSION_ADDED, - NM_TYPE_SESSION_MANAGER, - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, NM_TYPE_SESSION_INFO); - - signals[INIT_DONE] = - g_signal_new (NM_SESSION_MANAGER_INIT_DONE, - NM_TYPE_SESSION_MANAGER, - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -NMSessionManager * -nm_session_manager_get (void) -{ - static NMSessionManager *singleton = NULL; - - if (!singleton) { - singleton = NM_SESSION_MANAGER (g_object_new (NM_TYPE_SESSION_MANAGER, NULL)); - } - - return singleton; -} - -GQuark -nm_session_manager_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) { - ret = g_quark_from_string ("nm-session-manager-error"); - } - - return ret; -} diff --git a/src/system-settings/nm-session-manager.h b/src/system-settings/nm-session-manager.h deleted file mode 100644 index a7f8642ca..000000000 --- a/src/system-settings/nm-session-manager.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager user session tracker - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2010 Daniel Gnoutcheff - */ - -#ifndef NM_SESSION_MANAGER_H -#define NM_SESSION_MANAGER_H - -#include -#include -#include "nm-session-info.h" - -G_BEGIN_DECLS - -#define NM_SESSION_MANAGER_ERROR (nm_session_manager_error_quark()) - -enum { - NM_SESSION_MANAGER_ERROR_NOT_FOUND, - NM_SESSION_MANAGER_ERROR_INFO_GATHERING_FAILED, - NM_SESSION_MANAGER_ERROR_DISPOSED -} NMSessionManagerError; - -#define NM_TYPE_SESSION_MANAGER (nm_session_manager_get_type ()) -#define NM_SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SESSION_MANAGER, NMSessionManager)) -#define NM_SESSION_MANAGER_CLASS(class_struct) (G_TYPE_CHECK_CLASS_CAST ((class_struct), NM_TYPE_SESSION_MANAGER, NMSessionManagerClass)) -#define NM_IS_SESSION_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SESSION_MANAGER)) -#define NM_IS_SESSION_MANAGER_CLASS(class_struct) (G_TYPE_CHECK_CLASS_TYPE ((class_struct), NM_TYPE_SESSION_MANAGER)) -#define NM_SESSION_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SESSION_MANAGER, NMSessionManagerClass)) - -#define NM_SESSION_MANAGER_SESSION_ADDED "session-added" -#define NM_SESSION_MANAGER_INIT_DONE "init-done" - -typedef struct { - GObject parent; -} NMSessionManager; - -typedef struct { - GObjectClass parent_class; -} NMSessionManagerClass; - -typedef void (*NMSessionFunc) (NMSessionInfo *session, - GError *error, - gpointer user_data); - -NMSessionManager * nm_session_manager_get (void); - -gboolean nm_session_manager_is_initialized (NMSessionManager *manager); - -GSList * nm_session_manager_get_sessions (NMSessionManager *manager); - -void nm_session_manager_get_session (NMSessionManager *manager, - char *session_id, - NMSessionFunc callback, - gpointer user_data); - -void nm_session_manager_get_session_of_caller (NMSessionManager *manager, - DBusGMethodInvocation *method_call, - NMSessionFunc callback, - gpointer user_data); - -GType nm_session_manager_get_type (void); - -GQuark nm_session_manager_error_quark (void); - -G_END_DECLS - -#endif From 7b50607fc9220ba82ff1d5157a1eab591510eb26 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 11:36:38 -0500 Subject: [PATCH 045/264] settings: consolidate settings connection purged and removed signals They almost do the same thing. --- src/system-settings/nm-sysconfig-connection.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 947052ec5..0f7adb0dd 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -68,7 +68,6 @@ enum { UPDATED, CHECK_PERMISSIONS, REMOVED, - PURGED, LAST_SIGNAL }; @@ -427,7 +426,7 @@ do_delete (NMSysconfigConnection *connection, { g_object_ref (connection); set_visible (connection, FALSE); - g_signal_emit (connection, signals[PURGED], 0); + g_signal_emit (connection, signals[REMOVED], 0); callback (connection, NULL, user_data); g_object_unref (connection); } @@ -1054,15 +1053,6 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - signals[PURGED] = - g_signal_new (NM_SYSCONFIG_CONNECTION_PURGED, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_sysconfig_connection_object_info); From e5adfcbabe3416c25f5d6da945437be9b3e60735 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 11:40:43 -0500 Subject: [PATCH 046/264] settings: remove remnants of unused CheckPermissions signal --- introspection/nm-sysconfig-connection.xml | 13 +++++-------- src/system-settings/nm-sysconfig-connection.c | 2 -- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/introspection/nm-sysconfig-connection.xml b/introspection/nm-sysconfig-connection.xml index 427213269..b1bc962b5 100644 --- a/introspection/nm-sysconfig-connection.xml +++ b/introspection/nm-sysconfig-connection.xml @@ -43,11 +43,14 @@ - Emitted when some settings changed. + Emitted when some settings changed. Updates do include + connection permission changes, so clients should check whether + they still have permission to access the connection after + receiving this signal. - Contains complete connection setting parameters, including changes. + Contains complete connection setting parameters, including changes. @@ -58,12 +61,6 @@ - - - Emitted when a client's permission to access this connection may have changed. Generally, clients should re-test their ability to access this connecton whenever this signal is emmited. - - - diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 0f7adb0dd..061455b6c 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -66,9 +66,7 @@ enum { enum { UPDATED, - CHECK_PERMISSIONS, REMOVED, - LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; From edbf4a3ca243dd7ae110da80e870e4d4ba18deba Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 15:57:03 -0500 Subject: [PATCH 047/264] core: allow ConsoleKit usage to be disabled --- configure.ac | 19 +++++++++++ src/nm-session-monitor.c | 72 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/configure.ac b/configure.ac index e66a1f490..4dfda0357 100644 --- a/configure.ac +++ b/configure.ac @@ -253,6 +253,19 @@ if test "x$with_systemdsystemunitdir" != xno; then fi AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) +dnl +dnl Disable ConsoleKit support +dnl +AC_ARG_WITH(ck, AS_HELP_STRING([--without-ck], [Build NetworkManager without ConsoleKit session tracking support])) +AM_CONDITIONAL(WITH_CONSOLEKIT, test x"$with_ck" != xno) +no_ck=0 +if test x"$with_ck" = x"no"; then + no_ck="1" +else + with_ck="yes" +fi +AC_DEFINE_UNQUOTED(NO_CONSOLEKIT, $no_ck, [Define to disable use of ConsoleKit]) + PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8) AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_LIBS) @@ -597,6 +610,12 @@ else echo systemd support: no fi +if test -n "${with_ck}"; then + echo ConsoleKit support: ${with_ck} +else + echo ConsoleKit support: no +fi + echo echo Building documentation: ${with_docs} echo Building tests: ${with_tests} diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index 61d647901..b3d06543b 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -260,6 +260,10 @@ ensure_database (NMSessionMonitor *self, GError **error) { gboolean ret = FALSE; +#if NO_CONSOLEKIT + return TRUE; +#endif + if (self->database != NULL) { struct stat statbuf; @@ -305,6 +309,10 @@ nm_session_monitor_init (NMSessionMonitor *self) GError *error = NULL; GFile *file; +#if NO_CONSOLEKIT + return; +#endif + /* Sessions-by-user is responsible for destroying the Session objects */ self->sessions_by_user = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) session_free); @@ -384,6 +392,50 @@ nm_session_monitor_get (void) /* ---------------------------------------------------------------------------------------------------- */ +#if NO_CONSOLEKIT +static gboolean +uid_to_user (uid_t uid, const char **out_user, GError **error) +{ + struct passwd *pw; + + pw = getpwuid (uid); + if (!pw) { + g_set_error (error, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + "Could not get username for UID %d", + uid); + return FALSE; + } + + /* Ugly, but hey, use ConsoleKit */ + if (out_user) + *out_user = pw->pw_name; + return TRUE; +} + +static gboolean +user_to_uid (const char *user, uid_t *out_uid, GError **error) +{ + struct passwd *pw; + + pw = getpwnam (user); + if (!pw) { + g_set_error (error, + NM_SESSION_MONITOR_ERROR, + NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, + "Could not get UID for username '%s'", + user); + return FALSE; + } + + /* Ugly, but hey, use ConsoleKit */ + if (out_uid) + *out_uid = pw->pw_uid; + return TRUE; +} +#endif + /** * nm_session_monitor_user_has_session: * @monitor: A #NMSessionMonitor. @@ -403,6 +455,12 @@ nm_session_monitor_user_has_session (NMSessionMonitor *monitor, { Session *s; +#if NO_CONSOLEKIT + if (!user_to_uid (username, out_uid, error)) + return FALSE; + return TRUE; +#endif + if (!ensure_database (monitor, error)) return FALSE; @@ -440,6 +498,12 @@ nm_session_monitor_uid_has_session (NMSessionMonitor *monitor, { Session *s; +#if NO_CONSOLEKIT + if (!uid_to_user (uid, out_user, error)) + return FALSE; + return TRUE; +#endif + if (!ensure_database (monitor, error)) return FALSE; @@ -476,6 +540,10 @@ nm_session_monitor_user_active (NMSessionMonitor *monitor, { Session *s; +#if NO_CONSOLEKIT + return TRUE; +#endif + if (!ensure_database (monitor, error)) return FALSE; @@ -510,6 +578,10 @@ nm_session_monitor_uid_active (NMSessionMonitor *monitor, { Session *s; +#if NO_CONSOLEKIT + return TRUE; +#endif + if (!ensure_database (monitor, error)) return FALSE; From b51cef3cba3ddb19ba01a3d3ef15a37fb5ec9eaa Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Oct 2010 16:33:47 -0500 Subject: [PATCH 048/264] settings: clean up connection visibility and session change handling --- src/nm-session-monitor.c | 2 +- src/nm-session-monitor.h | 2 + src/system-settings/nm-sysconfig-connection.c | 12 +++ src/system-settings/nm-sysconfig-connection.h | 1 - src/system-settings/nm-sysconfig-settings.c | 98 +++++-------------- 5 files changed, 37 insertions(+), 78 deletions(-) diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index b3d06543b..7abc9926b 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -369,7 +369,7 @@ nm_session_monitor_class_init (NMSessionMonitorClass *klass) * * Emitted when something changes. */ - signals[CHANGED] = g_signal_new ("changed", + signals[CHANGED] = g_signal_new (NM_SESSION_MONITOR_CHANGED, NM_TYPE_SESSION_MONITOR, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMSessionMonitorClass, changed), diff --git a/src/nm-session-monitor.h b/src/nm-session-monitor.h index fe99fa4d6..77ea9a036 100644 --- a/src/nm-session-monitor.h +++ b/src/nm-session-monitor.h @@ -32,6 +32,8 @@ G_BEGIN_DECLS #define NM_IS_SESSION_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NM_TYPE_SESSION_MONITOR)) #define NM_IS_SESSION_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_SESSION_MONITOR)) +#define NM_SESSION_MONITOR_CHANGED "changed" + typedef struct _NMSessionMonitor NMSessionMonitor; typedef struct _NMSessionMonitorClass NMSessionMonitorClass; diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/system-settings/nm-sysconfig-connection.c index 061455b6c..759f1f3a6 100644 --- a/src/system-settings/nm-sysconfig-connection.c +++ b/src/system-settings/nm-sysconfig-connection.c @@ -76,7 +76,9 @@ typedef struct { GSList *pending_auths; /* List of PendingAuth structs*/ NMConnection *secrets; gboolean visible; /* Is this connection is visible by some session? */ + NMSessionMonitor *session_monitor; + guint session_changed_id; } NMSysconfigConnectionPrivate; /**************************************************************/ @@ -236,6 +238,12 @@ nm_sysconfig_connection_recheck_visibility (NMSysconfigConnection *self) set_visible (self, FALSE); } +static void +session_changed_cb (NMSessionMonitor *self, gpointer user_data) +{ + nm_sysconfig_connection_recheck_visibility (NM_SYSCONFIG_CONNECTION (user_data)); +} + /**************************************************************/ /* Update the settings of this connection to match that of 'new', taking care to @@ -957,6 +965,10 @@ nm_sysconfig_connection_init (NMSysconfigConnection *self) priv->visible = FALSE; priv->session_monitor = nm_session_monitor_get (); + priv->session_changed_id = g_signal_connect (priv->session_monitor, + NM_SESSION_MONITOR_CHANGED, + G_CALLBACK (session_changed_cb), + self); } static void diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/system-settings/nm-sysconfig-connection.h index 19962c00e..ca2df9531 100644 --- a/src/system-settings/nm-sysconfig-connection.h +++ b/src/system-settings/nm-sysconfig-connection.h @@ -36,7 +36,6 @@ G_BEGIN_DECLS #define NM_SYSCONFIG_CONNECTION_UPDATED "updated" #define NM_SYSCONFIG_CONNECTION_REMOVED "removed" -#define NM_SYSCONFIG_CONNECTION_PURGED "purged" #define NM_SYSCONFIG_CONNECTION_VISIBLE "visible" typedef struct _NMSysconfigConnection NMSysconfigConnection; diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 6045d9a51..254fd9104 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -102,9 +102,6 @@ typedef struct { DBusGConnection *bus; gboolean exported; - NMSessionMonitor *session_monitor; - guint session_monitor_id; - PolkitAuthority *authority; guint auth_changed_id; char *config_file; @@ -113,8 +110,7 @@ typedef struct { GSList *plugins; gboolean connections_loaded; - GHashTable *visible_connections; - GHashTable *all_connections; + GHashTable *connections; GSList *unmanaged_specs; } NMSysconfigSettingsPrivate; @@ -189,7 +185,7 @@ nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, load_connections (self); - g_hash_table_iter_init (&iter, priv->visible_connections); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, &key, NULL)) for_each_func (self, NM_SYSCONFIG_CONNECTION (key), user_data); } @@ -205,8 +201,8 @@ impl_settings_list_connections (NMSysconfigSettings *self, load_connections (self); - *connections = g_ptr_array_sized_new (g_hash_table_size (priv->visible_connections) + 1); - g_hash_table_iter_init (&iter, priv->visible_connections); + *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, &key, NULL)) g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (key)))); return TRUE; @@ -227,7 +223,7 @@ nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const c load_connections (self); - g_hash_table_iter_init (&iter, priv->visible_connections); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, &key, NULL)) { if (!strcmp (nm_connection_get_path (NM_CONNECTION (key)), path)) return NM_SYSCONFIG_CONNECTION (key); @@ -535,36 +531,11 @@ load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) return success; } -static void -session_monitor_changed_cb (NMSessionMonitor *monitor, gpointer user_data) -{ - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data; - - /* Update visibility on all connections */ - g_hash_table_iter_init (&iter, priv->all_connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - } -} - static void connection_removed (NMSysconfigConnection *connection, gpointer user_data) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); - - g_hash_table_remove (priv->visible_connections, connection); -} - -static void -connection_purged (NMSysconfigConnection *connection, - gpointer user_data) -{ - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data); - - g_hash_table_remove (priv->all_connections, connection); + g_hash_table_remove (NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data)->connections, connection); } static void @@ -574,47 +545,37 @@ claim_connection (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); - if (g_hash_table_lookup (priv->all_connections, connection)) + if (g_hash_table_lookup (priv->connections, connection)) /* A plugin is lying to us. */ return; - g_hash_table_insert (priv->all_connections, g_object_ref (connection), GINT_TO_POINTER (1)); + g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); - g_signal_connect (connection, - NM_SYSCONFIG_CONNECTION_PURGED, - G_CALLBACK (connection_purged), - self); - if (nm_sysconfig_connection_is_visible (connection)) { - g_hash_table_insert (priv->visible_connections, connection, GINT_TO_POINTER (1)); - g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); - } + /* Ensure it's initial visibility is up-to-date */ + nm_sysconfig_connection_recheck_visibility (connection); + + g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); } // TODO it seems that this is only ever used to remove a // NMDefaultWiredConnection, and it probably needs to stay that way. So this // *needs* a better name! static void -remove_connection (NMSysconfigSettings *self, - NMSysconfigConnection *connection, - gboolean do_signal) +remove_default_wired_connection (NMSysconfigSettings *self, + NMSysconfigConnection *connection, + gboolean do_signal) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - if (g_hash_table_lookup (priv->visible_connections, connection)) { + if (g_hash_table_lookup (priv->connections, connection)) { g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_REMOVED); - g_hash_table_remove (priv->visible_connections, connection); - } - - if (g_hash_table_lookup (priv->all_connections, connection)) { - g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_PURGED); - g_hash_table_remove (priv->all_connections, connection); + g_hash_table_remove (priv->connections, connection); } } @@ -927,7 +888,7 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) g_return_val_if_fail (mac != NULL, FALSE); /* Find a wired connection locked to the given MAC address, if any */ - g_hash_table_iter_init (&iter, priv->visible_connections); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, &key, NULL)) { NMConnection *connection = NM_CONNECTION (key); const char *connection_type; @@ -1134,7 +1095,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, id = nm_setting_connection_get_id (s_con); g_assert (id); - remove_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); + remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); if (add_new_connection (self, NM_CONNECTION (wired), &error)) { nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (wired), delete_cb, @@ -1226,7 +1187,7 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG); if (connection) - remove_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); + remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); } NMSysconfigSettings * @@ -1289,12 +1250,6 @@ dispose (GObject *object) g_slist_free (priv->pk_calls); priv->pk_calls = NULL; - if (priv->session_monitor) { - g_signal_handler_disconnect (priv->session_monitor, priv->session_monitor_id); - g_object_unref (priv->session_monitor); - priv->session_monitor = NULL; - } - G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); } @@ -1304,8 +1259,7 @@ finalize (GObject *object) NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); - g_hash_table_destroy (priv->visible_connections); - g_hash_table_destroy (priv->all_connections); + g_hash_table_destroy (priv->connections); clear_unmanaged_specs (self); @@ -1439,8 +1393,7 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GError *error = NULL; - priv->visible_connections = g_hash_table_new (g_direct_hash, g_direct_equal); - priv->all_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); priv->authority = polkit_authority_get_sync (NULL, &error); if (!priv->authority) { @@ -1449,12 +1402,5 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) error && error->message ? error->message : "(unknown)"); g_clear_error (&error); } - - priv->session_monitor = nm_session_monitor_get (); - g_assert (priv->session_monitor); - priv->session_monitor_id = g_signal_connect (priv->session_monitor, - "changed", - G_CALLBACK (session_monitor_changed_cb), - self); } From 84def2fedf8d113bf93d67145de3d383bf6de3b9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 15:47:10 -0500 Subject: [PATCH 049/264] settings: remove connection tracking from NMManager NMSysconfigSettings has the authoritative list of connections, no reason to duplicate all that tracking code in NMManager. Add the missing bits that the manager had to NMSysconfigSettings, and point NMPolicy at the settings object instead of NMManager for that. --- src/main.c | 15 +- src/nm-device-olpc-mesh.c | 6 +- src/nm-manager.c | 295 +++----------------- src/nm-manager.h | 24 +- src/nm-policy.c | 79 +++--- src/nm-policy.h | 10 +- src/system-settings/nm-sysconfig-settings.c | 215 +++++++++++--- src/system-settings/nm-sysconfig-settings.h | 25 +- src/vpn-manager/nm-vpn-connection.c | 2 +- 9 files changed, 310 insertions(+), 361 deletions(-) diff --git a/src/main.c b/src/main.c index 7e75f05ef..5b1a78045 100644 --- a/src/main.c +++ b/src/main.c @@ -453,6 +453,7 @@ main (int argc, char *argv[]) NMDBusManager *dbus_mgr = NULL; NMSupplicantManager *sup_mgr = NULL; NMDHCPManager *dhcp_mgr = NULL; + NMSysconfigSettings *settings = NULL; GError *error = NULL; gboolean wrote_pidfile = FALSE; char *cfg_log_level = NULL, *cfg_log_domains = NULL; @@ -672,7 +673,14 @@ main (int argc, char *argv[]) goto done; } - manager = nm_manager_get (config, + settings = nm_sysconfig_settings_new (config, plugins, &error); + if (!settings) { + nm_log_err (LOGD_CORE, "failed to initialize settings storage."); + goto done; + } + + manager = nm_manager_get (settings, + config, plugins, state_file, net_enabled, @@ -685,7 +693,7 @@ main (int argc, char *argv[]) goto done; } - policy = nm_policy_new (manager, vpn_manager); + policy = nm_policy_new (manager, vpn_manager, settings); if (policy == NULL) { nm_log_err (LOGD_CORE, "failed to initialize the policy."); goto done; @@ -733,6 +741,9 @@ done: if (manager) g_object_unref (manager); + if (settings) + g_object_unref (settings); + if (vpn_manager) g_object_unref (vpn_manager); diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index 546ecfafe..36b968ed8 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -652,7 +652,7 @@ dispose (GObject *object) device_cleanup (self); - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); if (priv->device_added_id) g_signal_handler_disconnect (manager, priv->device_added_id); g_object_unref (manager); @@ -850,7 +850,7 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other) priv->companion = other; /* When we've found the companion, stop listening for other devices */ - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); if (priv->device_added_id) { g_signal_handler_disconnect (manager, priv->device_added_id); priv->device_added_id = 0; @@ -905,7 +905,7 @@ check_companion_cb (gpointer user_data) if (priv->device_added_id != 0) return FALSE; - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); priv->device_added_id = g_signal_connect (manager, "device-added", G_CALLBACK (device_added_cb), self); diff --git a/src/nm-manager.c b/src/nm-manager.c index b98600d62..91a2879c0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -200,8 +200,7 @@ typedef struct { NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; - GHashTable *system_connections; - NMSysconfigSettings *sys_settings; + NMSysconfigSettings *settings; char *hostname; GSList *secrets_calls; @@ -244,10 +243,6 @@ enum { STATE_CHANGED, STATE_CHANGE, /* DEPRECATED */ PROPERTIES_CHANGED, - CONNECTIONS_ADDED, - CONNECTION_ADDED, - CONNECTION_UPDATED, - CONNECTION_REMOVED, CHECK_PERMISSIONS, USER_PERMISSIONS_CHANGED, @@ -490,7 +485,7 @@ remove_one_device (NMManager *manager, g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager); - nm_sysconfig_settings_device_removed (priv->sys_settings, device); + nm_sysconfig_settings_device_removed (priv->settings, device); g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); g_object_unref (device); @@ -580,15 +575,6 @@ nm_manager_get_state (NMManager *manager) return NM_MANAGER_GET_PRIVATE (manager)->state; } -static void -emit_removed (gpointer key, gpointer value, gpointer user_data) -{ - NMManager *manager = NM_MANAGER (user_data); - NMConnection *connection = NM_CONNECTION (value); - - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, connection); -} - static PendingActivation * pending_activation_new (NMManager *manager, PolkitAuthority *authority, @@ -756,106 +742,18 @@ get_active_connections (NMManager *manager, NMConnection *filter) return active; } -static void -remove_connection (NMManager *manager, - NMConnection *connection, - GHashTable *hash) -{ - /* Destroys the connection, then associated DBusGProxy due to the - * weak reference notify function placed on the connection when it - * was created. - */ - g_object_ref (connection); - g_hash_table_remove (hash, nm_connection_get_path (connection)); - g_signal_emit (manager, signals[CONNECTION_REMOVED], 0, connection); - g_object_unref (connection); - - bluez_manager_resync_devices (manager); -} - /*******************************************************************/ -/* System settings stuff via NMSysconfigSettings */ +/* Settings stuff via NMSysconfigSettings */ /*******************************************************************/ static void -system_connection_updated_cb (NMSysconfigConnection *connection, - gpointer unused, - NMManager *manager) +connections_changed (NMSysconfigSettings *settings, + NMSysconfigConnection *connection, + NMManager *manager) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const char *path; - NMSysconfigConnection *existing; - GError *error = NULL; - - path = nm_connection_get_path (NM_CONNECTION (connection)); - - existing = g_hash_table_lookup (priv->system_connections, path); - if (!existing) - return; - if (existing != connection) { - nm_log_warn (LOGD_SYS_SET, "existing connection didn't matched updated."); - return; - } - - if (!nm_connection_verify (NM_CONNECTION (existing), &error)) { - /* Updated connection invalid, remove existing connection */ - nm_log_warn (LOGD_SYS_SET, "invalid connection: '%s' / '%s' invalid: %d", - g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), - error->message, error->code); - g_error_free (error); - remove_connection (manager, NM_CONNECTION (existing), priv->system_connections); - return; - } - - g_signal_emit (manager, signals[CONNECTION_UPDATED], 0, existing); - bluez_manager_resync_devices (manager); } -static void -system_connection_removed_cb (NMSysconfigConnection *connection, - NMManager *manager) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const char *path; - - path = nm_connection_get_path (NM_CONNECTION (connection)); - - connection = g_hash_table_lookup (priv->system_connections, path); - if (connection) - remove_connection (manager, NM_CONNECTION (connection), priv->system_connections); -} - -static void -_new_connection (NMSysconfigSettings *settings, - NMSysconfigConnection *connection, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - const char *path; - - g_return_if_fail (connection != NULL); - - g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED, - G_CALLBACK (system_connection_updated_cb), self); - g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, - G_CALLBACK (system_connection_removed_cb), self); - - path = nm_connection_get_path (NM_CONNECTION (connection)); - g_hash_table_insert (priv->system_connections, g_strdup (path), - g_object_ref (connection)); - g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); -} - -static void -system_new_connection_cb (NMSysconfigSettings *settings, - NMSysconfigConnection *connection, - NMManager *self) -{ - _new_connection (settings, connection, self); -} - static void system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings, GParamSpec *pspec, @@ -1031,6 +929,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, gpointer user_data) { NMManager *manager = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); const struct ether_addr *ap_addr; const GByteArray *ap_ssid; GSList *iter; @@ -1046,7 +945,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ - connections = nm_manager_get_connections (manager); + connections = nm_sysconfig_settings_get_connections (priv->settings); for (iter = connections; iter && !done; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); @@ -1353,8 +1252,6 @@ add_device (NMManager *self, NMDevice *device) static guint32 devcount = 0; const GSList *unmanaged_specs; NMConnection *existing = NULL; - GHashTableIter iter; - gpointer value; gboolean managed = FALSE, enabled = FALSE; iface = nm_device_get_ip_iface (device); @@ -1433,9 +1330,7 @@ add_device (NMManager *self, NMDevice *device) if (nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (device))) { GSList *connections = NULL; - g_hash_table_iter_init (&iter, priv->system_connections); - while (g_hash_table_iter_next (&iter, NULL, &value)) - connections = g_slist_append (connections, value); + connections = nm_sysconfig_settings_get_connections (priv->settings); existing = nm_device_interface_connection_match_config (NM_DEVICE_INTERFACE (device), (const GSList *) connections); g_slist_free (connections); @@ -1451,7 +1346,7 @@ add_device (NMManager *self, NMDevice *device) } /* Start the device if it's supposed to be managed */ - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings); + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->settings); if ( !manager_sleeping (self) && !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) { nm_device_set_managed (device, @@ -1461,7 +1356,7 @@ add_device (NMManager *self, NMDevice *device) managed = TRUE; } - nm_sysconfig_settings_device_added (priv->sys_settings, device); + nm_sysconfig_settings_device_added (priv->settings, device); g_signal_emit (self, signals[DEVICE_ADDED], 0, device); /* If the device has a connection it can assume, do that now */ @@ -1516,10 +1411,11 @@ bluez_manager_find_connection (NMManager *manager, const char *bdaddr, guint32 capabilities) { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMConnection *found = NULL; GSList *connections, *l; - connections = nm_manager_get_connections (manager); + connections = nm_sysconfig_settings_get_connections (priv->settings); for (l = connections; l != NULL; l = l->next) { NMConnection *candidate = NM_CONNECTION (l->data); @@ -1884,7 +1780,7 @@ system_get_secrets_idle_cb (gpointer user_data) info->idle_id = 0; - connection = nm_sysconfig_settings_get_connection_by_path (priv->sys_settings, + connection = nm_sysconfig_settings_get_connection_by_path (priv->settings, info->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, @@ -2137,13 +2033,15 @@ nm_manager_activate_connection (NMManager *manager, static void check_pending_ready (NMManager *self, PendingActivation *pending) { - NMConnection *connection; + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSysconfigConnection *connection; const char *path = NULL; GError *error = NULL; /* Ok, we're authorized */ - connection = nm_manager_get_connection_by_object_path (self, pending->connection_path); + connection = nm_sysconfig_settings_get_connection_by_path (priv->settings, + pending->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, @@ -2152,7 +2050,7 @@ check_pending_ready (NMManager *self, PendingActivation *pending) } path = nm_manager_activate_connection (self, - connection, + NM_CONNECTION (connection), pending->specific_object_path, pending->device_path, TRUE, @@ -2388,7 +2286,7 @@ do_sleep_wake (NMManager *self) } else { nm_log_info (LOGD_SUSPEND, "waking up and re-enabling..."); - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->sys_settings); + unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->settings); /* Ensure rfkill state is up-to-date since we don't respond to state * changes during sleep. @@ -2847,73 +2745,6 @@ impl_manager_set_logging (NMManager *manager, return FALSE; } -/* Connections */ - -static int -connection_sort (gconstpointer pa, gconstpointer pb) -{ - NMConnection *a = NM_CONNECTION (pa); - NMSettingConnection *con_a; - NMConnection *b = NM_CONNECTION (pb); - NMSettingConnection *con_b; - - con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); - g_assert (con_a); - con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); - g_assert (con_b); - - if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { - if (nm_setting_connection_get_autoconnect (con_a)) - return -1; - return 1; - } - - if (nm_setting_connection_get_timestamp (con_a) > nm_setting_connection_get_timestamp (con_b)) - return -1; - else if (nm_setting_connection_get_timestamp (con_a) == nm_setting_connection_get_timestamp (con_b)) - return 0; - return 1; -} - -static void -connections_to_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_insert_sorted (*list, g_object_ref (value), connection_sort); -} - -/* Returns a GSList of referenced NMConnection objects, caller must - * unref the connections in the list and destroy the list. - */ -GSList * -nm_manager_get_connections (NMManager *manager) -{ - NMManagerPrivate *priv; - GSList *list = NULL; - - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - - priv = NM_MANAGER_GET_PRIVATE (manager); - g_hash_table_foreach (priv->system_connections, connections_to_slist, &list); - return list; -} - -NMConnection * -nm_manager_get_connection_by_object_path (NMManager *manager, - const char *path) -{ - NMManagerPrivate *priv; - NMConnection *connection = NULL; - - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - g_return_val_if_fail (path != NULL, NULL); - - priv = NM_MANAGER_GET_PRIVATE (manager); - connection = (NMConnection *) g_hash_table_lookup (priv->system_connections, path); - return connection; -} - GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager, NMConnection *connection) @@ -2951,13 +2782,8 @@ nm_manager_start (NMManager *self) nm_log_info (LOGD_CORE, "Networking is %s by state file", priv->net_enabled ? "enabled" : "disabled"); - system_unmanaged_devices_changed_cb (priv->sys_settings, NULL, self); - system_hostname_changed_cb (priv->sys_settings, NULL, self); - - /* Get all connections */ - nm_sysconfig_settings_for_each_connection (NM_MANAGER_GET_PRIVATE (self)->sys_settings, - _new_connection, - self); + system_unmanaged_devices_changed_cb (priv->settings, NULL, self); + system_hostname_changed_cb (priv->settings, NULL, self); nm_udev_manager_query_devices (priv->udev_mgr); bluez_manager_resync_devices (self); @@ -3178,7 +3004,8 @@ out: } NMManager * -nm_manager_get (const char *config_file, +nm_manager_get (NMSysconfigSettings *settings, + const char *config_file, const char *plugins, const char *state_file, gboolean initial_net_enabled, @@ -3194,6 +3021,8 @@ nm_manager_get (const char *config_file, if (singleton) return g_object_ref (singleton); + g_assert (settings); + singleton = (NMManager *) g_object_new (NM_TYPE_MANAGER, NULL); g_assert (singleton); @@ -3210,14 +3039,9 @@ nm_manager_get (const char *config_file, return NULL; } - priv->sys_settings = nm_sysconfig_settings_new (config_file, plugins, error); - if (!priv->sys_settings) { - g_object_unref (singleton); - return NULL; - } + priv->settings = settings; priv->config_file = g_strdup (config_file); - priv->state_file = g_strdup (state_file); priv->net_enabled = initial_net_enabled; @@ -3225,12 +3049,18 @@ nm_manager_get (const char *config_file, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = initial_wifi_enabled; priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = initial_wwan_enabled; - g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, + g_signal_connect (priv->settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); - g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, + g_signal_connect (priv->settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); - g_signal_connect (priv->sys_settings, "new-connection", - G_CALLBACK (system_new_connection_cb), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, + G_CALLBACK (connections_changed), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, + G_CALLBACK (connections_changed), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connections_changed), singleton); + g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + G_CALLBACK (connections_changed), singleton); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), NM_DBUS_PATH, @@ -3293,18 +3123,10 @@ dispose (GObject *object) TRUE); } - g_hash_table_foreach (priv->system_connections, emit_removed, manager); - g_hash_table_remove_all (priv->system_connections); - g_hash_table_destroy (priv->system_connections); - priv->system_connections = NULL; - g_free (priv->hostname); g_free (priv->config_file); - if (priv->sys_settings) { - g_object_unref (priv->sys_settings); - priv->sys_settings = NULL; - } + g_object_unref (priv->settings); if (priv->vpn_manager_id) { g_source_remove (priv->vpn_manager_id); @@ -3506,11 +3328,6 @@ nm_manager_init (NMManager *manager) priv->dbus_mgr = nm_dbus_manager_get (); - priv->system_connections = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - priv->modem_manager = nm_modem_manager_get (); priv->modem_added_id = g_signal_connect (priv->modem_manager, "modem-added", G_CALLBACK (modem_added), manager); @@ -3724,42 +3541,6 @@ nm_manager_class_init (NMManagerClass *manager_class) nm_properties_changed_signal_new (object_class, G_STRUCT_OFFSET (NMManagerClass, properties_changed)); - signals[CONNECTIONS_ADDED] = - g_signal_new ("connections-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connections_added), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[CONNECTION_ADDED] = - g_signal_new ("connection-added", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_added), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[CONNECTION_UPDATED] = - g_signal_new ("connection-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_updated), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[CONNECTION_REMOVED] = - g_signal_new ("connection-removed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMManagerClass, connection_removed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - signals[CHECK_PERMISSIONS] = g_signal_new ("check-permissions", G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/nm-manager.h b/src/nm-manager.h index 5bf92d602..2d0186b7c 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -20,13 +20,14 @@ */ #ifndef NM_MANAGER_H -#define NM_MANAGER_H 1 +#define NM_MANAGER_H #include #include #include #include "nm-device.h" #include "nm-device-interface.h" +#include "nm-sysconfig-settings.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) #define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) @@ -60,22 +61,12 @@ typedef struct { void (*device_removed) (NMManager *manager, NMDevice *device); void (*state_changed) (NMManager *manager, guint state); void (*properties_changed) (NMManager *manager, GHashTable *properties); - - void (*connections_added) (NMManager *manager); - - void (*connection_added) (NMManager *manager, - NMConnection *connection); - - void (*connection_updated) (NMManager *manager, - NMConnection *connection); - - void (*connection_removed) (NMManager *manager, - NMConnection *connection); } NMManagerClass; GType nm_manager_get_type (void); -NMManager *nm_manager_get (const char *config_file, +NMManager *nm_manager_get (NMSysconfigSettings *settings, + const char *config_file, const char *plugins, const char *state_file, gboolean initial_net_enabled, @@ -105,13 +96,6 @@ gboolean nm_manager_deactivate_connection (NMManager *manager, NMState nm_manager_get_state (NMManager *manager); -/* Connections */ - -GSList *nm_manager_get_connections (NMManager *manager); - -NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager, - const char *path); - GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager, NMConnection *connection); diff --git a/src/nm-policy.c b/src/nm-policy.c index df7689b72..793a5a7b4 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -56,6 +56,8 @@ struct NMPolicy { gulong vpn_activated_id; gulong vpn_deactivated_id; + NMSysconfigSettings *settings; + NMDevice *default_device4; NMDevice *default_device6; @@ -739,7 +741,7 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - connections = nm_manager_get_connections (policy->manager); + connections = nm_sysconfig_settings_get_connections (policy->settings); /* Remove connections that are in the invalid list. */ iter = connections; @@ -822,6 +824,7 @@ hostname_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) static void sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) { + NMPolicy *policy = user_data; gboolean sleeping = FALSE, enabled = FALSE; GSList *connections, *iter; @@ -830,7 +833,7 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) /* Clear the invalid flag on all connections so they'll get retried on wakeup */ if (sleeping || !enabled) { - connections = nm_manager_get_connections (manager); + connections = nm_sysconfig_settings_get_connections (policy->settings); for (iter = connections; iter; iter = g_slist_next (iter)) g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL); g_slist_free (connections); @@ -1043,14 +1046,7 @@ schedule_activate_all (NMPolicy *policy) } static void -connections_added (NMManager *manager, - gpointer user_data) -{ - schedule_activate_all ((NMPolicy *) user_data); -} - -static void -connection_added (NMManager *manager, +connection_added (NMSysconfigSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1058,7 +1054,7 @@ connection_added (NMManager *manager, } static void -connection_updated (NMManager *manager, +connection_updated (NMSysconfigSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1069,22 +1065,19 @@ connection_updated (NMManager *manager, } static void -connection_removed (NMManager *manager, - NMConnection *connection, - gpointer user_data) +_deactivate_if_active (NMManager *manager, NMConnection *connection) { NMSettingConnection *s_con; GPtrArray *list; int i; - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - if (!s_con) - return; - list = nm_manager_get_active_connections_by_connection (manager, connection); if (!list) return; + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + for (i = 0; i < list->len; i++) { char *path = g_ptr_array_index (list, i); GError *error = NULL; @@ -1100,13 +1093,32 @@ connection_removed (NMManager *manager, } static void -manager_user_permissions_changed (NMManager *manager, NMPolicy *policy) +connection_removed (NMSysconfigSettings *settings, + NMConnection *connection, + gpointer user_data) { - schedule_activate_all (policy); + NMPolicy *policy = user_data; + + _deactivate_if_active (policy->manager, connection); +} + +static void +connection_visibility_changed (NMSysconfigSettings *settings, + NMSysconfigConnection *connection, + gpointer user_data) +{ + NMPolicy *policy = user_data; + + if (nm_sysconfig_connection_is_visible (connection)) + schedule_activate_all (policy); + else + _deactivate_if_active (policy->manager, NM_CONNECTION (connection)); } NMPolicy * -nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager) +nm_policy_new (NMManager *manager, + NMVPNManager *vpn_manager, + NMSysconfigSettings *settings) { NMPolicy *policy; static gboolean initialized = FALSE; @@ -1160,28 +1172,25 @@ nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager) G_CALLBACK (device_removed), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - /* Large batch of connections added, manager doesn't want us to - * process each one individually. - */ - id = g_signal_connect (manager, "connections-added", - G_CALLBACK (connections_added), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - /* Single connection added */ - id = g_signal_connect (manager, "connection-added", + /* Listen for events related to connections */ + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, G_CALLBACK (connection_added), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - id = g_signal_connect (manager, "connection-updated", + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, + G_CALLBACK (connection_added), policy); + policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); + + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, G_CALLBACK (connection_updated), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - id = g_signal_connect (manager, "connection-removed", + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - id = g_signal_connect (manager, "user-permissions-changed", - G_CALLBACK (manager_user_permissions_changed), policy); + id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + G_CALLBACK (connection_visibility_changed), policy); policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); return policy; @@ -1227,6 +1236,8 @@ nm_policy_destroy (NMPolicy *policy) } g_slist_free (policy->dev_signal_ids); + g_object_unref (policy->settings); + /* Rewrite /etc/hosts on exit to ensure we don't leave stale IP addresses * lying around. FIXME: this will take out a valid IP address of an * ethernet device we're leaving active (ie, a connection we can "assume" diff --git a/src/nm-policy.h b/src/nm-policy.h index 7d99613cc..968d62019 100644 --- a/src/nm-policy.h +++ b/src/nm-policy.h @@ -15,22 +15,22 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2008 Red Hat, Inc. + * Copyright (C) 2004 - 2010 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ #ifndef NETWORK_MANAGER_POLICY_H #define NETWORK_MANAGER_POLICY_H -#include "NetworkManager.h" #include "nm-manager.h" #include "nm-vpn-manager.h" -#include "nm-device.h" -#include "nm-activation-request.h" +#include "nm-sysconfig-settings.h" typedef struct NMPolicy NMPolicy; -NMPolicy *nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager); +NMPolicy *nm_policy_new (NMManager *manager, + NMVPNManager *vpn_manager, + NMSysconfigSettings *settings); void nm_policy_destroy (NMPolicy *policy); #endif /* NETWORK_MANAGER_POLICY_H */ diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 254fd9104..2f7ac629a 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -120,7 +120,11 @@ G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT) enum { PROPERTIES_CHANGED, - NEW_CONNECTION, + CONNECTION_ADDED, + CONNECTION_UPDATED, + CONNECTION_REMOVED, + CONNECTION_VISIBILITY_CHANGED, + CONNECTIONS_LOADED, LAST_SIGNAL }; @@ -166,6 +170,8 @@ load_connections (NMSysconfigSettings *self) /* FIXME: Bad hack */ unmanaged_specs_changed (NULL, self); + + g_signal_emit (self, signals[CONNECTIONS_LOADED], 0); } void @@ -175,7 +181,7 @@ nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv; GHashTableIter iter; - gpointer key; + gpointer data; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); @@ -186,8 +192,8 @@ nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, load_connections (self); g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) - for_each_func (self, NM_SYSCONFIG_CONNECTION (key), user_data); + while (g_hash_table_iter_next (&iter, NULL, &data)) + for_each_func (self, NM_SYSCONFIG_CONNECTION (data), user_data); } static gboolean @@ -197,23 +203,65 @@ impl_settings_list_connections (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; - gpointer key; + gpointer data; load_connections (self); *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) - g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (key)))); + while (g_hash_table_iter_next (&iter, NULL, &data)) + g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (data)))); return TRUE; } +static int +connection_sort (gconstpointer pa, gconstpointer pb) +{ + NMConnection *a = NM_CONNECTION (pa); + NMSettingConnection *con_a; + NMConnection *b = NM_CONNECTION (pb); + NMSettingConnection *con_b; + + con_a = (NMSettingConnection *) nm_connection_get_setting (a, NM_TYPE_SETTING_CONNECTION); + g_assert (con_a); + con_b = (NMSettingConnection *) nm_connection_get_setting (b, NM_TYPE_SETTING_CONNECTION); + g_assert (con_b); + + if (nm_setting_connection_get_autoconnect (con_a) != nm_setting_connection_get_autoconnect (con_b)) { + if (nm_setting_connection_get_autoconnect (con_a)) + return -1; + return 1; + } + + if (nm_setting_connection_get_timestamp (con_a) > nm_setting_connection_get_timestamp (con_b)) + return -1; + else if (nm_setting_connection_get_timestamp (con_a) == nm_setting_connection_get_timestamp (con_b)) + return 0; + return 1; +} + +/* Returns a GSList of referenced NMConnection objects, caller must + * unref the connections in the list and destroy the list. + */ +GSList * +nm_sysconfig_settings_get_connections (NMSysconfigSettings *self) +{ + GHashTableIter iter; + gpointer key = NULL; + GSList *list = NULL; + + g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); + + g_hash_table_iter_init (&iter, NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self)->connections); + while (g_hash_table_iter_next (&iter, key, NULL)) + list = g_slist_insert_sorted (list, key, connection_sort); + return g_slist_reverse (list); +} + NMSysconfigConnection * nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const char *path) { NMSysconfigSettingsPrivate *priv; - GHashTableIter iter; - gpointer key; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); @@ -223,12 +271,7 @@ nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const c load_connections (self); - g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) { - if (!strcmp (nm_connection_get_path (NM_CONNECTION (key)), path)) - return NM_SYSCONFIG_CONNECTION (key); - } - return NULL; + return (NMSysconfigConnection *) g_hash_table_lookup (priv->connections, path); } static void @@ -532,10 +575,34 @@ load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) } static void -connection_removed (NMSysconfigConnection *connection, - gpointer user_data) +connection_removed (NMSysconfigConnection *connection, gpointer user_data) { + g_object_ref (connection); + g_hash_table_remove (NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data)->connections, connection); + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + signals[CONNECTION_REMOVED], + 0, + connection); + g_object_unref (connection); +} + +static void +connection_updated (NMSysconfigConnection *connection, gpointer user_data) +{ + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + signals[CONNECTION_UPDATED], + 0, + connection); +} + +static void +connection_visibility_changed (NMSysconfigConnection *connection, gpointer user_data) +{ + g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + signals[CONNECTION_VISIBILITY_CHANGED], + 0, + connection); } static void @@ -544,23 +611,64 @@ claim_connection (NMSysconfigSettings *self, gboolean do_export) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + static guint32 ec_counter = 0; + GError *error = NULL; + GHashTableIter iter; + gpointer data; + char *path; g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); - if (g_hash_table_lookup (priv->connections, connection)) - /* A plugin is lying to us. */ - return; + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + /* prevent duplicates */ + if (data == connection) + return; + } + + if (!nm_connection_verify (NM_CONNECTION (connection), &error)) { + nm_log_warn (LOGD_SYS_SET, "plugin provided invalid connection: '%s' / '%s' invalid: %d", + g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), + error->message, error->code); + g_error_free (error); + return; + } + + /* Ensure it's initial visibility is up-to-date */ + nm_sysconfig_connection_recheck_visibility (connection); - g_hash_table_insert (priv->connections, g_object_ref (connection), GINT_TO_POINTER (1)); g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); - /* Ensure it's initial visibility is up-to-date */ - nm_sysconfig_connection_recheck_visibility (connection); + g_signal_connect (connection, + NM_SYSCONFIG_CONNECTION_UPDATED, + G_CALLBACK (connection_updated), + self); - g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); + g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE, + G_CALLBACK (connection_visibility_changed), + self); + + /* Export the connection over D-Bus */ + g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); + path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, ec_counter++); + nm_connection_set_path (NM_CONNECTION (connection), path); + dbus_g_connection_register_g_object (priv->bus, path, G_OBJECT (connection)); + g_free (path); + + g_hash_table_insert (priv->connections, + (gpointer) nm_connection_get_path (NM_CONNECTION (connection)), + g_object_ref (connection)); + + /* Only emit the individual connection-added signal after connections + * have been initially loaded. While getting the first list of connections + * we suppress it, then send the connections-loaded signal after we're all + * done to minimize processing. + */ + if (priv->connections_loaded) + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); } // TODO it seems that this is only ever used to remove a @@ -572,10 +680,11 @@ remove_default_wired_connection (NMSysconfigSettings *self, gboolean do_signal) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + const char *path = nm_connection_get_path (NM_CONNECTION (connection)); - if (g_hash_table_lookup (priv->connections, connection)) { + if (g_hash_table_lookup (priv->connections, path)) { g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_REMOVED); - g_hash_table_remove (priv->connections, connection); + g_hash_table_remove (priv->connections, path); } } @@ -878,7 +987,7 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; - gpointer key; + gpointer data; NMSettingConnection *s_con; NMSettingWired *s_wired; const GByteArray *setting_mac; @@ -889,8 +998,8 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, &key, NULL)) { - NMConnection *connection = NM_CONNECTION (key); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + NMConnection *connection = NM_CONNECTION (data); const char *connection_type; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); @@ -1190,6 +1299,8 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); } +/***************************************************************/ + NMSysconfigSettings * nm_sysconfig_settings_new (const char *config_file, const char *plugins, @@ -1226,8 +1337,6 @@ nm_sysconfig_settings_new (const char *config_file, return self; } -/***************************************************************/ - static void dispose (GObject *object) { @@ -1350,15 +1459,51 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); - signals[NEW_CONNECTION] = - g_signal_new (NM_SYSCONFIG_SETTINGS_NEW_CONNECTION, + signals[CONNECTION_ADDED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - 0, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); + signals[CONNECTION_UPDATED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_updated), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_REMOVED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTION_VISIBILITY_CHANGED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_visibility_changed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[CONNECTIONS_LOADED] = + g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSysconfigSettingsClass, connections_loaded), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, NM_TYPE_SYSCONFIG_SETTINGS_ERROR); @@ -1393,7 +1538,7 @@ nm_sysconfig_settings_init (NMSysconfigSettings *self) NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GError *error = NULL; - priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); priv->authority = polkit_authority_get_sync (NULL, &error); if (!priv->authority) { diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index 948349820..9f8565daa 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -43,7 +43,11 @@ #define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" #define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" -#define NM_SYSCONFIG_SETTINGS_NEW_CONNECTION "new-connection" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED "connection-added" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED "connection-updated" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED "connection-removed" +#define NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" +#define NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED "connections-loaded" typedef struct { GObject parent_instance; @@ -54,6 +58,16 @@ typedef struct { /* Signals */ void (*properties_changed) (NMSysconfigSettings *self, GHashTable *properties); + + void (*connection_added) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connection_updated) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connection_removed) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connection_visibility_changed) (NMSysconfigSettings *self, NMConnection *connection); + + void (*connections_loaded) (NMSysconfigSettings *self); } NMSysconfigSettingsClass; GType nm_sysconfig_settings_get_type (void); @@ -70,10 +84,13 @@ void nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *settings, NMSysconfigSettingsForEachFunc for_each_func, gpointer user_data); -GSList * nm_sysconfig_settings_list_connections (NMSysconfigSettings *settings); +/* Returns a list of NMSysconfigConnections. Caller must free the list with + * g_slist_free(). + */ +GSList *nm_sysconfig_settings_get_connections (NMSysconfigSettings *settings); -NMSysconfigConnection * nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, - const char *path); +NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, + const char *path); const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 6c2acfb56..7b47b18da 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -30,11 +30,11 @@ #include "NetworkManager.h" #include "NetworkManagerVPN.h" #include "nm-vpn-connection.h" +#include "nm-device-interface.h" #include "nm-setting-connection.h" #include "nm-setting-vpn.h" #include "nm-setting-ip4-config.h" #include "nm-dbus-manager.h" -#include "nm-manager.h" #include "nm-system.h" #include "nm-logging.h" #include "nm-utils.h" From f1d4af699624a43eb454d1c56acf944cc2144879 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:17:44 -0500 Subject: [PATCH 050/264] settings: make sure we get our D-Bus connection before using it --- src/system-settings/nm-sysconfig-settings.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 2f7ac629a..4f77e84b9 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -99,8 +99,8 @@ static void impl_settings_save_hostname (NMSysconfigSettings *self, static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); typedef struct { + NMDBusManager *dbus_mgr; DBusGConnection *bus; - gboolean exported; PolkitAuthority *authority; guint auth_changed_id; @@ -1308,8 +1308,6 @@ nm_sysconfig_settings_new (const char *config_file, { NMSysconfigSettings *self; NMSysconfigSettingsPrivate *priv; - NMDBusManager *dbus_mgr; - DBusGConnection *bus; self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, NULL); @@ -1319,6 +1317,8 @@ nm_sysconfig_settings_new (const char *config_file, priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); priv->config_file = g_strdup (config_file); + priv->dbus_mgr = nm_dbus_manager_get (); + priv->bus = nm_dbus_manager_get_connection (priv->dbus_mgr); if (plugins) { /* Load the plugins; fail if a plugin is not found. */ @@ -1329,11 +1329,7 @@ nm_sysconfig_settings_new (const char *config_file, unmanaged_specs_changed (NULL, self); } - dbus_mgr = nm_dbus_manager_get (); - bus = nm_dbus_manager_get_connection (dbus_mgr); - dbus_g_connection_register_g_object (bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); - g_object_unref (dbus_mgr); - + dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); return self; } @@ -1359,6 +1355,8 @@ dispose (GObject *object) g_slist_free (priv->pk_calls); priv->pk_calls = NULL; + g_object_unref (priv->dbus_mgr); + G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); } From 02711a0e670aa3008c47029d77650a479d89dc0d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:20:41 -0500 Subject: [PATCH 051/264] settings: re-add exported NewConnection signal Oops, got removed in an earlier commit. --- src/system-settings/nm-sysconfig-settings.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 4f77e84b9..5a35acea2 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -126,6 +126,7 @@ enum { CONNECTION_VISIBILITY_CHANGED, CONNECTIONS_LOADED, + NEW_CONNECTION, /* exported, not used internally */ LAST_SIGNAL }; @@ -667,8 +668,13 @@ claim_connection (NMSysconfigSettings *self, * we suppress it, then send the connections-loaded signal after we're all * done to minimize processing. */ - if (priv->connections_loaded) + if (priv->connections_loaded) { + /* Internal added signal */ g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); + + /* Exported D-Bus signal */ + g_signal_emit (self, signals[NEW_CONNECTION], 0, connection); + } } // TODO it seems that this is only ever used to remove a @@ -1502,6 +1508,13 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + signals[NEW_CONNECTION] = + g_signal_new ("new-connection", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 0); + dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, NM_TYPE_SYSCONFIG_SETTINGS_ERROR); From 330cb3563000405384e2586302d99631e6a49825 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:22:18 -0500 Subject: [PATCH 052/264] policy: make sure we have a valid settings object --- src/nm-policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 793a5a7b4..028558c57 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1130,6 +1130,7 @@ nm_policy_new (NMManager *manager, policy = g_malloc0 (sizeof (NMPolicy)); policy->manager = g_object_ref (manager); + policy->settings = g_object_ref (settings); policy->update_state_id = 0; /* Grab hostname on startup and use that if nothing provides one */ @@ -1236,8 +1237,6 @@ nm_policy_destroy (NMPolicy *policy) } g_slist_free (policy->dev_signal_ids); - g_object_unref (policy->settings); - /* Rewrite /etc/hosts on exit to ensure we don't leave stale IP addresses * lying around. FIXME: this will take out a valid IP address of an * ethernet device we're leaving active (ie, a connection we can "assume" @@ -1250,6 +1249,7 @@ nm_policy_destroy (NMPolicy *policy) g_free (policy->orig_hostname); g_free (policy->cur_hostname); + g_object_unref (policy->settings); g_object_unref (policy->manager); g_free (policy); } From 153e11eeea21afa549d88157b77634a747db6013 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:23:47 -0500 Subject: [PATCH 053/264] settings: small optimization hash table already has the exported object path, no reason to ask the connection itself for it. --- src/system-settings/nm-sysconfig-settings.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 5a35acea2..bba9e6970 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -204,14 +204,14 @@ impl_settings_list_connections (NMSysconfigSettings *self, { NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; - gpointer data; + gpointer key; load_connections (self); *connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); g_hash_table_iter_init (&iter, priv->connections); - while (g_hash_table_iter_next (&iter, NULL, &data)) - g_ptr_array_add (*connections, g_strdup (nm_connection_get_path (NM_CONNECTION (data)))); + while (g_hash_table_iter_next (&iter, &key, NULL)) + g_ptr_array_add (*connections, g_strdup ((const char *) key)); return TRUE; } From 33deafe69dca99b12d947586f5aa53a62e0edf9b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:24:48 -0500 Subject: [PATCH 054/264] settings: return the right thing when listing connections --- src/system-settings/nm-sysconfig-settings.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index bba9e6970..f2163c229 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -248,14 +248,14 @@ GSList * nm_sysconfig_settings_get_connections (NMSysconfigSettings *self) { GHashTableIter iter; - gpointer key = NULL; + gpointer data = NULL; GSList *list = NULL; g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); g_hash_table_iter_init (&iter, NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self)->connections); - while (g_hash_table_iter_next (&iter, key, NULL)) - list = g_slist_insert_sorted (list, key, connection_sort); + while (g_hash_table_iter_next (&iter, NULL, &data)) + list = g_slist_insert_sorted (list, data, connection_sort); return g_slist_reverse (list); } From b3b722e23421727c970efca2fff431e397d32791 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:45:52 -0500 Subject: [PATCH 055/264] core: fix session monitor initialization Braindead error handling on my part. --- src/nm-session-monitor.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index 7abc9926b..0fdaa0fb8 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -144,6 +144,7 @@ check_key (GKeyFile *keyfile, const char *group, const char *key, GError **error static Session * session_new (GKeyFile *keyfile, const char *group, GError **error) { + GError *local = NULL; Session *s; struct passwd *pw; @@ -151,27 +152,27 @@ session_new (GKeyFile *keyfile, const char *group, GError **error) g_assert (s); s->uid = G_MAXUINT; /* paranoia */ - if (!check_key (keyfile, group, "uid", error)) - return FALSE; - s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", error); - if (error) + if (!check_key (keyfile, group, "uid", &local)) + goto error; + s->uid = (uid_t) g_key_file_get_integer (keyfile, group, "uid", &local); + if (local) goto error; - if (!check_key (keyfile, group, "is_active", error)) - return FALSE; - s->active = g_key_file_get_boolean (keyfile, group, "is_active", error); - if (error) + if (!check_key (keyfile, group, "is_active", &local)) + goto error; + s->active = g_key_file_get_boolean (keyfile, group, "is_active", &local); + if (local) goto error; - if (!check_key (keyfile, group, "is_local", error)) - return FALSE; - s->local = g_key_file_get_boolean (keyfile, group, "is_local", error); - if (error) + if (!check_key (keyfile, group, "is_local", &local)) + goto error; + s->local = g_key_file_get_boolean (keyfile, group, "is_local", &local); + if (local) goto error; pw = getpwuid (s->uid); if (!pw) { - g_set_error (error, + g_set_error (&local, NM_SESSION_MONITOR_ERROR, NM_SESSION_MONITOR_ERROR_UNKNOWN_USER, "Could not get username for UID %d", @@ -184,6 +185,7 @@ session_new (GKeyFile *keyfile, const char *group, GError **error) error: session_free (s); + g_propagate_error (error, local); return NULL; } From 3c32c02778c909a475a96f07e5bcd9308186497e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:46:32 -0500 Subject: [PATCH 056/264] policy: fix and clean up policy signal disconnection on dispose --- src/nm-policy.c | 87 ++++++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 028558c57..d33871c0e 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -49,7 +49,8 @@ struct NMPolicy { NMManager *manager; guint update_state_id; GSList *pending_activation_checks; - GSList *signal_ids; + GSList *manager_ids; + GSList *settings_ids; GSList *dev_signal_ids; NMVPNManager *vpn_manager; @@ -1115,6 +1116,24 @@ connection_visibility_changed (NMSysconfigSettings *settings, _deactivate_if_active (policy->manager, NM_CONNECTION (connection)); } +static void +_connect_manager_signal (NMPolicy *policy, const char *name, gpointer callback) +{ + guint id; + + id = g_signal_connect (policy->manager, name, callback, policy); + policy->manager_ids = g_slist_prepend (policy->manager_ids, GUINT_TO_POINTER (id)); +} + +static void +_connect_settings_signal (NMPolicy *policy, const char *name, gpointer callback) +{ + guint id; + + id = g_signal_connect (policy->settings, name, callback, policy); + policy->settings_ids = g_slist_prepend (policy->settings_ids, GUINT_TO_POINTER (id)); +} + NMPolicy * nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager, @@ -1149,51 +1168,19 @@ nm_policy_new (NMManager *manager, G_CALLBACK (vpn_connection_deactivated), policy); policy->vpn_deactivated_id = id; - id = g_signal_connect (manager, "state-changed", - G_CALLBACK (global_state_changed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (manager, "notify::" NM_MANAGER_HOSTNAME, - G_CALLBACK (hostname_changed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (manager, "notify::" NM_MANAGER_SLEEPING, - G_CALLBACK (sleeping_changed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (manager, "notify::" NM_MANAGER_NETWORKING_ENABLED, - G_CALLBACK (sleeping_changed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (manager, "device-added", - G_CALLBACK (device_added), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (manager, "device-removed", - G_CALLBACK (device_removed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - /* Listen for events related to connections */ - id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, - G_CALLBACK (connection_added), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, - G_CALLBACK (connection_added), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, - G_CALLBACK (connection_updated), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, - G_CALLBACK (connection_removed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); - - id = g_signal_connect (policy->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, - G_CALLBACK (connection_visibility_changed), policy); - policy->signal_ids = g_slist_append (policy->signal_ids, (gpointer) id); + _connect_manager_signal (policy, "state-changed", global_state_changed); + _connect_manager_signal (policy, "notify::" NM_MANAGER_HOSTNAME, hostname_changed); + _connect_manager_signal (policy, "notify::" NM_MANAGER_SLEEPING, sleeping_changed); + _connect_manager_signal (policy, "notify::" NM_MANAGER_NETWORKING_ENABLED, sleeping_changed); + _connect_manager_signal (policy, "device-added", device_added); + _connect_manager_signal (policy, "device-removed", device_removed); + _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, connection_added); + _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, connection_added); + _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, connection_updated); + _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, connection_removed); + _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + connection_visibility_changed); return policy; } @@ -1225,9 +1212,13 @@ nm_policy_destroy (NMPolicy *policy) g_signal_handler_disconnect (policy->vpn_manager, policy->vpn_deactivated_id); g_object_unref (policy->vpn_manager); - for (iter = policy->signal_ids; iter; iter = g_slist_next (iter)) - g_signal_handler_disconnect (policy->manager, (gulong) iter->data); - g_slist_free (policy->signal_ids); + for (iter = policy->manager_ids; iter; iter = g_slist_next (iter)) + g_signal_handler_disconnect (policy->manager, GPOINTER_TO_UINT (iter->data)); + g_slist_free (policy->manager_ids); + + for (iter = policy->settings_ids; iter; iter = g_slist_next (iter)) + g_signal_handler_disconnect (policy->settings, GPOINTER_TO_UINT (iter->data)); + g_slist_free (policy->settings_ids); for (iter = policy->dev_signal_ids; iter; iter = g_slist_next (iter)) { DeviceSignalID *data = (DeviceSignalID *) iter->data; From e2275bba68a90eaedccf6838d4c414b27af555ab Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:50:09 -0500 Subject: [PATCH 057/264] settings: fix handling of connection visibility changes --- src/system-settings/nm-sysconfig-settings.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index f2163c229..9f1fa58bd 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -598,7 +598,9 @@ connection_updated (NMSysconfigConnection *connection, gpointer user_data) } static void -connection_visibility_changed (NMSysconfigConnection *connection, gpointer user_data) +connection_visibility_changed (NMSysconfigConnection *connection, + GParamSpec *pspec, + gpointer user_data) { g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), signals[CONNECTION_VISIBILITY_CHANGED], From 6329fadb488a270d6e60ceaf3fd2825b56f9b7d3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:50:57 -0500 Subject: [PATCH 058/264] core: fix refcounting of settings object --- src/nm-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 91a2879c0..4333cf645 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -3039,7 +3039,7 @@ nm_manager_get (NMSysconfigSettings *settings, return NULL; } - priv->settings = settings; + priv->settings = g_object_ref (settings); priv->config_file = g_strdup (config_file); priv->state_file = g_strdup (state_file); From 18f819d71db92c68b0177465bf429b066fea19ed Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 16:57:31 -0500 Subject: [PATCH 059/264] policy: clean up device signal handling --- src/nm-policy.c | 65 +++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 43 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index d33871c0e..76dd63061 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -51,7 +51,7 @@ struct NMPolicy { GSList *pending_activation_checks; GSList *manager_ids; GSList *settings_ids; - GSList *dev_signal_ids; + GSList *dev_ids; NMVPNManager *vpn_manager; gulong vpn_activated_id; @@ -948,53 +948,32 @@ wireless_networks_changed (NMDeviceWifi *device, NMAccessPoint *ap, gpointer use typedef struct { gulong id; NMDevice *device; -} DeviceSignalID; +} DeviceSignalId; -static GSList * -add_device_signal_id (GSList *list, gulong id, NMDevice *device) +static void +_connect_device_signal (NMPolicy *policy, NMDevice *device, const char *name, gpointer callback) { - DeviceSignalID *data; + DeviceSignalId *data; - data = g_malloc0 (sizeof (DeviceSignalID)); - if (!data) - return list; - - data->id = id; + data = g_slice_new0 (DeviceSignalId); + g_assert (data); + data->id = g_signal_connect (device, name, callback, policy); data->device = device; - return g_slist_append (list, data); + policy->dev_ids = g_slist_prepend (policy->dev_ids, data); } static void device_added (NMManager *manager, NMDevice *device, gpointer user_data) { NMPolicy *policy = (NMPolicy *) user_data; - gulong id; - id = g_signal_connect (device, "state-changed", - G_CALLBACK (device_state_changed), - policy); - policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); - - id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, - G_CALLBACK (device_ip_config_changed), - policy); - policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); - - id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG, - G_CALLBACK (device_ip_config_changed), - policy); - policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); + _connect_device_signal (policy, device, "state-changed", device_state_changed); + _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG, device_ip_config_changed); + _connect_device_signal (policy, device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG, device_ip_config_changed); if (NM_IS_DEVICE_WIFI (device)) { - id = g_signal_connect (device, "access-point-added", - G_CALLBACK (wireless_networks_changed), - policy); - policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); - - id = g_signal_connect (device, "access-point-removed", - G_CALLBACK (wireless_networks_changed), - policy); - policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); + _connect_device_signal (policy, device, "access-point-added", wireless_networks_changed); + _connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed); } } @@ -1020,15 +999,15 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data) } /* Clear any signal handlers for this device */ - iter = policy->dev_signal_ids; + iter = policy->dev_ids; while (iter) { - DeviceSignalID *data = (DeviceSignalID *) iter->data; + DeviceSignalId *data = iter->data; GSList *next = g_slist_next (iter); if (data->device == device) { g_signal_handler_disconnect (data->device, data->id); - g_free (data); - policy->dev_signal_ids = g_slist_delete_link (policy->dev_signal_ids, iter); + g_slice_free (DeviceSignalId, data); + policy->dev_ids = g_slist_delete_link (policy->dev_ids, iter); } iter = next; } @@ -1220,13 +1199,13 @@ nm_policy_destroy (NMPolicy *policy) g_signal_handler_disconnect (policy->settings, GPOINTER_TO_UINT (iter->data)); g_slist_free (policy->settings_ids); - for (iter = policy->dev_signal_ids; iter; iter = g_slist_next (iter)) { - DeviceSignalID *data = (DeviceSignalID *) iter->data; + for (iter = policy->dev_ids; iter; iter = g_slist_next (iter)) { + DeviceSignalId *data = iter->data; g_signal_handler_disconnect (data->device, data->id); - g_free (data); + g_slice_free (DeviceSignalId, data); } - g_slist_free (policy->dev_signal_ids); + g_slist_free (policy->dev_ids); /* Rewrite /etc/hosts on exit to ensure we don't leave stale IP addresses * lying around. FIXME: this will take out a valid IP address of an From 1ec6b67162ba18ad124150f6064268ff30cf87e7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 20:05:23 -0500 Subject: [PATCH 060/264] settings: rename NMSysconfigSettings to NMSettings --- src/main.c | 4 +- src/nm-manager.c | 68 +++--- src/nm-manager.h | 4 +- src/nm-policy.c | 26 +- src/nm-policy.h | 10 +- src/system-settings/Makefile.am | 4 +- ...{nm-sysconfig-settings.c => nm-settings.c} | 228 +++++++++--------- src/system-settings/nm-settings.h | 103 ++++++++ src/system-settings/nm-sysconfig-settings.h | 103 -------- 9 files changed, 271 insertions(+), 279 deletions(-) rename src/system-settings/{nm-sysconfig-settings.c => nm-settings.c} (85%) create mode 100644 src/system-settings/nm-settings.h delete mode 100644 src/system-settings/nm-sysconfig-settings.h diff --git a/src/main.c b/src/main.c index 5b1a78045..bb67e4127 100644 --- a/src/main.c +++ b/src/main.c @@ -453,7 +453,7 @@ main (int argc, char *argv[]) NMDBusManager *dbus_mgr = NULL; NMSupplicantManager *sup_mgr = NULL; NMDHCPManager *dhcp_mgr = NULL; - NMSysconfigSettings *settings = NULL; + NMSettings *settings = NULL; GError *error = NULL; gboolean wrote_pidfile = FALSE; char *cfg_log_level = NULL, *cfg_log_domains = NULL; @@ -673,7 +673,7 @@ main (int argc, char *argv[]) goto done; } - settings = nm_sysconfig_settings_new (config, plugins, &error); + settings = nm_settings_new (config, plugins, &error); if (!settings) { nm_log_err (LOGD_CORE, "failed to initialize settings storage."); goto done; diff --git a/src/nm-manager.c b/src/nm-manager.c index 4333cf645..986a66a0d 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -52,7 +52,7 @@ #include "nm-hostname-provider.h" #include "nm-bluez-manager.h" #include "nm-bluez-common.h" -#include "nm-sysconfig-settings.h" +#include "nm-settings.h" #include "nm-sysconfig-connection.h" #include "nm-secrets-provider-interface.h" #include "nm-manager-auth.h" @@ -200,7 +200,7 @@ typedef struct { NMUdevManager *udev_mgr; NMBluezManager *bluez_mgr; - NMSysconfigSettings *settings; + NMSettings *settings; char *hostname; GSList *secrets_calls; @@ -485,7 +485,7 @@ remove_one_device (NMManager *manager, g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager); - nm_sysconfig_settings_device_removed (priv->settings, device); + nm_settings_device_removed (priv->settings, device); g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); g_object_unref (device); @@ -743,11 +743,11 @@ get_active_connections (NMManager *manager, NMConnection *filter) } /*******************************************************************/ -/* Settings stuff via NMSysconfigSettings */ +/* Settings stuff via NMSettings */ /*******************************************************************/ static void -connections_changed (NMSysconfigSettings *settings, +connections_changed (NMSettings *settings, NMSysconfigConnection *connection, NMManager *manager) { @@ -755,15 +755,15 @@ connections_changed (NMSysconfigSettings *settings, } static void -system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings, +system_unmanaged_devices_changed_cb (NMSettings *settings, GParamSpec *pspec, gpointer user_data) { - NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); const GSList *unmanaged_specs, *iter; - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (sys_settings); + unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); for (iter = priv->devices; iter; iter = g_slist_next (iter)) { NMDevice *device = NM_DEVICE (iter->data); gboolean managed; @@ -772,30 +772,28 @@ system_unmanaged_devices_changed_cb (NMSysconfigSettings *sys_settings, nm_device_set_managed (device, managed, managed ? NM_DEVICE_STATE_REASON_NOW_MANAGED : - NM_DEVICE_STATE_REASON_NOW_UNMANAGED); + NM_DEVICE_STATE_REASON_NOW_UNMANAGED); } } static void -system_hostname_changed_cb (NMSysconfigSettings *sys_settings, +system_hostname_changed_cb (NMSettings *settings, GParamSpec *pspec, gpointer user_data) { - NMManager *manager = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); char *hostname; - hostname = nm_sysconfig_settings_get_hostname (sys_settings); - + hostname = nm_settings_get_hostname (priv->settings); if (!hostname && !priv->hostname) return; - if (hostname && priv->hostname && !strcmp (hostname, priv->hostname)) return; g_free (priv->hostname); priv->hostname = (hostname && strlen (hostname)) ? g_strdup (hostname) : NULL; - g_object_notify (G_OBJECT (manager), NM_MANAGER_HOSTNAME); + g_object_notify (G_OBJECT (self), NM_MANAGER_HOSTNAME); g_free (hostname); } @@ -945,7 +943,7 @@ manager_hidden_ap_found (NMDeviceInterface *device, /* Look for this AP's BSSID in the seen-bssids list of a connection, * and if a match is found, copy over the SSID */ - connections = nm_sysconfig_settings_get_connections (priv->settings); + connections = nm_settings_get_connections (priv->settings); for (iter = connections; iter && !done; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); @@ -1330,7 +1328,7 @@ add_device (NMManager *self, NMDevice *device) if (nm_device_interface_can_assume_connections (NM_DEVICE_INTERFACE (device))) { GSList *connections = NULL; - connections = nm_sysconfig_settings_get_connections (priv->settings); + connections = nm_settings_get_connections (priv->settings); existing = nm_device_interface_connection_match_config (NM_DEVICE_INTERFACE (device), (const GSList *) connections); g_slist_free (connections); @@ -1346,7 +1344,7 @@ add_device (NMManager *self, NMDevice *device) } /* Start the device if it's supposed to be managed */ - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->settings); + unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); if ( !manager_sleeping (self) && !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) { nm_device_set_managed (device, @@ -1356,7 +1354,7 @@ add_device (NMManager *self, NMDevice *device) managed = TRUE; } - nm_sysconfig_settings_device_added (priv->settings, device); + nm_settings_device_added (priv->settings, device); g_signal_emit (self, signals[DEVICE_ADDED], 0, device); /* If the device has a connection it can assume, do that now */ @@ -1415,7 +1413,7 @@ bluez_manager_find_connection (NMManager *manager, NMConnection *found = NULL; GSList *connections, *l; - connections = nm_sysconfig_settings_get_connections (priv->settings); + connections = nm_settings_get_connections (priv->settings); for (l = connections; l != NULL; l = l->next) { NMConnection *candidate = NM_CONNECTION (l->data); @@ -1780,8 +1778,7 @@ system_get_secrets_idle_cb (gpointer user_data) info->idle_id = 0; - connection = nm_sysconfig_settings_get_connection_by_path (priv->settings, - info->connection_path); + connection = nm_settings_get_connection_by_path (priv->settings, info->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, @@ -2040,8 +2037,7 @@ check_pending_ready (NMManager *self, PendingActivation *pending) /* Ok, we're authorized */ - connection = nm_sysconfig_settings_get_connection_by_path (priv->settings, - pending->connection_path); + connection = nm_settings_get_connection_by_path (priv->settings, pending->connection_path); if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, @@ -2286,7 +2282,7 @@ do_sleep_wake (NMManager *self) } else { nm_log_info (LOGD_SUSPEND, "waking up and re-enabling..."); - unmanaged_specs = nm_sysconfig_settings_get_unmanaged_specs (priv->settings); + unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); /* Ensure rfkill state is up-to-date since we don't respond to state * changes during sleep. @@ -3004,7 +3000,7 @@ out: } NMManager * -nm_manager_get (NMSysconfigSettings *settings, +nm_manager_get (NMSettings *settings, const char *config_file, const char *plugins, const char *state_file, @@ -3049,22 +3045,20 @@ nm_manager_get (NMSysconfigSettings *settings, priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = initial_wifi_enabled; priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = initial_wwan_enabled; - g_signal_connect (priv->settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, + g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); - g_signal_connect (priv->settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, + g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); - g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, + g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_ADDED, G_CALLBACK (connections_changed), singleton); - g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, + g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_UPDATED, G_CALLBACK (connections_changed), singleton); - g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, + g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connections_changed), singleton); - g_signal_connect (priv->settings, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, G_CALLBACK (connections_changed), singleton); - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), - NM_DBUS_PATH, - G_OBJECT (singleton)); + dbus_g_connection_register_g_object (bus, NM_DBUS_PATH, G_OBJECT (singleton)); priv->udev_mgr = nm_udev_manager_new (); g_signal_connect (priv->udev_mgr, diff --git a/src/nm-manager.h b/src/nm-manager.h index 2d0186b7c..c19ac5e87 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -27,7 +27,7 @@ #include #include "nm-device.h" #include "nm-device-interface.h" -#include "nm-sysconfig-settings.h" +#include "nm-settings.h" #define NM_TYPE_MANAGER (nm_manager_get_type ()) #define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager)) @@ -65,7 +65,7 @@ typedef struct { GType nm_manager_get_type (void); -NMManager *nm_manager_get (NMSysconfigSettings *settings, +NMManager *nm_manager_get (NMSettings *settings, const char *config_file, const char *plugins, const char *state_file, diff --git a/src/nm-policy.c b/src/nm-policy.c index 76dd63061..a34124140 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -57,7 +57,7 @@ struct NMPolicy { gulong vpn_activated_id; gulong vpn_deactivated_id; - NMSysconfigSettings *settings; + NMSettings *settings; NMDevice *default_device4; NMDevice *default_device6; @@ -742,7 +742,7 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - connections = nm_sysconfig_settings_get_connections (policy->settings); + connections = nm_settings_get_connections (policy->settings); /* Remove connections that are in the invalid list. */ iter = connections; @@ -834,7 +834,7 @@ sleeping_changed (NMManager *manager, GParamSpec *pspec, gpointer user_data) /* Clear the invalid flag on all connections so they'll get retried on wakeup */ if (sleeping || !enabled) { - connections = nm_sysconfig_settings_get_connections (policy->settings); + connections = nm_settings_get_connections (policy->settings); for (iter = connections; iter; iter = g_slist_next (iter)) g_object_set_data (G_OBJECT (iter->data), INVALID_TAG, NULL); g_slist_free (connections); @@ -1026,7 +1026,7 @@ schedule_activate_all (NMPolicy *policy) } static void -connection_added (NMSysconfigSettings *settings, +connection_added (NMSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1034,7 +1034,7 @@ connection_added (NMSysconfigSettings *settings, } static void -connection_updated (NMSysconfigSettings *settings, +connection_updated (NMSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1073,7 +1073,7 @@ _deactivate_if_active (NMManager *manager, NMConnection *connection) } static void -connection_removed (NMSysconfigSettings *settings, +connection_removed (NMSettings *settings, NMConnection *connection, gpointer user_data) { @@ -1083,7 +1083,7 @@ connection_removed (NMSysconfigSettings *settings, } static void -connection_visibility_changed (NMSysconfigSettings *settings, +connection_visibility_changed (NMSettings *settings, NMSysconfigConnection *connection, gpointer user_data) { @@ -1116,7 +1116,7 @@ _connect_settings_signal (NMPolicy *policy, const char *name, gpointer callback) NMPolicy * nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager, - NMSysconfigSettings *settings) + NMSettings *settings) { NMPolicy *policy; static gboolean initialized = FALSE; @@ -1154,11 +1154,11 @@ nm_policy_new (NMManager *manager, _connect_manager_signal (policy, "device-added", device_added); _connect_manager_signal (policy, "device-removed", device_removed); - _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, connection_added); - _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, connection_added); - _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, connection_updated); - _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, connection_removed); - _connect_settings_signal (policy, NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + _connect_settings_signal (policy, NM_SETTINGS_CONNECTIONS_LOADED, connection_added); + _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_ADDED, connection_added); + _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_UPDATED, connection_updated); + _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_REMOVED, connection_removed); + _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, connection_visibility_changed); return policy; } diff --git a/src/nm-policy.h b/src/nm-policy.h index 968d62019..33796bcaa 100644 --- a/src/nm-policy.h +++ b/src/nm-policy.h @@ -19,18 +19,18 @@ * Copyright (C) 2007 - 2008 Novell, Inc. */ -#ifndef NETWORK_MANAGER_POLICY_H -#define NETWORK_MANAGER_POLICY_H +#ifndef NM_POLICY_H +#define NM_POLICY_H #include "nm-manager.h" #include "nm-vpn-manager.h" -#include "nm-sysconfig-settings.h" +#include "nm-settings.h" typedef struct NMPolicy NMPolicy; NMPolicy *nm_policy_new (NMManager *manager, NMVPNManager *vpn_manager, - NMSysconfigSettings *settings); + NMSettings *settings); void nm_policy_destroy (NMPolicy *policy); -#endif /* NETWORK_MANAGER_POLICY_H */ +#endif /* NM_POLICY_H */ diff --git a/src/system-settings/Makefile.am b/src/system-settings/Makefile.am index 67980767c..1a8bc66cf 100644 --- a/src/system-settings/Makefile.am +++ b/src/system-settings/Makefile.am @@ -13,8 +13,8 @@ BUILT_SOURCES = \ nm-sysconfig-connection-glue.h libsystem_settings_la_SOURCES = \ - nm-sysconfig-settings.c \ - nm-sysconfig-settings.h \ + nm-settings.c \ + nm-settings.h \ nm-inotify-helper.c \ nm-inotify-helper.h \ nm-polkit-helpers.h \ diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-settings.c similarity index 85% rename from src/system-settings/nm-sysconfig-settings.c rename to src/system-settings/nm-settings.c index 9f1fa58bd..ba7375eba 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-settings.c @@ -52,7 +52,7 @@ #include "../nm-device-ethernet.h" #include "nm-dbus-glib-types.h" -#include "nm-sysconfig-settings.h" +#include "nm-settings.h" #include "nm-sysconfig-connection.h" #include "nm-polkit-helpers.h" #include "nm-system-config-error.h" @@ -78,19 +78,19 @@ EXPORT(nm_sysconfig_connection_replace_settings) EXPORT(nm_sysconfig_connection_replace_and_commit) /* END LINKER CRACKROCK */ -static void claim_connection (NMSysconfigSettings *self, +static void claim_connection (NMSettings *self, NMSysconfigConnection *connection, gboolean do_export); -static gboolean impl_settings_list_connections (NMSysconfigSettings *self, +static gboolean impl_settings_list_connections (NMSettings *self, GPtrArray **connections, GError **error); -static void impl_settings_add_connection (NMSysconfigSettings *self, +static void impl_settings_add_connection (NMSettings *self, GHashTable *settings, DBusGMethodInvocation *context); -static void impl_settings_save_hostname (NMSysconfigSettings *self, +static void impl_settings_save_hostname (NMSettings *self, const char *hostname, DBusGMethodInvocation *context); @@ -112,11 +112,11 @@ typedef struct { gboolean connections_loaded; GHashTable *connections; GSList *unmanaged_specs; -} NMSysconfigSettingsPrivate; +} NMSettingsPrivate; -G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMSettings, nm_settings, G_TYPE_OBJECT) -#define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate)) +#define NM_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTINGS, NMSettingsPrivate)) enum { PROPERTIES_CHANGED, @@ -142,9 +142,9 @@ enum { }; static void -load_connections (NMSysconfigSettings *self) +load_connections (NMSettings *self) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; if (priv->connections_loaded) @@ -176,19 +176,19 @@ load_connections (NMSysconfigSettings *self) } void -nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, - NMSysconfigSettingsForEachFunc for_each_func, - gpointer user_data) +nm_settings_for_each_connection (NMSettings *self, + NMSettingsForEachFunc for_each_func, + gpointer user_data) { - NMSysconfigSettingsPrivate *priv; + NMSettingsPrivate *priv; GHashTableIter iter; gpointer data; g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + g_return_if_fail (NM_IS_SETTINGS (self)); g_return_if_fail (for_each_func != NULL); - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE (self); load_connections (self); @@ -198,11 +198,11 @@ nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *self, } static gboolean -impl_settings_list_connections (NMSysconfigSettings *self, +impl_settings_list_connections (NMSettings *self, GPtrArray **connections, GError **error) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; gpointer key; @@ -245,30 +245,30 @@ connection_sort (gconstpointer pa, gconstpointer pb) * unref the connections in the list and destroy the list. */ GSList * -nm_sysconfig_settings_get_connections (NMSysconfigSettings *self) +nm_settings_get_connections (NMSettings *self) { GHashTableIter iter; gpointer data = NULL; GSList *list = NULL; - g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); - g_hash_table_iter_init (&iter, NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self)->connections); + g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) list = g_slist_insert_sorted (list, data, connection_sort); return g_slist_reverse (list); } NMSysconfigConnection * -nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const char *path) +nm_settings_get_connection_by_path (NMSettings *self, const char *path) { - NMSysconfigSettingsPrivate *priv; + NMSettingsPrivate *priv; g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), NULL); + g_return_val_if_fail (NM_IS_SETTINGS (self), NULL); g_return_val_if_fail (path != NULL, NULL); - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE (self); load_connections (self); @@ -276,9 +276,9 @@ nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const c } static void -clear_unmanaged_specs (NMSysconfigSettings *self) +clear_unmanaged_specs (NMSettings *self) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); g_slist_foreach (priv->unmanaged_specs, (GFunc) g_free, NULL); g_slist_free (priv->unmanaged_specs); @@ -331,18 +331,18 @@ notify (GObject *object, GParamSpec *pspec) } const GSList * -nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self) +nm_settings_get_unmanaged_specs (NMSettings *self) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); load_connections (self); return priv->unmanaged_specs; } static NMSystemConfigInterface * -get_plugin (NMSysconfigSettings *self, guint32 capability) +get_plugin (NMSettings *self, guint32 capability) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; g_return_val_if_fail (self != NULL, NULL); @@ -361,9 +361,9 @@ get_plugin (NMSysconfigSettings *self, guint32 capability) /* Returns an allocated string which the caller owns and must eventually free */ char * -nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self) +nm_settings_get_hostname (NMSettings *self) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; char *hostname = NULL; @@ -390,13 +390,13 @@ plugin_connection_added (NMSystemConfigInterface *config, NMSysconfigConnection *connection, gpointer user_data) { - claim_connection (NM_SYSCONFIG_SETTINGS (user_data), connection, TRUE); + claim_connection (NM_SETTINGS (user_data), connection, TRUE); } static gboolean -find_unmanaged_device (NMSysconfigSettings *self, const char *needle) +find_unmanaged_device (NMSettings *self, const char *needle) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; for (iter = priv->unmanaged_specs; iter; iter = g_slist_next (iter)) { @@ -410,8 +410,8 @@ static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data) { - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (user_data); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettings *self = NM_SETTINGS (user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; clear_unmanaged_specs (self); @@ -431,7 +431,7 @@ unmanaged_specs_changed (NMSystemConfigInterface *config, g_slist_free (specs); } - g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS); + g_object_notify (G_OBJECT (self), NM_SETTINGS_UNMANAGED_SPECS); } static void @@ -439,20 +439,20 @@ hostname_changed (NMSystemConfigInterface *config, GParamSpec *pspec, gpointer user_data) { - g_object_notify (G_OBJECT (user_data), NM_SYSCONFIG_SETTINGS_HOSTNAME); + g_object_notify (G_OBJECT (user_data), NM_SETTINGS_HOSTNAME); } static void -add_plugin (NMSysconfigSettings *self, NMSystemConfigInterface *plugin) +add_plugin (NMSettings *self, NMSystemConfigInterface *plugin) { - NMSysconfigSettingsPrivate *priv; + NMSettingsPrivate *priv; char *pname = NULL; char *pinfo = NULL; - g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self)); + g_return_if_fail (NM_IS_SETTINGS (self)); g_return_if_fail (NM_IS_SYSTEM_CONFIG_INTERFACE (plugin)); - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE (self); priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); @@ -501,7 +501,7 @@ find_plugin (GSList *list, const char *pname) } static gboolean -load_plugins (NMSysconfigSettings *self, const char *plugins, GError **error) +load_plugins (NMSettings *self, const char *plugins, GError **error) { GSList *list = NULL; char **plist; @@ -580,8 +580,8 @@ connection_removed (NMSysconfigConnection *connection, gpointer user_data) { g_object_ref (connection); - g_hash_table_remove (NM_SYSCONFIG_SETTINGS_GET_PRIVATE (user_data)->connections, connection); - g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, connection); + g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection); @@ -591,7 +591,7 @@ connection_removed (NMSysconfigConnection *connection, gpointer user_data) static void connection_updated (NMSysconfigConnection *connection, gpointer user_data) { - g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_UPDATED], 0, connection); @@ -602,18 +602,18 @@ connection_visibility_changed (NMSysconfigConnection *connection, GParamSpec *pspec, gpointer user_data) { - g_signal_emit (NM_SYSCONFIG_SETTINGS (user_data), + g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_VISIBILITY_CHANGED], 0, connection); } static void -claim_connection (NMSysconfigSettings *self, +claim_connection (NMSettings *self, NMSysconfigConnection *connection, gboolean do_export) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); static guint32 ec_counter = 0; GError *error = NULL; GHashTableIter iter; @@ -683,11 +683,11 @@ claim_connection (NMSysconfigSettings *self, // NMDefaultWiredConnection, and it probably needs to stay that way. So this // *needs* a better name! static void -remove_default_wired_connection (NMSysconfigSettings *self, +remove_default_wired_connection (NMSettings *self, NMSysconfigConnection *connection, gboolean do_signal) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); const char *path = nm_connection_get_path (NM_CONNECTION (connection)); if (g_hash_table_lookup (priv->connections, path)) { @@ -697,7 +697,7 @@ remove_default_wired_connection (NMSysconfigSettings *self, } typedef struct { - NMSysconfigSettings *self; + NMSettings *self; DBusGMethodInvocation *context; PolkitSubject *subject; GCancellable *cancellable; @@ -712,7 +712,7 @@ typedef struct { #include "nm-dbus-manager.h" static PolkitCall * -polkit_call_new (NMSysconfigSettings *self, +polkit_call_new (NMSettings *self, DBusGMethodInvocation *context, NMConnection *connection, const char *hostname) @@ -751,11 +751,11 @@ polkit_call_free (PolkitCall *call) } static gboolean -add_new_connection (NMSysconfigSettings *self, +add_new_connection (NMSettings *self, NMConnection *connection, GError **error) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *tmp_error = NULL, *last_error = NULL; GSList *iter; gboolean success = FALSE; @@ -764,7 +764,7 @@ add_new_connection (NMSysconfigSettings *self, 1) plugin writes a connection. 2) plugin notices that a new connection is available for reading. 3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal. - 4) NMSysconfigSettings receives the signal and adds it to it's connection list. + 4) NMSettings receives the signal and adds it to it's connection list. */ for (iter = priv->plugins; iter && !success; iter = iter->next) { @@ -787,12 +787,12 @@ static void pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PolkitCall *call = user_data; - NMSysconfigSettings *self = call->self; - NMSysconfigSettingsPrivate *priv; + NMSettings *self = call->self; + NMSettingsPrivate *priv; PolkitAuthorizationResult *pk_result; GError *error = NULL, *add_error = NULL; - /* If NMSysconfigSettings is already gone, do nothing */ + /* If NMSettings is already gone, do nothing */ if (call->disposed) { error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, @@ -803,7 +803,7 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) return; } - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE (self); priv->pk_calls = g_slist_remove (priv->pk_calls, call); @@ -845,11 +845,11 @@ out: } static void -impl_settings_add_connection (NMSysconfigSettings *self, +impl_settings_add_connection (NMSettings *self, GHashTable *settings, DBusGMethodInvocation *context) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); PolkitCall *call; NMConnection *connection; GError *error = NULL; @@ -891,8 +891,8 @@ static void pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) { PolkitCall *call = user_data; - NMSysconfigSettings *self = call->self; - NMSysconfigSettingsPrivate *priv; + NMSettings *self = call->self; + NMSettingsPrivate *priv; PolkitAuthorizationResult *pk_result; GError *error = NULL; GSList *iter; @@ -909,7 +909,7 @@ pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) return; } - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE (self); priv->pk_calls = g_slist_remove (priv->pk_calls, call); @@ -959,11 +959,11 @@ out: } static void -impl_settings_save_hostname (NMSysconfigSettings *self, +impl_settings_save_hostname (NMSettings *self, const char *hostname, DBusGMethodInvocation *context) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); PolkitCall *call; GError *error = NULL; @@ -991,9 +991,9 @@ impl_settings_save_hostname (NMSysconfigSettings *self, } static gboolean -have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) +have_connection_for_device (NMSettings *self, GByteArray *mac) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; gpointer data; NMSettingConnection *s_con; @@ -1001,7 +1001,7 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) const GByteArray *setting_mac; gboolean ret = FALSE; - g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), FALSE); + g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); g_return_val_if_fail (mac != NULL, FALSE); /* Find a wired connection locked to the given MAC address, if any */ @@ -1044,9 +1044,9 @@ have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) /* Search through the list of blacklisted MAC addresses in the config file. */ static gboolean -is_mac_auto_wired_blacklisted (NMSysconfigSettings *self, const GByteArray *mac) +is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GKeyFile *config; char **list, **iter; gboolean found = FALSE; @@ -1095,9 +1095,9 @@ out: static void default_wired_deleted (NMDefaultWiredConnection *wired, const GByteArray *mac, - NMSysconfigSettings *self) + NMSettings *self) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingConnection *s_con; char *tmp; GKeyFile *config; @@ -1196,7 +1196,7 @@ delete_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) static gboolean default_wired_try_update (NMDefaultWiredConnection *wired, - NMSysconfigSettings *self) + NMSettings *self) { GError *error = NULL; NMSettingConnection *s_con; @@ -1239,7 +1239,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, } void -nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device) +nm_settings_device_added (NMSettings *self, NMDevice *device) { GByteArray *mac = NULL; struct ether_addr tmp; @@ -1295,7 +1295,7 @@ ignore: } void -nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device) +nm_settings_device_removed (NMSettings *self, NMDevice *device) { NMDefaultWiredConnection *connection; @@ -1309,20 +1309,19 @@ nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *devic /***************************************************************/ -NMSysconfigSettings * -nm_sysconfig_settings_new (const char *config_file, +NMSettings * +nm_settings_new (const char *config_file, const char *plugins, GError **error) { - NMSysconfigSettings *self; - NMSysconfigSettingsPrivate *priv; + NMSettings *self; + NMSettingsPrivate *priv; - self = g_object_new (NM_TYPE_SYSCONFIG_SETTINGS, - NULL); + self = g_object_new (NM_TYPE_SETTINGS, NULL); if (!self) return NULL; - priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv = NM_SETTINGS_GET_PRIVATE (self); priv->config_file = g_strdup (config_file); priv->dbus_mgr = nm_dbus_manager_get (); @@ -1344,8 +1343,8 @@ nm_sysconfig_settings_new (const char *config_file, static void dispose (GObject *object) { - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettings *self = NM_SETTINGS (object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; if (priv->auth_changed_id) { @@ -1365,14 +1364,14 @@ dispose (GObject *object) g_object_unref (priv->dbus_mgr); - G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); } static void finalize (GObject *object) { - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettings *self = NM_SETTINGS (object); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); g_hash_table_destroy (priv->connections); @@ -1383,26 +1382,26 @@ finalize (GObject *object) g_free (priv->config_file); - G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); + G_OBJECT_CLASS (nm_settings_parent_class)->finalize (object); } static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object); + NMSettings *self = NM_SETTINGS (object); const GSList *specs, *iter; GSList *copy = NULL; switch (prop_id) { case PROP_UNMANAGED_SPECS: - specs = nm_sysconfig_settings_get_unmanaged_specs (self); + specs = nm_settings_get_unmanaged_specs (self); for (iter = specs; iter; iter = g_slist_next (iter)) copy = g_slist_append (copy, g_strdup (iter->data)); g_value_take_boxed (value, copy); break; case PROP_HOSTNAME: - g_value_take_string (value, nm_sysconfig_settings_get_hostname (self)); + g_value_take_string (value, nm_settings_get_hostname (self)); /* Don't ever pass NULL through D-Bus */ if (!g_value_get_string (value)) @@ -1418,11 +1417,11 @@ get_property (GObject *object, guint prop_id, } static void -nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) +nm_settings_class_init (NMSettingsClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - g_type_class_add_private (class, sizeof (NMSysconfigSettingsPrivate)); + g_type_class_add_private (class, sizeof (NMSettingsPrivate)); /* virtual methods */ object_class->notify = notify; @@ -1434,7 +1433,7 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) g_object_class_install_property (object_class, PROP_UNMANAGED_SPECS, - g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, + g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "Unamanged device specs", "Unmanaged device specs", DBUS_TYPE_G_LIST_OF_STRING, @@ -1442,7 +1441,7 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) g_object_class_install_property (object_class, PROP_HOSTNAME, - g_param_spec_string (NM_SYSCONFIG_SETTINGS_HOSTNAME, + g_param_spec_string (NM_SETTINGS_HOSTNAME, "Hostname", "Persistent hostname", NULL, @@ -1450,7 +1449,7 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) g_object_class_install_property (object_class, PROP_CAN_MODIFY, - g_param_spec_boolean (NM_SYSCONFIG_SETTINGS_CAN_MODIFY, + g_param_spec_boolean (NM_SETTINGS_CAN_MODIFY, "CanModify", "Can modify anything (hostname, connections, etc)", FALSE, @@ -1461,51 +1460,51 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) g_signal_new ("properties-changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed), + G_STRUCT_OFFSET (NMSettingsClass, properties_changed), NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); signals[CONNECTION_ADDED] = - g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED, + g_signal_new (NM_SETTINGS_CONNECTION_ADDED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_added), + G_STRUCT_OFFSET (NMSettingsClass, connection_added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_UPDATED] = - g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED, + g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_updated), + G_STRUCT_OFFSET (NMSettingsClass, connection_updated), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_REMOVED] = - g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED, + g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_removed), + G_STRUCT_OFFSET (NMSettingsClass, connection_removed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_VISIBILITY_CHANGED] = - g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + g_signal_new (NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, connection_visibility_changed), + G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTIONS_LOADED] = - g_signal_new (NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED, + g_signal_new (NM_SETTINGS_CONNECTIONS_LOADED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSysconfigSettingsClass, connections_loaded), + G_STRUCT_OFFSET (NMSettingsClass, connections_loaded), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); @@ -1540,15 +1539,14 @@ nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class) dbus_g_error_domain_register (NM_SETTING_WIRELESS_ERROR, NULL, NM_TYPE_SETTING_WIRELESS_ERROR); dbus_g_error_domain_register (NM_SETTING_ERROR, NULL, NM_TYPE_SETTING_ERROR); - dbus_g_object_type_install_info (NM_TYPE_SYSCONFIG_SETTINGS, - &dbus_glib_nm_settings_object_info); + dbus_g_object_type_install_info (NM_TYPE_SETTINGS, &dbus_glib_nm_settings_object_info); } static void -nm_sysconfig_settings_init (NMSysconfigSettings *self) +nm_settings_init (NMSettings *self) { - NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *error = NULL; priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); diff --git a/src/system-settings/nm-settings.h b/src/system-settings/nm-settings.h new file mode 100644 index 000000000..51c454fd9 --- /dev/null +++ b/src/system-settings/nm-settings.h @@ -0,0 +1,103 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * Søren Sandmann + * Dan Williams + * Tambet Ingo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2008 Novell, Inc. + */ + +#ifndef __NM_SETTINGS_H__ +#define __NM_SETTINGS_H__ + +#include + +#include "nm-sysconfig-connection.h" +#include "nm-system-config-interface.h" +#include "nm-device.h" + +#define NM_TYPE_SETTINGS (nm_settings_get_type ()) +#define NM_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS, NMSettings)) +#define NM_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS, NMSettingsClass)) +#define NM_IS_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS)) +#define NM_IS_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS)) +#define NM_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS, NMSettingsClass)) + +#define NM_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" +#define NM_SETTINGS_HOSTNAME "hostname" +#define NM_SETTINGS_CAN_MODIFY "can-modify" + +#define NM_SETTINGS_CONNECTION_ADDED "connection-added" +#define NM_SETTINGS_CONNECTION_UPDATED "connection-updated" +#define NM_SETTINGS_CONNECTION_REMOVED "connection-removed" +#define NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" +#define NM_SETTINGS_CONNECTIONS_LOADED "connections-loaded" + +typedef struct { + GObject parent_instance; +} NMSettings; + +typedef struct { + GObjectClass parent_class; + + /* Signals */ + void (*properties_changed) (NMSettings *self, GHashTable *properties); + + void (*connection_added) (NMSettings *self, NMConnection *connection); + + void (*connection_updated) (NMSettings *self, NMConnection *connection); + + void (*connection_removed) (NMSettings *self, NMConnection *connection); + + void (*connection_visibility_changed) (NMSettings *self, NMConnection *connection); + + void (*connections_loaded) (NMSettings *self); +} NMSettingsClass; + +GType nm_settings_get_type (void); + +NMSettings *nm_settings_new (const char *config_file, + const char *plugins, + GError **error); + +typedef void (*NMSettingsForEachFunc) (NMSettings *settings, + NMSysconfigConnection *connection, + gpointer user_data); + +void nm_settings_for_each_connection (NMSettings *settings, + NMSettingsForEachFunc for_each_func, + gpointer user_data); + +/* Returns a list of NMSysconfigConnections. Caller must free the list with + * g_slist_free(). + */ +GSList *nm_settings_get_connections (NMSettings *settings); + +NMSysconfigConnection *nm_settings_get_connection_by_path (NMSettings *settings, + const char *path); + +const GSList *nm_settings_get_unmanaged_specs (NMSettings *self); + +char *nm_settings_get_hostname (NMSettings *self); + +void nm_settings_device_added (NMSettings *self, NMDevice *device); + +void nm_settings_device_removed (NMSettings *self, NMDevice *device); + +#endif /* __NM_SETTINGS_H__ */ diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h deleted file mode 100644 index 9f8565daa..000000000 --- a/src/system-settings/nm-sysconfig-settings.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * Søren Sandmann - * Dan Williams - * Tambet Ingo - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2007 - 2009 Red Hat, Inc. - * (C) Copyright 2008 Novell, Inc. - */ - -#ifndef __NM_SYSCONFIG_SETTINGS_H__ -#define __NM_SYSCONFIG_SETTINGS_H__ - -#include - -#include "nm-sysconfig-connection.h" -#include "nm-system-config-interface.h" -#include "nm-device.h" - -#define NM_TYPE_SYSCONFIG_SETTINGS (nm_sysconfig_settings_get_type ()) -#define NM_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettings)) -#define NM_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) -#define NM_IS_SYSCONFIG_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_SETTINGS)) -#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS)) -#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass)) - -#define NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS "unmanaged-specs" -#define NM_SYSCONFIG_SETTINGS_HOSTNAME "hostname" -#define NM_SYSCONFIG_SETTINGS_CAN_MODIFY "can-modify" - -#define NM_SYSCONFIG_SETTINGS_CONNECTION_ADDED "connection-added" -#define NM_SYSCONFIG_SETTINGS_CONNECTION_UPDATED "connection-updated" -#define NM_SYSCONFIG_SETTINGS_CONNECTION_REMOVED "connection-removed" -#define NM_SYSCONFIG_SETTINGS_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" -#define NM_SYSCONFIG_SETTINGS_CONNECTIONS_LOADED "connections-loaded" - -typedef struct { - GObject parent_instance; -} NMSysconfigSettings; - -typedef struct { - GObjectClass parent_class; - - /* Signals */ - void (*properties_changed) (NMSysconfigSettings *self, GHashTable *properties); - - void (*connection_added) (NMSysconfigSettings *self, NMConnection *connection); - - void (*connection_updated) (NMSysconfigSettings *self, NMConnection *connection); - - void (*connection_removed) (NMSysconfigSettings *self, NMConnection *connection); - - void (*connection_visibility_changed) (NMSysconfigSettings *self, NMConnection *connection); - - void (*connections_loaded) (NMSysconfigSettings *self); -} NMSysconfigSettingsClass; - -GType nm_sysconfig_settings_get_type (void); - -NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file, - const char *plugins, - GError **error); - -typedef void (*NMSysconfigSettingsForEachFunc) (NMSysconfigSettings *settings, - NMSysconfigConnection *connection, - gpointer user_data); - -void nm_sysconfig_settings_for_each_connection (NMSysconfigSettings *settings, - NMSysconfigSettingsForEachFunc for_each_func, - gpointer user_data); - -/* Returns a list of NMSysconfigConnections. Caller must free the list with - * g_slist_free(). - */ -GSList *nm_sysconfig_settings_get_connections (NMSysconfigSettings *settings); - -NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *settings, - const char *path); - -const GSList *nm_sysconfig_settings_get_unmanaged_specs (NMSysconfigSettings *self); - -char *nm_sysconfig_settings_get_hostname (NMSysconfigSettings *self); - -void nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device); - -void nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device); - -#endif /* __NM_SYSCONFIG_SETTINGS_H__ */ From 83ab4ec2ee62e75028a6025243c7f07485d4ca81 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 20:22:14 -0500 Subject: [PATCH 061/264] settings: system-settings -> settings --- configure.ac | 2 +- po/POTFILES.in | 2 +- po/as.po | 2 +- po/bg.po | 2 +- po/bn_IN.po | 2 +- po/cs.po | 2 +- po/de.po | 2 +- po/el.po | 2 +- po/en_GB.po | 2 +- po/es.po | 2 +- po/eu.po | 2 +- po/fr.po | 2 +- po/gl.po | 2 +- po/gu.po | 2 +- po/hi.po | 2 +- po/hu.po | 2 +- po/id.po | 2 +- po/it.po | 2 +- po/ja.po | 2 +- po/kn.po | 2 +- po/ko.po | 2 +- po/lt.po | 2 +- po/ml.po | 2 +- po/mr.po | 2 +- po/or.po | 2 +- po/pa.po | 2 +- po/pl.po | 2 +- po/pt_BR.po | 2 +- po/ru.po | 2 +- po/sl.po | 2 +- po/sv.po | 2 +- po/ta.po | 2 +- po/te.po | 2 +- po/zh_CN.po | 2 +- po/zh_TW.po | 2 +- src/Makefile.am | 6 +++--- src/nm-policy.c | 2 +- src/{system-settings => settings}/Makefile.am | 10 +++++----- .../nm-default-wired-connection.c | 0 .../nm-default-wired-connection.h | 0 src/{system-settings => settings}/nm-inotify-helper.c | 0 src/{system-settings => settings}/nm-inotify-helper.h | 0 src/{system-settings => settings}/nm-polkit-helpers.h | 0 src/{system-settings => settings}/nm-settings.c | 0 src/{system-settings => settings}/nm-settings.h | 0 .../nm-sysconfig-connection.c | 0 .../nm-sysconfig-connection.h | 0 .../nm-system-config-error.c | 0 .../nm-system-config-error.h | 0 .../nm-system-config-interface.c | 0 .../nm-system-config-interface.h | 0 system-settings/plugins/ifcfg-rh/Makefile.am | 2 +- system-settings/plugins/ifcfg-suse/Makefile.am | 2 +- system-settings/plugins/ifnet/Makefile.am | 2 +- system-settings/plugins/ifnet/tests/Makefile.am | 2 +- system-settings/plugins/ifupdown/Makefile.am | 2 +- system-settings/plugins/keyfile/Makefile.am | 2 +- 57 files changed, 50 insertions(+), 50 deletions(-) rename src/{system-settings => settings}/Makefile.am (89%) rename src/{system-settings => settings}/nm-default-wired-connection.c (100%) rename src/{system-settings => settings}/nm-default-wired-connection.h (100%) rename src/{system-settings => settings}/nm-inotify-helper.c (100%) rename src/{system-settings => settings}/nm-inotify-helper.h (100%) rename src/{system-settings => settings}/nm-polkit-helpers.h (100%) rename src/{system-settings => settings}/nm-settings.c (100%) rename src/{system-settings => settings}/nm-settings.h (100%) rename src/{system-settings => settings}/nm-sysconfig-connection.c (100%) rename src/{system-settings => settings}/nm-sysconfig-connection.h (100%) rename src/{system-settings => settings}/nm-system-config-error.c (100%) rename src/{system-settings => settings}/nm-system-config-error.h (100%) rename src/{system-settings => settings}/nm-system-config-interface.c (100%) rename src/{system-settings => settings}/nm-system-config-interface.h (100%) diff --git a/configure.ac b/configure.ac index 4dfda0357..1a2c16ad9 100644 --- a/configure.ac +++ b/configure.ac @@ -518,7 +518,7 @@ src/ppp-manager/Makefile src/dnsmasq-manager/Makefile src/modem-manager/Makefile src/bluez-manager/Makefile -src/system-settings/Makefile +src/settings/Makefile src/backends/Makefile libnm-util/libnm-util.pc libnm-util/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index a7a3ecb48..d4d8c4b1e 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -18,7 +18,7 @@ src/dhcp-manager/nm-dhcp-dhclient.c src/dhcp-manager/nm-dhcp-manager.c src/logging/nm-logging.c src/dns-manager/nm-dns-manager.c -src/system-settings/nm-default-wired-connection.c +src/settings/nm-default-wired-connection.c system-settings/plugins/ifcfg-rh/reader.c system-settings/plugins/ifnet/connection_parser.c diff --git a/po/as.po b/po/as.po index 46e41809b..78a2cd3a9 100644 --- a/po/as.po +++ b/po/as.po @@ -1598,7 +1598,7 @@ msgstr "মন কৰিব: libc resolver ৰ দ্বাৰা ৩ তকৈ msgid "The nameservers listed below may not be recognized." msgstr "নিম্নলিখিত নাম-সেৱকসমূহ চিনাক্ত ন'হ'বও পাৰে ।" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "স্বয়ংক্ৰিয় %s" diff --git a/po/bg.po b/po/bg.po index 5a1e7c1c0..578cee9d0 100644 --- a/po/bg.po +++ b/po/bg.po @@ -1877,7 +1877,7 @@ msgstr "ЗАБЕЛЕЖКА: libc може да не поддържа повеч msgid "The nameservers listed below may not be recognized." msgstr "Долните сървъри за имена може да не бъдат разпознати." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Автоматично %s" diff --git a/po/bn_IN.po b/po/bn_IN.po index cf275dad6..372d7bb2a 100644 --- a/po/bn_IN.po +++ b/po/bn_IN.po @@ -1597,7 +1597,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "নিম্নলিখিত নেম-সার্ভারগুলি সনাক্ত না হওয়ার সম্ভাবনা রয়েছে।" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "স্বয়ংক্রিয় %s" diff --git a/po/cs.po b/po/cs.po index 4c59825e8..d541b5860 100644 --- a/po/cs.po +++ b/po/cs.po @@ -1344,7 +1344,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Jmenné servery uvedené v následujícím seznamu nelze rozpoznat." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "%s (automaticky)" diff --git a/po/de.po b/po/de.po index 07a6a3b24..90de5c22e 100644 --- a/po/de.po +++ b/po/de.po @@ -1809,7 +1809,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Die nachfolgend gelisteten Nameserver werden eventuell nicht erkannt." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/el.po b/po/el.po index cb9fa186b..c6db6f79b 100644 --- a/po/el.po +++ b/po/el.po @@ -1773,7 +1773,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Οι κάτωθι εξυπηρετητές ονομάτων ίσως να μην αναγνωρίζονται." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Αυτόματο %s" diff --git a/po/en_GB.po b/po/en_GB.po index ef279f8fa..528f915c2 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -326,7 +326,7 @@ msgstr "NOTE: the libc resolver may not support more than 3 nameservers." msgid "The nameservers listed below may not be recognized." msgstr "The nameservers listed below may not be recognised." -#: ../src/system-settings/nm-default-wired-connection.c:194 +#: ../src/settings/nm-default-wired-connection.c:194 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/es.po b/po/es.po index 74746f4a4..2ef45cbca 100644 --- a/po/es.po +++ b/po/es.po @@ -1768,7 +1768,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Puede que los servidores de nombres listados abajo no se reconozcan." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/eu.po b/po/eu.po index 5a584ec36..68b8204a4 100644 --- a/po/eu.po +++ b/po/eu.po @@ -1308,7 +1308,7 @@ msgstr "OHARRA: libc-en ebaztaileak ez du 3 izen-zerbitzari baino gehiago onartz msgid "The nameservers listed below may not be recognized." msgstr "Azpian zerrendatutako izen-zenbitzariak ez dira ezagutuko." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/fr.po b/po/fr.po index 25b6c76b8..6aa67c8c2 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1621,7 +1621,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Les serveurs de noms listés ci-dessous peuvent ne pas être reconnus." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/gl.po b/po/gl.po index 4adefda78..62dc71f3f 100644 --- a/po/gl.po +++ b/po/gl.po @@ -1732,7 +1732,7 @@ msgstr "NOTE: o importador libc non permite máis de 3 nomes de servidores." msgid "The nameservers listed below may not be recognized." msgstr "Os nomes de servidores listados a seguir poden non ser recoñecidos" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/gu.po b/po/gu.po index 3fa8cf333..68c97d715 100644 --- a/po/gu.po +++ b/po/gu.po @@ -1596,7 +1596,7 @@ msgstr "નોંધ: libc સુધારનાર એ ૩ નામ સર્ msgid "The nameservers listed below may not be recognized." msgstr "નીચે યાદી થયેલ નામસર્વરો એ ઓળખી શકાતા નથી." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "%s સ્વયં કરો" diff --git a/po/hi.po b/po/hi.po index aab5c0346..59b00c4a8 100644 --- a/po/hi.po +++ b/po/hi.po @@ -1691,7 +1691,7 @@ msgstr "नोट: libc समाधानकर्ता 3 नेमसर् msgid "The nameservers listed below may not be recognized." msgstr "नीचे सूची में दिया गया नेमसर्वर पहचाना नहीं जा सकता है." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "स्वतः %s" diff --git a/po/hu.po b/po/hu.po index 0ca4386f2..942b17b1e 100644 --- a/po/hu.po +++ b/po/hu.po @@ -1780,7 +1780,7 @@ msgstr "MEGJEGYZÉS: a libc feloldó nem támogat háromnál több névkiszolgá msgid "The nameservers listed below may not be recognized." msgstr "Az alább felsorolt névkiszolgálók lehet, hogy nem kerülnek felismerésre." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Automatikus %s" diff --git a/po/id.po b/po/id.po index b88792905..e8adc1510 100644 --- a/po/id.po +++ b/po/id.po @@ -1706,7 +1706,7 @@ msgstr "CATATAN: resolver libc mungkin tak mendukung lebih dari 3 nameserver." msgid "The nameservers listed below may not be recognized." msgstr "Nameserver yang terdaftar di bawah mungkin tak dikenali." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Otomatis %s" diff --git a/po/it.po b/po/it.po index dd24604d5..08de04994 100644 --- a/po/it.po +++ b/po/it.po @@ -1610,7 +1610,7 @@ msgstr "NOTA: il risolutore libc non supporta più di 3 server di nomi." msgid "The nameservers listed below may not be recognized." msgstr "I server di nomi elencati sotto non possono essere riconosciuti." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "%s (automatica)" diff --git a/po/ja.po b/po/ja.po index 4b49f0089..37f0e8296 100644 --- a/po/ja.po +++ b/po/ja.po @@ -1598,7 +1598,7 @@ msgstr "注記: libc リゾルバは 3つ以上のネームサーバーをサ msgid "The nameservers listed below may not be recognized." msgstr "以下の一覧にあるネームサーバーは認識されないかも知れません。" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "自動 %s" diff --git a/po/kn.po b/po/kn.po index 54769baa7..6d172a0d7 100644 --- a/po/kn.po +++ b/po/kn.po @@ -1700,7 +1700,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "ಈ ಕೆಳಗೆ ಸೂಚಿಸಲಾದ ನಾಮಪರಿಚಾರಕಗಳನ್ನು ಗುರುತಿಸಲಾಗಿಲ್ಲ." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "ಸ್ವಯಂ %s" diff --git a/po/ko.po b/po/ko.po index e2cc426bc..20b749afd 100644 --- a/po/ko.po +++ b/po/ko.po @@ -1598,7 +1598,7 @@ msgstr "주의: libc 주소 검색은 3개를 초과하는 네임서버를 지 msgid "The nameservers listed below may not be recognized." msgstr "아래 열거된 네임서버를 인식하지 못할 수 있습니다." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "자동 %s" diff --git a/po/lt.po b/po/lt.po index 6c1d170c3..2de5aed61 100644 --- a/po/lt.po +++ b/po/lt.po @@ -1696,7 +1696,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Žemiau pateikti vardų serveriai gali būti neatpažinti." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Automatinis %s" diff --git a/po/ml.po b/po/ml.po index 0d9796f9f..59b0b0f26 100644 --- a/po/ml.po +++ b/po/ml.po @@ -1594,7 +1594,7 @@ msgstr "കുറിപ്പു്: libc റിസോള്‍വര്‍ 3 msgid "The nameservers listed below may not be recognized." msgstr "താഴെ പറഞ്ഞിരിക്കുന്ന നെയിംസര്‍വറുകള്‍ തിരിച്ചറിയപ്പെടുന്നവയല്ല." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "ഓട്ടോ %s" diff --git a/po/mr.po b/po/mr.po index 67335ad2e..03f93b272 100644 --- a/po/mr.po +++ b/po/mr.po @@ -1680,7 +1680,7 @@ msgstr "NOTE: libc रिजॉलव्हर 3 पेक्षा जास् msgid "The nameservers listed below may not be recognized." msgstr "खालिल यादीतील नेमसर्व्हर्स् अनोळखी राहतील." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "स्वयं %s" diff --git a/po/or.po b/po/or.po index bba0d598c..32eb1aa11 100644 --- a/po/or.po +++ b/po/or.po @@ -1696,7 +1696,7 @@ msgstr "ଟିପ୍ପଣୀ: libc resolver 3 ରୁ ଅଧିକ nameserverଗ msgid "The nameservers listed below may not be recognized." msgstr "ନିମ୍ନରେ ତାଲିକାଭୁକ୍ତ nameserverଗୁଡ଼ିକୁ ଚିହ୍ନି ହୋଇନପାରେ." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "ସ୍ୱୟଂ %s" diff --git a/po/pa.po b/po/pa.po index cf3777a70..87092b0f3 100644 --- a/po/pa.po +++ b/po/pa.po @@ -1755,7 +1755,7 @@ msgstr "ਨੋਟ: libc ਰਿਜ਼ੋਲਵਰ ੩ ਤੋਂ ਵੱਧ ਨੇ msgid "The nameservers listed below may not be recognized." msgstr "ਹੇਠਾਂ ਦਿੱਤੇ ਨੇਮ-ਸਰਵਰ ਪਛਾਣੇ ਨਹੀਂ ਜਾ ਸਕਦੇ।" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "ਆਟੋ %s" diff --git a/po/pl.po b/po/pl.po index f1b0650d0..58ad3e7e5 100644 --- a/po/pl.po +++ b/po/pl.po @@ -1780,7 +1780,7 @@ msgstr "UWAGA: obsługa nazw libc nie obsługuje więcej niż 3 serwery nazw." msgid "The nameservers listed below may not be recognized." msgstr "Poniższe serwery nazw nie mogą nie zostać rozpoznane." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Automatyczne %s" diff --git a/po/pt_BR.po b/po/pt_BR.po index 40919e8a6..3b364b50b 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -1321,7 +1321,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Os servidores de nomes listados abaixo podem não ser reconhecidos." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Auto %s" diff --git a/po/ru.po b/po/ru.po index 2595ab3c6..5dc18f383 100644 --- a/po/ru.po +++ b/po/ru.po @@ -1604,7 +1604,7 @@ msgstr "" msgid "The nameservers listed below may not be recognized." msgstr "Нижеперечисленные сервера могут быть пропущены." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Авто %s" diff --git a/po/sl.po b/po/sl.po index cb37ee828..33af9c1e5 100644 --- a/po/sl.po +++ b/po/sl.po @@ -1839,7 +1839,7 @@ msgstr "OPOMBA: razreševalnik libc morda ne podpira več kot 3 imenskih strežn msgid "The nameservers listed below may not be recognized." msgstr "Navedeni imenski strežniki morda ne bodo prepoznani." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Samodejno %s" diff --git a/po/sv.po b/po/sv.po index dc9869ed1..590abfae0 100644 --- a/po/sv.po +++ b/po/sv.po @@ -1857,7 +1857,7 @@ msgstr "OBSERVERA: uppslag via glibc kanske inte har stöd för fler än 3 namns msgid "The nameservers listed below may not be recognized." msgstr "Namnservrarna listade nedan kanske inte kommer att kännas igen." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "Automatisk %s" diff --git a/po/ta.po b/po/ta.po index 8ab5caeb6..44125c38b 100644 --- a/po/ta.po +++ b/po/ta.po @@ -1602,7 +1602,7 @@ msgstr "குறிப்பு: இந்த libc மறுதீர்வா msgid "The nameservers listed below may not be recognized." msgstr "கீழே பட்டியலிட்டப்படுள்ள பெயர்சேவையகங்கள் கண்டுபிடிக்கப்படவில்லை." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "தானியக்கி %s" diff --git a/po/te.po b/po/te.po index cf0556141..a8d55575c 100644 --- a/po/te.po +++ b/po/te.po @@ -1689,7 +1689,7 @@ msgstr "గమనిక: libc రిజాల్వర్ 3 నామపు స msgid "The nameservers listed below may not be recognized." msgstr "క్రిందన జాబితాచేసివున్న నామపుసేవికలు గుర్తించబడక పోవచ్చును." -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "స్వయంచాలక %s" diff --git a/po/zh_CN.po b/po/zh_CN.po index 81e2e6b6a..5f4b64f4c 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -1690,7 +1690,7 @@ msgstr "注意:libc 解析器可能不支持超过三个名字服务器。" msgid "The nameservers listed below may not be recognized." msgstr "以下列出的名字服务器可能无法被识别。" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "自动 %s" diff --git a/po/zh_TW.po b/po/zh_TW.po index 25e81bbe1..d6e530fdf 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -1599,7 +1599,7 @@ msgstr "注意:libc 解析器不支援 3 個以上的名稱伺服器。" msgid "The nameservers listed below may not be recognized." msgstr "下面列出的名稱伺服器可能不會被辨識。" -#: ../src/system-settings/nm-default-wired-connection.c:157 +#: ../src/settings/nm-default-wired-connection.c:157 #, c-format msgid "Auto %s" msgstr "自動 %s" diff --git a/src/Makefile.am b/src/Makefile.am index 5f42b7ab0..aab9ce65b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,7 +10,7 @@ SUBDIRS= \ dnsmasq-manager \ modem-manager \ bluez-manager \ - system-settings \ + settings \ . \ tests @@ -26,7 +26,7 @@ INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/src/dnsmasq-manager \ -I${top_srcdir}/src/modem-manager \ -I$(top_srcdir)/src/bluez-manager \ - -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/src/settings \ -I${top_srcdir}/libnm-util \ -I${top_srcdir}/libnm-glib \ -I${top_srcdir}/callouts @@ -239,7 +239,7 @@ NetworkManager_LDADD = \ ./ppp-manager/libppp-manager.la \ ./modem-manager/libmodem-manager.la \ ./bluez-manager/libbluez-manager.la \ - ./system-settings/libsystem-settings.la \ + ./settings/libsettings.la \ ./backends/libnmbackend.la \ $(top_builddir)/libnm-util/libnm-util.la \ $(DBUS_LIBS) \ diff --git a/src/nm-policy.c b/src/nm-policy.c index a34124140..25a64ab67 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -330,7 +330,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best4, NMDevice *best6) /* Hostname precedence order: * - * 1) a configured hostname (from system-settings) + * 1) a configured hostname (from settings) * 2) automatic hostname from the default device's config (DHCP, VPN, etc) * 3) the original hostname when NM started * 4) reverse-DNS of the best device's IPv4 address diff --git a/src/system-settings/Makefile.am b/src/settings/Makefile.am similarity index 89% rename from src/system-settings/Makefile.am rename to src/settings/Makefile.am index 1a8bc66cf..384175005 100644 --- a/src/system-settings/Makefile.am +++ b/src/settings/Makefile.am @@ -6,13 +6,13 @@ INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/src \ -I${top_builddir}/marshallers -noinst_LTLIBRARIES = libsystem-settings.la +noinst_LTLIBRARIES = libsettings.la BUILT_SOURCES = \ nm-settings-glue.h \ nm-sysconfig-connection-glue.h -libsystem_settings_la_SOURCES = \ +libsettings_la_SOURCES = \ nm-settings.c \ nm-settings.h \ nm-inotify-helper.c \ @@ -27,7 +27,7 @@ libsystem_settings_la_SOURCES = \ nm-default-wired-connection.c \ nm-default-wired-connection.h -libsystem_settings_la_CPPFLAGS = \ +libsettings_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ $(GMODULE_CFLAGS) \ @@ -42,7 +42,7 @@ libsystem_settings_la_CPPFLAGS = \ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \ -DPLUGINDIR=\"$(pkglibdir)\" -libsystem_settings_la_LIBADD = \ +libsettings_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/marshallers/libmarshallers.la \ @@ -52,7 +52,7 @@ libsystem_settings_la_LIBADD = \ $(GMODULE_LIBS) \ $(POLKIT_LIBS) -libsystem_settings_la_LDFLAGS = -rdynamic +libsettings_la_LDFLAGS = -rdynamic nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml diff --git a/src/system-settings/nm-default-wired-connection.c b/src/settings/nm-default-wired-connection.c similarity index 100% rename from src/system-settings/nm-default-wired-connection.c rename to src/settings/nm-default-wired-connection.c diff --git a/src/system-settings/nm-default-wired-connection.h b/src/settings/nm-default-wired-connection.h similarity index 100% rename from src/system-settings/nm-default-wired-connection.h rename to src/settings/nm-default-wired-connection.h diff --git a/src/system-settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c similarity index 100% rename from src/system-settings/nm-inotify-helper.c rename to src/settings/nm-inotify-helper.c diff --git a/src/system-settings/nm-inotify-helper.h b/src/settings/nm-inotify-helper.h similarity index 100% rename from src/system-settings/nm-inotify-helper.h rename to src/settings/nm-inotify-helper.h diff --git a/src/system-settings/nm-polkit-helpers.h b/src/settings/nm-polkit-helpers.h similarity index 100% rename from src/system-settings/nm-polkit-helpers.h rename to src/settings/nm-polkit-helpers.h diff --git a/src/system-settings/nm-settings.c b/src/settings/nm-settings.c similarity index 100% rename from src/system-settings/nm-settings.c rename to src/settings/nm-settings.c diff --git a/src/system-settings/nm-settings.h b/src/settings/nm-settings.h similarity index 100% rename from src/system-settings/nm-settings.h rename to src/settings/nm-settings.h diff --git a/src/system-settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c similarity index 100% rename from src/system-settings/nm-sysconfig-connection.c rename to src/settings/nm-sysconfig-connection.c diff --git a/src/system-settings/nm-sysconfig-connection.h b/src/settings/nm-sysconfig-connection.h similarity index 100% rename from src/system-settings/nm-sysconfig-connection.h rename to src/settings/nm-sysconfig-connection.h diff --git a/src/system-settings/nm-system-config-error.c b/src/settings/nm-system-config-error.c similarity index 100% rename from src/system-settings/nm-system-config-error.c rename to src/settings/nm-system-config-error.c diff --git a/src/system-settings/nm-system-config-error.h b/src/settings/nm-system-config-error.h similarity index 100% rename from src/system-settings/nm-system-config-error.h rename to src/settings/nm-system-config-error.h diff --git a/src/system-settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c similarity index 100% rename from src/system-settings/nm-system-config-interface.c rename to src/settings/nm-system-config-interface.c diff --git a/src/system-settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h similarity index 100% rename from src/system-settings/nm-system-config-interface.h rename to src/settings/nm-system-config-interface.h diff --git a/system-settings/plugins/ifcfg-rh/Makefile.am b/system-settings/plugins/ifcfg-rh/Makefile.am index 54d686bb4..9874d352b 100644 --- a/system-settings/plugins/ifcfg-rh/Makefile.am +++ b/system-settings/plugins/ifcfg-rh/Makefile.am @@ -23,7 +23,7 @@ libifcfg_rh_io_la_SOURCES = \ utils.h INCLUDES = \ - -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-glib \ -I$(top_srcdir)/libnm-util \ diff --git a/system-settings/plugins/ifcfg-suse/Makefile.am b/system-settings/plugins/ifcfg-suse/Makefile.am index f28f57f79..3db8ed31d 100644 --- a/system-settings/plugins/ifcfg-suse/Makefile.am +++ b/system-settings/plugins/ifcfg-suse/Makefile.am @@ -10,7 +10,7 @@ libnm_settings_plugin_ifcfg_suse_la_CPPFLAGS = \ $(GMODULE_CFLAGS) \ $(DBUS_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -I${top_srcdir}/src/system-settings \ + -I${top_srcdir}/src/settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ diff --git a/system-settings/plugins/ifnet/Makefile.am b/system-settings/plugins/ifnet/Makefile.am index f63f8ca71..52056ffda 100644 --- a/system-settings/plugins/ifnet/Makefile.am +++ b/system-settings/plugins/ifnet/Makefile.am @@ -1,6 +1,6 @@ SUBDIRS = . tests INCLUDES = \ - -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-glib \ -I$(top_srcdir)/libnm-util diff --git a/system-settings/plugins/ifnet/tests/Makefile.am b/system-settings/plugins/ifnet/tests/Makefile.am index ead3f1fc4..42a91d60c 100644 --- a/system-settings/plugins/ifnet/tests/Makefile.am +++ b/system-settings/plugins/ifnet/tests/Makefile.am @@ -2,7 +2,7 @@ INCLUDES=-I$(top_srcdir)/system-settings/plugins/ifnet\ -I$(top_srcdir)/libnm-glib \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/src/system-settings + -I$(top_srcdir)/src/settings TESTS = check_ifnet check_PROGRAMS = check_ifnet check_ifnet_SOURCES = test_all.c diff --git a/system-settings/plugins/ifupdown/Makefile.am b/system-settings/plugins/ifupdown/Makefile.am index 652e545fc..1bbcc1928 100644 --- a/system-settings/plugins/ifupdown/Makefile.am +++ b/system-settings/plugins/ifupdown/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS=. tests INCLUDES = \ - -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-glib \ -I$(top_srcdir)/libnm-util diff --git a/system-settings/plugins/keyfile/Makefile.am b/system-settings/plugins/keyfile/Makefile.am index 1c1fd4a7d..5052a6306 100644 --- a/system-settings/plugins/keyfile/Makefile.am +++ b/system-settings/plugins/keyfile/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS=. tests INCLUDES = \ - -I$(top_srcdir)/src/system-settings \ + -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_srcdir)/libnm-glib From 3f64bf5e365ffe8a5114a12ae45f6dd770ca6023 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 27 Oct 2010 20:38:26 -0500 Subject: [PATCH 062/264] settings: rename NM_SYSCONFIG_SETTINGS_ERROR -> NM_SETTINGS_ERROR --- src/settings/Makefile.am | 4 +- src/settings/nm-settings-error.c | 75 +++++++++++++++++++ src/settings/nm-settings-error.h | 52 +++++++++++++ src/settings/nm-settings.c | 38 +++++----- src/settings/nm-sysconfig-connection.c | 54 ++++++------- src/settings/nm-system-config-error.c | 75 ------------------- src/settings/nm-system-config-error.h | 52 ------------- system-settings/plugins/ifcfg-rh/plugin.c | 22 +++--- .../plugins/ifupdown/nm-ifupdown-connection.c | 6 +- system-settings/plugins/keyfile/writer.c | 1 - 10 files changed, 189 insertions(+), 190 deletions(-) create mode 100644 src/settings/nm-settings-error.c create mode 100644 src/settings/nm-settings-error.h delete mode 100644 src/settings/nm-system-config-error.c delete mode 100644 src/settings/nm-system-config-error.h diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am index 384175005..0fc8b1fb5 100644 --- a/src/settings/Makefile.am +++ b/src/settings/Makefile.am @@ -18,8 +18,8 @@ libsettings_la_SOURCES = \ nm-inotify-helper.c \ nm-inotify-helper.h \ nm-polkit-helpers.h \ - nm-system-config-error.c \ - nm-system-config-error.h \ + nm-settings-error.c \ + nm-settings-error.h \ nm-system-config-interface.c \ nm-system-config-interface.h \ nm-sysconfig-connection.c \ diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c new file mode 100644 index 000000000..025ae581a --- /dev/null +++ b/src/settings/nm-settings-error.c @@ -0,0 +1,75 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2010 Red Hat, Inc. + */ + +#include "nm-settings-error.h" + +GQuark +nm_settings_error_quark (void) +{ + static GQuark ret = 0; + + if (ret == 0) + ret = g_quark_from_static_string ("nm-settings-error"); + + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_settings_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + ENUM_ENTRY (NM_SETTINGS_ERROR_GENERAL, "GeneralError"), + + /* The connection was invalid. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"), + /* The connection is read-only; modifications are not allowed. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"), + /* A bug in the settings service caused the error. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"), + /* Retrieval or request of secrets failed. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"), + /* The request for secrets was canceled. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"), + /* The request could not be completed because permission was denied. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"), + /* The requested setting does not existing in this connection. */ + ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"), + + ENUM_ENTRY (NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), + ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), + ENUM_ENTRY (NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), + ENUM_ENTRY (NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), + ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), + ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), + ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), + { 0, 0, 0 } + }; + + etype = g_enum_register_static ("NMSettingsError", values); + } + + return etype; +} diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h new file mode 100644 index 000000000..45996a2f2 --- /dev/null +++ b/src/settings/nm-settings-error.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 - 2010 Red Hat, Inc. + */ + +#ifndef NM_SETTINGS_ERROR_H +#define NM_SETTINGS_ERROR_H + +#include +#include + +enum { + NM_SETTINGS_ERROR_GENERAL = 0, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, + NM_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, + NM_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + NM_SETTINGS_ERROR_INVALID_SETTING, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, + NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, + NM_SETTINGS_ERROR_ADD_FAILED, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, +}; + +#define NM_SETTINGS_ERROR (nm_settings_error_quark ()) +#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) + +GQuark nm_settings_error_quark (void); +GType nm_settings_error_get_type (void); + +#endif /* NM_SETTINGS_ERROR_H */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index ba7375eba..37621c063 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -55,7 +55,7 @@ #include "nm-settings.h" #include "nm-sysconfig-connection.h" #include "nm-polkit-helpers.h" -#include "nm-system-config-error.h" +#include "nm-settings-error.h" #include "nm-default-wired-connection.h" #include "nm-logging.h" #include "nm-dbus-manager.h" @@ -794,8 +794,8 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) /* If NMSettings is already gone, do nothing */ if (call->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, "Request was canceled."); dbus_g_method_return_error (call->context, error); g_error_free (error); @@ -818,8 +818,8 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) /* Caller didn't successfully authenticate */ if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); dbus_g_method_return_error (call->context, error); goto out; @@ -828,8 +828,8 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) if (add_new_connection (self, call->connection, &add_error)) dbus_g_method_return (call->context); else { - error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_ADD_FAILED, "Saving connection failed: (%d) %s", add_error ? add_error->code : -1, (add_error && add_error->message) ? add_error->message : "(unknown)"); @@ -864,8 +864,8 @@ impl_settings_add_connection (NMSettings *self, /* Do any of the plugins support adding? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "None of the registered plugins support add."); dbus_g_method_return_error (context, error); g_error_free (error); @@ -900,8 +900,8 @@ pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) /* If our NMSysconfigConnection is already gone, do nothing */ if (call->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, "Request was canceled."); dbus_g_method_return_error (call->context, error); g_error_free (error); @@ -924,8 +924,8 @@ pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) /* Caller didn't successfully authenticate */ if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); dbus_g_method_return_error (call->context, error); goto out; @@ -945,8 +945,8 @@ pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) if (success) { dbus_g_method_return (call->context); } else { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "Saving the hostname failed."); dbus_g_method_return_error (call->context, error); } @@ -969,8 +969,8 @@ impl_settings_save_hostname (NMSettings *self, /* Do any of the plugins support setting the hostname? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "None of the registered plugins support setting the hostname."); dbus_g_method_return_error (context, error); g_error_free (error); @@ -1516,9 +1516,9 @@ nm_settings_class_init (NMSettingsClass *class) g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 0); - dbus_g_error_domain_register (NM_SYSCONFIG_SETTINGS_ERROR, + dbus_g_error_domain_register (NM_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, - NM_TYPE_SYSCONFIG_SETTINGS_ERROR); + NM_TYPE_SETTINGS_ERROR); /* And register all the settings errors with D-Bus */ dbus_g_error_domain_register (NM_CONNECTION_ERROR, NULL, NM_TYPE_CONNECTION_ERROR); diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 759f1f3a6..a1da54e49 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -29,7 +29,7 @@ #include "nm-sysconfig-connection.h" #include "nm-session-monitor.h" #include "nm-dbus-manager.h" -#include "nm-system-config-error.h" +#include "nm-settings-error.h" #include "nm-dbus-glib-types.h" #include "nm-polkit-helpers.h" #include "nm-logging.h" @@ -132,8 +132,8 @@ uid_in_acl (NMConnection *self, /* Reject the request if the request comes from no session at all */ if (nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, "No session found for uid %d (%s)", uid, local && local->message ? local->message : "unknown"); @@ -143,8 +143,8 @@ uid_in_acl (NMConnection *self, if (!user) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, "Could not determine username for uid %d", uid); return FALSE; @@ -170,8 +170,8 @@ uid_in_acl (NMConnection *self, } g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, "uid %d has no permission to perform this operation", uid); return FALSE; @@ -339,8 +339,8 @@ nm_sysconfig_connection_commit_changes (NMSysconfigConnection *connection, callback, user_data); } else { - GError *error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + GError *error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, "%s: %s:%d commit_changes() unimplemented", __func__, __FILE__, __LINE__); callback (connection, error, user_data); g_error_free (error); @@ -361,8 +361,8 @@ nm_sysconfig_connection_delete (NMSysconfigConnection *connection, callback, user_data); } else { - GError *error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + GError *error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, "%s: %s:%d delete() unimplemented", __func__, __FILE__, __LINE__); callback (connection, error, user_data); g_error_free (error); @@ -389,8 +389,8 @@ nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, callback, user_data); } else { - GError *error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + GError *error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); callback (connection, NULL, error, user_data); g_error_free (error); @@ -531,8 +531,8 @@ get_secrets (NMSysconfigConnection *connection, * nm_sysconfig_connection_replace_settings(). */ if (!priv->secrets) { - error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, "%s.%d - Internal error; secrets cache invalid.", __FILE__, __LINE__); (*callback) (connection, NULL, error, user_data); @@ -542,8 +542,8 @@ get_secrets (NMSysconfigConnection *connection, setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); if (!setting) { - error = g_error_new (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_SETTING, + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_SETTING, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); (*callback) (connection, NULL, error, user_data); @@ -605,8 +605,8 @@ auth_pk_cb (GObject *object, GAsyncResult *result, gpointer user_data) GError *error = NULL; if (info->disposed) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, "Request was canceled."); goto out; } @@ -618,8 +618,8 @@ auth_pk_cb (GObject *object, GAsyncResult *result, gpointer user_data) goto out; if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); goto out; } @@ -650,8 +650,8 @@ auth_start (NMSysconfigConnection *self, /* Get the caller's UID */ if (!nm_auth_get_caller_uid (context, NULL, &sender_uid, &error_desc)) { - error = g_error_new_literal (NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); goto error; } @@ -714,8 +714,8 @@ check_writable (NMConnection *connection, GError **error) NM_TYPE_SETTING_CONNECTION); if (!s_con) { g_set_error_literal (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, "Connection did not have required 'connection' setting"); return FALSE; } @@ -726,8 +726,8 @@ check_writable (NMConnection *connection, GError **error) */ if (nm_setting_connection_get_read_only (s_con)) { g_set_error_literal (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_READ_ONLY_CONNECTION, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_READ_ONLY_CONNECTION, "Connection is read-only"); return FALSE; } diff --git a/src/settings/nm-system-config-error.c b/src/settings/nm-system-config-error.c deleted file mode 100644 index a4e52a6b6..000000000 --- a/src/settings/nm-system-config-error.c +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. - */ - -#include "nm-system-config-error.h" - -GQuark -nm_sysconfig_settings_error_quark (void) -{ - static GQuark ret = 0; - - if (ret == 0) - ret = g_quark_from_static_string ("nm_sysconfig_settings_error"); - - return ret; -} - -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } - -GType -nm_sysconfig_settings_error_get_type (void) -{ - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = { - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, "GeneralError"), - - /* The connection was invalid. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, "InvalidConnection"), - /* The connection is read-only; modifications are not allowed. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_READ_ONLY_CONNECTION, "ReadOnlyConnection"), - /* A bug in the settings service caused the error. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, "InternalError"), - /* Retrieval or request of secrets failed. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "SecretsUnavailable"), - /* The request for secrets was canceled. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, "SecretsRequestCanceled"), - /* The request could not be completed because permission was denied. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"), - /* The requested setting does not existing in this connection. */ - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"), - - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), - ENUM_ENTRY (NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), - { 0, 0, 0 } - }; - - etype = g_enum_register_static ("NMSysconfigSettingsError", values); - } - - return etype; -} diff --git a/src/settings/nm-system-config-error.h b/src/settings/nm-system-config-error.h deleted file mode 100644 index 82753fde0..000000000 --- a/src/settings/nm-system-config-error.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. - */ - -#ifndef NM_SYSTEM_CONFIG_ERROR_H -#define NM_SYSTEM_CONFIG_ERROR_H - -#include -#include - -enum { - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL = 0, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, - NM_SYSCONFIG_SETTINGS_ERROR_READ_ONLY_CONNECTION, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_UNAVAILABLE, - NM_SYSCONFIG_SETTINGS_ERROR_SECRETS_REQUEST_CANCELED, - NM_SYSCONFIG_SETTINGS_ERROR_PERMISSION_DENIED, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_SETTING, - NM_SYSCONFIG_SETTINGS_ERROR_NOT_PRIVILEGED, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_ADD_FAILED, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, - NM_SYSCONFIG_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, -}; - -#define NM_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_quark ()) -#define NM_TYPE_SYSCONFIG_SETTINGS_ERROR (nm_sysconfig_settings_error_get_type ()) - -GQuark nm_sysconfig_settings_error_quark (void); -GType nm_sysconfig_settings_error_get_type (void); - -#endif /* NM_SYSTEM_CONFIG_ERROR_H */ diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 5bd57a030..215ba6a9d 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -43,7 +43,7 @@ #include "nm-dbus-glib-types.h" #include "plugin.h" #include "nm-system-config-interface.h" -#include "nm-system-config-error.h" +#include "nm-settings-error.h" #include "nm-ifcfg-connection.h" #include "nm-inotify-helper.h" @@ -544,8 +544,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, if (!g_path_is_absolute (in_ifcfg)) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, "ifcfg path '%s' is not absolute", in_ifcfg); return FALSE; } @@ -553,8 +553,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, connection = g_hash_table_lookup (priv->connections, in_ifcfg); if (!connection || nm_ifcfg_connection_get_unmanaged_spec (connection)) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INVALID_CONNECTION, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, "ifcfg file '%s' unknown", in_ifcfg); return FALSE; } @@ -562,8 +562,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); if (!s_con) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, "unable to retrieve the connection setting"); return FALSE; } @@ -571,8 +571,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, uuid = nm_setting_connection_get_uuid (s_con); if (!uuid) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, "unable to get the UUID"); return FALSE; } @@ -580,8 +580,8 @@ impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, path = nm_connection_get_path (NM_CONNECTION (connection)); if (!path) { g_set_error (error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_INTERNAL_ERROR, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INTERNAL_ERROR, "unable to get the connection D-Bus path"); return FALSE; } diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c index 3c584cc3f..ef0d09450 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include "nm-ifupdown-connection.h" #include "parser.h" @@ -72,8 +72,8 @@ get_secrets (NMSysconfigConnection *connection, /* FIXME: Only wifi secrets are supported for now */ if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)) { g_set_error (&error, - NM_SYSCONFIG_SETTINGS_ERROR, - NM_SYSCONFIG_SETTINGS_ERROR_GENERAL, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, "%s.%d - security setting name not supported '%s'.", __FILE__, __LINE__, setting_name); PLUGIN_PRINT ("SCPlugin-Ifupdown", "%s", error->message); diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index c6c9bbb81..ffac35cff 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -39,7 +39,6 @@ #include #include "nm-dbus-glib-types.h" -#include "nm-system-config-error.h" #include "writer.h" #include "common.h" From d1faa496d089cc260bd6e20ad378114784ef85c9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 28 Oct 2010 09:29:16 -0500 Subject: [PATCH 063/264] ifcfg-rh: remove unused UDI stuff --- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 19 ------------------- .../plugins/ifcfg-rh/nm-ifcfg-connection.h | 1 - 2 files changed, 20 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index e8df1b376..221230525 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -59,7 +59,6 @@ typedef struct { char *route6file; int route6file_wd; - char *udi; char *unmanaged; } NMIfcfgConnectionPrivate; @@ -67,7 +66,6 @@ enum { PROP_0, PROP_FILENAME, PROP_UNMANAGED, - PROP_UDI, LAST_PROP }; @@ -239,8 +237,6 @@ finalize (GObject *object) NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); NMInotifyHelper *ih; - g_free (priv->udi); - nm_connection_clear_secrets (NM_CONNECTION (object)); ih = nm_inotify_helper_get (); @@ -280,10 +276,6 @@ set_property (GObject *object, guint prop_id, case PROP_UNMANAGED: priv->unmanaged = g_value_dup_string (value); break; - case PROP_UDI: - /* Construct only */ - priv->udi = g_value_dup_string (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -303,9 +295,6 @@ get_property (GObject *object, guint prop_id, case PROP_UNMANAGED: g_value_set_string (value, priv->unmanaged); break; - case PROP_UDI: - g_value_set_string (value, priv->udi); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -344,14 +333,6 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) NULL, G_PARAM_READWRITE)); - g_object_class_install_property - (object_class, PROP_UDI, - g_param_spec_string (NM_IFCFG_CONNECTION_UDI, - "UDI", - "UDI", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - signals[IFCFG_CHANGED] = g_signal_new ("ifcfg-changed", G_OBJECT_CLASS_TYPE (object_class), diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 5cac5d9c8..860c428ca 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -35,7 +35,6 @@ G_BEGIN_DECLS #define NM_IFCFG_CONNECTION_FILENAME "filename" #define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged" -#define NM_IFCFG_CONNECTION_UDI "udi" typedef struct { NMSysconfigConnection parent; From 090329d0be6f1785421991db12ec57079baccd7a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 11:02:56 -0500 Subject: [PATCH 064/264] ifnet: fix include name broken by 3f64bf5e365ffe8a5114a12ae45f6dd770ca6023 --- system-settings/plugins/ifnet/nm-ifnet-connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.c b/system-settings/plugins/ifnet/nm-ifnet-connection.c index bfcb7202b..561a7cffc 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.c +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "nm-ifnet-connection.h" #include "connection_parser.h" #include "net_parser.h" From 8a6e2b656058135b1729a8e167326f07455ad084 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 13:56:23 -0500 Subject: [PATCH 065/264] ifnet: constify tons of stuff Use 'const char *' where appropriate. --- .../plugins/ifnet/connection_parser.c | 490 ++++++++++-------- .../plugins/ifnet/connection_parser.h | 29 +- system-settings/plugins/ifnet/net_parser.c | 37 +- system-settings/plugins/ifnet/net_parser.h | 16 +- system-settings/plugins/ifnet/net_utils.c | 159 +++--- system-settings/plugins/ifnet/net_utils.h | 42 +- .../plugins/ifnet/nm-ifnet-connection.c | 8 +- system-settings/plugins/ifnet/plugin.c | 27 +- .../plugins/ifnet/tests/test_all.c | 28 +- system-settings/plugins/ifnet/wpa_parser.c | 31 +- system-settings/plugins/ifnet/wpa_parser.h | 18 +- 11 files changed, 461 insertions(+), 424 deletions(-) diff --git a/system-settings/plugins/ifnet/connection_parser.c b/system-settings/plugins/ifnet/connection_parser.c index f9fae51f3..dc9f681d0 100644 --- a/system-settings/plugins/ifnet/connection_parser.c +++ b/system-settings/plugins/ifnet/connection_parser.c @@ -50,7 +50,7 @@ get_prefix (void) } static void -update_connection_id (NMConnection * connection, gchar * conn_name) +update_connection_id (NMConnection *connection, const char *conn_name) { gchar *idstr = NULL; gchar *uuid_base = NULL; @@ -73,30 +73,37 @@ update_connection_id (NMConnection * connection, gchar * conn_name) g_free (idstr); } -static gboolean -eap_simple_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, gboolean phase2, GError ** error); +static gboolean eap_simple_reader (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); + static gboolean eap_tls_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, - gboolean phase2, GError ** error); + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); static gboolean eap_peap_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, - gboolean phase2, GError ** error); + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); static gboolean eap_ttls_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, - gboolean phase2, GError ** error); + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); typedef struct { const char *method; - gboolean (*reader) (const char *eap_method, gchar * ssid, - NMSetting8021x * s_8021x, - gboolean phase2, GError ** error); + gboolean (*reader) (const char *eap_method, + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error); gboolean wifi_phase2_only; } EAPReader; @@ -116,10 +123,12 @@ static EAPReader eap_readers[] = { /* reading identity and password */ static gboolean eap_simple_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, gboolean phase2, GError ** error) + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) { - char *value; + const char *value; /* identity */ value = wpa_get_value (ssid, "identity"); @@ -147,17 +156,18 @@ eap_simple_reader (const char *eap_method, static gboolean eap_tls_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, gboolean phase2, GError ** error) + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) { - char *value; - char *ca_cert = NULL; - char *client_cert = NULL; - char *privkey = NULL; - char *privkey_password = NULL; + const char *value; + const char *ca_cert = NULL; + const char *client_cert = NULL; + const char *privkey = NULL; + const char *privkey_password = NULL; gboolean success = FALSE; - NMSetting8021xCKFormat privkey_format = - NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; /* identity */ value = wpa_get_value (ssid, "identity"); @@ -275,14 +285,15 @@ eap_tls_reader (const char *eap_method, static gboolean eap_peap_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, gboolean phase2, GError ** error) + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) { - char *ca_cert = NULL; - char *inner_auth = NULL; - char *peapver = NULL; - char *lower; - char **list = NULL, **iter; + const char *ca_cert = NULL; + const char *inner_auth = NULL; + const char *peapver = NULL; + char **list = NULL, **iter, *lower; gboolean success = FALSE; ca_cert = wpa_get_value (ssid, "ca_cert"); @@ -375,15 +386,16 @@ eap_peap_reader (const char *eap_method, static gboolean eap_ttls_reader (const char *eap_method, - gchar * ssid, - NMSetting8021x * s_8021x, gboolean phase2, GError ** error) + const char *ssid, + NMSetting8021x *s_8021x, + gboolean phase2, + GError **error) { gboolean success = FALSE; - char *anon_ident = NULL; - char *ca_cert = NULL; - char *tmp; - char **list = NULL, **iter; - char *inner_auth = NULL; + const char *anon_ident = NULL; + const char *ca_cert = NULL; + const char *tmp; + char **list = NULL, **iter, *inner_auth = NULL; /* ca cert */ ca_cert = wpa_get_value (ssid, "ca_cert"); @@ -464,37 +476,35 @@ eap_ttls_reader (const char *eap_method, /* type is already decided by net_parser, this function is just used to * doing tansformation*/ static const gchar * -guess_connection_type (gchar * conn_name) +guess_connection_type (const char *conn_name) { const gchar *type = ifnet_get_data (conn_name, "type"); - const gchar *name = conn_name; const gchar *ret_type = NULL; - if (name && !strcmp ("ppp", type)) + if (!g_strcmp0 (type, "ppp")) ret_type = NM_SETTING_PPPOE_SETTING_NAME; - if (name && !strcmp ("wireless", type)) + if (!g_strcmp0 (type, "wireless")) ret_type = NM_SETTING_WIRELESS_SETTING_NAME; if (!ret_type) ret_type = NM_SETTING_WIRED_SETTING_NAME; PLUGIN_PRINT (IFNET_PLUGIN_NAME, - "guessed connection type (%s) = %s", name, ret_type); + "guessed connection type (%s) = %s", conn_name, ret_type); return ret_type; } /* Reading mac address for setting connection option. * Unmanaged device mac address is required by NetworkManager*/ static gboolean -read_mac_address (gchar * conn_name, GByteArray ** array, GError ** error) +read_mac_address (const char *conn_name, GByteArray **array, GError **error) { - gchar *value = ifnet_get_data (conn_name, "mac"); + const char *value = ifnet_get_data (conn_name, "mac"); struct ether_addr *mac; - if (!value || !strlen (value)) { + if (!value || !strlen (value)) return TRUE; - } mac = ether_aton (value); if (!mac) { @@ -504,18 +514,18 @@ read_mac_address (gchar * conn_name, GByteArray ** array, GError ** error) } *array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, - ETH_ALEN); + g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); return TRUE; } static void -make_wired_connection_setting (NMConnection * connection, gchar * conn_name, - GError ** error) +make_wired_connection_setting (NMConnection *connection, + const char *conn_name, + GError **error) { GByteArray *mac = NULL; NMSettingWired *s_wired = NULL; - gchar *value = NULL; + const char *value = NULL; s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); @@ -552,12 +562,14 @@ make_wired_connection_setting (NMConnection * connection, gchar * conn_name, /* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/ static void -make_ip4_setting (NMConnection * connection, gchar * conn_name, GError ** error) +make_ip4_setting (NMConnection *connection, + const char *conn_name, + GError **error) { NMSettingIP4Config *ip4_setting = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - gchar *value; + const char *value; gboolean is_static_block = is_static_ip4 (conn_name); ip_block *iblock = NULL; @@ -618,10 +630,9 @@ make_ip4_setting (NMConnection * connection, gchar * conn_name, GError ** error) } g_object_set (ip4_setting, - NM_SETTING_IP4_CONFIG_METHOD, - NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, - !has_default_ip4_route (conn_name), NULL); + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, + NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, !has_default_ip4_route (conn_name), + NULL); } /* add dhcp hostname and client id */ @@ -651,13 +662,14 @@ make_ip4_setting (NMConnection * connection, gchar * conn_name, GError ** error) set_ip4_dns_servers (ip4_setting, conn_name); /* DNS searches */ - value = (gchar *) ifnet_get_data (conn_name, "dns_search"); + value = ifnet_get_data (conn_name, "dns_search"); if (value) { + char *stripped = g_strdup (value); char **searches = NULL; - strip_string (value, '"'); + strip_string (stripped, '"'); - searches = g_strsplit (value, " ", 0); + searches = g_strsplit (stripped, " ", 0); if (searches) { char **item; @@ -678,7 +690,8 @@ make_ip4_setting (NMConnection * connection, gchar * conn_name, GError ** error) iblock = convert_ip4_routes_block (conn_name); while (iblock) { ip_block *current_iblock = iblock; - gchar *metric_str; + const char *metric_str; + char *stripped; long int metric; NMIP4Route *route = nm_ip4_route_new (); @@ -693,10 +706,12 @@ make_ip4_setting (NMConnection * connection, gchar * conn_name, GError ** error) } else { metric_str = ifnet_get_global_data ("metric"); if (metric_str) { + stripped = g_strdup (metric_str); + strip_string (stripped, '"'); metric = strtol (metric_str, NULL, 10); nm_ip4_route_set_metric (route, (guint32) metric); - g_free (metric_str); + g_free (stripped); } } @@ -718,7 +733,9 @@ make_ip4_setting (NMConnection * connection, gchar * conn_name, GError ** error) } static void -make_ip6_setting (NMConnection * connection, gchar * conn_name, GError ** error) +make_ip6_setting (NMConnection *connection, + const char *conn_name, + GError **error) { NMSettingIP6Config *s_ip6 = NULL; gboolean is_static_block = is_static_ip6 (conn_name); @@ -726,7 +743,7 @@ make_ip6_setting (NMConnection * connection, gchar * conn_name, GError ** error) // used to disable IPv6 gboolean ipv6_enabled = FALSE; gchar *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; - gchar *value; + const char *value; ip6_block *iblock; gboolean never_default = !has_default_ip6_route (conn_name); @@ -816,7 +833,8 @@ make_ip6_setting (NMConnection * connection, gchar * conn_name, GError ** error) /* Add all IPv6 routes */ while (iblock) { ip6_block *current_iblock = iblock; - gchar *metric_str; + const char *metric_str; + char *stripped; long int metric = 1; NMIP6Route *route = nm_ip6_route_new (); @@ -831,10 +849,12 @@ make_ip6_setting (NMConnection * connection, gchar * conn_name, GError ** error) } else { metric_str = ifnet_get_global_data ("metric"); if (metric_str) { + stripped = g_strdup (metric_str); + strip_string (stripped, '"'); metric = strtol (metric_str, NULL, 10); nm_ip6_route_set_metric (route, (guint32) metric); - g_free (metric_str); + g_free (stripped); } else nm_ip6_route_set_metric (route, (guint32) 1); } @@ -862,16 +882,17 @@ make_ip6_setting (NMConnection * connection, gchar * conn_name, GError ** error) } static NMSetting * -make_wireless_connection_setting (gchar * conn_name, - NMSetting8021x ** s_8021x, GError ** error) +make_wireless_connection_setting (const char *conn_name, + NMSetting8021x **s_8021x, + GError **error) { GByteArray *array, *mac = NULL; NMSettingWireless *wireless_setting = NULL; gboolean adhoc = FALSE; - gchar *value; - gchar *type; + const char *value; + const char *type; - /* PPP over WIFI is not supported */ + /* PPP over WIFI is not supported yet */ g_return_val_if_fail (conn_name != NULL && strcmp (ifnet_get_data (conn_name, "type"), "ppp") != 0, NULL); @@ -899,8 +920,8 @@ make_wireless_connection_setting (gchar * conn_name, /* handle ssid (hex and ascii) */ if (conn_name) { gsize ssid_len = 0, value_len = strlen (conn_name); - char *p = conn_name, *tmp; - char buf[33]; + const char *p; + char *tmp, *converted = NULL; ssid_len = value_len; if ((value_len > 2) && (g_str_has_prefix (conn_name, "0x"))) { @@ -923,11 +944,11 @@ make_wireless_connection_setting (gchar * conn_name, goto error; } - tmp = utils_hexstr2bin (conn_name + 2, value_len - 2); + tmp = utils_hexstr2bin (p, value_len - 2); ssid_len = (value_len - 2) / 2; - memcpy (buf, tmp, ssid_len); + converted = g_malloc0 (ssid_len + 1); + memcpy (converted, tmp, ssid_len); g_free (tmp); - p = &buf[0]; } if (ssid_len > 32 || ssid_len == 0) { @@ -937,10 +958,10 @@ make_wireless_connection_setting (gchar * conn_name, goto error; } array = g_byte_array_sized_new (ssid_len); - g_byte_array_append (array, (const guint8 *) p, ssid_len); - g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, array, - NULL); + g_byte_array_append (array, (const guint8 *) (converted ? converted : conn_name), ssid_len); + g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, array, NULL); g_byte_array_free (array, TRUE); + g_free (converted); } else { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing SSID"); @@ -1010,10 +1031,10 @@ make_wireless_connection_setting (gchar * conn_name, } static NMSettingWirelessSecurity * -make_leap_setting (gchar * ssid, GError ** error) +make_leap_setting (const char *ssid, GError **error) { NMSettingWirelessSecurity *wsec; - char *value; + const char *value; wsec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); @@ -1052,31 +1073,34 @@ make_leap_setting (gchar * ssid, GError ** error) } static gboolean -add_one_wep_key (gchar * ssid, gchar * key, int key_idx, - NMSettingWirelessSecurity * s_wsec, GError ** error) +add_one_wep_key (const char *ssid, + const char *key, + int key_idx, + NMSettingWirelessSecurity *s_wsec, + GError **error) { - gchar *value; + const char *value; + char *converted = NULL; gboolean success = FALSE; g_return_val_if_fail (ssid != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (key_idx >= 0 && key_idx <= 3, FALSE); g_return_val_if_fail (s_wsec != NULL, FALSE); + value = wpa_get_value (ssid, key); if (!value) return TRUE; - key = NULL; + /* Validate keys */ if (strlen (value) == 10 || strlen (value) == 26) { /* Hexadecimal WEP key */ - char *p = value; - - if (!is_hex (p)) { + if (!is_hex (value)) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Invalid hexadecimal WEP key."); goto out; } - key = g_strdup (value); + converted = g_strdup (value); } else if (value[0] == '"' && (strlen (value) == 7 || strlen (value) == 15)) { /* ASCII passphrase */ @@ -1091,7 +1115,7 @@ add_one_wep_key (gchar * ssid, gchar * key, int key_idx, } - key = utils_bin2hexstr (tmp, strlen (tmp), strlen (tmp) * 2); + converted = utils_bin2hexstr (tmp, strlen (tmp), strlen (tmp) * 2); g_free (tmp); } else { g_set_error (error, ifnet_plugin_error_quark (), 0, @@ -1099,19 +1123,20 @@ add_one_wep_key (gchar * ssid, gchar * key, int key_idx, goto out; } - if (key) { - nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, key); - g_free (key); + if (converted) { + nm_setting_wireless_security_set_wep_key (s_wsec, key_idx, converted); + g_free (converted); success = TRUE; } - out: +out: return success; - } static gboolean -add_wep_keys (gchar * ssid, NMSettingWirelessSecurity * s_wsec, GError ** error) +add_wep_keys (const char *ssid, + NMSettingWirelessSecurity *s_wsec, + GError **error) { if (!add_one_wep_key (ssid, "wep_key0", 0, s_wsec, error)) return FALSE; @@ -1126,11 +1151,10 @@ add_wep_keys (gchar * ssid, NMSettingWirelessSecurity * s_wsec, GError ** error) } static NMSettingWirelessSecurity * -make_wep_setting (gchar * ssid, GError ** error) +make_wep_setting (const char *ssid, GError **error) { - gchar *auth_alg; + const char *auth_alg, *value; int default_key_idx = 0; - gchar *value; NMSettingWirelessSecurity *s_wireless_sec; s_wireless_sec = @@ -1226,9 +1250,10 @@ make_wep_setting (gchar * ssid, GError ** error) } static char * -parse_wpa_psk (gchar * psk, GError ** error) +parse_wpa_psk (const char *psk, GError **error) { - gchar *p, *hashed = NULL; + const char *p = psk; + char *hashed = NULL; gboolean quoted = FALSE; if (!psk) { @@ -1243,12 +1268,11 @@ parse_wpa_psk (gchar * psk, GError ** error) * the passphrase contains spaces. */ - p = psk; - if (p[0] == '"' && psk[strlen (psk) - 1] == '"') + if (psk[0] == '"' && psk[strlen (psk) - 1] == '"') quoted = TRUE; if (!quoted && (strlen (psk) == 64)) { /* Verify the hex PSK; 64 digits */ - if (!is_hex (p)) { + if (!is_hex (psk)) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Invalid WPA_PSK (contains non-hexadecimal characters)"); @@ -1256,17 +1280,21 @@ parse_wpa_psk (gchar * psk, GError ** error) } hashed = g_strdup (psk); } else { - strip_string (p, '"'); + char *stripped = g_strdup (psk); + + strip_string (stripped, '"'); /* Length check */ if (strlen (p) < 8 || strlen (p) > 63) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Invalid WPA_PSK (passphrases must be between " "8 and 63 characters long (inclusive))"); + g_free (stripped); goto out; } - hashed = g_strdup (p); + hashed = g_strdup (stripped); + g_free (stripped); } if (!hashed) { @@ -1275,24 +1303,25 @@ parse_wpa_psk (gchar * psk, GError ** error) goto out; } - out: +out: return hashed; } static gboolean -fill_wpa_ciphers (gchar * ssid, - NMSettingWirelessSecurity * wsec, - gboolean group, gboolean adhoc) +fill_wpa_ciphers (const char *ssid, + NMSettingWirelessSecurity *wsec, + gboolean group, + gboolean adhoc) { - char *value = NULL, *p; + const char *value; char **list = NULL, **iter; int i = 0; - p = value = wpa_get_value (ssid, group ? "group" : "pairwise"); + value = wpa_get_value (ssid, group ? "group" : "pairwise"); if (!value) return TRUE; - list = g_strsplit_set (p, " ", 0); + list = g_strsplit_set (value, " ", 0); for (iter = list; iter && *iter; iter++, i++) { /* Ad-Hoc configurations cannot have pairwise ciphers, and can only * have one group cipher. Ignore any additional group ciphers and @@ -1344,10 +1373,13 @@ fill_wpa_ciphers (gchar * ssid, } static NMSetting8021x * -fill_8021x (gchar * ssid, gchar * key_mgmt, gboolean wifi, GError ** error) +fill_8021x (const char *ssid, + const char *key_mgmt, + gboolean wifi, + GError **error) { NMSetting8021x *s_8021x; - char *value; + const char *value; char **list, **iter; value = wpa_get_value (ssid, "eap"); @@ -1420,10 +1452,13 @@ fill_8021x (gchar * ssid, gchar * key_mgmt, gboolean wifi, GError ** error) } static NMSettingWirelessSecurity * -make_wpa_setting (gchar * ssid, NMSetting8021x ** s_8021x, GError ** error) +make_wpa_setting (const char *ssid, + NMSetting8021x **s_8021x, + GError **error) { NMSettingWirelessSecurity *wsec; - char *value, *lower; + const char *value; + char *lower; gboolean adhoc = FALSE; if (!exist_ssid (ssid)) { @@ -1462,7 +1497,7 @@ make_wpa_setting (gchar * ssid, NMSetting8021x ** s_8021x, GError ** error) } if (!strcmp (value, "WPA-PSK")) { - gchar *psk = parse_wpa_psk (wpa_get_value (ssid, "psk"), error); + char *psk = parse_wpa_psk (wpa_get_value (ssid, "psk"), error); if (!psk) goto error; @@ -1506,14 +1541,14 @@ make_wpa_setting (gchar * ssid, NMSetting8021x ** s_8021x, GError ** error) } static NMSettingWirelessSecurity * -make_wireless_security_setting (gchar * - conn_name, - NMSetting8021x ** s_8021x, GError ** error) +make_wireless_security_setting (const char *conn_name, + NMSetting8021x **s_8021x, + GError ** error) { NMSettingWirelessSecurity *wsec = NULL; - gchar *ssid; + const char *ssid; gboolean adhoc = FALSE; - gchar *value; + const char *value; g_return_val_if_fail (conn_name != NULL && strcmp (ifnet_get_data (conn_name, "type"), @@ -1557,12 +1592,13 @@ make_wireless_security_setting (gchar * /* Currently only support username and password */ static void -make_pppoe_connection_setting (NMConnection * connection, - gchar * conn_name, GError ** error) +make_pppoe_connection_setting (NMConnection *connection, + const char *conn_name, + GError **error) { NMSettingPPPOE *s_pppoe; NMSettingPPP *s_ppp; - gchar *value; + const char *value; s_pppoe = NM_SETTING_PPPOE (nm_setting_pppoe_new ()); @@ -1590,7 +1626,7 @@ make_pppoe_connection_setting (NMConnection * connection, } NMConnection * -ifnet_update_connection_from_config_block (gchar * conn_name, GError ** error) +ifnet_update_connection_from_config_block (const char *conn_name, GError **error) { const gchar *type = NULL; NMConnection *connection = NULL; @@ -1598,7 +1634,7 @@ ifnet_update_connection_from_config_block (gchar * conn_name, GError ** error) NMSetting8021x *s_8021x = NULL; NMSettingWirelessSecurity *wsec = NULL; gboolean auto_conn = TRUE; - gchar *value = NULL; + const char *value = NULL; gboolean success = FALSE; connection = nm_connection_new (); @@ -1642,14 +1678,11 @@ ifnet_update_connection_from_config_block (gchar * conn_name, GError ** error) } } else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { /* wireless setting */ - NMSetting *wireless_setting = - make_wireless_connection_setting (conn_name, - &s_8021x, - error); + NMSetting *wireless_setting; - if (!wireless_setting) { + wireless_setting = make_wireless_connection_setting (conn_name, &s_8021x, error); + if (!wireless_setting) goto error; - } nm_connection_add_setting (connection, wireless_setting); if (error && *error) { @@ -1659,8 +1692,7 @@ ifnet_update_connection_from_config_block (gchar * conn_name, GError ** error) } /* wireless security setting */ - wsec = - make_wireless_security_setting (conn_name, &s_8021x, error); + wsec = make_wireless_security_setting (conn_name, &s_8021x, error); if (wsec) { nm_connection_add_setting (connection, NM_SETTING (wsec)); @@ -1698,12 +1730,12 @@ ifnet_update_connection_from_config_block (gchar * conn_name, GError ** error) if (error && *error) PLUGIN_WARN (IFNET_PLUGIN_NAME, "Found error: %s", (*error)->message); - PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection verified %s:%d", conn_name, - success); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Connection verified %s:%d", conn_name, success); if (!success) goto error; return connection; - error: + +error: g_object_unref (setting); g_object_unref (connection); return NULL; @@ -1795,10 +1827,11 @@ static const ObjectType phase2_p12_type = { }; static gboolean -write_object (NMSetting8021x * s_8021x, - gchar * conn_name, - const GByteArray * override_data, - const ObjectType * objtype, GError ** error) +write_object (NMSetting8021x *s_8021x, + const char *conn_name, + const GByteArray *override_data, + const ObjectType *objtype, + GError **error) { NMSetting8021xCKScheme scheme; const char *path = NULL; @@ -1844,8 +1877,10 @@ write_object (NMSetting8021x * s_8021x, } static gboolean -write_8021x_certs (NMSetting8021x * s_8021x, - gboolean phase2, gchar * conn_name, GError ** error) +write_8021x_certs (NMSetting8021x *s_8021x, + gboolean phase2, + const char *conn_name, + GError **error) { char *password = NULL; const ObjectType *otype = NULL; @@ -1948,8 +1983,10 @@ write_8021x_certs (NMSetting8021x * s_8021x, } static gboolean -write_8021x_setting (NMConnection * connection, - gchar * conn_name, gboolean wired, GError ** error) +write_8021x_setting (NMConnection *connection, + const char *conn_name, + gboolean wired, + GError **error) { NMSetting8021x *s_8021x; const char *value; @@ -2192,20 +2229,24 @@ write_wireless_security_setting (NMConnection * connection, /* remove old ssid and add new one*/ static void -update_wireless_ssid (NMConnection * connection, gchar * conn_name, - gchar * ssid, gboolean hex) +update_wireless_ssid (NMConnection *connection, + const char *conn_name, + const char *ssid, + gboolean hex) { ifnet_delete_network (conn_name); - ifnet_add_connection (ssid, "wireless"); - wpa_delete_security (conn_name); + + ifnet_add_connection (ssid, "wireless"); wpa_add_security (ssid); } static gboolean -write_wireless_setting (NMConnection * connection, - gchar ** conn_name_ptr, gboolean * no_8021x, - GError ** error) +write_wireless_setting (NMConnection *connection, + const char *conn_name, + gboolean *no_8021x, + const char **out_new_name, + GError **error) { NMSettingWireless *s_wireless; const GByteArray *ssid, *mac, *bssid; @@ -2214,11 +2255,8 @@ write_wireless_setting (NMConnection * connection, guint32 mtu, i; gboolean adhoc = FALSE, hex_ssid = FALSE; gchar *ssid_str, *tmp; - gchar *conn_name = *conn_name_ptr; - s_wireless = - (NMSettingWireless *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_WIRELESS); + s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); if (!s_wireless) { g_set_error (error, ifnet_plugin_error_quark (), 0, "Missing '%s' setting", @@ -2258,10 +2296,8 @@ write_wireless_setting (NMConnection * connection, g_string_append (str, "0x"); for (i = 0; i < ssid->len; i++) g_string_append_printf (str, "%02X", ssid->data[i]); - update_wireless_ssid (connection, conn_name, str->str, - hex_ssid); - ssid_str = g_strdup (str->str); - g_string_free (str, TRUE); + update_wireless_ssid (connection, conn_name, str->str, hex_ssid); + ssid_str = g_string_free (str, FALSE); } else { /* Printable SSIDs get quoted */ memset (buf, 0, sizeof (buf)); @@ -2321,14 +2357,17 @@ write_wireless_setting (NMConnection * connection, return FALSE; } else wpa_delete_security (ssid_str); - *conn_name_ptr = ifnet_get_data (ssid_str, "name"); + + if (out_new_name) + *out_new_name = ifnet_get_data (ssid_str, "name"); g_free (ssid_str); return TRUE; } static gboolean -write_wired_setting (NMConnection * connection, gchar * conn_name, - GError ** error) +write_wired_setting (NMConnection *connection, + const char *conn_name, + GError **error) { NMSettingWired *s_wired; const GByteArray *mac; @@ -2370,7 +2409,7 @@ write_wired_setting (NMConnection * connection, gchar * conn_name, } static void -write_connection_setting (NMSettingConnection * s_con, gchar * conn_name) +write_connection_setting (NMSettingConnection *s_con, const char *conn_name) { ifnet_set_data (conn_name, "auto", nm_setting_connection_get_autoconnect (s_con) ? "true" : @@ -2378,8 +2417,7 @@ write_connection_setting (NMSettingConnection * s_con, gchar * conn_name) } static gboolean -write_ip4_setting (NMConnection * connection, gchar * conn_name, - GError ** error) +write_ip4_setting (NMConnection *connection, const char *conn_name, GError **error) { NMSettingIP4Config *s_ip4; const char *value; @@ -2537,8 +2575,7 @@ write_ip4_setting (NMConnection * connection, gchar * conn_name, } static gboolean -write_route6_file (NMSettingIP6Config * s_ip6, gchar * conn_name, - GError ** error) +write_route6_file (NMSettingIP6Config *s_ip6, const char *conn_name, GError **error) { char dest[INET6_ADDRSTRLEN + 1]; char next_hop[INET6_ADDRSTRLEN + 1]; @@ -2547,7 +2584,7 @@ write_route6_file (NMSettingIP6Config * s_ip6, gchar * conn_name, guint32 prefix; guint32 i, num; GString *routes_string; - gchar *old_routes; + const char *old_routes; g_return_val_if_fail (s_ip6 != NULL, FALSE); num = nm_setting_ip6_config_get_num_routes (s_ip6); @@ -2585,8 +2622,7 @@ write_route6_file (NMSettingIP6Config * s_ip6, gchar * conn_name, } static gboolean -write_ip6_setting (NMConnection * connection, gchar * conn_name, - GError ** error) +write_ip6_setting (NMConnection *connection, const char *conn_name, GError **error) { NMSettingIP6Config *s_ip6; const char *value; @@ -2616,7 +2652,7 @@ write_ip6_setting (NMConnection * connection, gchar * conn_name, /* nothing to do now */ } else { // if (!strcmp(value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) { - gchar *config = ifnet_get_data (conn_name, "config"); + const char *config = ifnet_get_data (conn_name, "config"); gchar *tmp; if (!config) @@ -2635,7 +2671,7 @@ write_ip6_setting (NMConnection * connection, gchar * conn_name, ifnet_set_data (conn_name, "enable_ipv6", "true"); if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) { - gchar *config = ifnet_get_data (conn_name, "config"); + const char *config = ifnet_get_data (conn_name, "config"); gchar *tmp; GString *ip_str; @@ -2667,7 +2703,7 @@ write_ip6_setting (NMConnection * connection, gchar * conn_name, /* DNS Servers */ num = nm_setting_ip6_config_get_num_dns (s_ip6); if (num > 0) { - gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers"); + const char *dns_servers = ifnet_get_data (conn_name, "dns_servers"); gchar *tmp; GString *dns_string = g_string_new (NULL); @@ -2691,7 +2727,7 @@ write_ip6_setting (NMConnection * connection, gchar * conn_name, /* DNS Searches */ num = nm_setting_ip6_config_get_num_dns_searches (s_ip6); if (num > 0) { - char *ip4_domains; + const char *ip4_domains; ip4_domains = ifnet_get_data (conn_name, "dns_search"); if (!ip4_domains) @@ -2719,7 +2755,7 @@ write_ip6_setting (NMConnection * connection, gchar * conn_name, } static gboolean -write_pppoe_setting (gchar * conn_name, NMSettingPPPOE * s_pppoe) +write_pppoe_setting (const char *conn_name, NMSettingPPPOE * s_pppoe) { const gchar *value; @@ -2738,11 +2774,12 @@ write_pppoe_setting (gchar * conn_name, NMSettingPPPOE * s_pppoe) } gboolean -ifnet_update_parsers_by_connection (NMConnection * connection, - gchar * conn_name, - gchar ** nm_conn_name, - gchar * config_file, - gchar * wpa_file, GError ** error) +ifnet_update_parsers_by_connection (NMConnection *connection, + const char *conn_name, + const char *config_file, + const char *wpa_file, + const char **out_new_name, + GError **error) { NMSettingConnection *s_con; NMSettingIP6Config *s_ip6; @@ -2750,6 +2787,7 @@ ifnet_update_parsers_by_connection (NMConnection * connection, const char *type; gboolean no_8021x = FALSE; gboolean wired = FALSE, pppoe = TRUE; + const char *new_name = NULL; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting @@ -2776,16 +2814,14 @@ ifnet_update_parsers_by_connection (NMConnection * connection, no_8021x = TRUE; } else if (!strcmp (type, NM_SETTING_WIRELESS_SETTING_NAME)) { /* Writing wireless setting */ - if (!write_wireless_setting - (connection, &conn_name, &no_8021x, error)) + if (!write_wireless_setting (connection, conn_name, &no_8021x, &new_name, error)) goto out; } else if (!strcmp (type, NM_SETTING_PPPOE_SETTING_NAME)) { + NMSettingPPPOE *s_pppoe; + /* Writing pppoe setting */ - if (! - (write_pppoe_setting - (conn_name, - NM_SETTING_PPPOE (nm_connection_get_setting - (connection, NM_TYPE_SETTING_PPPOE))))) + s_pppoe = NM_SETTING_PPPOE (nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE)); + if (!write_pppoe_setting (conn_name, s_pppoe)) goto out; pppoe = TRUE; wired = TRUE; @@ -2796,6 +2832,12 @@ ifnet_update_parsers_by_connection (NMConnection * connection, goto out; } + /* connection name may have been updated; use it when writing out + * the rest of the settings. + */ + if (new_name) + conn_name = new_name; + //FIXME wired connection doesn't support 8021x now if (!no_8021x) { if (!write_8021x_setting (connection, conn_name, wired, error)) @@ -2806,9 +2848,7 @@ ifnet_update_parsers_by_connection (NMConnection * connection, if (!write_ip4_setting (connection, conn_name, error)) goto out; - s_ip6 = - (NMSettingIP6Config *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_IP6_CONFIG); + s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); if (s_ip6) { /* IPv6 Setting */ if (!write_ip6_setting (connection, conn_name, error)) @@ -2821,19 +2861,21 @@ ifnet_update_parsers_by_connection (NMConnection * connection, /* connection id will be displayed in nm-applet */ update_connection_id (connection, conn_name); - if (nm_conn_name) - *nm_conn_name = g_strdup (conn_name); success = ifnet_flush_to_file (config_file); if (success) wpa_flush_to_file (wpa_file); - out: + if (out_new_name) + *out_new_name = new_name; + +out: return success; } gboolean -ifnet_delete_connection_in_parsers (gchar * conn_name, - gchar * config_file, gchar * wpa_file) +ifnet_delete_connection_in_parsers (const char *conn_name, + const char *config_file, + const char *wpa_file) { gboolean result = FALSE; @@ -2933,30 +2975,20 @@ get_wireless_name (NMConnection * connection) gboolean ifnet_add_new_connection (NMConnection * connection, - gchar * config_file, gchar * wpa_file, - GError ** error) + const char *config_file, + const char *wpa_file, + GError **error) { NMSettingConnection *s_con; gboolean success = FALSE; const char *type; gchar *new_type, *new_name = NULL; - s_con = - NM_SETTING_CONNECTION (nm_connection_get_setting - (connection, NM_TYPE_SETTING_CONNECTION)); - if (!s_con) { - g_set_error (error, ifnet_plugin_error_quark (), 0, - "Missing '%s' setting", - NM_SETTING_CONNECTION_SETTING_NAME); - return FALSE; - } - + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); type = nm_setting_connection_get_connection_type (s_con); - if (!type) { - g_set_error (error, ifnet_plugin_error_quark (), 0, - "Missing connection type!"); - goto out; - } + g_assert (type); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding %s connection", type); /* get name and type @@ -2982,15 +3014,19 @@ ifnet_add_new_connection (NMConnection * connection, goto out; } - if (ifnet_add_connection (new_name, new_type)) - success = - ifnet_update_parsers_by_connection (connection, new_name, - NULL, config_file, - wpa_file, error); + if (ifnet_add_connection (new_name, new_type)) { + success = ifnet_update_parsers_by_connection (connection, + new_name, + config_file, + wpa_file, + NULL, + error); + } + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Added new connection: %s, result: %s", new_name, success ? "success" : "fail"); - out: +out: if (new_name) g_free (new_name); return success; diff --git a/system-settings/plugins/ifnet/connection_parser.h b/system-settings/plugins/ifnet/connection_parser.h index b006954cc..24c1f7e90 100644 --- a/system-settings/plugins/ifnet/connection_parser.h +++ b/system-settings/plugins/ifnet/connection_parser.h @@ -24,20 +24,23 @@ #include #include "net_parser.h" -NMConnection *ifnet_update_connection_from_config_block (gchar * conn_name, - GError ** error); +NMConnection *ifnet_update_connection_from_config_block (const char *conn_name, + GError **error); /* nm_conn_name is used to update nm_ifnet_connection's priv data */ -gboolean ifnet_update_parsers_by_connection (NMConnection * connection, - gchar * conn_name, - gchar ** nm_conn_name, - gchar * config_file, - gchar * wpa_file, GError ** error); +gboolean ifnet_update_parsers_by_connection (NMConnection *connection, + const char *conn_name, + const char *config_file, + const char *wpa_file, + const char **out_new_name, + GError **error); -gboolean ifnet_delete_connection_in_parsers (gchar * conn_name, - gchar * config_file, - gchar * wpa_file); -gboolean ifnet_add_new_connection (NMConnection * connection, - gchar * config_file, gchar * wpa_file, - GError ** error); +gboolean ifnet_delete_connection_in_parsers (const char *conn_name, + const char *config_file, + const char *wpa_file); + +gboolean ifnet_add_new_connection (NMConnection *connection, + const char *config_file, + const char *wpa_file, + GError ** error); #endif diff --git a/system-settings/plugins/ifnet/net_parser.c b/system-settings/plugins/ifnet/net_parser.c index b4a381dee..79084ff88 100644 --- a/system-settings/plugins/ifnet/net_parser.c +++ b/system-settings/plugins/ifnet/net_parser.c @@ -58,24 +58,24 @@ add_new_connection_config (const gchar * type, const gchar * name) } gboolean -ifnet_add_connection (gchar * name, gchar * type) +ifnet_add_connection (const char *name, const char *type) { if (add_new_connection_config (type, name)) { PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Adding network for %s", name); net_parser_data_changed = TRUE; return TRUE; - } else - return FALSE; + } + return FALSE; } gboolean -ifnet_has_connection (gchar * conn_name) +ifnet_has_connection (const char *conn_name) { return g_hash_table_lookup (conn_table, conn_name) != NULL; } static GHashTable * -get_connection_config (gchar * name) +get_connection_config (const char *name) { return g_hash_table_lookup (conn_table, name); } @@ -87,7 +87,7 @@ static gchar *ignore_name[] = { }; static gboolean -ignore_connection_name (gchar * name) +ignore_connection_name (const char *name) { gboolean result = FALSE; guint i = 0; @@ -194,8 +194,8 @@ destroy_connection_config (GHashTable * conn) } // read settings from /etc/NetworkManager/nm-system-settings.conf -gchar * -ifnet_get_global_setting (gchar * group, gchar * key) +const char * +ifnet_get_global_setting (const char *group, const char *key) { GError *error = NULL; GKeyFile *keyfile = g_key_file_new (); @@ -362,8 +362,8 @@ ifnet_init (gchar * config_file) return TRUE; } -gchar * -ifnet_get_data (gchar * conn_name, const gchar * key) +const char * +ifnet_get_data (const char *conn_name, const char *key) { GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); @@ -373,7 +373,7 @@ ifnet_get_data (gchar * conn_name, const gchar * key) } void -ifnet_set_data (gchar * conn_name, gchar * key, gchar * value) +ifnet_set_data (const char *conn_name, const char *key, const char *value) { gpointer orin_key = NULL, orin_value = NULL; GHashTable *conn = g_hash_table_lookup (conn_table, conn_name); @@ -396,17 +396,10 @@ ifnet_set_data (gchar * conn_name, gchar * key, gchar * value) } // Remember to free return value -gchar * +const char * ifnet_get_global_data (const gchar * key) { - gchar *result = g_hash_table_lookup (global_settings_table, key); - - if (result) - result = g_strdup (result); - else - return NULL; - strip_string (result, '"'); - return result; + return g_hash_table_lookup (global_settings_table, key); } // Return names of legal connections @@ -455,7 +448,7 @@ format_ips (gchar * value, gchar ** out_line, gchar * key, gchar * name) } gboolean -ifnet_flush_to_file (gchar * config_file) +ifnet_flush_to_file (const char *config_file) { GIOChannel *channel; GError **error = NULL; @@ -584,7 +577,7 @@ ifnet_flush_to_file (gchar * config_file) } gboolean -ifnet_delete_network (gchar * conn_name) +ifnet_delete_network (const char *conn_name) { GHashTable *network = NULL; diff --git a/system-settings/plugins/ifnet/net_parser.h b/system-settings/plugins/ifnet/net_parser.h index 73a44c857..5b9fadaec 100644 --- a/system-settings/plugins/ifnet/net_parser.h +++ b/system-settings/plugins/ifnet/net_parser.h @@ -33,14 +33,14 @@ void ifnet_destroy (void); /* Reader functions */ GList *ifnet_get_connection_names (void); -gchar *ifnet_get_data (gchar * conn_name, const gchar * key); -gchar *ifnet_get_global_data (const gchar * key); -gchar *ifnet_get_global_setting (gchar * group, gchar * key); -gboolean ifnet_has_connection (gchar * conn_name); +const char *ifnet_get_data (const char *conn_name, const char *key); +const char *ifnet_get_global_data (const char *key); +const char *ifnet_get_global_setting (const char *group, const char *key); +gboolean ifnet_has_connection (const char *conn_name); /* Writer functions */ -gboolean ifnet_flush_to_file (gchar * config_file); -void ifnet_set_data (gchar * conn_name, gchar * key, gchar * value); -gboolean ifnet_add_connection (gchar * name, gchar * type); -gboolean ifnet_delete_network (gchar * conn_name); +gboolean ifnet_flush_to_file (const char *config_file); +void ifnet_set_data (const char *conn_name, const char *key, const char *value); +gboolean ifnet_add_connection (const char *name, const char *type); +gboolean ifnet_delete_network (const char *conn_name); #endif diff --git a/system-settings/plugins/ifnet/net_utils.c b/system-settings/plugins/ifnet/net_utils.c index 8a541979d..eecb5d74d 100644 --- a/system-settings/plugins/ifnet/net_utils.c +++ b/system-settings/plugins/ifnet/net_utils.c @@ -60,40 +60,34 @@ strip_string (gchar * str, gchar t) } gboolean -is_hex (gchar * value) +is_hex (const char *value) { - gchar *p; + const char *p = value; - if (!value) + if (!p) return FALSE; - p = value; while (*p) { - if (!isxdigit (*p)) { + if (!isxdigit (*p++)) return FALSE; - } - p++; } return TRUE; } gboolean -is_ascii (gchar * value) +is_ascii (const char *value) { - gchar *p; + const char *p = value; - p = value; while (*p) { - if (!isascii (*p)) { + if (!isascii (*p++)) return FALSE; - } - p++; } return TRUE; } gboolean -is_true (char *str) +is_true (const char *str) { if (!g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "true")) @@ -195,7 +189,7 @@ ifnet_plugin_error_quark (void) } gboolean -reload_parsers () +reload_parsers (void) { ifnet_destroy (); wpa_parser_destroy (); @@ -206,7 +200,7 @@ reload_parsers () } gchar * -read_hostname (gchar * path) +read_hostname (const char *path) { gchar *contents = NULL, *result = NULL, *tmp; gchar **all_lines = NULL; @@ -235,21 +229,23 @@ read_hostname (gchar * path) } gboolean -write_hostname (const gchar * hostname, gchar * path) +write_hostname (const gchar *hostname, const char *path) { - gchar *contents = g_strdup_printf ("#Generated by NetworkManager\n" - "hostname=\"%s\"\n", hostname); - gboolean result = g_file_set_contents (path, contents, -1, NULL); + gboolean result; + char *contents; + contents = g_strdup_printf ("#Generated by NetworkManager\n" + "hostname=\"%s\"\n", hostname); + result = g_file_set_contents (path, contents, -1, NULL); g_free (contents); return result; } gboolean -is_static_ip4 (gchar * conn_name) +is_static_ip4 (const char *conn_name) { - gchar *data = ifnet_get_data (conn_name, "config"); - gchar *dhcp6; + const char *data = ifnet_get_data (conn_name, "config"); + const char *dhcp6; if (!data) return FALSE; @@ -270,9 +266,9 @@ is_static_ip4 (gchar * conn_name) } gboolean -is_static_ip6 (gchar * conn_name) +is_static_ip6 (const char *conn_name) { - gchar *data = ifnet_get_data (conn_name, "config"); + const char *data = ifnet_get_data (conn_name, "config"); if (!data) return TRUE; @@ -280,9 +276,9 @@ is_static_ip6 (gchar * conn_name) } gboolean -is_ip4_address (gchar * in_address) +is_ip4_address (const char *in_address) { - gchar *pattern = + const char *pattern = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$"; gchar *address = g_strdup (in_address); gboolean result = FALSE; @@ -308,17 +304,15 @@ is_ip4_address (gchar * in_address) } gboolean -is_ip6_address (gchar * in_address) +is_ip6_address (const char *in_address) { struct in6_addr tmp_ip6_addr; - gchar *tmp; - gchar *address = g_strdup (in_address); + gchar *tmp, *address; gboolean result = FALSE; - if (!address) { - g_free (address); + if (!in_address) return FALSE; - } + address = g_strdup (in_address); g_strstrip (address); if ((tmp = strchr (address, '/')) != NULL) *tmp = '\0'; @@ -330,7 +324,7 @@ is_ip6_address (gchar * in_address) } gboolean -has_ip6_address (gchar * conn_name) +has_ip6_address (const char *conn_name) { gchar **ipset; guint length; @@ -353,30 +347,29 @@ has_ip6_address (gchar * conn_name) } gboolean -has_default_route (gchar * conn_name, gboolean (*check_fn) (gchar *)) +has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)) { - gchar *routes = NULL, *tmp, *end; + char *routes = NULL, *end, *tmp; + gboolean success = FALSE; g_return_val_if_fail (conn_name != NULL, FALSE); - tmp = ifnet_get_data (conn_name, "routes"); - if (!tmp) + + routes = g_strdup (ifnet_get_data (conn_name, "routes")); + if (!routes) return FALSE; - routes = g_strdup (tmp); + tmp = strstr (routes, "default via "); - if (!tmp) { - goto error; + if (tmp) { + tmp += strlen ("default via "); + g_strstrip (tmp); + if ((end = strstr (tmp, "\"")) != NULL) + *end = '\0'; + if (check_fn (tmp)) + success = TRUE; } - tmp += strlen ("default via "); - g_strstrip (tmp); - if ((end = strstr (tmp, "\"")) != NULL) - *end = '\0'; - if (check_fn (tmp)) { - g_free (routes); - return TRUE; - } - error: + g_free (routes); - return FALSE; + return success; } static ip_block * @@ -529,28 +522,28 @@ get_ip6_next_hop (gchar * next_hop) } ip_block * -convert_ip4_config_block (gchar * conn_name) +convert_ip4_config_block (const char *conn_name) { gchar **ipset; guint length; guint i; gchar *ip; - guint32 def_gateway; - gchar *routes; + guint32 def_gateway = 0; + const char *routes; gchar *pos; ip_block *start = NULL, *current = NULL, *iblock = NULL; - gchar *pattern = + const char *pattern = "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))"; - GRegex *regex = g_regex_new (pattern, 0, 0, NULL); g_return_val_if_fail (conn_name != NULL, NULL); + ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); length = g_strv_length (ipset); + routes = ifnet_get_data (conn_name, "routes"); if (routes) def_gateway = get_ip4_gateway (strstr (routes, "default")); - else - def_gateway = 0; + for (i = 0; i < length; i++) { ip = ipset[i]; ip = strip_string (ip, '"'); @@ -559,9 +552,13 @@ convert_ip4_config_block (gchar * conn_name) gchar *ip_start, *ip_prefix; gchar *begin_str, *end_str; int begin, end, j; + GRegex *regex; GMatchInfo *match_info; + regex = g_regex_new (pattern, 0, 0, NULL); g_regex_match (regex, ip, 0, &match_info); + g_regex_unref (regex); + if (!g_match_info_matches (match_info)) { g_match_info_free (match_info); continue; @@ -620,12 +617,11 @@ convert_ip4_config_block (gchar * conn_name) } } g_strfreev (ipset); - g_regex_unref (regex); return start; } ip6_block * -convert_ip6_config_block (gchar * conn_name) +convert_ip6_config_block (const char *conn_name) { gchar **ipset; guint length; @@ -654,16 +650,17 @@ convert_ip6_config_block (gchar * conn_name) } ip_block * -convert_ip4_routes_block (gchar * conn_name) +convert_ip4_routes_block (const char *conn_name) { gchar **ipset; guint length; guint i; gchar *ip; - gchar *routes; + const char *routes; ip_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); + routes = ifnet_get_data (conn_name, "routes"); if (!routes) return NULL; @@ -691,13 +688,13 @@ convert_ip4_routes_block (gchar * conn_name) } ip6_block * -convert_ip6_routes_block (gchar * conn_name) +convert_ip6_routes_block (const char *conn_name) { gchar **ipset; guint length; guint i; gchar *ip, *tmp_addr; - gchar *routes; + const char *routes; ip6_block *start = NULL, *current = NULL, *iblock = NULL; struct in6_addr *tmp_ip6_addr; @@ -766,18 +763,22 @@ destroy_ip6_block (ip6_block * iblock) } void -set_ip4_dns_servers (NMSettingIP4Config * s_ip4, gchar * conn_name) +set_ip4_dns_servers (NMSettingIP4Config *s_ip4, const char *conn_name) { - gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers"); - gchar **server_list; + const char *dns_servers; + gchar **server_list, *stripped; guint length, i; struct in_addr tmp_ip4_addr; guint32 new_dns; + dns_servers = ifnet_get_data (conn_name, "dns_servers"); if (!dns_servers) return; - strip_string (dns_servers, '"'); - server_list = g_strsplit (dns_servers, " ", 0); + stripped = g_strdup (dns_servers); + strip_string (stripped, '"'); + server_list = g_strsplit (stripped, " ", 0); + g_free (stripped); + length = g_strv_length (server_list); if (length) g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, @@ -803,17 +804,22 @@ set_ip4_dns_servers (NMSettingIP4Config * s_ip4, gchar * conn_name) } void -set_ip6_dns_servers (NMSettingIP6Config * s_ip6, gchar * conn_name) +set_ip6_dns_servers (NMSettingIP6Config *s_ip6, const char *conn_name) { - gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers"); - gchar **server_list; + const char *dns_servers; + gchar **server_list, *stripped; guint length, i; struct in6_addr tmp_ip6_addr; + dns_servers = ifnet_get_data (conn_name, "dns_servers"); if (!dns_servers) return; - strip_string (dns_servers, '"'); - server_list = g_strsplit (dns_servers, " ", 0); + + stripped = g_strdup (dns_servers); + strip_string (stripped, '"'); + server_list = g_strsplit (stripped, " ", 0); + g_free (stripped); + length = g_strv_length (server_list); if (length) g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, @@ -839,7 +845,7 @@ set_ip6_dns_servers (NMSettingIP6Config * s_ip6, gchar * conn_name) } gboolean -is_managed (gchar * conn_name) +is_managed (const char *conn_name) { gchar *config; @@ -855,13 +861,14 @@ is_managed (gchar * conn_name) void get_dhcp_hostname_and_client_id (char **hostname, char **client_id) { - gchar *dhcp_client = ifnet_get_global_setting ("main", "dhcp"); + const char *dhcp_client; const gchar *dhcpcd_conf = "/etc/dhcpcd.conf"; const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf"; gchar *line = NULL, *tmp = NULL, *contents = NULL; gchar **all_lines; guint line_num, i; + dhcp_client = ifnet_get_global_setting ("main", "dhcp"); *hostname = NULL; *client_id = NULL; if (dhcp_client) { diff --git a/system-settings/plugins/ifnet/net_utils.h b/system-settings/plugins/ifnet/net_utils.h index ba7af39c2..42f8d6725 100644 --- a/system-settings/plugins/ifnet/net_utils.h +++ b/system-settings/plugins/ifnet/net_utils.h @@ -27,8 +27,8 @@ #include #include #include "net_parser.h" -#define has_default_ip4_route(conn_name) has_default_route((conn_name),&is_ip4_address) -#define has_default_ip6_route(conn_name) has_default_route((conn_name),&is_ip6_address) +#define has_default_ip4_route(conn_name) has_default_route((conn_name), &is_ip4_address) +#define has_default_ip6_route(conn_name) has_default_route((conn_name), &is_ip6_address) typedef struct _ip_block { guint32 ip; @@ -44,36 +44,36 @@ typedef struct _ip6_block { struct _ip6_block *next; } ip6_block; -gchar *read_hostname (gchar * path); -gboolean write_hostname (const gchar * hostname, gchar * path); -gboolean is_static_ip4 (gchar * conn_name); -gboolean is_static_ip6 (gchar * conn_name); -gboolean is_ip4_address (gchar * in_address); -gboolean is_ip6_address (gchar * in_address); -gboolean has_ip6_address (gchar * conn_name); -gboolean has_default_route (gchar * conn_name, gboolean (*check_fn) (gchar *)); +gchar *read_hostname (const char *path); +gboolean write_hostname (const char *hostname, const char *path); +gboolean is_static_ip4 (const char *conn_name); +gboolean is_static_ip6 (const char *conn_name); +gboolean is_ip4_address (const char *in_address); +gboolean is_ip6_address (const char *in_address); +gboolean has_ip6_address (const char *conn_name); +gboolean has_default_route (const char *conn_name, gboolean (*check_fn) (const char *)); gboolean reload_parsers (void); -ip_block *convert_ip4_config_block (gchar * conn_name); -ip6_block *convert_ip6_config_block (gchar * conn_name); -ip_block *convert_ip4_routes_block (gchar * conn_name); -ip6_block *convert_ip6_routes_block (gchar * conn_name); +ip_block *convert_ip4_config_block (const char *conn_name); +ip6_block *convert_ip6_config_block (const char *conn_name); +ip_block *convert_ip4_routes_block (const char *conn_name); +ip6_block *convert_ip6_routes_block (const char *conn_name); void destroy_ip_block (ip_block * iblock); void destroy_ip6_block (ip6_block * iblock); -void set_ip4_dns_servers (NMSettingIP4Config * s_ip4, gchar * conn_name); -void set_ip6_dns_servers (NMSettingIP6Config * s_ip6, gchar * conn_name); +void set_ip4_dns_servers (NMSettingIP4Config * s_ip4, const char *conn_name); +void set_ip6_dns_servers (NMSettingIP6Config * s_ip6, const char *conn_name); -gchar *strip_string (gchar * str, gchar t); -gboolean is_managed (gchar * conn_name); +gchar *strip_string (gchar *str, gchar t); +gboolean is_managed (const char *conn_name); GQuark ifnet_plugin_error_quark (void); gchar *utils_hexstr2bin (const gchar * hex, size_t len); gchar *utils_bin2hexstr (const gchar * bytes, int len, int final_len); -gboolean is_hex (gchar * value); -gboolean is_ascii (gchar * value); -gboolean is_true (gchar * str); +gboolean is_hex (const char *value); +gboolean is_ascii (const char *value); +gboolean is_true (const char *str); void get_dhcp_hostname_and_client_id (char **hostname, char **client_id); diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.c b/system-settings/plugins/ifnet/nm-ifnet-connection.c index 561a7cffc..13af19239 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.c +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.c @@ -90,18 +90,16 @@ commit_changes (NMSysconfigConnection *connection, gpointer user_data) { GError *error = NULL; - gchar *new_conn_name = NULL; NMIfnetConnectionPrivate *priv = NM_IFNET_CONNECTION_GET_PRIVATE (connection); + const char *new_name = NULL; g_signal_emit (connection, signals[IFNET_CANCEL_MONITORS], 0); if (!ifnet_update_parsers_by_connection (NM_CONNECTION (connection), priv->conn_name, - &new_conn_name, CONF_NET_FILE, WPA_SUPPLICANT_CONF, + &new_name, &error)) { - if (new_conn_name) - g_free (new_conn_name); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Failed to update %s", priv->conn_name); reload_parsers (); callback (connection, error, user_data); @@ -111,7 +109,7 @@ commit_changes (NMSysconfigConnection *connection, } g_free (priv->conn_name); - priv->conn_name = new_conn_name; + priv->conn_name = g_strdup (new_name); NM_SYSCONFIG_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, callback, user_data); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s", priv->conn_name); diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index 0bc333615..1d95049c0 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -126,20 +126,11 @@ write_system_hostname (NMSystemConfigInterface * config, static gboolean is_managed_plugin () { - gchar *result = NULL; + const char *result = NULL; - result = - ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, - IFNET_KEY_FILE_KEY_MANAGED); - if (result) { - if (is_true (result)) { - g_free (result); - return TRUE; - } else { - g_free (result); - return FALSE; - } - } + result = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, IFNET_KEY_FILE_KEY_MANAGED); + if (result) + return is_true (result); return IFNET_MANAGE_WELL_KNOWN_DEFAULT; } @@ -300,10 +291,9 @@ reload_connections (gpointer config) G_CALLBACK (cancel_monitors), config); old = g_hash_table_lookup (priv->config_connections, conn_name); if (old && exported) { - gchar *auto_refresh = - ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, - "auto_refresh"); + const char *auto_refresh; + auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh"); if (auto_refresh && is_true (auto_refresh)) { if (!nm_connection_compare (NM_CONNECTION (old), NM_CONNECTION @@ -354,8 +344,9 @@ reload_connections (gpointer config) } static gboolean -add_connection (NMSystemConfigInterface * config, - NMConnection * connection, GError ** error) +add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error) { gboolean result; diff --git a/system-settings/plugins/ifnet/tests/test_all.c b/system-settings/plugins/ifnet/tests/test_all.c index ba9839761..1f6b9f5a2 100644 --- a/system-settings/plugins/ifnet/tests/test_all.c +++ b/system-settings/plugins/ifnet/tests/test_all.c @@ -202,7 +202,7 @@ test_convert_ipv4_routes_block () static void test_wpa_parser () { - gchar *value; + const char *value; ASSERT (exist_ssid ("example"), "get wsec", "ssid myxjtu2 is not found"); @@ -273,23 +273,31 @@ test_update_connection () { GError **error = NULL; NMConnection *connection; + gboolean success; connection = ifnet_update_connection_from_config_block ("eth0", error); ASSERT (connection != NULL, "get connection", "get connection failed: %s", error == NULL ? "None" : (*error)->message); - ASSERT (ifnet_update_parsers_by_connection - (connection, "eth0", NULL, "net.generate", - "wpa_supplicant.conf.generate", error), "update connection", - "update connection failed %s", "eth0"); - connection = - ifnet_update_connection_from_config_block ("0xab3ace", error); + + success = ifnet_update_parsers_by_connection (connection, "eth0", + "net.generate", + "wpa_supplicant.conf.generate", + NULL, + error); + ASSERT (success, "update connection", "update connection failed %s", "eth0"); + + connection = ifnet_update_connection_from_config_block ("0xab3ace", error); ASSERT (connection != NULL, "get connection", "get connection failed: %s", error == NULL ? "None" : (*error)->message); - ASSERT (ifnet_update_parsers_by_connection - (connection, "0xab3ace", NULL, "net.generate", - "wpa_supplicant.conf.generate", error), "update connection", + + success = ifnet_update_parsers_by_connection (connection, "0xab3ace", + "net.generate", + "wpa_supplicant.conf.generate", + NULL, + error); + ASSERT (success, "update connection", "update connection failed %s", "0xab3ace"); } diff --git a/system-settings/plugins/ifnet/wpa_parser.c b/system-settings/plugins/ifnet/wpa_parser.c index 5e94108e9..a3ca5225a 100644 --- a/system-settings/plugins/ifnet/wpa_parser.c +++ b/system-settings/plugins/ifnet/wpa_parser.c @@ -35,7 +35,7 @@ static GHashTable *wsec_global_table = NULL; static gboolean wpa_parser_data_changed = FALSE; static long -wpa_get_long (GHashTable * table, gchar * key) +wpa_get_long (GHashTable *table, const char *key) { return atol (g_hash_table_lookup (table, key)); } @@ -57,14 +57,15 @@ destroy_security (GHashTable * network) } static GHashTable * -add_security (GHashTable * security) +add_security (GHashTable *security) { GHashTable *oldsecurity; - gchar *ssid = g_hash_table_lookup (security, "ssid"), *ssid_key; - gchar *value; + const char *ssid, *value; + char *ssid_key; gboolean is_hex_ssid; /* Every security information should have a ssid */ + ssid = g_hash_table_lookup (security, "ssid"); if (!ssid) { destroy_security (security); return NULL; @@ -181,7 +182,7 @@ add_keys_from_net () while (iter) { gchar *conn_name = iter->data; GHashTable *table; - gchar *key_str; + const char *key_str; if ((key_str = ifnet_get_data (conn_name, "key")) == NULL) { iter = g_list_next (iter); @@ -247,7 +248,7 @@ add_global_data (gchar * line) } void -wpa_parser_init (gchar * wpa_supplicant_conf) +wpa_parser_init (const char *wpa_supplicant_conf) { GIOChannel *channel = NULL; gchar *line; @@ -315,8 +316,8 @@ wpa_parser_init (gchar * wpa_supplicant_conf) add_keys_from_net (); } -gchar * -wpa_get_value (gchar * ssid, gchar * key) +const char * +wpa_get_value (const char *ssid, const char *key) { GHashTable *target = g_hash_table_lookup (wsec_table, ssid); @@ -326,13 +327,13 @@ wpa_get_value (gchar * ssid, gchar * key) } gboolean -exist_ssid (gchar * ssid) +exist_ssid (const char *ssid) { return g_hash_table_lookup (wsec_table, ssid) != NULL; } GHashTable * -_get_hash_table (gchar * ssid) +_get_hash_table (const char *ssid) { return g_hash_table_lookup (wsec_table, ssid); } @@ -355,7 +356,7 @@ need_quote (gchar * key) } gboolean -wpa_flush_to_file (gchar * config_file) +wpa_flush_to_file (const char *config_file) { GIOChannel *channel; GError **error = NULL; @@ -446,7 +447,7 @@ wpa_flush_to_file (gchar * config_file) /* If value is NULL, this method will delete old key value pair */ void -wpa_set_data (gchar * ssid, gchar * key, gchar * value) +wpa_set_data (const char *ssid, const char *key, const char *value) { gpointer orig_key = NULL, orig_value = NULL; GHashTable *security = g_hash_table_lookup (wsec_table, ssid); @@ -474,13 +475,13 @@ wpa_set_data (gchar * ssid, gchar * key, gchar * value) } gboolean -wpa_has_security (gchar * ssid) +wpa_has_security (const char *ssid) { return g_hash_table_lookup (wsec_table, ssid) != NULL; } gboolean -wpa_add_security (gchar * ssid) +wpa_add_security (const char *ssid) { if (wpa_has_security (ssid)) return FALSE; @@ -508,7 +509,7 @@ wpa_add_security (gchar * ssid) } gboolean -wpa_delete_security (gchar * ssid) +wpa_delete_security (const char *ssid) { gpointer orig_key, orig_value; diff --git a/system-settings/plugins/ifnet/wpa_parser.h b/system-settings/plugins/ifnet/wpa_parser.h index 55b0ec0c6..7fd77a056 100644 --- a/system-settings/plugins/ifnet/wpa_parser.h +++ b/system-settings/plugins/ifnet/wpa_parser.h @@ -23,18 +23,18 @@ #define _WPA_PARSER_H #define WPA_SUPPLICANT_CONF "/etc/wpa_supplicant/wpa_supplicant.conf" #include -void wpa_parser_init (gchar * wpa_supplicant_conf); +void wpa_parser_init (const char *wpa_supplicant_conf); void wpa_parser_destroy (void); /* reader functions */ -gchar *wpa_get_value (gchar * ssid, gchar * key); -gboolean exist_ssid (gchar * ssid); -GHashTable *_get_hash_table (gchar * ssid); -gboolean wpa_has_security (gchar * ssid); +const char *wpa_get_value (const char *ssid, const char *key); +gboolean exist_ssid (const char *ssid); +GHashTable *_get_hash_table (const char *ssid); +gboolean wpa_has_security (const char *ssid); /* writer functions */ -gboolean wpa_flush_to_file (gchar * config_file); -void wpa_set_data (gchar * ssid, gchar * key, gchar * value); -gboolean wpa_add_security (gchar * ssid); -gboolean wpa_delete_security (gchar * ssid); +gboolean wpa_flush_to_file (const char *config_file); +void wpa_set_data (const char *ssid, const char *key, const char *value); +gboolean wpa_add_security (const char *ssid); +gboolean wpa_delete_security (const char *ssid); #endif From 28b17c8b4f40b5b074056bb9f041daab4c07f24d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 13:58:23 -0500 Subject: [PATCH 066/264] ifnet: trivial cleanups --- system-settings/plugins/ifnet/plugin.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index 1d95049c0..66b124be6 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -63,15 +63,12 @@ typedef struct { gpointer user_data; } FileMonitorInfo; -static void system_config_interface_init (NMSystemConfigInterface * - system_config_interface_class); +static void system_config_interface_init (NMSystemConfigInterface *class); -static void - reload_connections (gpointer config); +static void reload_connections (gpointer config); G_DEFINE_TYPE_EXTENDED (SCPluginIfnet, sc_plugin_ifnet, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, - system_config_interface_init)) + G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, system_config_interface_init)) #define SC_PLUGIN_IFNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_IFNET, SCPluginIfnetPrivate)) /* static void @@ -433,7 +430,7 @@ SCPluginIfnet_init (NMSystemConfigInterface * config) } static GSList * -SCPluginIfnet_get_connections (NMSystemConfigInterface * config) +get_connections (NMSystemConfigInterface * config) { SCPluginIfnetPrivate *priv = SC_PLUGIN_IFNET_GET_PRIVATE (config); GSList *connections = NULL; @@ -459,15 +456,12 @@ SCPluginIfnet_get_connections (NMSystemConfigInterface * config) } static void -system_config_interface_init (NMSystemConfigInterface * - system_config_interface_class) +system_config_interface_init (NMSystemConfigInterface *class) { - system_config_interface_class->init = SCPluginIfnet_init; - system_config_interface_class->get_connections = - SCPluginIfnet_get_connections; - system_config_interface_class->get_unmanaged_specs = - get_unmanaged_specs; - system_config_interface_class->add_connection = add_connection; + class->init = SCPluginIfnet_init; + class->get_connections = get_connections; + class->get_unmanaged_specs = get_unmanaged_specs; + class->add_connection = add_connection; } static void From 856a1c6b2c9437ac03d210f5b7ecd0d08da71fcd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 14:01:22 -0500 Subject: [PATCH 067/264] ifnet: fix memory leak --- system-settings/plugins/ifnet/net_parser.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/system-settings/plugins/ifnet/net_parser.c b/system-settings/plugins/ifnet/net_parser.c index 79084ff88..98cfc2f1b 100644 --- a/system-settings/plugins/ifnet/net_parser.c +++ b/system-settings/plugins/ifnet/net_parser.c @@ -404,17 +404,18 @@ ifnet_get_global_data (const gchar * key) // Return names of legal connections GList * -ifnet_get_connection_names () +ifnet_get_connection_names (void) { GList *names = g_hash_table_get_keys (conn_table); GList *result = NULL; while (names) { if (!ignore_connection_name (names->data)) - result = g_list_append (result, names->data); + result = g_list_prepend (result, names->data); names = names->next; } - return result; + g_list_free (names); + return g_list_reverse (result); } /* format IP and route for writing */ From 37845af95401d1445531161d1f8c0a349cedb9a4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 14:34:33 -0500 Subject: [PATCH 068/264] settings: return new connection object path from AddConnection Finally. --- introspection/nm-settings.xml | 5 + libnm-glib/nm-remote-settings.c | 29 ++- libnm-glib/nm-remote-settings.h | 1 + src/settings/nm-settings.c | 108 +++++--- src/settings/nm-system-config-interface.c | 10 +- src/settings/nm-system-config-interface.h | 16 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 64 +++-- .../plugins/ifcfg-rh/nm-ifcfg-connection.h | 4 +- system-settings/plugins/ifcfg-rh/plugin.c | 236 +++++++++--------- .../plugins/ifnet/connection_parser.c | 10 +- .../plugins/ifnet/connection_parser.h | 8 +- .../plugins/ifnet/nm-ifnet-connection.c | 68 ++--- .../plugins/ifnet/nm-ifnet-connection.h | 8 +- system-settings/plugins/ifnet/plugin.c | 117 ++++----- .../plugins/keyfile/nm-keyfile-connection.c | 96 ++----- .../plugins/keyfile/nm-keyfile-connection.h | 8 +- system-settings/plugins/keyfile/plugin.c | 182 ++++++++------ 17 files changed, 465 insertions(+), 505 deletions(-) diff --git a/introspection/nm-settings.xml b/introspection/nm-settings.xml index f10a6e1c6..f816b0870 100644 --- a/introspection/nm-settings.xml +++ b/introspection/nm-settings.xml @@ -29,6 +29,11 @@ Connection settings and properties. + + + Object path of the new connection that was just added. + + diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index f263df29f..7b614854a 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -154,12 +154,12 @@ connection_init_result_cb (NMRemoteConnection *remote, g_signal_emit (self, signals[CONNECTIONS_READ], 0); } -static void +static NMRemoteConnection * new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) { NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); - NMRemoteConnection *connection; + NMRemoteConnection *connection = NULL; connection = nm_remote_connection_new (priv->bus, path); if (connection) { @@ -177,6 +177,7 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) */ g_hash_table_insert (priv->pending, g_strdup (path), connection); } + return connection; } static void @@ -205,17 +206,17 @@ fetch_connections_done (DBusGProxy *proxy, } /* Let listeners know we are done getting connections */ - if (connections->len == 0) { + if (connections->len == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); - return; + else { + for (i = 0; i < connections->len; i++) { + char *path = g_ptr_array_index (connections, i); + + new_connection_cb (proxy, path, user_data); + g_free (path); + } } - for (i = 0; connections && (i < connections->len); i++) { - char *path = g_ptr_array_index (connections, i); - - new_connection_cb (proxy, path, user_data); - g_free (path); - } g_ptr_array_free (connections, TRUE); } @@ -268,13 +269,19 @@ typedef struct { static void add_connection_done (DBusGProxy *proxy, + char *path, GError *error, gpointer user_data) { AddConnectionInfo *info = user_data; + NMRemoteConnection *connection; + + connection = new_connection_cb (proxy, path, info->self); + g_assert (connection); + info->callback (info->self, connection, error, info->callback_data); - info->callback (info->self, error, info->callback_data); g_free (info); + g_free (path); } /** * nm_remote_settings_add_connection: diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index a1d3cee83..78c7e827f 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -51,6 +51,7 @@ typedef struct _NMRemoteSettingsClass NMRemoteSettingsClass; typedef void (*NMRemoteSettingsAddConnectionFunc) (NMRemoteSettings *settings, + NMRemoteConnection *connection, GError *error, gpointer user_data); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 37621c063..3b1653995 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -129,7 +129,6 @@ enum { NEW_CONNECTION, /* exported, not used internally */ LAST_SIGNAL }; - static guint signals[LAST_SIGNAL] = { 0 }; enum { @@ -575,16 +574,45 @@ load_plugins (NMSettings *self, const char *plugins, GError **error) return success; } +#define REMOVED_ID_TAG "removed-id-tag" +#define UPDATED_ID_TAG "updated-id-tag" +#define VISIBLE_ID_TAG "visible-id-tag" + static void -connection_removed (NMSysconfigConnection *connection, gpointer user_data) +connection_removed (NMSysconfigConnection *obj, gpointer user_data) { + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data); + GObject *connection = G_OBJECT (obj); + guint id; + g_object_ref (connection); - g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, connection); + /* Disconnect signal handlers, as plugins might still keep references + * to the connection (and thus the signal handlers would still be live) + * even after NMSettings has dropped all its references. + */ + + id = GPOINTER_TO_UINT (g_object_get_data (connection, REMOVED_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); + + id = GPOINTER_TO_UINT (g_object_get_data (connection, UPDATED_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); + + id = GPOINTER_TO_UINT (g_object_get_data (connection, VISIBLE_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); + + /* Unregister the connection with D-Bus and forget about it */ + dbus_g_connection_unregister_g_object (priv->bus, connection); + g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, + (gpointer) nm_connection_get_path (NM_CONNECTION (connection))); g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection); + g_object_unref (connection); } @@ -619,6 +647,7 @@ claim_connection (NMSettings *self, GHashTableIter iter; gpointer data; char *path; + guint id; g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); @@ -640,19 +669,20 @@ claim_connection (NMSettings *self, /* Ensure it's initial visibility is up-to-date */ nm_sysconfig_connection_recheck_visibility (connection); - g_signal_connect (connection, - NM_SYSCONFIG_CONNECTION_REMOVED, - G_CALLBACK (connection_removed), - self); + id = g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, + G_CALLBACK (connection_removed), + self); + g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id)); - g_signal_connect (connection, - NM_SYSCONFIG_CONNECTION_UPDATED, - G_CALLBACK (connection_updated), - self); + id = g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED, + G_CALLBACK (connection_updated), + self); + g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id)); - g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE, - G_CALLBACK (connection_visibility_changed), - self); + id = g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE, + G_CALLBACK (connection_visibility_changed), + self); + g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id)); /* Export the connection over D-Bus */ g_warn_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); @@ -750,7 +780,7 @@ polkit_call_free (PolkitCall *call) g_free (call); } -static gboolean +static NMSysconfigConnection * add_new_connection (NMSettings *self, NMConnection *connection, GError **error) @@ -758,29 +788,28 @@ add_new_connection (NMSettings *self, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *tmp_error = NULL, *last_error = NULL; GSList *iter; - gboolean success = FALSE; + NMSysconfigConnection *added = NULL; - /* Here's how it works: - 1) plugin writes a connection. - 2) plugin notices that a new connection is available for reading. - 3) plugin reads the new connection (the one it wrote in 1) and emits 'connection-added' signal. - 4) NMSettings receives the signal and adds it to it's connection list. - */ - - for (iter = priv->plugins; iter && !success; iter = iter->next) { - success = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), - connection, - &tmp_error); + /* 1) plugin writes the NMConnection to disk + * 2) plugin creates a new NMSysconfigConnection subclass with the settings + * from the NMConnection and returns it to the settings service + * 3) settings service exports the new NMSysconfigConnection subclass + * 4) plugin notices that something on the filesystem has changed + * 5) plugin reads the changes and ignores them because they will + * contain the same data as the connection it already knows about + */ + for (iter = priv->plugins; iter && !added; iter = g_slist_next (iter)) { + added = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), + connection, + &tmp_error); g_clear_error (&last_error); - if (!success) { - last_error = tmp_error; - tmp_error = NULL; - } + if (!added) + g_propagate_error (&last_error, tmp_error); } - if (!success) - *error = last_error; - return success; + if (!added) + g_propagate_error (error, last_error); + return added; } static void @@ -791,6 +820,7 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) NMSettingsPrivate *priv; PolkitAuthorizationResult *pk_result; GError *error = NULL, *add_error = NULL; + NMSysconfigConnection *added_connection; /* If NMSettings is already gone, do nothing */ if (call->disposed) { @@ -825,8 +855,9 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) goto out; } - if (add_new_connection (self, call->connection, &add_error)) - dbus_g_method_return (call->context); + added_connection = add_new_connection (self, call->connection, &add_error); + if (added_connection) + dbus_g_method_return (call->context, added_connection); else { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_ADD_FAILED, @@ -1201,6 +1232,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, GError *error = NULL; NMSettingConnection *s_con; const char *id; + NMSysconfigConnection *added; /* Try to move this default wired conneciton to a plugin so that it has * persistent storage. @@ -1213,7 +1245,8 @@ default_wired_try_update (NMDefaultWiredConnection *wired, g_assert (id); remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); - if (add_new_connection (self, NM_CONNECTION (wired), &error)) { + added = add_new_connection (self, NM_CONNECTION (wired), &error); + if (added) { nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (wired), delete_cb, NULL); @@ -1229,6 +1262,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, id, error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); /* If there was an error, don't destroy the default wired connection, * but add it back to the system settings service. Connection is already diff --git a/src/settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c index f522a9b44..b5f9d7207 100644 --- a/src/settings/nm-system-config-interface.c +++ b/src/settings/nm-system-config-interface.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ @@ -146,18 +146,16 @@ nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config) return NULL; } -gboolean +NMSysconfigConnection * nm_system_config_interface_add_connection (NMSystemConfigInterface *config, NMConnection *connection, GError **error) { - gboolean success = FALSE; - g_return_val_if_fail (config != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection) - success = NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error); + return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->add_connection (config, connection, error); - return success; + return NULL; } diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h index 439586a40..f31beabc3 100644 --- a/src/settings/nm-system-config-interface.h +++ b/src/settings/nm-system-config-interface.h @@ -117,11 +117,13 @@ struct _NMSystemConfigInterface { GSList * (*get_unmanaged_specs) (NMSystemConfigInterface *config); /* - * Add a new connection. + * Save the given connection to backing storage, and return a new + * NMSysconfigConnection subclass that contains the same settings as the + * original connection. */ - gboolean (*add_connection) (NMSystemConfigInterface *config, - NMConnection *connection, - GError **error); + NMSysconfigConnection * (*add_connection) (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); /* Signals */ @@ -142,9 +144,9 @@ GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *con GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config); -gboolean nm_system_config_interface_add_connection (NMSystemConfigInterface *config, - NMConnection *connection, - GError **error); +NMSysconfigConnection *nm_system_config_interface_add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); G_END_DECLS diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 221230525..d43ab103f 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2009 Red Hat, Inc. + * Copyright (C) 2008 - 2010 Red Hat, Inc. */ #include @@ -47,7 +47,7 @@ G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECT typedef struct { gulong ih_event_id; - char *filename; + char *path; int file_wd; char *keyfile; @@ -64,9 +64,7 @@ typedef struct { enum { PROP_0, - PROP_FILENAME, PROP_UNMANAGED, - LAST_PROP }; @@ -87,7 +85,10 @@ files_changed_cb (NMInotifyHelper *ih, NMIfcfgConnection *self = NM_IFCFG_CONNECTION (user_data); NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); - if ((evt->wd != priv->file_wd) && (evt->wd != priv->keyfile_wd) && (evt->wd != priv->routefile_wd) && (evt->wd != priv->route6file_wd)) + if ( (evt->wd != priv->file_wd) + && (evt->wd != priv->keyfile_wd) + && (evt->wd != priv->routefile_wd) + && (evt->wd != priv->route6file_wd)) return; /* push the event up to the plugin */ @@ -95,7 +96,8 @@ files_changed_cb (NMInotifyHelper *ih, } NMIfcfgConnection * -nm_ifcfg_connection_new (const char *filename, +nm_ifcfg_connection_new (const char *full_path, + NMConnection *source, GError **error, gboolean *ignore_error) { @@ -108,14 +110,24 @@ nm_ifcfg_connection_new (const char *filename, char *route6file = NULL; NMInotifyHelper *ih; - g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (full_path != NULL, NULL); - tmp = connection_from_file (filename, NULL, NULL, NULL, &unmanaged, &keyfile, &routefile, &route6file, error, ignore_error); - if (!tmp) - return NULL; + /* If we're given a connection already, prefer that instead of re-reading */ + if (source) + tmp = g_object_ref (source); + else { + tmp = connection_from_file (full_path, NULL, NULL, NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + error, + ignore_error); + if (!tmp) + return NULL; + } object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, - NM_IFCFG_CONNECTION_FILENAME, filename, NM_IFCFG_CONNECTION_UNMANAGED, unmanaged, NULL); if (!object) { @@ -128,11 +140,12 @@ nm_ifcfg_connection_new (const char *filename, g_object_unref (tmp); priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); + priv->path = g_strdup (full_path); ih = nm_inotify_helper_get (); priv->ih_event_id = g_signal_connect (ih, "event", G_CALLBACK (files_changed_cb), object); - priv->file_wd = nm_inotify_helper_add_watch (ih, filename); + priv->file_wd = nm_inotify_helper_add_watch (ih, full_path); priv->keyfile = keyfile; priv->keyfile_wd = nm_inotify_helper_add_watch (ih, keyfile); @@ -147,11 +160,11 @@ nm_ifcfg_connection_new (const char *filename, } const char * -nm_ifcfg_connection_get_filename (NMIfcfgConnection *self) +nm_ifcfg_connection_get_path (NMIfcfgConnection *self) { g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL); - return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->filename; + return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->path; } const char * @@ -176,7 +189,7 @@ commit_changes (NMSysconfigConnection *connection, * processes on-disk, read the existing connection back in and only rewrite * it if it's really changed. */ - reread = connection_from_file (priv->filename, NULL, NULL, NULL, + reread = connection_from_file (priv->path, NULL, NULL, NULL, &unmanaged, &keyfile, &routefile, &route6file, NULL, NULL); g_free (unmanaged); @@ -191,7 +204,7 @@ commit_changes (NMSysconfigConnection *connection, if (!writer_update_connection (NM_CONNECTION (connection), IFCFG_DIR, - priv->filename, + priv->path, priv->keyfile, &error)) { callback (connection, error, user_data); @@ -212,7 +225,7 @@ do_delete (NMSysconfigConnection *connection, { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); - g_unlink (priv->filename); + g_unlink (priv->path); if (priv->keyfile) g_unlink (priv->keyfile); if (priv->routefile) @@ -243,7 +256,7 @@ finalize (GObject *object) g_signal_handler_disconnect (ih, priv->ih_event_id); - g_free (priv->filename); + g_free (priv->path); if (priv->file_wd >= 0) nm_inotify_helper_remove_watch (ih, priv->file_wd); @@ -269,10 +282,6 @@ set_property (GObject *object, guint prop_id, NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); switch (prop_id) { - case PROP_FILENAME: - /* Construct only */ - priv->filename = g_value_dup_string (value); - break; case PROP_UNMANAGED: priv->unmanaged = g_value_dup_string (value); break; @@ -289,9 +298,6 @@ get_property (GObject *object, guint prop_id, NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); switch (prop_id) { - case PROP_FILENAME: - g_value_set_string (value, priv->filename); - break; case PROP_UNMANAGED: g_value_set_string (value, priv->unmanaged); break; @@ -317,14 +323,6 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) sysconfig_class->commit_changes = commit_changes; /* Properties */ - g_object_class_install_property - (object_class, PROP_FILENAME, - g_param_spec_string (NM_IFCFG_CONNECTION_FILENAME, - "FileName", - "File name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_UNMANAGED, g_param_spec_string (NM_IFCFG_CONNECTION_UNMANAGED, diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 860c428ca..4d9d699bc 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -33,7 +33,6 @@ G_BEGIN_DECLS #define NM_IS_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION)) #define NM_IFCFG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass)) -#define NM_IFCFG_CONNECTION_FILENAME "filename" #define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged" typedef struct { @@ -47,10 +46,11 @@ typedef struct { GType nm_ifcfg_connection_get_type (void); NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename, + NMConnection *source, GError **error, gboolean *ignore_error); -const char *nm_ifcfg_connection_get_filename (NMIfcfgConnection *self); +const char *nm_ifcfg_connection_get_path (NMIfcfgConnection *self); const char *nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self); diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 215ba6a9d..9e52b35df 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -18,7 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2010 Red Hat, Inc. */ #include @@ -62,20 +62,12 @@ static gboolean impl_ifcfgrh_get_ifcfg_details (SCPluginIfcfg *plugin, #include "nm-ifcfg-rh-glue.h" +static void connection_new_or_changed (SCPluginIfcfg *plugin, + const char *path, + NMIfcfgConnection *existing); + static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class); -static void connection_changed_handler (SCPluginIfcfg *plugin, - const char *path, - NMIfcfgConnection *connection, - gboolean *do_remove, - gboolean *do_new); - -static void handle_connection_remove_or_new (SCPluginIfcfg *plugin, - const char *path, - NMIfcfgConnection *connection, - gboolean do_remove, - gboolean do_new); - G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0, G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE, system_config_interface_init)) @@ -109,65 +101,67 @@ static void connection_ifcfg_changed (NMIfcfgConnection *connection, gpointer user_data) { SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data); - gboolean do_remove = FALSE, do_new = FALSE; const char *path; - path = nm_ifcfg_connection_get_filename (connection); + path = nm_ifcfg_connection_get_path (connection); g_return_if_fail (path != NULL); - connection_changed_handler (plugin, path, connection, &do_remove, &do_new); - handle_connection_remove_or_new (plugin, path, connection, do_remove, do_new); + connection_new_or_changed (plugin, path, connection); } static NMIfcfgConnection * -read_one_connection (SCPluginIfcfg *plugin, const char *filename) +_internal_new_connection (SCPluginIfcfg *self, + const char *path, + NMConnection *source, + GError **error) { - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); NMIfcfgConnection *connection; - GError *error = NULL; + NMSettingConnection *s_con; + const char *cid; + GError *local = NULL; gboolean ignore_error = FALSE; - PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", filename); + if (!source) { + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "parsing %s ... ", path); + } - connection = nm_ifcfg_connection_new (filename, &error, &ignore_error); - if (connection) { - NMSettingConnection *s_con; - const char *cid; - - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - - cid = nm_setting_connection_get_id (s_con); - g_assert (cid); - - g_hash_table_insert (priv->connections, - (gpointer) nm_ifcfg_connection_get_filename (connection), - g_object_ref (connection)); - PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid); - - if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { - PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its " - "device due to NM_CONTROLLED/BRIDGE/VLAN.", cid); - g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); - } else { - /* Wait for the connection to become unmanaged once it knows the - * UDI of it's device, if/when the device gets plugged in. - */ - g_signal_connect (G_OBJECT (connection), "notify::unmanaged", - G_CALLBACK (connection_unmanaged_changed), plugin); - } - - /* watch changes of ifcfg hardlinks */ - g_signal_connect (G_OBJECT (connection), "ifcfg-changed", - G_CALLBACK (connection_ifcfg_changed), plugin); - } else { + connection = nm_ifcfg_connection_new (path, source, &local, &ignore_error); + if (!connection) { if (!ignore_error) { PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " error: %s", - (error && error->message) ? error->message : "(unknown)"); + (local && local->message) ? local->message : "(unknown)"); } - g_clear_error (&error); + g_propagate_error (error, local); + return NULL; } + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + cid = nm_setting_connection_get_id (s_con); + g_assert (cid); + + g_hash_table_insert (priv->connections, + (gpointer) nm_ifcfg_connection_get_path (connection), + connection); + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " read connection '%s'", cid); + + if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its " + "device due to NM_CONTROLLED/BRIDGE/VLAN.", cid); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + } else { + /* Wait for the connection to become unmanaged once it knows the + * hardware IDs of its device, if/when the device gets plugged in. + */ + g_signal_connect (G_OBJECT (connection), "notify::" NM_IFCFG_CONNECTION_UNMANAGED, + G_CALLBACK (connection_unmanaged_changed), self); + } + + /* watch changes of ifcfg hardlinks */ + g_signal_connect (G_OBJECT (connection), "ifcfg-changed", + G_CALLBACK (connection_ifcfg_changed), self); + return connection; } @@ -188,7 +182,7 @@ read_connections (SCPluginIfcfg *plugin) continue; full_path = g_build_filename (IFCFG_DIR, item, NULL); - read_one_connection (plugin, full_path); + _internal_new_connection (plugin, full_path, NULL, NULL); g_free (full_path); } @@ -213,26 +207,53 @@ commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused) } static void -connection_changed_handler (SCPluginIfcfg *plugin, - const char *path, - NMIfcfgConnection *connection, - gboolean *do_remove, - gboolean *do_new) +remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) +{ + SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (self); + gboolean managed = FALSE; + const char *path; + + g_return_if_fail (self != NULL); + g_return_if_fail (connection != NULL); + + managed = !!nm_ifcfg_connection_get_unmanaged_spec (connection); + path = nm_ifcfg_connection_get_path (connection); + + g_hash_table_remove (priv->connections, path); + g_signal_emit_by_name (connection, NM_SYSCONFIG_CONNECTION_REMOVED); + + /* Emit unmanaged changes _after_ removing the connection */ + if (managed == FALSE) + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); +} + +static void +connection_new_or_changed (SCPluginIfcfg *self, + const char *path, + NMIfcfgConnection *existing) { NMIfcfgConnection *new; GError *error = NULL; gboolean ignore_error = FALSE; const char *new_unmanaged = NULL, *old_unmanaged = NULL; - g_return_if_fail (plugin != NULL); + g_return_if_fail (self != NULL); g_return_if_fail (path != NULL); - g_return_if_fail (connection != NULL); - g_return_if_fail (do_remove != NULL); - g_return_if_fail (do_new != NULL); + if (!existing) { + /* Completely new connection */ + new = _internal_new_connection (self, path, NULL, NULL); + if (new && !nm_ifcfg_connection_get_unmanaged_spec (new)) { + /* Only managed connections are announced to the settings service */ + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); + } + return; + } + + /* Existing connection that got changed */ PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path); - new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, &error, &ignore_error); + new = (NMIfcfgConnection *) nm_ifcfg_connection_new (path, NULL, &error, &ignore_error); if (!new) { /* errors reading connection; remove it */ if (!ignore_error) { @@ -242,19 +263,23 @@ connection_changed_handler (SCPluginIfcfg *plugin, g_clear_error (&error); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", path); - *do_remove = TRUE; + remove_connection (self, existing); return; } - /* Successfully read connection changes */ + /* Successfully read connection */ - old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection)); + old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing)); new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new)); if (new_unmanaged) { if (!old_unmanaged) { - /* Unexport the connection by destroying it, then re-creating it as unmanaged */ - *do_remove = *do_new = TRUE; + /* Unexport the connection by telling the settings service it's + * been removed, and notify the settings service by signalling that + * unmanaged specs have changed. + */ + g_signal_emit_by_name (existing, NM_SYSCONFIG_CONNECTION_REMOVED); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } } else { if (old_unmanaged) { /* now managed */ @@ -263,60 +288,25 @@ connection_changed_handler (SCPluginIfcfg *plugin, s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (new), NM_TYPE_SETTING_CONNECTION); g_assert (s_con); - cid = nm_setting_connection_get_id (s_con); g_assert (cid); PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Managing connection '%s' and its " "device because NM_CONTROLLED was true.", cid); - g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing); } - nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (connection), + nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (existing), NM_CONNECTION (new), commit_cb, NULL); /* Update unmanaged status */ - g_object_set (connection, "unmanaged", new_unmanaged, NULL); - g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } g_object_unref (new); } -static void -handle_connection_remove_or_new (SCPluginIfcfg *plugin, - const char *path, - NMIfcfgConnection *connection, - gboolean do_remove, - gboolean do_new) -{ - SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); - - g_return_if_fail (plugin != NULL); - g_return_if_fail (path != NULL); - - if (do_remove) { - const char *unmanaged; - - g_return_if_fail (connection != NULL); - - unmanaged = nm_ifcfg_connection_get_unmanaged_spec (connection); - g_hash_table_remove (priv->connections, path); - g_signal_emit_by_name (connection, "removed"); - - /* Emit unmanaged changes _after_ removing the connection */ - if (unmanaged) - g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); - } - - if (do_new) { - connection = read_one_connection (plugin, path); - if (connection) { - if (!nm_ifcfg_connection_get_unmanaged_spec (connection)) - g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); - } - } -} static void dir_changed (GFileMonitor *monitor, GFile *file, @@ -328,7 +318,6 @@ dir_changed (GFileMonitor *monitor, SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin); char *path, *name; NMIfcfgConnection *connection; - gboolean do_remove = FALSE, do_new = FALSE; path = g_file_get_path (file); if (utils_should_ignore_file (path, FALSE)) { @@ -345,17 +334,12 @@ dir_changed (GFileMonitor *monitor, case G_FILE_MONITOR_EVENT_DELETED: PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name); if (connection) - handle_connection_remove_or_new (plugin, name, connection, TRUE, FALSE); + remove_connection (plugin, connection); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - /* Update */ - if (!connection) - do_new = TRUE; - else - connection_changed_handler (plugin, name, connection, &do_remove, &do_new); - - handle_connection_remove_or_new (plugin, name, connection, do_remove, do_new); + /* Update or new */ + connection_new_or_changed (plugin, name, connection); break; default: break; @@ -445,12 +429,22 @@ get_unmanaged_specs (NMSystemConfigInterface *config) return list; } -static gboolean +static NMSysconfigConnection * add_connection (NMSystemConfigInterface *config, NMConnection *connection, GError **error) { - return writer_new_connection (connection, IFCFG_DIR, NULL, error); + SCPluginIfcfg *self = SC_PLUGIN_IFCFG (config); + NMIfcfgConnection *added = NULL; + char *path = NULL; + + /* Write it out first, then add the connection to our internal list */ + if (writer_new_connection (connection, IFCFG_DIR, &path, error)) { + added = _internal_new_connection (self, path, connection, error); + g_free (path); + } + return NM_SYSCONFIG_CONNECTION (added); + } #define SC_NETWORK_FILE SYSCONFDIR"/sysconfig/network" diff --git a/system-settings/plugins/ifnet/connection_parser.c b/system-settings/plugins/ifnet/connection_parser.c index dc9f681d0..877957729 100644 --- a/system-settings/plugins/ifnet/connection_parser.c +++ b/system-settings/plugins/ifnet/connection_parser.c @@ -2973,8 +2973,8 @@ get_wireless_name (NMConnection * connection) return result; } -gboolean -ifnet_add_new_connection (NMConnection * connection, +char * +ifnet_add_new_connection (NMConnection *connection, const char *config_file, const char *wpa_file, GError **error) @@ -3024,10 +3024,10 @@ ifnet_add_new_connection (NMConnection * connection, } PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Added new connection: %s, result: %s", - new_name, success ? "success" : "fail"); + new_name, success ? "success" : "fail"); out: - if (new_name) + if (!success) g_free (new_name); - return success; + return success ? new_name : NULL; } diff --git a/system-settings/plugins/ifnet/connection_parser.h b/system-settings/plugins/ifnet/connection_parser.h index 24c1f7e90..2154f56e6 100644 --- a/system-settings/plugins/ifnet/connection_parser.h +++ b/system-settings/plugins/ifnet/connection_parser.h @@ -39,8 +39,8 @@ gboolean ifnet_delete_connection_in_parsers (const char *conn_name, const char *config_file, const char *wpa_file); -gboolean ifnet_add_new_connection (NMConnection *connection, - const char *config_file, - const char *wpa_file, - GError ** error); +char * ifnet_add_new_connection (NMConnection *connection, + const char *config_file, + const char *wpa_file, + GError ** error); #endif diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.c b/system-settings/plugins/ifnet/nm-ifnet-connection.c index 13af19239..8e774de8f 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.c +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.c @@ -57,25 +57,32 @@ typedef struct { } NMIfnetConnectionPrivate; NMIfnetConnection * -nm_ifnet_connection_new (gchar * conn_name) +nm_ifnet_connection_new (const char *conn_name, NMConnection *source) { NMConnection *tmp; GObject *object; GError **error = NULL; g_return_val_if_fail (conn_name != NULL, NULL); - tmp = ifnet_update_connection_from_config_block (conn_name, error); - if (!tmp) - return NULL; - object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, - NM_IFNET_CONNECTION_CONN_NAME, - conn_name, NULL); + + if (source) + tmp = g_object_ref (source); + else { + tmp = ifnet_update_connection_from_config_block (conn_name, error); + if (!tmp) + return NULL; + } + + object = (GObject *) g_object_new (NM_TYPE_IFNET_CONNECTION, NULL); if (!object) { g_object_unref (tmp); return NULL; } + + NM_IFNET_CONNECTION_GET_PRIVATE (object)->conn_name = g_strdup (conn_name); nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); g_object_unref (tmp); + return NM_IFNET_CONNECTION (object); } @@ -144,44 +151,6 @@ do_delete (NMSysconfigConnection *connection, g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); } -static void -set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - NMIfnetConnectionPrivate *priv = - NM_IFNET_CONNECTION_GET_PRIVATE (object); - g_return_if_fail (priv); - - switch (prop_id) { - case PROP_CONN_NAME: - if (priv->conn_name) - g_free (priv->conn_name); - priv->conn_name = g_strdup (g_value_get_pointer (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - NMIfnetConnectionPrivate *priv = - NM_IFNET_CONNECTION_GET_PRIVATE (object); - g_return_if_fail (priv); - - switch (prop_id) { - case PROP_CONN_NAME: - g_value_set_pointer (value, priv->conn_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static void finalize (GObject * object) { @@ -203,19 +172,10 @@ nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) g_type_class_add_private (ifnet_connection_class, sizeof (NMIfnetConnectionPrivate)); - object_class->set_property = set_property; - object_class->get_property = get_property; object_class->finalize = finalize; sysconfig_class->delete = do_delete; sysconfig_class->commit_changes = commit_changes; - /* Properties */ - g_object_class_install_property - (object_class, PROP_CONN_NAME, - g_param_spec_pointer (NM_IFNET_CONNECTION_CONN_NAME, - "config_block", - "", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); signals[IFNET_SETUP_MONITORS] = g_signal_new ("ifnet_setup_monitors", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.h b/system-settings/plugins/ifnet/nm-ifnet-connection.h index 8b3d495f0..cde260a45 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.h +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.h @@ -26,14 +26,15 @@ #include "net_parser.h" G_BEGIN_DECLS + #define NM_TYPE_IFNET_CONNECTION (nm_ifnet_connection_get_type ()) #define NM_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnection)) #define NM_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) #define NM_IS_IFNET_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFNET_CONNECTION)) #define NM_IS_IFNET_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFNET_CONNECTION)) #define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) -#define NM_IFNET_CONNECTION_CONN_NAME "connection_name" - typedef struct { + +typedef struct { NMSysconfigConnection parent; } NMIfnetConnection; @@ -43,7 +44,8 @@ typedef struct { GType nm_ifnet_connection_get_type (void); -NMIfnetConnection *nm_ifnet_connection_new (gchar * conn_name); +NMIfnetConnection *nm_ifnet_connection_new (const char *conn_name, + NMConnection *source); G_END_DECLS #endif /* NM_IFNET_CONNECTION_H */ diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index 66b124be6..c0077c875 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -201,18 +201,6 @@ commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused) } } -static void -update_old_connection (gchar * conn_name, - NMIfnetConnection * old_conn, - NMIfnetConnection * new_conn, - SCPluginIfnetPrivate * priv) -{ - nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (old_conn), - NM_CONNECTION (new_conn), - commit_cb, NULL); - g_object_unref (new_conn); -} - static void setup_monitors (NMIfnetConnection * connection, gpointer user_data) { @@ -267,90 +255,85 @@ reload_connections (gpointer config) if (!reload_parsers ()) return; - PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections"); - conn_names = ifnet_get_connection_names (); - new_conn_names = - g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) { - NMIfnetConnection *exported; - NMIfnetConnection *old; - gchar *conn_name = g_strdup (n_iter->data); - /* add the new connection */ - exported = nm_ifnet_connection_new (conn_name); - if (!exported) { - g_free (conn_name); + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Loading connections"); + + conn_names = ifnet_get_connection_names (); + new_conn_names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + for (n_iter = conn_names; n_iter; n_iter = g_list_next (n_iter)) { + NMIfnetConnection *new; + NMIfnetConnection *old; + const char *conn_name = n_iter->data; + + /* read the new connection */ + new = nm_ifnet_connection_new (conn_name, NULL); + if (!new) continue; - } - g_signal_connect (G_OBJECT (exported), "ifnet_setup_monitors", - G_CALLBACK (setup_monitors), config); - g_signal_connect (G_OBJECT (exported), "ifnet_cancel_monitors", - G_CALLBACK (cancel_monitors), config); + + g_signal_connect (G_OBJECT (new), "ifnet_setup_monitors", + G_CALLBACK (setup_monitors), config); + g_signal_connect (G_OBJECT (new), "ifnet_cancel_monitors", + G_CALLBACK (cancel_monitors), config); + old = g_hash_table_lookup (priv->config_connections, conn_name); - if (old && exported) { + if (old && new) { const char *auto_refresh; auto_refresh = ifnet_get_global_setting (IFNET_KEY_FILE_GROUP, "auto_refresh"); if (auto_refresh && is_true (auto_refresh)) { if (!nm_connection_compare (NM_CONNECTION (old), - NM_CONNECTION - (exported), - NM_SETTING_COMPARE_FLAG_EXACT)) - { - PLUGIN_PRINT (IFNET_PLUGIN_NAME, - "Auto refreshing %s", - conn_name); - g_signal_emit_by_name (old, "removed"); - g_hash_table_remove - (priv->config_connections, - conn_name); - g_hash_table_insert - (priv->config_connections, - g_strdup (conn_name), exported); + NM_CONNECTION (new), + NM_SETTING_COMPARE_FLAG_EXACT)) { + PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name); + + /* Remove and re-add to disconnect and reconnect with new settings */ + g_signal_emit_by_name (old, NM_SYSCONFIG_CONNECTION_REMOVED); + g_hash_table_remove (priv->config_connections, conn_name); + g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); if (is_managed (conn_name)) - g_signal_emit_by_name (self, - NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, - exported); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); } - } else - update_old_connection (conn_name, old, - exported, priv); - g_signal_emit_by_name (self, - NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); - } else if (exported) { - g_hash_table_insert (priv->config_connections, - g_strdup (conn_name), exported); + } else { + /* Update existing connection with new settings */ + nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (old), + NM_CONNECTION (new), + commit_cb, NULL); + g_object_unref (new); + } + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + } else if (new) { + g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); if (is_managed (conn_name)) - g_signal_emit_by_name (self, - NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, - exported); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new); } - g_hash_table_insert (new_conn_names, conn_name, conn_name); + g_hash_table_insert (new_conn_names, (gpointer) conn_name, (gpointer) conn_name); } + /* remove unused connections */ g_hash_table_iter_init (&iter, priv->config_connections); while (g_hash_table_iter_next (&iter, &key, &value)) { if (!g_hash_table_lookup (new_conn_names, key)) { - g_signal_emit_by_name (value, "removed"); + g_signal_emit_by_name (value, NM_SYSCONFIG_CONNECTION_REMOVED); g_hash_table_remove (priv->config_connections, key); } } - g_hash_table_remove_all (new_conn_names); g_hash_table_destroy (new_conn_names); g_list_free (conn_names); } -static gboolean +static NMSysconfigConnection * add_connection (NMSystemConfigInterface *config, - NMConnection *connection, + NMConnection *source, GError **error) { - gboolean result; + NMIfnetConnection *connection = NULL; + char *conn_name; - result = ifnet_add_new_connection (connection, CONF_NET_FILE, - WPA_SUPPLICANT_CONF, error); + conn_name = ifnet_add_new_connection (source, CONF_NET_FILE, WPA_SUPPLICANT_CONF, error); + if (conn_name) + connection = nm_ifnet_connection_new (conn_name, source); reload_connections (config); - return result; + return connection ? NM_SYSCONFIG_CONNECTION (connection) : NULL; } static void diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index e14986917..99d6888c2 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -37,40 +37,38 @@ G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CON #define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate)) typedef struct { - char *filename; + char *path; } NMKeyfileConnectionPrivate; -enum { - PROP_0, - PROP_FILENAME, - - LAST_PROP -}; - NMKeyfileConnection * -nm_keyfile_connection_new (const char *filename, GError **error) +nm_keyfile_connection_new (const char *full_path, + NMConnection *source, + GError **error) { GObject *object; NMKeyfileConnectionPrivate *priv; NMSettingConnection *s_con; NMConnection *tmp; - g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (full_path != NULL, NULL); - tmp = connection_from_file (filename, error); - if (!tmp) - return NULL; + /* If we're given a connection already, prefer that instead of re-reading */ + if (source) + tmp = g_object_ref (source); + else { + tmp = connection_from_file (full_path, error); + if (!tmp) + return NULL; + } - object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, - NM_KEYFILE_CONNECTION_FILENAME, filename, - NULL); + object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL); if (!object) { g_object_unref (tmp); return NULL; } priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); - g_assert (priv->filename); + priv->path = g_strdup (full_path); /* Update our settings with what was read from the file */ nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); @@ -100,11 +98,11 @@ nm_keyfile_connection_new (const char *filename, GError **error) } const char * -nm_keyfile_connection_get_filename (NMKeyfileConnection *self) +nm_keyfile_connection_get_path (NMKeyfileConnection *self) { g_return_val_if_fail (NM_IS_KEYFILE_CONNECTION (self), NULL); - return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->filename; + return NM_KEYFILE_CONNECTION_GET_PRIVATE (self)->path; } static void @@ -113,21 +111,21 @@ commit_changes (NMSysconfigConnection *connection, gpointer user_data) { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); - char *filename = NULL; + char *path = NULL; GError *error = NULL; - if (!write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &filename, &error)) { + if (!write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &path, &error)) { callback (connection, error, user_data); g_clear_error (&error); return; } - if (g_strcmp0 (priv->filename, filename)) { + if (g_strcmp0 (priv->path, path)) { /* Update the filename if it changed */ - g_free (priv->filename); - priv->filename = filename; + g_free (priv->path); + priv->path = path; } else - g_free (filename); + g_free (path); NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, callback, @@ -141,7 +139,7 @@ do_delete (NMSysconfigConnection *connection, { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); - g_unlink (priv->filename); + g_unlink (priv->path); NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, callback, @@ -162,44 +160,11 @@ finalize (GObject *object) nm_connection_clear_secrets (NM_CONNECTION (object)); - g_free (priv->filename); + g_free (priv->path); G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->finalize (object); } -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_FILENAME: - /* Construct only */ - priv->filename = g_value_dup_string (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); - - switch (prop_id) { - case PROP_FILENAME: - g_value_set_string (value, priv->filename); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - static void nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class) { @@ -209,18 +174,7 @@ nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_c g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); /* Virtual methods */ - object_class->set_property = set_property; - object_class->get_property = get_property; object_class->finalize = finalize; sysconfig_class->commit_changes = commit_changes; sysconfig_class->delete = do_delete; - - /* Properties */ - g_object_class_install_property - (object_class, PROP_FILENAME, - g_param_spec_string (NM_KEYFILE_CONNECTION_FILENAME, - "FileName", - "File name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.h b/system-settings/plugins/keyfile/nm-keyfile-connection.h index 68e795a6c..ab7b42eaa 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.h +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.h @@ -33,8 +33,6 @@ G_BEGIN_DECLS #define NM_IS_KEYFILE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_KEYFILE_CONNECTION)) #define NM_KEYFILE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass)) -#define NM_KEYFILE_CONNECTION_FILENAME "filename" - typedef struct { NMSysconfigConnection parent; } NMKeyfileConnection; @@ -45,9 +43,11 @@ typedef struct { GType nm_keyfile_connection_get_type (void); -NMKeyfileConnection *nm_keyfile_connection_new (const char *filename, GError **error); +NMKeyfileConnection *nm_keyfile_connection_new (const char *filename, + NMConnection *source, + GError **error); -const char *nm_keyfile_connection_get_filename (NMKeyfileConnection *self); +const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self); G_END_DECLS diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 815650e91..847829ac8 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -67,13 +67,49 @@ typedef struct { gboolean disposed; } SCPluginKeyfilePrivate; +static NMSysconfigConnection * +_internal_new_connection (SCPluginKeyfile *self, + const char *full_path, + NMConnection *source, + const char **out_cid, + GError **error) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + NMSettingConnection *s_con; + const char *cid, *uuid; + NMKeyfileConnection *connection; + + g_return_val_if_fail (full_path != NULL, NULL); + + connection = nm_keyfile_connection_new (full_path, source, error); + if (!connection) + return NULL; + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), + NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + cid = nm_setting_connection_get_id (s_con); + g_assert (cid); + uuid = nm_setting_connection_get_uuid (s_con); + g_assert (uuid); + + g_hash_table_insert (priv->hash, + (gpointer) nm_keyfile_connection_get_path (connection), + connection); + + if (out_cid) + *out_cid = cid; + return NM_SYSCONFIG_CONNECTION (connection); +} + static void read_connections (NMSystemConfigInterface *config) { - SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); GDir *dir; GError *error = NULL; - const char *item; + const char *item, *cid; dir = g_dir_open (KEYFILE_DIR, 0, &error); if (!dir) { @@ -86,62 +122,28 @@ read_connections (NMSystemConfigInterface *config) } while ((item = g_dir_read_name (dir))) { - NMKeyfileConnection *connection; + NMSysconfigConnection *connection; char *full_path; full_path = g_build_filename (KEYFILE_DIR, item, NULL); PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item); - connection = nm_keyfile_connection_new (full_path, &error); + + connection = _internal_new_connection (self, full_path, NULL, &cid, &error); if (connection) { - NMSettingConnection *s_con; - const char *cid; - - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - - cid = nm_setting_connection_get_id (s_con); - g_assert (cid); - - g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_filename (connection), - connection); - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", cid); } else { PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); } + g_clear_error (&error); g_free (full_path); } g_dir_close (dir); } -typedef struct { - const char *uuid; - NMKeyfileConnection *found; -} FindByUUIDInfo; - static void -find_by_uuid (gpointer key, gpointer data, gpointer user_data) +update_connection_settings_commit_cb (NMSysconfigConnection *orig, GError *error, gpointer user_data) { - NMKeyfileConnection *keyfile = NM_KEYFILE_CONNECTION (data); - FindByUUIDInfo *info = user_data; - NMSettingConnection *s_con; - const char *uuid; - - if (info->found) - return; - - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (keyfile), NM_TYPE_SETTING_CONNECTION); - - uuid = s_con ? nm_setting_connection_get_uuid (s_con) : NULL; - if (uuid && !strcmp (info->uuid, uuid)) - info->found = keyfile; -} - -static void -update_connection_settings_commit_cb (NMSysconfigConnection *orig, GError *error, gpointer user_data) { if (error) { g_warning ("%s: '%s' / '%s' invalid: %d", __func__, @@ -180,6 +182,28 @@ remove_connection (SCPluginKeyfile *self, g_object_unref (connection); } +static NMKeyfileConnection * +find_by_uuid (SCPluginKeyfile *self, const char *uuid) +{ + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data = NULL; + + g_return_val_if_fail (uuid != NULL, NULL); + + g_hash_table_iter_init (&iter, priv->hash); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + NMConnection *candidate = NM_CONNECTION (data); + NMSettingConnection *s_con; + + s_con = (NMSettingConnection *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (strcmp (uuid, nm_setting_connection_get_uuid (s_con)) == 0) + return NM_KEYFILE_CONNECTION (candidate); + } + return NULL; +} + static void dir_changed (GFileMonitor *monitor, GFile *file, @@ -188,30 +212,31 @@ dir_changed (GFileMonitor *monitor, gpointer user_data) { NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data); - SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); - char *name; + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + char *full_path; NMKeyfileConnection *connection; GError *error = NULL; - name = g_file_get_path (file); - connection = g_hash_table_lookup (priv->hash, name); + full_path = g_file_get_path (file); + connection = g_hash_table_lookup (priv->hash, full_path); switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: if (connection) { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", name); - remove_connection (SC_PLUGIN_KEYFILE (config), connection, name); + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", full_path); + remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); } break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name); + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); if (connection) { /* Update */ NMKeyfileConnection *tmp; - tmp = nm_keyfile_connection_new (name, &error); + tmp = nm_keyfile_connection_new (full_path, NULL, &error); if (tmp) { update_connection_settings (connection, tmp); g_object_unref (tmp); @@ -220,40 +245,33 @@ dir_changed (GFileMonitor *monitor, PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - remove_connection (SC_PLUGIN_KEYFILE (config), connection, name); + remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); } } else { /* New */ - connection = nm_keyfile_connection_new (name, &error); + connection = nm_keyfile_connection_new (full_path, NULL, &error); if (connection) { - NMSettingConnection *s_con; - const char *connection_uuid; NMKeyfileConnection *found = NULL; + NMSettingConnection *s_con; /* Connection renames will show up as different files but with * the same UUID. Try to find the original connection. */ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); - connection_uuid = s_con ? nm_setting_connection_get_uuid (s_con) : NULL; - - if (connection_uuid) { - FindByUUIDInfo info = { .found = NULL, .uuid = connection_uuid }; - - g_hash_table_foreach (priv->hash, find_by_uuid, &info); - found = info.found; - } + g_assert (s_con); /* A connection rename is treated just like an update except * there's a bit more housekeeping with the hash table. */ + found = find_by_uuid (self, nm_setting_connection_get_uuid (s_con)); if (found) { - const char *old_filename = nm_keyfile_connection_get_filename (connection); + const char *old_path = nm_keyfile_connection_get_path (connection); /* Removing from the hash table should drop the last reference, * but of course we want to keep the connection around. */ g_object_ref (found); - g_hash_table_remove (priv->hash, old_filename); + g_hash_table_remove (priv->hash, old_path); /* Updating settings should update the NMKeyfileConnection's * filename property too. @@ -262,14 +280,14 @@ dir_changed (GFileMonitor *monitor, /* Re-insert the connection back into the hash with the new filename */ g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_filename (found), + (gpointer) nm_keyfile_connection_get_path (found), found); /* Get rid of the temporary connection */ g_object_unref (connection); } else { g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_filename (connection), + (gpointer) nm_keyfile_connection_get_path (connection), connection); g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); } @@ -284,7 +302,7 @@ dir_changed (GFileMonitor *monitor, break; } - g_free (name); + g_free (full_path); } static void @@ -352,38 +370,42 @@ setup_monitoring (NMSystemConfigInterface *config) } } -static void -hash_to_slist (gpointer key, gpointer value, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_prepend (*list, value); -} - /* Plugin */ static GSList * get_connections (NMSystemConfigInterface *config) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (config); - GSList *connections = NULL; + GHashTableIter iter; + gpointer data = NULL; + GSList *list = NULL; if (!priv->hash) { setup_monitoring (config); read_connections (config); } - g_hash_table_foreach (priv->hash, hash_to_slist, &connections); - - return connections; + g_hash_table_iter_init (&iter, priv->hash); + while (g_hash_table_iter_next (&iter, NULL, &data)) + list = g_slist_prepend (list, data); + return list; } -static gboolean +static NMSysconfigConnection * add_connection (NMSystemConfigInterface *config, NMConnection *connection, GError **error) { - return write_connection (connection, KEYFILE_DIR, 0, 0, NULL, error); + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + NMSysconfigConnection *added = NULL; + char *path = NULL; + + /* Write it out first, then add the connection to our internal list */ + if (write_connection (connection, KEYFILE_DIR, 0, 0, &path, error)) { + added = _internal_new_connection (self, path, connection, NULL, error); + g_free (path); + } + return added; } static GSList * From c2ca4298fab719c11a32115564cc395c0d48efa9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 16:58:07 -0500 Subject: [PATCH 069/264] ifcfg-rh: ensure connection is still alive for the removal signal --- system-settings/plugins/ifcfg-rh/plugin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 9e52b35df..4ef5bd6a1 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -219,8 +219,10 @@ remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) managed = !!nm_ifcfg_connection_get_unmanaged_spec (connection); path = nm_ifcfg_connection_get_path (connection); + g_object_ref (connection); g_hash_table_remove (priv->connections, path); g_signal_emit_by_name (connection, NM_SYSCONFIG_CONNECTION_REMOVED); + g_object_unref (connection); /* Emit unmanaged changes _after_ removing the connection */ if (managed == FALSE) From 9d725be3a97cd8f2ea00637712f61b1790c50add Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 22:05:23 -0500 Subject: [PATCH 070/264] settings: fix signature of connection updated handler --- src/settings/nm-settings.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 3b1653995..10e591bd9 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -608,6 +608,8 @@ connection_removed (NMSysconfigConnection *obj, gpointer user_data) dbus_g_connection_unregister_g_object (priv->bus, connection); g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, (gpointer) nm_connection_get_path (NM_CONNECTION (connection))); + + /* Re-emit for listeners like NMPolicy */ g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, @@ -617,8 +619,11 @@ connection_removed (NMSysconfigConnection *obj, gpointer user_data) } static void -connection_updated (NMSysconfigConnection *connection, gpointer user_data) +connection_updated (NMSysconfigConnection *connection, + GHashTable *settings, + gpointer user_data) { + /* Re-emit for listeners like NMPolicy */ g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_UPDATED], 0, @@ -630,6 +635,7 @@ connection_visibility_changed (NMSysconfigConnection *connection, GParamSpec *pspec, gpointer user_data) { + /* Re-emit for listeners like NMPolicy */ g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_VISIBILITY_CHANGED], 0, From 85db10a13f0bc7587428db7ec5a2852916c6999f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 22:10:32 -0500 Subject: [PATCH 071/264] settings: fix connection addition Need to make sure we actually export the connection over D-Bus (via claim_connection()) before we try to return its object path in the AddConnection reply. Second, we need to send the path as a string in the reply, not an object, since the return type is an object path. --- src/settings/nm-settings.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 10e591bd9..c214874db 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -792,7 +792,7 @@ add_new_connection (NMSettings *self, GError **error) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GError *tmp_error = NULL, *last_error = NULL; + GError *add_error = NULL; GSList *iter; NMSysconfigConnection *added = NULL; @@ -804,18 +804,18 @@ add_new_connection (NMSettings *self, * 5) plugin reads the changes and ignores them because they will * contain the same data as the connection it already knows about */ - for (iter = priv->plugins; iter && !added; iter = g_slist_next (iter)) { - added = nm_system_config_interface_add_connection (NM_SYSTEM_CONFIG_INTERFACE (iter->data), - connection, - &tmp_error); - g_clear_error (&last_error); - if (!added) - g_propagate_error (&last_error, tmp_error); - } + for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { + NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); - if (!added) - g_propagate_error (error, last_error); - return added; + g_clear_error (error); + added = nm_system_config_interface_add_connection (plugin, connection, &add_error); + if (added) { + claim_connection (self, added, TRUE); + return added; + } + g_propagate_error (error, add_error); + } + return NULL; } static void @@ -826,7 +826,7 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) NMSettingsPrivate *priv; PolkitAuthorizationResult *pk_result; GError *error = NULL, *add_error = NULL; - NMSysconfigConnection *added_connection; + NMSysconfigConnection *added; /* If NMSettings is already gone, do nothing */ if (call->disposed) { @@ -861,9 +861,9 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) goto out; } - added_connection = add_new_connection (self, call->connection, &add_error); - if (added_connection) - dbus_g_method_return (call->context, added_connection); + added = add_new_connection (self, call->connection, &add_error); + if (added) + dbus_g_method_return (call->context, nm_connection_get_path (NM_CONNECTION (added))); else { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_ADD_FAILED, From 947efa3080d5a1bb2f6905615cd1a211bd1f6922 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 22:31:23 -0500 Subject: [PATCH 072/264] libnm-util: verify permissions property type Connections are normally created from hashes using g_object_set() which calls that object's set_property handler. But GObject does not allow errors to be returned from property handlers, so if the type doesn't match what it should be, the property does not get set, and error is printed to stdout, and life goes on. But that's not what we want for the permissions property since the client might expect that property to be set, but the connection now is available to everyone. So validate the permissions property type (its really the only one we need to be so paranoid about) and return an error when the incoming property type is wrong. --- libnm-util/nm-connection.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 820ef3aa0..ffcda5ded 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -29,6 +29,7 @@ #include "nm-connection.h" #include "nm-utils.h" #include "nm-utils-private.h" +#include "nm-dbus-glib-types.h" #include "nm-setting-8021x.h" #include "nm-setting-bluetooth.h" @@ -456,6 +457,32 @@ nm_connection_get_setting_by_name (NMConnection *connection, const char *name) return type ? nm_connection_get_setting (connection, type) : NULL; } +static gboolean +validate_permissions_type (GHashTable *hash, GError **error) +{ + GHashTable *s_con; + GValue *permissions; + + /* Ensure the connection::permissions item (if present) is the correct + * type, otherwise the g_object_set() will throw a warning and ignore the + * error, leaving us with no permissions. + */ + s_con = g_hash_table_lookup (hash, NM_SETTING_CONNECTION_SETTING_NAME); + if (s_con) { + permissions = g_hash_table_lookup (s_con, NM_SETTING_CONNECTION_PERMISSIONS); + if (permissions) { + if (!G_VALUE_HOLDS (permissions, DBUS_TYPE_G_LIST_OF_STRING)) { + g_set_error_literal (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Wrong permissions property type; should be a list of strings."); + return FALSE; + } + } + } + return TRUE; +} + /** * nm_connection_replace_settings: * @connection: a #NMConnection @@ -476,6 +503,9 @@ nm_connection_replace_settings (NMConnection *connection, if (error) g_return_val_if_fail (*error == NULL, FALSE); + if (!validate_permissions_type (new_settings, error)) + return FALSE; + g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings); g_hash_table_foreach (new_settings, parse_one_setting, connection); @@ -974,6 +1004,9 @@ nm_connection_new_from_hash (GHashTable *hash, GError **error) g_return_val_if_fail (hash != NULL, NULL); + if (!validate_permissions_type (hash, error)) + return FALSE; + connection = nm_connection_new (); g_hash_table_foreach (hash, parse_one_setting, connection); From 453ea4d5c78c58a7b9a135643bd24627a9ca8127 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 23:13:57 -0500 Subject: [PATCH 073/264] settings: make sure we use a clear error every time --- src/settings/nm-settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index c214874db..f5f5806f0 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -792,7 +792,6 @@ add_new_connection (NMSettings *self, GError **error) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GError *add_error = NULL; GSList *iter; NMSysconfigConnection *added = NULL; @@ -806,6 +805,7 @@ add_new_connection (NMSettings *self, */ for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data); + GError *add_error = NULL; g_clear_error (error); added = nm_system_config_interface_add_connection (plugin, connection, &add_error); From 034aee641a9732688c78dda178547ba1588ed5fb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 23:14:42 -0500 Subject: [PATCH 074/264] ifcfg-rh: fix possible warning 'added' won't always be valid, and thus the GObject typecast could fail. Use a C typecast instead. --- system-settings/plugins/ifcfg-rh/plugin.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 4ef5bd6a1..0c01f153a 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -445,8 +445,7 @@ add_connection (NMSystemConfigInterface *config, added = _internal_new_connection (self, path, connection, error); g_free (path); } - return NM_SYSCONFIG_CONNECTION (added); - + return (NMSysconfigConnection *) added; } #define SC_NETWORK_FILE SYSCONFDIR"/sysconfig/network" From d3e640eacfd4462da06d76798f62b7fe1228d366 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 23:15:38 -0500 Subject: [PATCH 075/264] ifcfg-rh: propagate errors from updating new connection settings --- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index d43ab103f..218054c1c 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -130,14 +130,15 @@ nm_ifcfg_connection_new (const char *full_path, object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION, NM_IFCFG_CONNECTION_UNMANAGED, unmanaged, NULL); - if (!object) { - g_object_unref (tmp); - return NULL; - } + if (!object) + goto out; /* Update our settings with what was read from the file */ - nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); - g_object_unref (tmp); + if (!nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, error)) { + g_object_unref (object); + object = NULL; + goto out; + } priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object); priv->path = g_strdup (full_path); @@ -156,7 +157,9 @@ nm_ifcfg_connection_new (const char *full_path, priv->route6file = route6file; priv->route6file_wd = nm_inotify_helper_add_watch (ih, route6file); - return NM_IFCFG_CONNECTION (object); +out: + g_object_unref (tmp); + return (NMIfcfgConnection *) object; } const char * @@ -254,7 +257,8 @@ finalize (GObject *object) ih = nm_inotify_helper_get (); - g_signal_handler_disconnect (ih, priv->ih_event_id); + if (priv->ih_event_id) + g_signal_handler_disconnect (ih, priv->ih_event_id); g_free (priv->path); if (priv->file_wd >= 0) From b93cad014949ab6baa60416e9365d941e2a15fc3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 23:16:04 -0500 Subject: [PATCH 076/264] keyfile: propagate errors from updating new connection settings --- .../plugins/keyfile/nm-keyfile-connection.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 99d6888c2..d19b709d9 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -62,17 +62,18 @@ nm_keyfile_connection_new (const char *full_path, } object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL); - if (!object) { - g_object_unref (tmp); - return NULL; - } + if (!object) + goto out; priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); priv->path = g_strdup (full_path); /* Update our settings with what was read from the file */ - nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); - g_object_unref (tmp); + if (!nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, error)) { + g_object_unref (object); + object = NULL; + goto out; + } /* if for some reason the connection didn't have a UUID, add one */ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (object), NM_TYPE_SETTING_CONNECTION); @@ -94,7 +95,9 @@ nm_keyfile_connection_new (const char *full_path, } } - return NM_KEYFILE_CONNECTION (object); +out: + g_object_unref (tmp); + return (NMKeyfileConnection *) object; } const char * From 8f699a77f2e4d825aa73c9c794637cf504a3e9b2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 29 Oct 2010 23:19:41 -0500 Subject: [PATCH 077/264] libnm-util: check all valid permissions property types --- libnm-util/nm-connection.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index ffcda5ded..105dcbe14 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -471,7 +471,8 @@ validate_permissions_type (GHashTable *hash, GError **error) if (s_con) { permissions = g_hash_table_lookup (s_con, NM_SETTING_CONNECTION_PERMISSIONS); if (permissions) { - if (!G_VALUE_HOLDS (permissions, DBUS_TYPE_G_LIST_OF_STRING)) { + if ( !G_VALUE_HOLDS (permissions, G_TYPE_STRV) + && !G_VALUE_HOLDS (permissions, DBUS_TYPE_G_LIST_OF_STRING)) { g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, From 3391a0035424fcac3fa67008b70b9e45ed96f5a2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 16 Nov 2010 18:23:27 -0600 Subject: [PATCH 078/264] core: fix up merge damage --- src/nm-manager.c | 12 +++--------- system-settings/plugins/ifcfg-rh/plugin.c | 4 ++-- system-settings/plugins/keyfile/plugin.c | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 2459e6db4..a32973b4f 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -438,7 +438,7 @@ nm_manager_update_state (NMManager *manager) } static void -ignore_cb (NMSettingsConnectionInterface *connection, GError *error, gpointer user_data) +ignore_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) { } @@ -448,7 +448,6 @@ update_active_connection_timestamp (NMManager *manager, NMDevice *device) NMActRequest *req; NMConnection *connection; NMSettingConnection *s_con; - NMSettingsConnectionInterface *connection_interface; NMManagerPrivate *priv; g_return_if_fail (NM_IS_DEVICE (device)); @@ -461,19 +460,14 @@ update_active_connection_timestamp (NMManager *manager, NMDevice *device) connection = nm_act_request_get_connection (req); g_assert (connection); - if (nm_connection_get_scope (connection) != NM_CONNECTION_SCOPE_SYSTEM) - return; - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION)); + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), NULL); if (nm_setting_connection_get_read_only (s_con)) return; - connection_interface = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (priv->sys_settings), - nm_connection_get_path (connection)); - nm_settings_connection_interface_update (connection_interface, ignore_cb, NULL); + nm_sysconfig_connection_commit_changes (NM_SYSCONFIG_CONNECTION (connection), ignore_cb, NULL); } static void diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 9853987cc..8ebe19649 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -272,7 +272,7 @@ connection_new_or_changed (SCPluginIfcfg *self, /* Successfully read connection changes */ /* When the connections are the same, nothing is done */ - if (nm_connection_compare (NM_CONNECTION (connection), + if (nm_connection_compare (NM_CONNECTION (existing), NM_CONNECTION (new), NM_SETTING_COMPARE_FLAG_EXACT)) { g_object_unref (new); @@ -281,7 +281,7 @@ connection_new_or_changed (SCPluginIfcfg *self, PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "updating %s", path); - old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (connection)); + old_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (existing)); new_unmanaged = nm_ifcfg_connection_get_unmanaged_spec (NM_IFCFG_CONNECTION (new)); if (new_unmanaged) { diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index cf0993bbe..5dddf494b 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -248,7 +248,7 @@ dir_changed (GFileMonitor *monitor, if (!nm_connection_compare (NM_CONNECTION (connection), NM_CONNECTION (tmp), NM_SETTING_COMPARE_FLAG_EXACT)) { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name); + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); update_connection_settings (connection, tmp); } g_object_unref (tmp); @@ -260,7 +260,7 @@ dir_changed (GFileMonitor *monitor, remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); } } else { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", name); + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); /* New */ connection = nm_keyfile_connection_new (full_path, NULL, &error); From 10643979047c4dfc8654fc8de320095a6f96418e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 16:56:34 -0600 Subject: [PATCH 079/264] core: add helper to access authentication result --- src/nm-manager-auth.c | 9 +++++++++ src/nm-manager-auth.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index e6d4778a4..c10b1b1db 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -165,6 +165,15 @@ nm_auth_chain_set_data (NMAuthChain *self, } } +NMAuthCallResult +nm_auth_chain_get_result (NMAuthChain *self, const char *permission) +{ + g_return_val_if_fail (self != NULL, NM_AUTH_CALL_RESULT_UNKNOWN); + g_return_val_if_fail (permission != NULL, NM_AUTH_CALL_RESULT_UNKNOWN); + + return GPOINTER_TO_UINT (nm_auth_chain_get_data (self, permission)); +} + static void nm_auth_chain_check_done (NMAuthChain *self) { diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 9fae64c5f..a03bf6248 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -76,6 +76,9 @@ void nm_auth_chain_set_data (NMAuthChain *chain, gpointer data, GDestroyNotify data_destroy); +NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *chain, + const char *permission); + gboolean nm_auth_chain_add_call (NMAuthChain *chain, const char *permission, gboolean allow_interaction); From 98dab62d925fd77e72b4616763785655e75462ab Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 17:02:21 -0600 Subject: [PATCH 080/264] core: simplify device disconnect flow --- src/nm-manager.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index a32973b4f..301cd8792 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1192,34 +1192,32 @@ deactivate_disconnect_check_error (GError *auth_error, static void disconnect_net_auth_done_cb (NMAuthChain *chain, - GError *error, + GError *auth_error, DBusGMethodInvocation *context, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GError *ret_error = NULL; + GError *error = NULL; NMAuthCallResult result; NMDevice *device; priv->auth_chains = g_slist_remove (priv->auth_chains, chain); result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL)); - ret_error = deactivate_disconnect_check_error (error, result, "Disconnect"); - if (ret_error) { - dbus_g_method_return_error (context, ret_error); - g_error_free (ret_error); - goto done; + error = deactivate_disconnect_check_error (auth_error, result, "Disconnect"); + if (!error) { + device = nm_auth_chain_get_data (chain, "device"); + if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &error)) + g_assert (error); } - device = nm_auth_chain_get_data (chain, "device"); - if (!nm_device_interface_disconnect (NM_DEVICE_INTERFACE (device), &ret_error)) { - dbus_g_method_return_error (context, ret_error); - g_clear_error (&ret_error); - } else + if (error) + dbus_g_method_return_error (context, error); + else dbus_g_method_return (context); -done: + g_clear_error (&error); nm_auth_chain_unref (chain); } From 3de9332f094a260d3434626c039dcbc79744953d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 17:33:00 -0600 Subject: [PATCH 081/264] trivial: be a bit more paranoid about re-exporting connections --- src/settings/nm-settings.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index f5f5806f0..f37b14b0d 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -656,6 +656,7 @@ claim_connection (NMSettings *self, guint id; g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) { From 02d942320d8dfe2a51046ff6861e7ec8fb5b2d9e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 17:42:22 -0600 Subject: [PATCH 082/264] core: fix nm_settings_get_connections() result confusion It used to reference items in the list, but no longer does because that's stupid. Fixes some merge damage and a leak. --- src/nm-manager.c | 25 ++++++++++--------------- src/nm-policy.c | 9 +++------ src/settings/nm-settings.c | 6 +++--- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 301cd8792..740a9a5b0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -992,32 +992,27 @@ manager_hidden_ap_found (NMDeviceInterface *device, s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); if (!s_wireless) - goto next; + continue; num_bssids = nm_setting_wireless_get_num_seen_bssids (s_wireless); if (num_bssids < 1) - goto next; + continue; ssid = nm_setting_wireless_get_ssid (s_wireless); g_assert (ssid); - for (i = 0; i < num_bssids; i++) { + for (i = 0; i < num_bssids && !done; i++) { const char *seen_bssid = nm_setting_wireless_get_seen_bssid (s_wireless, i); struct ether_addr seen_addr; - if (!ether_aton_r (seen_bssid, &seen_addr)) - continue; - - if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr))) - continue; - - /* Copy the SSID from the connection to the AP */ - nm_ap_set_ssid (ap, ssid); - done = TRUE; + if (ether_aton_r (seen_bssid, &seen_addr)) { + if (memcmp (ap_addr, &seen_addr, sizeof (struct ether_addr))) { + /* Copy the SSID from the connection to the AP */ + nm_ap_set_ssid (ap, ssid); + done = TRUE; + } + } } - -next: - g_object_unref (connection); } g_slist_free (connections); } diff --git a/src/nm-policy.c b/src/nm-policy.c index 4f525459f..6bad928cf 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -767,11 +767,9 @@ auto_activate_device (gpointer user_data) if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) { guint retries = get_connection_auto_retries (iter_connection); - if (retries == 0) { - connections = g_slist_remove_link (connections, iter); - g_object_unref (iter_connection); - g_slist_free (iter); - } else if (retries > 0) + if (retries == 0) + connections = g_slist_remove (connections, iter_connection); + else if (retries > 0) set_connection_auto_retries (iter_connection, retries - 1); } else { /* Set the initial # of retries for auto-connection */ @@ -802,7 +800,6 @@ auto_activate_device (gpointer user_data) } } - g_slist_foreach (connections, (GFunc) g_object_unref, NULL); g_slist_free (connections); out: diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index f37b14b0d..8454eb5bb 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -240,8 +240,8 @@ connection_sort (gconstpointer pa, gconstpointer pb) return 1; } -/* Returns a GSList of referenced NMConnection objects, caller must - * unref the connections in the list and destroy the list. +/* Returns a list of NMSysconfigConnections. Caller must free the list with + * g_slist_free(). */ GSList * nm_settings_get_connections (NMSettings *self) @@ -255,7 +255,7 @@ nm_settings_get_connections (NMSettings *self) g_hash_table_iter_init (&iter, NM_SETTINGS_GET_PRIVATE (self)->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) list = g_slist_insert_sorted (list, data, connection_sort); - return g_slist_reverse (list); + return list; } NMSysconfigConnection * From 670da10764bfac54a94b2250558aa4dc19ab333a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 17:44:33 -0600 Subject: [PATCH 083/264] settings: port SaveHostname to NMAuthChain Every line of code we remove can then be spent on rainbows and kittens. --- src/settings/nm-settings.c | 93 ++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 8454eb5bb..93bdf1d13 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -107,6 +107,7 @@ typedef struct { char *config_file; GSList *pk_calls; + GSList *auths; GSList *plugins; gboolean connections_loaded; @@ -926,74 +927,67 @@ impl_settings_add_connection (NMSettings *self, } static void -pk_hostname_cb (GObject *object, GAsyncResult *result, gpointer user_data) +pk_hostname_cb (NMAuthChain *chain, + GError *chain_error, + DBusGMethodInvocation *context, + gpointer user_data) { - PolkitCall *call = user_data; - NMSettings *self = call->self; - NMSettingsPrivate *priv; - PolkitAuthorizationResult *pk_result; + NMSettings *self = NM_SETTINGS (user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMAuthCallResult result; + gboolean success = FALSE; GError *error = NULL; GSList *iter; - gboolean success = FALSE; + const char *hostname; + + priv->auths = g_slist_remove (priv->auths, chain); /* If our NMSysconfigConnection is already gone, do nothing */ - if (call->disposed) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; + if (chain_error) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, + "Error checking authorization: %s", + chain_error->message ? chain_error->message : "(unknown)"); + goto done; } - priv = NM_SETTINGS_GET_PRIVATE (self); - - priv->pk_calls = g_slist_remove (priv->pk_calls, call); - - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - /* Some random error happened */ - if (error) { - dbus_g_method_return_error (call->context, error); - goto out; - } + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); /* Caller didn't successfully authenticate */ - if (!polkit_authorization_result_get_is_authorized (pk_result)) { + if ( result != NM_AUTH_CALL_RESULT_YES + && result != NM_AUTH_CALL_RESULT_AUTH) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); - dbus_g_method_return_error (call->context, error); - goto out; + goto done; } /* Set the hostname in all plugins */ + hostname = nm_auth_chain_get_data (chain, "hostname"); for (iter = priv->plugins; iter; iter = iter->next) { NMSystemConfigInterfaceCapabilities caps = NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE; g_object_get (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_CAPABILITIES, &caps, NULL); if (caps & NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME) { - g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, call->hostname, NULL); + g_object_set (G_OBJECT (iter->data), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME, hostname, NULL); success = TRUE; } } - if (success) { - dbus_g_method_return (call->context); - } else { + if (!success) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "Saving the hostname failed."); - dbus_g_method_return_error (call->context, error); } -out: +done: + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); + g_clear_error (&error); - polkit_call_free (call); - if (pk_result) - g_object_unref (pk_result); + nm_auth_chain_unref (chain); } static void @@ -1002,7 +996,7 @@ impl_settings_save_hostname (NMSettings *self, DBusGMethodInvocation *context) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - PolkitCall *call; + NMAuthChain *chain; GError *error = NULL; /* Do any of the plugins support setting the hostname? */ @@ -1015,17 +1009,12 @@ impl_settings_save_hostname (NMSettings *self, return; } - call = polkit_call_new (self, context, NULL, hostname); - g_assert (call); - polkit_authority_check_authorization (priv->authority, - call->subject, - NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - call->cancellable, - pk_hostname_cb, - call); - priv->pk_calls = g_slist_append (priv->pk_calls, call); + /* Otherwise validate the user request */ + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self); + g_assert (chain); + priv->auths = g_slist_append (priv->auths, chain); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, TRUE); + nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free); } static gboolean @@ -1403,6 +1392,10 @@ dispose (GObject *object) g_slist_free (priv->pk_calls); priv->pk_calls = NULL; + for (iter = priv->auths; iter; iter = g_slist_next (iter)) + nm_auth_chain_unref ((NMAuthChain *) iter->data); + g_slist_free (priv->auths); + g_object_unref (priv->dbus_mgr); G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); From 1bbc62447745e5b2f67b0dd6b0160c57ed5e72cd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 17:53:37 -0600 Subject: [PATCH 084/264] settings: port AddConnection to NMAuthChain More code saved. Yay. --- src/settings/nm-settings.c | 150 +++++++++---------------------------- 1 file changed, 35 insertions(+), 115 deletions(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 93bdf1d13..970c2b6f9 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -106,7 +106,6 @@ typedef struct { guint auth_changed_id; char *config_file; - GSList *pk_calls; GSList *auths; GSList *plugins; @@ -734,60 +733,6 @@ remove_default_wired_connection (NMSettings *self, } } -typedef struct { - NMSettings *self; - DBusGMethodInvocation *context; - PolkitSubject *subject; - GCancellable *cancellable; - gboolean disposed; - - NMConnection *connection; - gpointer callback_data; - - char *hostname; -} PolkitCall; - -#include "nm-dbus-manager.h" - -static PolkitCall * -polkit_call_new (NMSettings *self, - DBusGMethodInvocation *context, - NMConnection *connection, - const char *hostname) -{ - PolkitCall *call; - char *sender; - - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (context != NULL, NULL); - - call = g_malloc0 (sizeof (PolkitCall)); - call->self = self; - call->cancellable = g_cancellable_new (); - call->context = context; - if (connection) - call->connection = g_object_ref (connection); - if (hostname) - call->hostname = g_strdup (hostname); - - sender = dbus_g_method_get_sender (context); - call->subject = polkit_system_bus_name_new (sender); - g_free (sender); - - return call; -} - -static void -polkit_call_free (PolkitCall *call) -{ - if (call->connection) - g_object_unref (call->connection); - g_object_unref (call->cancellable); - g_free (call->hostname); - g_object_unref (call->subject); - g_free (call); -} - static NMSysconfigConnection * add_new_connection (NMSettings *self, NMConnection *connection, @@ -821,51 +766,43 @@ add_new_connection (NMSettings *self, } static void -pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) +pk_add_cb (NMAuthChain *chain, + GError *chain_error, + DBusGMethodInvocation *context, + gpointer user_data) { - PolkitCall *call = user_data; - NMSettings *self = call->self; - NMSettingsPrivate *priv; - PolkitAuthorizationResult *pk_result; + NMSettings *self = NM_SETTINGS (user_data); + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMAuthCallResult result; GError *error = NULL, *add_error = NULL; + NMConnection *connection; NMSysconfigConnection *added; - /* If NMSettings is already gone, do nothing */ - if (call->disposed) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - dbus_g_method_return_error (call->context, error); - g_error_free (error); - polkit_call_free (call); - return; + priv->auths = g_slist_remove (priv->auths, chain); + + /* If our NMSysconfigConnection is already gone, do nothing */ + if (chain_error) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, + "Error checking authorization: %s", + chain_error->message ? chain_error->message : "(unknown)"); + goto done; } - priv = NM_SETTINGS_GET_PRIVATE (self); - - priv->pk_calls = g_slist_remove (priv->pk_calls, call); - - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - /* Some random error happened */ - if (error) { - dbus_g_method_return_error (call->context, error); - goto out; - } + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); /* Caller didn't successfully authenticate */ - if (!polkit_authorization_result_get_is_authorized (pk_result)) { + if (result != NM_AUTH_CALL_RESULT_YES) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); - dbus_g_method_return_error (call->context, error); - goto out; + goto done; } - added = add_new_connection (self, call->connection, &add_error); + connection = nm_auth_chain_get_data (chain, "connection"); + added = add_new_connection (self, connection, &add_error); if (added) - dbus_g_method_return (call->context, nm_connection_get_path (NM_CONNECTION (added))); + dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (added))); else { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_ADD_FAILED, @@ -873,14 +810,14 @@ pk_add_cb (GObject *object, GAsyncResult *result, gpointer user_data) add_error ? add_error->code : -1, (add_error && add_error->message) ? add_error->message : "(unknown)"); g_error_free (add_error); - dbus_g_method_return_error (call->context, error); } -out: +done: + if (error) + dbus_g_method_return_error (context, error); + g_clear_error (&error); - polkit_call_free (call); - if (pk_result) - g_object_unref (pk_result); + nm_auth_chain_unref (chain); } static void @@ -889,7 +826,7 @@ impl_settings_add_connection (NMSettings *self, DBusGMethodInvocation *context) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - PolkitCall *call; + NMAuthChain *chain; NMConnection *connection; GError *error = NULL; @@ -911,19 +848,12 @@ impl_settings_add_connection (NMSettings *self, return; } - call = polkit_call_new (self, context, connection, NULL); - g_assert (call); - polkit_authority_check_authorization (priv->authority, - call->subject, - NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - call->cancellable, - pk_add_cb, - call); - priv->pk_calls = g_slist_append (priv->pk_calls, call); - - g_object_unref (connection); + /* Otherwise validate the user request */ + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self); + g_assert (chain); + priv->auths = g_slist_append (priv->auths, chain); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + nm_auth_chain_set_data (chain, "connection", connection, g_object_unref); } static void @@ -1382,16 +1312,6 @@ dispose (GObject *object) priv->auth_changed_id = 0; } - /* Cancel PolicyKit requests */ - for (iter = priv->pk_calls; iter; iter = g_slist_next (iter)) { - PolkitCall *call = iter->data; - - call->disposed = TRUE; - g_cancellable_cancel (call->cancellable); - } - g_slist_free (priv->pk_calls); - priv->pk_calls = NULL; - for (iter = priv->auths; iter; iter = g_slist_next (iter)) nm_auth_chain_unref ((NMAuthChain *) iter->data); g_slist_free (priv->auths); From c0f5872b5a6573e968698649aeb983e072c89972 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Nov 2010 17:54:04 -0600 Subject: [PATCH 085/264] settings: don't accept possible auth as success for saving hostname Since user interaction is allowed when the permission for SaveHostname is requested, if the user didn't authorize completely when polkit returns, we don't want to proceed with the request. Otherwise we might get into a situation where it's possible for the user to authorize, but they didn't, and previously the code would allow the request. --- src/settings/nm-settings.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 970c2b6f9..d3ceba05b 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -884,8 +884,7 @@ pk_hostname_cb (NMAuthChain *chain, result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); /* Caller didn't successfully authenticate */ - if ( result != NM_AUTH_CALL_RESULT_YES - && result != NM_AUTH_CALL_RESULT_AUTH) { + if (result != NM_AUTH_CALL_RESULT_YES) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Insufficient privileges."); From ca063e4d0ccbd262b9e44294e26b35c24fbb8c75 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 10:36:18 -0600 Subject: [PATCH 086/264] libnm-util: add nm_setting_connection_permissions_has_user() Utility function to determine whether a given username is in the ACL. --- libnm-util/libnm-util.ver | 1 + libnm-util/nm-setting-connection.c | 74 ++++++++++++++++++++++++++ libnm-util/nm-setting-connection.h | 1 + src/settings/nm-sysconfig-connection.c | 19 +------ 4 files changed, 78 insertions(+), 17 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 8f5ddbe74..3196ebc66 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -115,6 +115,7 @@ global: nm_setting_connection_get_read_only; nm_setting_connection_get_num_permissions; nm_setting_connection_get_permission; + nm_setting_connection_permissions_has_user; nm_setting_duplicate; nm_setting_enumerate_values; nm_setting_error_get_type; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 644ed59ca..79bd73f00 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -211,6 +211,80 @@ nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 i) return (const char *) g_slist_nth_data (priv->permissions, i); } +#define USER_TAG "user:" + +/* Extract the username from the permission string and dump to a buffer */ +static gboolean +perm_to_user (const char *perm, char *out_user, gsize out_user_size) +{ + const char *end; + gsize userlen; + + g_return_val_if_fail (perm != NULL, FALSE); + g_return_val_if_fail (out_user != NULL, FALSE); + + if (!g_str_has_prefix (perm, USER_TAG)) + return FALSE; + perm += strlen (USER_TAG); + + /* Look for trailing ':' */ + end = strchr (perm, ':'); + if (!end) + end = perm + strlen (perm); + + userlen = end - perm; + if (userlen > (out_user_size + 1)) + return FALSE; + memcpy (out_user, perm, userlen); + out_user[userlen] = '\0'; + return TRUE; +} + +/** + * nm_setting_connection_permissions_user_allowed: + * @setting: the #NMSettingConnection + * @uname: the user name to check permissions for + * + * Checks whether the given username is allowed to view/access this connection. + * + * Returns: %TRUE if the requested user is allowed to view this connection, + * %FALSE if the given user is not allowed to view this connection + */ +gboolean +nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, + const char *uname) +{ + NMSettingConnectionPrivate *priv; + guint32 num, i; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (uname != NULL, FALSE); + g_return_val_if_fail (*uname != '\0', FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + /* Match the username returned by the session check to a user in the ACL */ + num = nm_setting_connection_get_num_permissions (setting); + if (num == 0) + return TRUE; /* visible to all */ + + for (i = 0; i < num; i++) { + const char *perm; + char buf[75]; + + perm = nm_setting_connection_get_permission (setting, i); + g_assert (perm); + if (perm_to_user (perm, buf, sizeof (buf))) { + if (strcmp (buf, uname) == 0) { + /* Yay, permitted */ + return TRUE; + } + } + } + + return FALSE; +} + /** * nm_setting_connection_get_autoconnect: * @setting: the #NMSettingConnection diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 49dacb0b3..e62263c2d 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -107,6 +107,7 @@ guint64 nm_setting_connection_get_timestamp (NMSettingConnection *set gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); const char *nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 index); +gboolean nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname); /* FIXME: need add/remove calls for permissions */ diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index a1da54e49..a926953ec 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -151,23 +151,8 @@ uid_in_acl (NMConnection *self, } /* Match the username returned by the session check to a user in the ACL */ - num = nm_setting_connection_get_num_permissions (s_con); - if (num == 0) - return TRUE; /* visible to all */ - - for (i = 0; i < num; i++) { - const char *perm; - char buf[75]; - - perm = nm_setting_connection_get_permission (s_con, i); - g_assert (perm); - if (perm_to_user (perm, buf, sizeof (buf))) { - if (strcmp (buf, user) == 0) { - /* Yay, permitted */ - return TRUE; - } - } - } + if (nm_setting_connection_permissions_user_allowed (s_con, user)) + return TRUE; g_set_error (error, NM_SETTINGS_ERROR, From 9db44c42eef025b9b2eb771ac73f4e3b1773af49 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 10:55:21 -0600 Subject: [PATCH 087/264] settings: remove unused variables --- src/settings/nm-sysconfig-connection.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index a926953ec..f1d8a9c7e 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -119,7 +119,6 @@ uid_in_acl (NMConnection *self, GError **error) { NMSettingConnection *s_con; - guint32 num, i; const char *user = NULL; GError *local = NULL; From 09a6f45ead4353ef033a9d6d79ea4b4d2966dda9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 12:29:50 -0600 Subject: [PATCH 088/264] libnm-util: fix symbol visibility of nm_setting_connection_permissions_user_allowed --- libnm-util/libnm-util.ver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 3196ebc66..8eaaad6b2 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -115,7 +115,7 @@ global: nm_setting_connection_get_read_only; nm_setting_connection_get_num_permissions; nm_setting_connection_get_permission; - nm_setting_connection_permissions_has_user; + nm_setting_connection_permissions_user_allowed; nm_setting_duplicate; nm_setting_enumerate_values; nm_setting_error_get_type; From fe3002d9f1f300d839cfa8bd560bae64af2bd592 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 12:40:38 -0600 Subject: [PATCH 089/264] settings: fix permission checking during add --- src/settings/nm-settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index d3ceba05b..bb93cf724 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -789,7 +789,7 @@ pk_add_cb (NMAuthChain *chain, goto done; } - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { From 64c817ddccc72d43d82e5e0e70ccbf322ac14e11 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 12:51:35 -0600 Subject: [PATCH 090/264] test: add hostname test helper --- test/set-hostname.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 test/set-hostname.py diff --git a/test/set-hostname.py b/test/set-hostname.py new file mode 100755 index 000000000..4c8995d25 --- /dev/null +++ b/test/set-hostname.py @@ -0,0 +1,27 @@ +#!/bin/env python +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2010 Red Hat, Inc. +# + +import dbus +import sys + +bus = dbus.SystemBus() +proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Settings") +settings = dbus.Interface(proxy, "org.freedesktop.NetworkManager.Settings") +settings.SaveHostname(sys.argv[1]) + From ac2438518dec18024aa0efb9a1bbebc1fe84391e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 12:53:24 -0600 Subject: [PATCH 091/264] settings: don't allow addition of invisible connections Ensure that only connections which are visible to the user adding the connection may be added. --- src/settings/nm-settings.c | 77 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index bb93cf724..622e8ee98 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -765,6 +766,35 @@ add_new_connection (NMSettings *self, return NULL; } +static char * +get_user_name (gulong uid) +{ + struct passwd pwd; + struct passwd *result; + char *buf, *uname = NULL; + size_t bufsize; + int s; + + bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); + if (bufsize == -1) + bufsize = 16384; /* adequate fallback */ + + buf = g_malloc0 (bufsize); + g_assert (buf); + + s = getpwuid_r (uid, &pwd, buf, bufsize, &result); + if (result) + uname = g_strdup (pwd.pw_name); + else if (s == 0) { + nm_log_dbg (LOGD_SYS_SET, "Lookup failed for UID %lu: not found", uid); + } else { + nm_log_dbg (LOGD_SYS_SET, "Lookup failed for UID %lu: %d", uid, s); + } + + g_free (buf); + return uname; +} + static void pk_add_cb (NMAuthChain *chain, GError *chain_error, @@ -777,6 +807,8 @@ pk_add_cb (NMAuthChain *chain, GError *error = NULL, *add_error = NULL; NMConnection *connection; NMSysconfigConnection *added; + gulong caller_uid = G_MAXULONG; + const char *error_desc = NULL; priv->auths = g_slist_remove (priv->auths, chain); @@ -799,7 +831,52 @@ pk_add_cb (NMAuthChain *chain, goto done; } + /* If the caller isn't root, make sure the connection can be viewed by + * the user that's adding it. + */ + if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Unable to determine UID of request: %s.", + error_desc ? error_desc : "(unknown)"); + goto done; + } + connection = nm_auth_chain_get_data (chain, "connection"); + + /* Ensure the caller's username exists in the connection's permissions, + * or that the permissions is empty (ie, visible by everyone). + */ + if (0 != caller_uid) { + NMSettingConnection *s_con; + char *uname; + gboolean allowed; + + uname = get_user_name (caller_uid); + if (!uname) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Unable to determine username for UID %lu.", + caller_uid); + goto done; + } + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + allowed = nm_setting_connection_permissions_user_allowed (s_con, uname); + g_free (uname); + + if (allowed == FALSE) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Cannot add an inaccessible connection."); + goto done; + } + + /* Caller is allowed to add this connection */ + } + added = add_new_connection (self, connection, &add_error); if (added) dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (added))); From c3c9d93b1dddc5fe8b3426082cea02c5e7d8c2c9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 13:04:15 -0600 Subject: [PATCH 092/264] settings: fix session checking for connection operations --- src/settings/nm-sysconfig-connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index f1d8a9c7e..360bcf7d1 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -129,7 +129,7 @@ uid_in_acl (NMConnection *self, g_assert (s_con); /* Reject the request if the request comes from no session at all */ - if (nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { + if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, From eccca738aa0438f614f584e14ee7052b18956066 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 13:47:04 -0600 Subject: [PATCH 093/264] core: make nm_auth_get_caller_uid() error description non-const For consistency with the next commit, so we don't need to remember when to free the description or not. --- src/nm-manager-auth.c | 8 ++++---- src/nm-manager-auth.h | 2 +- src/nm-manager.c | 12 ++++++++---- src/settings/nm-settings.c | 3 ++- src/settings/nm-sysconfig-connection.c | 3 ++- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index c10b1b1db..54e10688c 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -327,7 +327,7 @@ gboolean nm_auth_get_caller_uid (DBusGMethodInvocation *context, NMDBusManager *dbus_mgr, gulong *out_uid, - const char **out_error_desc) + char **out_error_desc) { DBusConnection *connection; char *sender = NULL; @@ -348,14 +348,14 @@ nm_auth_get_caller_uid (DBusGMethodInvocation *context, sender = dbus_g_method_get_sender (context); if (!sender) { if (out_error_desc) - *out_error_desc = "Could not determine D-Bus requestor"; + *out_error_desc = g_strdup ("Could not determine D-Bus requestor"); goto out; } connection = nm_dbus_manager_get_dbus_connection (dbus_mgr); if (!connection) { if (out_error_desc) - *out_error_desc = "Could not get the D-Bus system bus"; + *out_error_desc = g_strdup ("Could not get the D-Bus system bus"); goto out; } @@ -364,7 +364,7 @@ nm_auth_get_caller_uid (DBusGMethodInvocation *context, *out_uid = dbus_bus_get_unix_user (connection, sender, &dbus_error); if (dbus_error_is_set (&dbus_error)) { if (out_error_desc) - *out_error_desc = "Could not determine the user ID of the requestor"; + *out_error_desc = g_strdup_printf ("Could not determine the user ID of the requestor"); dbus_error_free (&dbus_error); *out_uid = G_MAXULONG; } else diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index a03bf6248..c50e840c7 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -89,7 +89,7 @@ void nm_auth_chain_unref (NMAuthChain *chain); gboolean nm_auth_get_caller_uid (DBusGMethodInvocation *context, NMDBusManager *dbus_mgr, gulong *out_uid, - const char **out_error_desc); + char **out_error_desc); #endif /* NM_MANAGER_AUTH_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 740a9a5b0..3002debf6 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -685,7 +685,7 @@ static void pending_activation_check_authorized (PendingActivation *pending, NMDBusManager *dbus_mgr) { - const char *error_desc = NULL; + char *error_desc = NULL; gulong sender_uid = G_MAXULONG; GError *error; @@ -701,6 +701,7 @@ pending_activation_check_authorized (PendingActivation *pending, error_desc); pending->callback (pending, error); g_error_free (error); + g_free (error_desc); return; } @@ -1225,7 +1226,7 @@ manager_device_disconnect_request (NMDevice *device, NMActRequest *req; GError *error = NULL; gulong sender_uid = G_MAXULONG; - const char *error_desc = NULL; + char *error_desc = NULL; req = nm_device_get_act_request (device); if (!req) { @@ -1249,6 +1250,7 @@ manager_device_disconnect_request (NMDevice *device, error_desc); dbus_g_method_return_error (context, error); g_error_free (error); + g_free (error_desc); return; } @@ -2225,7 +2227,7 @@ impl_manager_deactivate_connection (NMManager *self, GSList *iter; NMAuthChain *chain; gulong sender_uid = G_MAXULONG; - const char *error_desc = NULL; + char *error_desc = NULL; /* Check for device connections first */ for (iter = priv->devices; iter; iter = g_slist_next (iter)) { @@ -2267,6 +2269,7 @@ impl_manager_deactivate_connection (NMManager *self, error_desc); dbus_g_method_return_error (context, error); g_error_free (error); + g_free (error_desc); return; } @@ -2599,7 +2602,7 @@ impl_manager_enable (NMManager *self, NMAuthChain *chain; GError *error = NULL; gulong sender_uid = G_MAXULONG; - const char *error_desc = NULL; + char *error_desc = NULL; g_return_if_fail (NM_IS_MANAGER (self)); @@ -2620,6 +2623,7 @@ impl_manager_enable (NMManager *self, error_desc); dbus_g_method_return_error (context, error); g_error_free (error); + g_free (error_desc); return; } diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 622e8ee98..2aed950e7 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -808,7 +808,7 @@ pk_add_cb (NMAuthChain *chain, NMConnection *connection; NMSysconfigConnection *added; gulong caller_uid = G_MAXULONG; - const char *error_desc = NULL; + char *error_desc = NULL; priv->auths = g_slist_remove (priv->auths, chain); @@ -839,6 +839,7 @@ pk_add_cb (NMAuthChain *chain, NM_SETTINGS_ERROR_NOT_PRIVILEGED, "Unable to determine UID of request: %s.", error_desc ? error_desc : "(unknown)"); + g_free (error_desc); goto done; } diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 360bcf7d1..96b546a53 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -629,7 +629,7 @@ auth_start (NMSysconfigConnection *self, gulong sender_uid = G_MAXULONG; GError *error = NULL; char *sender; - const char *error_desc = NULL; + char *error_desc = NULL; PolkitSubject *subject; /* Get the caller's UID */ @@ -637,6 +637,7 @@ auth_start (NMSysconfigConnection *self, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); + g_free (error); goto error; } From 47eaf97d67be3113dfa4caff10c01a2c35adb6de Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 13:49:47 -0600 Subject: [PATCH 094/264] core: add nm_auth_uid_in_acl() For checking whether a specific user ID is: 1) in a known session 2) allowed by the connection's permissions ACL --- src/nm-manager-auth.c | 50 ++++++++++++++++++++++++++++++++++++++++--- src/nm-manager-auth.h | 8 +++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index 54e10688c..b3a71cbdb 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -18,13 +18,14 @@ * Copyright (C) 2010 Red Hat, Inc. */ +#include +#include + +#include #include "nm-manager-auth.h" #include "nm-logging.h" #include "nm-dbus-manager.h" -#include -#include - struct NMAuthChain { guint32 refcount; PolkitAuthority *authority; @@ -375,3 +376,46 @@ out: g_free (sender); return success; } + +gboolean +nm_auth_uid_in_acl (NMConnection *connection, + NMSessionMonitor *smon, + gulong uid, + char **out_error_desc) +{ + NMSettingConnection *s_con; + const char *user = NULL; + GError *local = NULL; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (smon != NULL, FALSE); + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + /* Reject the request if the request comes from no session at all */ + if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { + if (out_error_desc) { + *out_error_desc = g_strdup_printf ("No session found for uid %lu (%s)", + uid, + local && local->message ? local->message : "unknown"); + } + return FALSE; + } + + if (!user) { + if (out_error_desc) + *out_error_desc = g_strdup_printf ("Could not determine username for uid %lu", uid); + return FALSE; + } + + /* Match the username returned by the session check to a user in the ACL */ + if (!nm_setting_connection_permissions_user_allowed (s_con, user)) { + if (out_error_desc) + *out_error_desc = g_strdup_printf ("uid %lu has no permission to perform this operation", uid); + return FALSE; + } + + return TRUE; +} + diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index c50e840c7..df686db44 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -25,7 +25,9 @@ #include #include +#include #include "nm-dbus-manager.h" +#include "nm-session-monitor.h" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" #define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" @@ -91,5 +93,11 @@ gboolean nm_auth_get_caller_uid (DBusGMethodInvocation *context, gulong *out_uid, char **out_error_desc); +/* Caller must free returned error description */ +gboolean nm_auth_uid_in_acl (NMConnection *connection, + NMSessionMonitor *smon, + gulong uid, + char **out_error_desc); + #endif /* NM_MANAGER_AUTH_H */ From a53c31427d520706ce1fe5629fee3d7d58c998a3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 14:05:33 -0600 Subject: [PATCH 095/264] settings: make use of nm_auth_uid_in_acl() --- src/settings/nm-settings.c | 94 +++++++------------------- src/settings/nm-sysconfig-connection.c | 59 +++------------- 2 files changed, 34 insertions(+), 119 deletions(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 2aed950e7..0c9aa43d2 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -107,6 +107,7 @@ typedef struct { guint auth_changed_id; char *config_file; + NMSessionMonitor *session_monitor; GSList *auths; GSList *plugins; @@ -766,35 +767,6 @@ add_new_connection (NMSettings *self, return NULL; } -static char * -get_user_name (gulong uid) -{ - struct passwd pwd; - struct passwd *result; - char *buf, *uname = NULL; - size_t bufsize; - int s; - - bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); - if (bufsize == -1) - bufsize = 16384; /* adequate fallback */ - - buf = g_malloc0 (bufsize); - g_assert (buf); - - s = getpwuid_r (uid, &pwd, buf, bufsize, &result); - if (result) - uname = g_strdup (pwd.pw_name); - else if (s == 0) { - nm_log_dbg (LOGD_SYS_SET, "Lookup failed for UID %lu: not found", uid); - } else { - nm_log_dbg (LOGD_SYS_SET, "Lookup failed for UID %lu: %d", uid, s); - } - - g_free (buf); - return uname; -} - static void pk_add_cb (NMAuthChain *chain, GError *chain_error, @@ -849,29 +821,11 @@ pk_add_cb (NMAuthChain *chain, * or that the permissions is empty (ie, visible by everyone). */ if (0 != caller_uid) { - NMSettingConnection *s_con; - char *uname; - gboolean allowed; - - uname = get_user_name (caller_uid); - if (!uname) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - "Unable to determine username for UID %lu.", - caller_uid); - goto done; - } - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - g_assert (s_con); - - allowed = nm_setting_connection_permissions_user_allowed (s_con, uname); - g_free (uname); - - if (allowed == FALSE) { + if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) { error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - "Cannot add an inaccessible connection."); + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + error_desc); + g_free (error_desc); goto done; } @@ -1377,6 +1331,25 @@ nm_settings_new (const char *config_file, return self; } +static void +nm_settings_init (NMSettings *self) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GError *error = NULL; + + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + + priv->authority = polkit_authority_get_sync (NULL, &error); + if (!priv->authority) { + nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } + + priv->session_monitor = nm_session_monitor_get (); +} + static void dispose (GObject *object) { @@ -1395,6 +1368,8 @@ dispose (GObject *object) g_object_unref (priv->dbus_mgr); + g_object_unref (priv->session_monitor); + G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); } @@ -1574,20 +1549,3 @@ nm_settings_class_init (NMSettingsClass *class) } -static void -nm_settings_init (NMSettings *self) -{ - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GError *error = NULL; - - priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - - priv->authority = polkit_authority_get_sync (NULL, &error); - if (!priv->authority) { - nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s", - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); - g_clear_error (&error); - } -} - diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 96b546a53..b25736117 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -112,55 +112,6 @@ perm_to_user (const char *perm, char *out_user, gsize out_user_size) return TRUE; } -static gboolean -uid_in_acl (NMConnection *self, - NMSessionMonitor *smon, - const uid_t uid, - GError **error) -{ - NMSettingConnection *s_con; - const char *user = NULL; - GError *local = NULL; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (smon != NULL, FALSE); - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (self, NM_TYPE_SETTING_CONNECTION)); - g_assert (s_con); - - /* Reject the request if the request comes from no session at all */ - if (!nm_session_monitor_uid_has_session (smon, uid, &user, &local)) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "No session found for uid %d (%s)", - uid, - local && local->message ? local->message : "unknown"); - g_clear_error (&local); - return FALSE; - } - - if (!user) { - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Could not determine username for uid %d", - uid); - return FALSE; - } - - /* Match the username returned by the session check to a user in the ACL */ - if (nm_setting_connection_permissions_user_allowed (s_con, user)) - return TRUE; - - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "uid %d has no permission to perform this operation", - uid); - return FALSE; -} - /**************************************************************/ static void @@ -643,8 +594,14 @@ auth_start (NMSysconfigConnection *self, /* Make sure the UID can view this connection */ if (0 != sender_uid) { - if (!uid_in_acl (NM_CONNECTION (self), priv->session_monitor, sender_uid, &error)) { - g_assert (error); + if (!nm_auth_uid_in_acl (NM_CONNECTION (self), + priv->session_monitor, + sender_uid, + &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); goto error; } } From c11ba3ea101366e86d78519ed5cb5ed59d688a0a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 14:05:57 -0600 Subject: [PATCH 096/264] settings: GHashTable isn't a GObject subclass --- src/settings/nm-sysconfig-connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index b25736117..37b39052e 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -704,7 +704,7 @@ get_settings_auth_cb (NMSysconfigConnection *self, dbus_g_method_return (context, settings); g_object_unref (no_secrets); - g_object_unref (settings); + g_hash_table_destroy (settings); } static void From 858fc2c4b8070a340f6dea5b075cb3af5f3fc4e6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 14:21:21 -0600 Subject: [PATCH 097/264] trivial: remove incorrect comment --- src/settings/nm-settings.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 0c9aa43d2..24a863225 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -784,7 +784,6 @@ pk_add_cb (NMAuthChain *chain, priv->auths = g_slist_remove (priv->auths, chain); - /* If our NMSysconfigConnection is already gone, do nothing */ if (chain_error) { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_GENERAL, From 042468a86e97003397f24e342b6ca0d2f9ef008c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 14:24:58 -0600 Subject: [PATCH 098/264] settings: convert more hand-rolled polkit to NMAuthChain --- src/settings/nm-sysconfig-connection.c | 129 +++++++++---------------- 1 file changed, 43 insertions(+), 86 deletions(-) diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 37b39052e..cf86118e7 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -73,7 +73,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { PolkitAuthority *authority; - GSList *pending_auths; /* List of PendingAuth structs*/ + GSList *pending_auths; /* List of pending authentication requests */ NMConnection *secrets; gboolean visible; /* Is this connection is visible by some session? */ @@ -508,64 +508,44 @@ typedef void (*AuthCallback) (NMSysconfigConnection *connection, GError *error, gpointer data); -typedef struct { - NMSysconfigConnection *self; - DBusGMethodInvocation *context; - GCancellable *cancellable; - gboolean disposed; - +static void +pk_auth_cb (NMAuthChain *chain, + GError *chain_error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (user_data); + NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; + NMAuthCallResult result; AuthCallback callback; gpointer callback_data; -} PendingAuth; -static void -auth_finish (PendingAuth *info, GError *error) -{ - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); - priv->pending_auths = g_slist_remove (priv->pending_auths, info); + priv->pending_auths = g_slist_remove (priv->pending_auths, chain); - info->callback (info->self, info->context, error, info->callback_data); + /* If our NMSysconfigConnection is already gone, do nothing */ + if (chain_error) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_GENERAL, + "Error checking authorization: %s", + chain_error->message ? chain_error->message : "(unknown)"); + } else { + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); - g_object_unref (info->cancellable); - memset (info, 0, sizeof (PendingAuth)); - g_slice_free (PendingAuth, info); -} - -static void -auth_pk_cb (GObject *object, GAsyncResult *result, gpointer user_data) -{ - PendingAuth *info = user_data; - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (info->self); - PolkitAuthorizationResult *pk_result = NULL; - GError *error = NULL; - - if (info->disposed) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, - "Request was canceled."); - goto out; + /* Caller didn't successfully authenticate */ + if (result != NM_AUTH_CALL_RESULT_YES) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Insufficient privileges."); + } } - pk_result = polkit_authority_check_authorization_finish (priv->authority, - result, - &error); - if (error) - goto out; + callback = nm_auth_chain_get_data (chain, "callback"); + callback_data = nm_auth_chain_get_data (chain, "callback-data"); + callback (self, context, error, callback_data); - if (!polkit_authorization_result_get_is_authorized (pk_result)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - "Insufficient privileges."); - goto out; - } - -out: - auth_finish (info, error); - - if (error) - g_error_free (error); - if (pk_result) - g_object_unref (pk_result); + g_clear_error (&error); + nm_auth_chain_unref (chain); } static void @@ -576,12 +556,10 @@ auth_start (NMSysconfigConnection *self, gpointer callback_data) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); - PendingAuth *info; + NMAuthChain *chain; gulong sender_uid = G_MAXULONG; GError *error = NULL; - char *sender; char *error_desc = NULL; - PolkitSubject *subject; /* Get the caller's UID */ if (!nm_auth_get_caller_uid (context, NULL, &sender_uid, &error_desc)) { @@ -606,35 +584,18 @@ auth_start (NMSysconfigConnection *self, } } - if (!check_modify) { + if (check_modify) { + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self); + g_assert (chain); + priv->pending_auths = g_slist_append (priv->pending_auths, chain); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); + } else { + /* Don't need polkit auth, automatic success */ callback (self, context, NULL, callback_data); - return; } - info = g_slice_new (PendingAuth); - info->self = self; - info->context = context; - info->cancellable = NULL; - info->disposed = FALSE; - info->callback_data = callback_data; - info->cancellable = g_cancellable_new(); - - sender = dbus_g_method_get_sender (info->context); - subject = polkit_system_bus_name_new (sender); - g_free (sender); - - priv->pending_auths = g_slist_prepend (priv->pending_auths, info); - - /* Kick off the PolicyKit request */ - polkit_authority_check_authorization (priv->authority, - subject, - NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, - NULL, - POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION, - info->cancellable, - auth_pk_cb, - info); - g_object_unref (subject); return; error: @@ -924,12 +885,8 @@ dispose (GObject *object) g_object_unref (priv->secrets); /* Cancel PolicyKit requests */ - for (iter = priv->pending_auths; iter; iter = g_slist_next (iter)) { - PendingAuth *call = iter->data; - - call->disposed = TRUE; - g_cancellable_cancel (call->cancellable); - } + for (iter = priv->pending_auths; iter; iter = g_slist_next (iter)) + nm_auth_chain_unref ((NMAuthChain *) iter->data); g_slist_free (priv->pending_auths); priv->pending_auths = NULL; From 87aa9a141264eef18423e0a5969b15a422ac8e18 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 14:27:47 -0600 Subject: [PATCH 099/264] test: add helper for testing connection addition --- test/add-connection.py | 59 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 test/add-connection.py diff --git a/test/add-connection.py b/test/add-connection.py new file mode 100755 index 000000000..817d6914c --- /dev/null +++ b/test/add-connection.py @@ -0,0 +1,59 @@ +#!/bin/env python +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Copyright (C) 2010 Red Hat, Inc. +# + +import dbus +import sys + +s_wired = dbus.Dictionary({'duplex': 'full'}) +s_con = dbus.Dictionary({ + 'type': '802-3-ethernet', + 'uuid': '7371bb78-c1f7-42a3-a9db-5b9566e8ca07', + 'id': sys.argv[1]}) + +if len(sys.argv) > 2: + s_con['permissions'] = ["user:%s:" % sys.argv[2]] + +addr1 = dbus.Array([dbus.UInt32(50462986L), dbus.UInt32(8L), dbus.UInt32(16908554L)], signature=dbus.Signature('u')) +s_ip4 = dbus.Dictionary({ + 'addresses': dbus.Array([addr1], signature=dbus.Signature('au')), + 'method': 'manual'}) + +s_ip6 = dbus.Dictionary({'method': 'ignore'}) + +con = dbus.Dictionary({ + '802-3-ethernet': s_wired, + 'connection': s_con, + 'ipv4': s_ip4, + 'ipv6': s_ip6}) + + +bus = dbus.SystemBus() + +proxy = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager/Settings") +settings = dbus.Interface(proxy, "org.freedesktop.NetworkManager.Settings") + +new_con_path = settings.AddConnection(con) + +con_proxy = bus.get_object("org.freedesktop.NetworkManager", new_con_path) +con = dbus.Interface(con_proxy, "org.freedesktop.NetworkManager.Settings.Connection") + +print "New connection object path: %s" % new_con_path +print con.GetSettings() + + From 9d077444a9193627b7f0e1f4c17dcc7b802b7fa4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 2 Dec 2010 14:34:38 -0600 Subject: [PATCH 100/264] settings: remove settings dict from connection 'updated' signal New connections should not be pushed out in the Updated signal because signals cannot be restricted to particular clients, and some clients may not have permission to view the connection. Upon receiving the Updated signal, clients should re-read the connection using GetSettings to ensure that the client still has permissions to view the connection, and to get the updated settings. --- introspection/nm-sysconfig-connection.xml | 13 ++++--------- src/settings/nm-settings.c | 4 +--- src/settings/nm-sysconfig-connection.c | 21 +++------------------ 3 files changed, 8 insertions(+), 30 deletions(-) diff --git a/introspection/nm-sysconfig-connection.xml b/introspection/nm-sysconfig-connection.xml index b1bc962b5..da8c6a6b2 100644 --- a/introspection/nm-sysconfig-connection.xml +++ b/introspection/nm-sysconfig-connection.xml @@ -43,16 +43,11 @@ - Emitted when some settings changed. Updates do include - connection permission changes, so clients should check whether - they still have permission to access the connection after - receiving this signal. + Emitted when any settings or permissions change. When handling + this signal, clients should re-read the connection using the + GetSettings method to get the changes and to ensure the client + still has permission to access the connection. - - - Contains complete connection setting parameters, including changes. - - diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 24a863225..d00595240 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -621,9 +621,7 @@ connection_removed (NMSysconfigConnection *obj, gpointer user_data) } static void -connection_updated (NMSysconfigConnection *connection, - GHashTable *settings, - gpointer user_data) +connection_updated (NMSysconfigConnection *connection, gpointer user_data) { /* Re-emit for listeners like NMPolicy */ g_signal_emit (NM_SETTINGS (user_data), diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index cf86118e7..678c51f8e 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -334,28 +334,13 @@ nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, /**************************************************************/ -static void -emit_updated (NMSysconfigConnection *connection) -{ - NMConnection *tmp; - GHashTable *settings; - - tmp = nm_connection_duplicate (NM_CONNECTION (connection)); - nm_connection_clear_secrets (tmp); - settings = nm_connection_to_hash (tmp); - g_object_unref (tmp); - - g_signal_emit (connection, signals[UPDATED], 0, settings); - g_hash_table_destroy (settings); -} - static void commit_changes (NMSysconfigConnection *connection, NMSysconfigConnectionCommitFunc callback, gpointer user_data) { g_object_ref (connection); - emit_updated (connection); + g_signal_emit (connection, signals[UPDATED], 0); callback (connection, NULL, user_data); g_object_unref (connection); } @@ -950,8 +935,8 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) G_SIGNAL_RUN_FIRST, 0, NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); signals[REMOVED] = g_signal_new (NM_SYSCONFIG_CONNECTION_REMOVED, From ffb808f4c4cef3de21f11d1e6081e17bbb1fd40a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 10:46:09 -0600 Subject: [PATCH 101/264] core: fix possible leak in error path --- src/nm-manager-auth.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index b3a71cbdb..da147fcc6 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -400,6 +400,7 @@ nm_auth_uid_in_acl (NMConnection *connection, uid, local && local->message ? local->message : "unknown"); } + g_clear_error (&local); return FALSE; } From 0a8f7aeb56631f11019f4ac7661a363af5bd6e6d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 11:36:55 -0600 Subject: [PATCH 102/264] core: use #defines for NMDBusManager signal names Helps catch typos at compile time instead of runtime. --- src/bluez-manager/nm-bluez-manager.c | 4 ++-- src/modem-manager/nm-modem-manager.c | 2 +- src/nm-dbus-manager.c | 4 ++-- src/nm-dbus-manager.h | 3 +++ src/supplicant-manager/nm-supplicant-manager.c | 2 +- src/vpn-manager/nm-vpn-service.c | 3 ++- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/bluez-manager/nm-bluez-manager.c b/src/bluez-manager/nm-bluez-manager.c index 59849d3bd..5381151ea 100644 --- a/src/bluez-manager/nm-bluez-manager.c +++ b/src/bluez-manager/nm-bluez-manager.c @@ -317,12 +317,12 @@ nm_bluez_manager_init (NMBluezManager *self) g_assert (priv->dbus_mgr); g_signal_connect (priv->dbus_mgr, - "name-owner-changed", + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, G_CALLBACK (name_owner_changed_cb), self); g_signal_connect (priv->dbus_mgr, - "dbus-connection-changed", + NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED, G_CALLBACK (dbus_connection_changed_cb), self); diff --git a/src/modem-manager/nm-modem-manager.c b/src/modem-manager/nm-modem-manager.c index 28f7b94d0..f5ade50c0 100644 --- a/src/modem-manager/nm-modem-manager.c +++ b/src/modem-manager/nm-modem-manager.c @@ -371,7 +371,7 @@ nm_modem_manager_init (NMModemManager *self) priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->dbus_mgr = nm_dbus_manager_get (); - g_signal_connect (priv->dbus_mgr, "name-owner-changed", + g_signal_connect (priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED, G_CALLBACK (nm_modem_manager_name_owner_changed), self); diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index dec0615ff..8552f559e 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -105,7 +105,7 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass) object_class->dispose = nm_dbus_manager_dispose; signals[DBUS_CONNECTION_CHANGED] = - g_signal_new ("dbus-connection-changed", + g_signal_new (NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMDBusManagerClass, dbus_connection_changed), @@ -113,7 +113,7 @@ nm_dbus_manager_class_init (NMDBusManagerClass *klass) G_TYPE_NONE, 1, G_TYPE_POINTER); signals[NAME_OWNER_CHANGED] = - g_signal_new ("name-owner-changed", + g_signal_new (NM_DBUS_MANAGER_NAME_OWNER_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMDBusManagerClass, name_owner_changed), diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h index 275ae4e09..3c4d283d9 100644 --- a/src/nm-dbus-manager.h +++ b/src/nm-dbus-manager.h @@ -40,6 +40,9 @@ typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection, #define NM_IS_DBUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_DBUS_MANAGER)) #define NM_DBUS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_DBUS_MANAGER, NMDBusManagerClass)) +#define NM_DBUS_MANAGER_DBUS_CONNECTION_CHANGED "dbus-connection-changed" +#define NM_DBUS_MANAGER_NAME_OWNER_CHANGED "name-owner-changed" + typedef struct { GObject parent; } NMDBusManager; diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index 35ef749cb..e1330fd7b 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -234,7 +234,7 @@ nm_supplicant_manager_init (NMSupplicantManager * self) priv->dbus_mgr = nm_dbus_manager_get (); priv->name_owner_id = g_signal_connect (priv->dbus_mgr, - "name-owner-changed", + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, G_CALLBACK (name_owner_changed), self); priv->running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, WPAS_DBUS_SERVICE); diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c index 3d44d9004..3377cd9ad 100644 --- a/src/vpn-manager/nm-vpn-service.c +++ b/src/vpn-manager/nm-vpn-service.c @@ -415,7 +415,8 @@ nm_vpn_service_init (NMVPNService *self) NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self); priv->dbus_mgr = nm_dbus_manager_get (); - priv->name_owner_id = g_signal_connect (priv->dbus_mgr, "name-owner-changed", + priv->name_owner_id = g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, G_CALLBACK (nm_vpn_service_name_owner_changed), self); } From cf7cc2492d8b55ab9eb9af6bc6592d2cd1f0631b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 12:32:22 -0600 Subject: [PATCH 103/264] logging: LOGD_SYS_SET -> LOGD_SETTINGS --- man/NetworkManager.conf.5.in | 4 ++-- src/logging/nm-logging.c | 4 ++-- src/logging/nm-logging.h | 2 +- src/nm-session-monitor.c | 4 ++-- src/settings/nm-inotify-helper.c | 4 ++-- src/settings/nm-settings.c | 14 +++++++------- src/settings/nm-sysconfig-connection.c | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/man/NetworkManager.conf.5.in b/man/NetworkManager.conf.5.in index ba575c941..a4777cbb9 100644 --- a/man/NetworkManager.conf.5.in +++ b/man/NetworkManager.conf.5.in @@ -160,9 +160,9 @@ warning messages. .B domains=\fI,, ...\fP The following log domains are available: [NONE, HW, RKILL, ETHER, WIFI, BT, MB, DHCP4, DHCP6, PPP, WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT, -USER_SET, SYS_SET, SUSPEND, CORE, DEVICE, OLPC]. When "NONE" is given by itself, +USER_SET, SETTINGS, SUSPEND, CORE, DEVICE, OLPC]. When "NONE" is given by itself, logging is disabled. MB = Mobile Broadband, USER_SET = user settings operations -and communication, SYS_SET = system settings service operations, OLPC = OLPC +and communication, SETTINGS = settings/config service operations, OLPC = OLPC Mesh device operations, CORE = core daemon operations, DEVICE = activation and general interface operations. .SH "SEE ALSO" diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c index 5b5622fd7..5d804f90d 100644 --- a/src/logging/nm-logging.c +++ b/src/logging/nm-logging.c @@ -42,7 +42,7 @@ static guint32 log_domains = \ LOGD_HW | LOGD_RFKILL | LOGD_ETHER | LOGD_WIFI | LOGD_BT | LOGD_MB | \ LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_IP4 | LOGD_IP6 | LOGD_AUTOIP4 | \ LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_USER_SET | \ - LOGD_SYS_SET | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH; + LOGD_SETTINGS | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH; typedef struct { guint32 num; @@ -77,7 +77,7 @@ static const LogDesc domain_descs[] = { { LOGD_SHARING, "SHARING" }, { LOGD_SUPPLICANT,"SUPPLICANT" }, { LOGD_USER_SET, "USER_SET" }, - { LOGD_SYS_SET, "SYS_SET" }, + { LOGD_SETTINGS, "SETTINGS" }, { LOGD_SUSPEND, "SUSPEND" }, { LOGD_CORE, "CORE" }, { LOGD_DEVICE, "DEVICE" }, diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h index e4abcf75c..5e1d050b4 100644 --- a/src/logging/nm-logging.h +++ b/src/logging/nm-logging.h @@ -46,7 +46,7 @@ enum { LOGD_SHARING = 0x00008000, /* Connection sharing/dnsmasq */ LOGD_SUPPLICANT = 0x00010000, /* WiFi and 802.1x */ LOGD_USER_SET = 0x00020000, /* User settings */ - LOGD_SYS_SET = 0x00040000, /* System settings */ + LOGD_SETTINGS = 0x00040000, /* Settings */ LOGD_SUSPEND = 0x00080000, /* Suspend/Resume */ LOGD_CORE = 0x00100000, /* Core daemon and policy stuff */ LOGD_DEVICE = 0x00200000, /* Device state and activation */ diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index 0fdaa0fb8..a70067a98 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -323,7 +323,7 @@ nm_session_monitor_init (NMSessionMonitor *self) error = NULL; if (!ensure_database (self, &error)) { - nm_log_err (LOGD_SYS_SET, "Error loading " CKDB_PATH ": %s", error->message); + nm_log_err (LOGD_CORE, "Error loading " CKDB_PATH ": %s", error->message); g_error_free (error); } @@ -332,7 +332,7 @@ nm_session_monitor_init (NMSessionMonitor *self) self->database_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error); g_object_unref (file); if (self->database_monitor == NULL) { - nm_log_err (LOGD_SYS_SET, "Error monitoring " CKDB_PATH ": %s", error->message); + nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message); g_error_free (error); } else { g_signal_connect (self->database_monitor, diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c index 0ee168e54..f44fee823 100644 --- a/src/settings/nm-inotify-helper.c +++ b/src/settings/nm-inotify-helper.c @@ -123,14 +123,14 @@ init_inotify (NMInotifyHelper *self) priv->ifd = inotify_init (); if (priv->ifd == -1) { - nm_log_warn (LOGD_SYS_SET, "couldn't initialize inotify"); + nm_log_warn (LOGD_SETTINGS, "couldn't initialize inotify"); return FALSE; } /* Watch the inotify descriptor for file/directory change events */ channel = g_io_channel_unix_new (priv->ifd); if (!channel) { - nm_log_warn (LOGD_SYS_SET, "couldn't create new GIOChannel"); + nm_log_warn (LOGD_SETTINGS, "couldn't create new GIOChannel"); close (priv->ifd); priv->ifd = -1; return FALSE; diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index d00595240..7c2e7c2c2 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -471,7 +471,7 @@ add_plugin (NMSettings *self, NMSystemConfigInterface *plugin) g_signal_connect (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED, G_CALLBACK (unmanaged_specs_changed), self); - nm_log_info (LOGD_SYS_SET, "Loaded plugin %s: %s", pname, pinfo); + nm_log_info (LOGD_SETTINGS, "Loaded plugin %s: %s", pname, pinfo); g_free (pname); g_free (pinfo); } @@ -666,7 +666,7 @@ claim_connection (NMSettings *self, } if (!nm_connection_verify (NM_CONNECTION (connection), &error)) { - nm_log_warn (LOGD_SYS_SET, "plugin provided invalid connection: '%s' / '%s' invalid: %d", + nm_log_warn (LOGD_SETTINGS, "plugin provided invalid connection: '%s' / '%s' invalid: %d", g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)), error->message, error->code); g_error_free (error); @@ -1043,7 +1043,7 @@ is_mac_auto_wired_blacklisted (NMSettings *self, const GByteArray *mac) config = g_key_file_new (); if (!config) { - nm_log_warn (LOGD_SYS_SET, "not enough memory to load config file."); + nm_log_warn (LOGD_SETTINGS, "not enough memory to load config file."); return FALSE; } @@ -1208,11 +1208,11 @@ default_wired_try_update (NMDefaultWiredConnection *wired, g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), DEFAULT_WIRED_TAG, NULL); - nm_log_info (LOGD_SYS_SET, "Saved default wired connection '%s' to persistent storage", id); + nm_log_info (LOGD_SETTINGS, "Saved default wired connection '%s' to persistent storage", id); return FALSE; } - nm_log_warn (LOGD_SYS_SET, "couldn't save default wired connection '%s': %d / %s", + nm_log_warn (LOGD_SETTINGS, "couldn't save default wired connection '%s': %d / %s", id, error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); @@ -1268,7 +1268,7 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) id = nm_setting_connection_get_id (s_con); g_assert (id); - nm_log_info (LOGD_SYS_SET, "Added default wired connection '%s' for %s", + nm_log_info (LOGD_SETTINGS, "Added default wired connection '%s' for %s", id, nm_device_get_udi (device)); g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self); @@ -1338,7 +1338,7 @@ nm_settings_init (NMSettings *self) priv->authority = polkit_authority_get_sync (NULL, &error); if (!priv->authority) { - nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s", + nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 678c51f8e..ebbca95fa 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -841,7 +841,7 @@ nm_sysconfig_connection_init (NMSysconfigConnection *self) priv->authority = polkit_authority_get_sync (NULL, NULL); if (!priv->authority) { - nm_log_warn (LOGD_SYS_SET, "failed to create PolicyKit authority: (%d) %s", + nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", error ? error->code : -1, error && error->message ? error->message : "(unknown)"); g_clear_error (&error); From 66291ec204f67c3f0d7a12389e5a5cb6e3baa300 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 12:36:02 -0600 Subject: [PATCH 104/264] logging: LOGD_USER_SET -> LOGD_AGENTS --- man/NetworkManager.conf.5.in | 2 +- src/logging/nm-logging.c | 4 ++-- src/logging/nm-logging.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/man/NetworkManager.conf.5.in b/man/NetworkManager.conf.5.in index a4777cbb9..0f061ea04 100644 --- a/man/NetworkManager.conf.5.in +++ b/man/NetworkManager.conf.5.in @@ -161,7 +161,7 @@ warning messages. The following log domains are available: [NONE, HW, RKILL, ETHER, WIFI, BT, MB, DHCP4, DHCP6, PPP, WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT, USER_SET, SETTINGS, SUSPEND, CORE, DEVICE, OLPC]. When "NONE" is given by itself, -logging is disabled. MB = Mobile Broadband, USER_SET = user settings operations +logging is disabled. MB = Mobile Broadband, AGENTS = secret agents operations and communication, SETTINGS = settings/config service operations, OLPC = OLPC Mesh device operations, CORE = core daemon operations, DEVICE = activation and general interface operations. diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c index 5d804f90d..31a5ab3c7 100644 --- a/src/logging/nm-logging.c +++ b/src/logging/nm-logging.c @@ -41,7 +41,7 @@ static guint32 log_level = LOGL_INFO | LOGL_WARN | LOGL_ERR; static guint32 log_domains = \ LOGD_HW | LOGD_RFKILL | LOGD_ETHER | LOGD_WIFI | LOGD_BT | LOGD_MB | \ LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_IP4 | LOGD_IP6 | LOGD_AUTOIP4 | \ - LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_USER_SET | \ + LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_AGENTS | \ LOGD_SETTINGS | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH; typedef struct { @@ -76,7 +76,7 @@ static const LogDesc domain_descs[] = { { LOGD_VPN, "VPN" }, { LOGD_SHARING, "SHARING" }, { LOGD_SUPPLICANT,"SUPPLICANT" }, - { LOGD_USER_SET, "USER_SET" }, + { LOGD_AGENTS, "AGENTS" }, { LOGD_SETTINGS, "SETTINGS" }, { LOGD_SUSPEND, "SUSPEND" }, { LOGD_CORE, "CORE" }, diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h index 5e1d050b4..8f111e996 100644 --- a/src/logging/nm-logging.h +++ b/src/logging/nm-logging.h @@ -45,7 +45,7 @@ enum { LOGD_VPN = 0x00004000, LOGD_SHARING = 0x00008000, /* Connection sharing/dnsmasq */ LOGD_SUPPLICANT = 0x00010000, /* WiFi and 802.1x */ - LOGD_USER_SET = 0x00020000, /* User settings */ + LOGD_AGENTS = 0x00020000, /* Secret agents */ LOGD_SETTINGS = 0x00040000, /* Settings */ LOGD_SUSPEND = 0x00080000, /* Suspend/Resume */ LOGD_CORE = 0x00100000, /* Core daemon and policy stuff */ From a30cf198584d2b9c6c902a73dc576ac12a9d847f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 12:38:19 -0600 Subject: [PATCH 105/264] agent: add agent manager and minimal agent class --- include/NetworkManager.h | 2 + introspection/Makefile.am | 3 +- introspection/all.xml | 1 + introspection/nm-agent-manager.xml | 38 +++ src/Makefile.am | 12 +- src/nm-agent-manager.c | 366 +++++++++++++++++++++++++++++ src/nm-agent-manager.h | 50 ++++ src/nm-secret-agent.c | 94 ++++++++ src/nm-secret-agent.h | 46 ++++ 9 files changed, 609 insertions(+), 3 deletions(-) create mode 100644 introspection/nm-agent-manager.xml create mode 100644 src/nm-agent-manager.c create mode 100644 src/nm-agent-manager.h create mode 100644 src/nm-secret-agent.c create mode 100644 src/nm-secret-agent.h diff --git a/include/NetworkManager.h b/include/NetworkManager.h index eef2bb1d1..ea05c1f49 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -52,6 +52,8 @@ #define NM_DBUS_PATH_SETTINGS_CONNECTION "/org/freedesktop/NetworkManager/Settings/Connection" #define NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS "org.freedesktop.NetworkManager.Settings.Connection.Secrets" +#define NM_DBUS_INTERFACE_AGENT_MANAGER NM_DBUS_INTERFACE ".AgentManager" +#define NM_DBUS_PATH_AGENT_MANAGER "/org/freedesktop/NetworkManager/AgentManager" /* * Types of NetworkManager states diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 009250426..54877c754 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -23,5 +23,6 @@ EXTRA_DIST = \ nm-ppp-manager.xml \ nm-active-connection.xml \ nm-dhcp4-config.xml \ - nm-dhcp6-config.xml + nm-dhcp6-config.xml \ + nm-agent-manager.xml diff --git a/introspection/all.xml b/introspection/all.xml index 1f33708e5..73084e1ce 100644 --- a/introspection/all.xml +++ b/introspection/all.xml @@ -42,6 +42,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + diff --git a/introspection/nm-agent-manager.xml b/introspection/nm-agent-manager.xml new file mode 100644 index 000000000..0b1e3e6e8 --- /dev/null +++ b/introspection/nm-agent-manager.xml @@ -0,0 +1,38 @@ + + + + + + + + Called by secret Agents to register their ability to provide and save + network secrets. + + + + + + Identifies this agent; only one agent in each user session may use the + same identifier. Identifier formatting follows the same rules as + D-Bus bus names with the exception that the ':' character is not + allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the + identifier is limited in length to 255 characters with a minimum + of 3 characters. An example valid identifier is 'org.gnome.nm-applet' + (without quotes). + + + + + + + Called by secret Agents to notify NetworkManager that they will no + longer handle requests for network secrets. Agents are automatically + unregistered when they disconnect from D-Bus. + + + + + + + + diff --git a/src/Makefile.am b/src/Makefile.am index 217026aef..9e27f7e93 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -149,7 +149,11 @@ NetworkManager_SOURCES = \ nm-dhcp6-config.h \ nm-rfkill.h \ nm-session-monitor.c \ - nm-session-monitor.h + nm-session-monitor.h \ + nm-agent-manager.c \ + nm-agent-manager.h \ + nm-secret-agent.c \ + nm-secret-agent.h nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $< @@ -193,6 +197,9 @@ nm-device-cdma-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml nm-device-gsm-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_gsm --mode=glib-server --output=$@ $< +nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $< + BUILT_SOURCES = \ nm-access-point-glue.h \ nm-manager-glue.h \ @@ -207,7 +214,8 @@ BUILT_SOURCES = \ nm-ip6-config-glue.h \ nm-active-connection-glue.h \ nm-dhcp4-config-glue.h \ - nm-dhcp6-config-glue.h + nm-dhcp6-config-glue.h \ + nm-agent-manager-glue.h NetworkManager_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c new file mode 100644 index 000000000..6b1225e1f --- /dev/null +++ b/src/nm-agent-manager.c @@ -0,0 +1,366 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#include +#include +#include + +#include +#include +#include + +#include "NetworkManager.h" +#include "nm-agent-manager.h" +#include "nm-secret-agent.h" +#include "nm-manager-auth.h" + +G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) + +#define NM_AGENT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_AGENT_MANAGER, \ + NMAgentManagerPrivate)) + +typedef struct { + gboolean disposed; + + NMDBusManager *dbus_mgr; + NMSessionMonitor *session_monitor; + + /* Hashed by owner name, not identifier, since two agents in different + * sessions can use the same identifier. + */ + GHashTable *agents; +} NMAgentManagerPrivate; + + +static void impl_agent_manager_register (NMAgentManager *self, + const char *identifier, + DBusGMethodInvocation *context); + +static void impl_agent_manager_unregister (NMAgentManager *self, + DBusGMethodInvocation *context); + +#include "nm-agent-manager-glue.h" + +/********************************************************************/ + +#define NM_AGENT_MANAGER_ERROR (nm_agent_manager_error_quark ()) +#define NM_TYPE_AGENT_MANAGER_ERROR (nm_agent_manager_error_get_type ()) + +typedef enum { + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN = 0, + NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, + NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR +} NMAgentManagerError; + +static GQuark +nm_agent_manager_error_quark (void) +{ + static GQuark ret = 0; + + if (G_UNLIKELY (ret == 0)) + ret = g_quark_from_static_string ("nm-agent-manager-error"); + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +static GType +nm_agent_manager_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Unable to determine caller's sender or UID */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, "SenderUnknown"), + /* Permission for some operation was denied */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, "PermissionDenied"), + /* The caller's session could not be determined */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, "SessionNotFound"), + /* The identifier was invalid */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, "InvalidIdentifier"), + /* Request was not from a registered agent */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"), + /* Some internal error occurred */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "InternalError"), + { 0, 0, 0 } + }; + + etype = g_enum_register_static ("NMAgentManagerError", values); + } + return etype; +} + +/*************************************************************/ + +static gboolean +remove_agent (NMAgentManager *self, const char *owner) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + NMSecretAgent *agent; + + g_return_val_if_fail (owner != NULL, FALSE); + + agent = g_hash_table_lookup (priv->agents, owner); + if (!agent) + return FALSE; + + /* FIXME: signal agent removal */ + + g_hash_table_remove (priv->agents, owner); + return TRUE; +} + +/*************************************************************/ + +static gboolean +validate_identifier (const char *identifier, GError **error) +{ + const char *p = identifier; + size_t id_len; + + if (!identifier) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "No identifier was given"); + return FALSE; + } + + /* Length between 3 and 255 characters inclusive */ + id_len = strlen (identifier); + if (id_len < 3 || id_len > 255) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier length not between 3 and 255 characters (inclusive)"); + return FALSE; + } + + if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier must not start or end with '.'"); + return FALSE; + } + + /* FIXME: do complete validation here */ + while (p && *p) { + if (!isalnum (*p) && (*p != '_') && (*p != '-')) { + g_set_error (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier contains invalid character '%c'", *p); + return FALSE; + } + + if ((*p == '.') && (*(p + 1) == '.')) { + g_set_error_literal (error, + NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, + "Identifier contains two '.' characters in sequence"); + return FALSE; + } + } + + return TRUE; +} + +static void +impl_agent_manager_register (NMAgentManager *self, + const char *identifier, + DBusGMethodInvocation *context) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + char *error_desc = NULL, *sender = NULL; + gulong sender_uid = G_MAXULONG; + GError *error = NULL, *local = NULL; + NMSecretAgent *agent; + + if (!nm_auth_get_caller_uid (context, + priv->dbus_mgr, + &sender_uid, + &error_desc)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + error_desc); + g_free (error_desc); + goto done; + } + + if (!nm_session_monitor_uid_has_session (priv->session_monitor, + sender_uid, + NULL, + &local)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, + local && local->message ? local->message : "Session not found"); + goto done; + } + + sender = dbus_g_method_get_sender (context); + if (!sender) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + "Failed to get D-Bus request sender"); + goto done; + } + + /* Validate the identifier */ + if (!validate_identifier (identifier, &error)) + goto done; + + /* Success, add the new agent */ + agent = nm_secret_agent_new (sender, identifier); + if (!agent) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, + "Failed to initialize the agent"); + goto done; + } + + g_hash_table_insert (priv->agents, g_strdup (sender), agent); + dbus_g_method_return (context); + +done: + if (error) + dbus_g_method_return_error (context, error); + g_clear_error (&error); + g_clear_error (&local); + g_free (sender); +} + +static void +impl_agent_manager_unregister (NMAgentManager *self, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + char *sender = NULL; + + sender = dbus_g_method_get_sender (context); + if (!sender) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_SENDER_UNKNOWN, + "Failed to get D-Bus request sender"); + goto done; + } + + /* Found the agent, unregister and remove it */ + if (!remove_agent (self, sender)) { + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, + "Caller is not registered as an Agent"); + goto done; + } + + dbus_g_method_return (context); + +done: + if (error) + dbus_g_method_return_error (context, error); + g_clear_error (&error); + g_free (sender); +} + +/*************************************************************/ + +static void +name_owner_changed_cb (NMDBusManager *dbus_mgr, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + if (old_owner) { + /* The agent quit, so remove it and let interested clients know */ + remove_agent (NM_AGENT_MANAGER (user_data), old_owner); + } +} + +/*************************************************************/ + +NMAgentManager * +nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor) +{ + NMAgentManager *self; + NMAgentManagerPrivate *priv; + DBusGConnection *connection; + + g_return_val_if_fail (dbus_mgr != NULL, NULL); + + self = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); + if (self) { + priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + priv->session_monitor = g_object_ref (session_monitor); + priv->dbus_mgr = g_object_ref (dbus_mgr); + connection = nm_dbus_manager_get_connection (dbus_mgr); + dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_AGENT_MANAGER, G_OBJECT (self)); + + g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed_cb), + self); + } + + return self; +} + +static void +nm_agent_manager_init (NMAgentManager *self) +{ +} + +static void +dispose (GObject *object) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object); + + if (priv->disposed) + return; + priv->disposed = TRUE; + + g_object_unref (priv->session_monitor); + g_object_unref (priv->dbus_mgr); + + g_hash_table_destroy (priv->agents); + + G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); +} + +static void +nm_agent_manager_class_init (NMAgentManagerClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMAgentManagerPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; + + dbus_g_error_domain_register (NM_AGENT_MANAGER_ERROR, + NM_DBUS_INTERFACE_AGENT_MANAGER, + NM_TYPE_AGENT_MANAGER_ERROR); +} diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h new file mode 100644 index 000000000..59a31bdd9 --- /dev/null +++ b/src/nm-agent-manager.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#ifndef NM_AGENT_MANAGER_H +#define NM_AGENT_MANAGER_H + +#include +#include + +#include "nm-dbus-manager.h" +#include "nm-session-monitor.h" + +#define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) +#define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) +#define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) +#define NM_IS_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_AGENT_MANAGER)) +#define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_AGENT_MANAGER)) +#define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) + +typedef struct { + GObject parent; +} NMAgentManager; + +typedef struct { + GObjectClass parent; +} NMAgentManagerClass; + +GType nm_agent_manager_get_type (void); + +NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr, + NMSessionMonitor *session_monitor); + +#endif /* NM_AGENT_MANAGER_H */ diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c new file mode 100644 index 000000000..85fd23475 --- /dev/null +++ b/src/nm-secret-agent.c @@ -0,0 +1,94 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#include + +#include +#include +#include + +#include "nm-secret-agent.h" + +G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) + +#define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SECRET_AGENT, \ + NMSecretAgentPrivate)) + +typedef struct { + gboolean disposed; + + char *owner; + char *identifier; +} NMSecretAgentPrivate; + +/*************************************************************/ + +NMSecretAgent * +nm_secret_agent_new (const char *owner, const char *identifier) +{ + NMSecretAgent *self; + NMSecretAgentPrivate *priv; + + g_return_val_if_fail (owner != NULL, NULL); + g_return_val_if_fail (identifier != NULL, NULL); + + self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL); + if (self) { + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->owner = g_strdup (owner); + priv->identifier = g_strdup (identifier); + } + + return self; +} + +static void +nm_secret_agent_init (NMSecretAgent *self) +{ +} + +static void +dispose (GObject *object) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object); + + if (priv->disposed) + return; + priv->disposed = TRUE; + + g_free (priv->owner); + g_free (priv->identifier); + + G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); +} + +static void +nm_secret_agent_class_init (NMSecretAgentClass *config_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (config_class); + + g_type_class_add_private (config_class, sizeof (NMSecretAgentPrivate)); + + /* virtual methods */ + object_class->dispose = dispose; +} + diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h new file mode 100644 index 000000000..ecd7792cc --- /dev/null +++ b/src/nm-secret-agent.h @@ -0,0 +1,46 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + */ + +#ifndef NM_SECRET_AGENT_H +#define NM_SECRET_AGENT_H + +#include +#include + +#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) +#define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) +#define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) +#define NM_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT)) +#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SECRET_AGENT)) +#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) + +typedef struct { + GObject parent; +} NMSecretAgent; + +typedef struct { + GObjectClass parent; +} NMSecretAgentClass; + +GType nm_secret_agent_get_type (void); + +NMSecretAgent *nm_secret_agent_new (const char *owner, const char *identifier); + +#endif /* NM_SECRET_AGENT_H */ From e716e7507b6897d2fcbea22be27f999d691f5b8f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 13:32:45 -0600 Subject: [PATCH 106/264] agent: log agent registration --- src/nm-agent-manager.c | 12 +++++++++++- src/nm-secret-agent.c | 35 ++++++++++++++++++++++++++++++++++- src/nm-secret-agent.h | 10 +++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 6b1225e1f..378143bfe 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -27,6 +27,7 @@ #include #include "NetworkManager.h" +#include "nm-logging.h" #include "nm-agent-manager.h" #include "nm-secret-agent.h" #include "nm-manager-auth.h" @@ -128,6 +129,11 @@ remove_agent (NMAgentManager *self, const char *owner) /* FIXME: signal agent removal */ + nm_log_dbg (LOGD_AGENTS, "(%s/%s) agent unregistered for UID %ld", + nm_secret_agent_get_dbus_owner (agent), + nm_secret_agent_get_identifier (agent), + nm_secret_agent_get_owner_uid (agent)); + g_hash_table_remove (priv->agents, owner); return TRUE; } @@ -233,7 +239,7 @@ impl_agent_manager_register (NMAgentManager *self, goto done; /* Success, add the new agent */ - agent = nm_secret_agent_new (sender, identifier); + agent = nm_secret_agent_new (sender, identifier, sender_uid); if (!agent) { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, @@ -242,6 +248,10 @@ impl_agent_manager_register (NMAgentManager *self, } g_hash_table_insert (priv->agents, g_strdup (sender), agent); + nm_log_dbg (LOGD_AGENTS, "(%s/%s) agent registered for UID %ld", + nm_secret_agent_get_dbus_owner (agent), + nm_secret_agent_get_identifier (agent), + nm_secret_agent_get_owner_uid (agent)); dbus_g_method_return (context); done: diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c index 85fd23475..0a1c8b723 100644 --- a/src/nm-secret-agent.c +++ b/src/nm-secret-agent.c @@ -37,12 +37,44 @@ typedef struct { char *owner; char *identifier; + uid_t owner_uid; } NMSecretAgentPrivate; /*************************************************************/ +const char * +nm_secret_agent_get_dbus_owner (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, NULL); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner; +} + +const char * +nm_secret_agent_get_identifier (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, NULL); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->identifier; +} + +uid_t +nm_secret_agent_get_owner_uid (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, G_MAXUINT); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), G_MAXUINT); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner_uid; +} + +/*************************************************************/ + NMSecretAgent * -nm_secret_agent_new (const char *owner, const char *identifier) +nm_secret_agent_new (const char *owner, + const char *identifier, + uid_t owner_uid) { NMSecretAgent *self; NMSecretAgentPrivate *priv; @@ -56,6 +88,7 @@ nm_secret_agent_new (const char *owner, const char *identifier) priv->owner = g_strdup (owner); priv->identifier = g_strdup (identifier); + priv->owner_uid = owner_uid; } return self; diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h index ecd7792cc..d5fb6b246 100644 --- a/src/nm-secret-agent.h +++ b/src/nm-secret-agent.h @@ -41,6 +41,14 @@ typedef struct { GType nm_secret_agent_get_type (void); -NMSecretAgent *nm_secret_agent_new (const char *owner, const char *identifier); +NMSecretAgent *nm_secret_agent_new (const char *owner, + const char *identifier, + uid_t owner_uid); + +const char *nm_secret_agent_get_dbus_owner (NMSecretAgent *agent); + +const char *nm_secret_agent_get_identifier (NMSecretAgent *agent); + +uid_t nm_secret_agent_get_owner_uid (NMSecretAgent *agent); #endif /* NM_SECRET_AGENT_H */ From ff101f4946a9b53889b4c9ce8a58b9a86d70a62f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 12 Dec 2010 21:17:34 -0600 Subject: [PATCH 107/264] settings: remove callback from nm_sysconfig_connection_get_secrets() No reason it needs to use the callback pattern anymore. --- src/settings/nm-sysconfig-connection.c | 117 ++++++------------ src/settings/nm-sysconfig-connection.h | 24 ++-- .../plugins/ifupdown/nm-ifupdown-connection.c | 35 +----- 3 files changed, 53 insertions(+), 123 deletions(-) diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index ebbca95fa..72c97770b 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -304,36 +304,6 @@ nm_sysconfig_connection_delete (NMSysconfigConnection *connection, } } -void -nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSysconfigConnectionGetSecretsFunc callback, - gpointer user_data) -{ - g_return_if_fail (connection != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); - g_return_if_fail (callback != NULL); - - if (NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->get_secrets) { - NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->get_secrets (connection, - setting_name, - hints, - request_new, - callback, - user_data); - } else { - GError *error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INTERNAL_ERROR, - "%s: %s:%d get_secrets() unimplemented", __func__, __FILE__, __LINE__); - callback (connection, NULL, error, user_data); - g_error_free (error); - } -} - -/**************************************************************/ - static void commit_changes (NMSysconfigConnection *connection, NMSysconfigConnectionCommitFunc callback, @@ -357,6 +327,15 @@ do_delete (NMSysconfigConnection *connection, g_object_unref (connection); } +/**************************************************************/ + +static gboolean +supports_secrets (NMSysconfigConnection *connection, const char *setting_name) +{ + /* All secrets supported */ + return TRUE; +} + static GValue * string_to_gvalue (const char *str) { @@ -411,7 +390,7 @@ add_secrets (NMSetting *setting, if (tmp) g_hash_table_insert (secrets, g_strdup (key), string_to_gvalue (tmp)); } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { - /* Flatten the string hash by pulling its keys/values out */ + /* Flatten the string hash by pulling its keys/values out; for VPN secrets */ g_hash_table_foreach (g_value_get_boxed (value), copy_one_secret, secrets); } else if (G_VALUE_TYPE (value) == DBUS_TYPE_G_UCHAR_ARRAY) { GByteArray *array; @@ -431,19 +410,17 @@ destroy_gvalue (gpointer data) g_slice_free (GValue, value); } -static void -get_secrets (NMSysconfigConnection *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSysconfigConnectionGetSecretsFunc callback, - gpointer user_data) +GHashTable * +nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + GError **error) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); GHashTable *settings = NULL; GHashTable *secrets = NULL; NMSetting *setting; - GError *error = NULL; /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() * will clear secrets on this object's settings. priv->secrets should be @@ -451,24 +428,18 @@ get_secrets (NMSysconfigConnection *connection, * nm_sysconfig_connection_replace_settings(). */ if (!priv->secrets) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "%s.%d - Internal error; secrets cache invalid.", - __FILE__, __LINE__); - (*callback) (connection, NULL, error, user_data); - g_error_free (error); - return; + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "%s.%d - Internal error; secrets cache invalid.", + __FILE__, __LINE__); + return NULL; } setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); if (!setting) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_SETTING, - "%s.%d - Connection didn't have requested setting '%s'.", - __FILE__, __LINE__, setting_name); - (*callback) (connection, NULL, error, user_data); - g_error_free (error); - return; + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, + "%s.%d - Connection didn't have requested setting '%s'.", + __FILE__, __LINE__, setting_name); + return NULL; } /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that @@ -482,8 +453,8 @@ get_secrets (NMSysconfigConnection *connection, nm_setting_enumerate_values (setting, add_secrets, secrets); g_hash_table_insert (settings, g_strdup (setting_name), secrets); - callback (connection, settings, NULL, user_data); - g_hash_table_destroy (settings); + + return secrets; } /**** User authorization **************************************/ @@ -774,20 +745,6 @@ typedef struct { gboolean request_new; } GetSecretsInfo; -static void -con_secrets_cb (NMSysconfigConnection *connection, - GHashTable *secrets, - GError *error, - gpointer user_data) -{ - DBusGMethodInvocation *context = user_data; - - if (error) - dbus_g_method_return_error (context, error); - else - dbus_g_method_return (context, secrets); -} - static void secrets_auth_cb (NMSysconfigConnection *self, DBusGMethodInvocation *context, @@ -795,18 +752,26 @@ secrets_auth_cb (NMSysconfigConnection *self, gpointer data) { GetSecretsInfo *info = data; + GHashTable *secrets; + GError *local = NULL; if (error) { dbus_g_method_return_error (context, error); goto out; } - nm_sysconfig_connection_get_secrets (self, - info->setting_name, - (const char **) info->hints, - info->request_new, - con_secrets_cb, - context); + secrets = nm_sysconfig_connection_get_secrets (self, + info->setting_name, + (const char **) info->hints, + info->request_new, + &error); + if (secrets) { + dbus_g_method_return (context, secrets); + g_hash_table_destroy (secrets); + } else { + dbus_g_method_return_error (context, local); + g_clear_error (&local); + } out: g_free (info->setting_name); @@ -917,7 +882,7 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) class->commit_changes = commit_changes; class->delete = do_delete; - class->get_secrets = get_secrets; + class->supports_secrets = supports_secrets; /* Properties */ g_object_class_install_property diff --git a/src/settings/nm-sysconfig-connection.h b/src/settings/nm-sysconfig-connection.h index ca2df9531..18024a5e0 100644 --- a/src/settings/nm-sysconfig-connection.h +++ b/src/settings/nm-sysconfig-connection.h @@ -50,11 +50,6 @@ typedef void (*NMSysconfigConnectionDeleteFunc) (NMSysconfigConnection *connecti GError *error, gpointer user_data); -typedef void (*NMSysconfigConnectionGetSecretsFunc) (NMSysconfigConnection *connection, - GHashTable *secrets, - GError *error, - gpointer user_data); - struct _NMSysconfigConnection { NMConnection parent; }; @@ -70,12 +65,8 @@ struct _NMSysconfigConnectionClass { NMSysconfigConnectionDeleteFunc callback, gpointer user_data); - void (*get_secrets) (NMSysconfigConnection *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSysconfigConnectionGetSecretsFunc callback, - gpointer user_data); + gboolean (*supports_secrets) (NMSysconfigConnection *connection, + const char *setting_name); }; GType nm_sysconfig_connection_get_type (void); @@ -97,12 +88,11 @@ void nm_sysconfig_connection_delete (NMSysconfigConnection *connection, NMSysconfigConnectionDeleteFunc callback, gpointer user_data); -void nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, - const char *setting_name, - const char **hints, - gboolean request_new, - NMSysconfigConnectionGetSecretsFunc callback, - gpointer user_data); +GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + GError **error); gboolean nm_sysconfig_connection_is_visible (NMSysconfigConnection *self); diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c index ef0d09450..17d250c28 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -57,37 +57,12 @@ nm_ifupdown_connection_new (if_block *block) NULL); } -static void -get_secrets (NMSysconfigConnection *connection, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - NMSysconfigConnectionGetSecretsFunc callback, - gpointer user_data) +static gboolean +supports_secrets (NMSysconfigConnection *connection, const char *setting_name) { - GError *error = NULL; + PLUGIN_PRINT ("SCPlugin-Ifupdown", "supports_secrets() for setting_name: '%s'", setting_name); - PLUGIN_PRINT ("SCPlugin-Ifupdown", "get_secrets() for setting_name:'%s'", setting_name); - - /* FIXME: Only wifi secrets are supported for now */ - if (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)) { - g_set_error (&error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_GENERAL, - "%s.%d - security setting name not supported '%s'.", - __FILE__, __LINE__, setting_name); - PLUGIN_PRINT ("SCPlugin-Ifupdown", "%s", error->message); - callback (connection, NULL, error, user_data); - g_error_free (error); - return; - } - - NM_SYSCONFIG_CONNECTION_CLASS (nm_ifupdown_connection_parent_class)->get_secrets (connection, - setting_name, - hints, - request_new, - callback, - user_data); + return (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); } static void @@ -180,7 +155,7 @@ nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connectio object_class->set_property = set_property; object_class->get_property = get_property; - connection_class->get_secrets = get_secrets; + connection_class->supports_secrets = supports_secrets; /* Properties */ g_object_class_install_property From 58088129f76a21fa45f7abe596857832df5d7b57 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 12 Dec 2010 21:29:13 -0600 Subject: [PATCH 108/264] settings: only use one hint nm_sysconfig_connection_get_secrets() Never used more than one anyway. --- src/settings/nm-sysconfig-connection.c | 10 +++++----- src/settings/nm-sysconfig-connection.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 72c97770b..3a280b943 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -413,7 +413,7 @@ destroy_gvalue (gpointer data) GHashTable * nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, const char *setting_name, - const char **hints, + const char *hint, gboolean request_new, GError **error) { @@ -741,7 +741,7 @@ impl_sysconfig_connection_delete (NMSysconfigConnection *self, typedef struct { char *setting_name; - char **hints; + char *hint; gboolean request_new; } GetSecretsInfo; @@ -762,7 +762,7 @@ secrets_auth_cb (NMSysconfigConnection *self, secrets = nm_sysconfig_connection_get_secrets (self, info->setting_name, - (const char **) info->hints, + info->hint, info->request_new, &error); if (secrets) { @@ -775,7 +775,7 @@ secrets_auth_cb (NMSysconfigConnection *self, out: g_free (info->setting_name); - g_strfreev (info->hints); + g_free (info->hint); g_slice_free (GetSecretsInfo, info); } @@ -788,7 +788,7 @@ impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, { GetSecretsInfo *info = g_slice_new (GetSecretsInfo); info->setting_name = g_strdup (setting_name); - info->hints = g_strdupv ((char **) hints); + info->hint = (hints && hints[0]) ? g_strdup (hints[0]) : NULL; info->request_new = request_new; auth_start (self, context, TRUE, secrets_auth_cb, info); diff --git a/src/settings/nm-sysconfig-connection.h b/src/settings/nm-sysconfig-connection.h index 18024a5e0..aaf926c1b 100644 --- a/src/settings/nm-sysconfig-connection.h +++ b/src/settings/nm-sysconfig-connection.h @@ -90,7 +90,7 @@ void nm_sysconfig_connection_delete (NMSysconfigConnection *connection, GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, const char *setting_name, - const char **hints, + const char *hint, gboolean request_new, GError **error); From 62a2c34e271ec3b0a9892240ffd693ae57932d5e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 13 Dec 2010 13:11:51 -0600 Subject: [PATCH 109/264] core: simplify secrets handling during activation Instead of a bizare mechanism of signals back to the manager object that used to be required because of the user/system settings split, let each place that needs secrets request those secrets itself. This flattens the secrets request process a ton and the code flow significantly. Previously the get secrets flow was something like this: nm_act_request_get_secrets () nm_secrets_provider_interface_get_secrets () emits manager-get-secrets signal provider_get_secerts () system_get_secrets () system_get_secrets_idle_cb () nm_sysconfig_connection_get_secrets () system_get_secrets_reply_cb () nm_secrets_provider_interface_get_secrets_result () signal failure or success now instead we do something like this: nm_agent_manager_get_secrets () nm_agent_manager_get_secrets () request_start_secrets () nm_sysconfig_connection_get_secrets () return failure or success to callback --- src/Makefile.am | 2 - src/modem-manager/nm-modem-gsm.c | 10 +- src/modem-manager/nm-modem.c | 175 ++++--- src/modem-manager/nm-modem.h | 24 +- src/nm-activation-request.c | 718 ++++++++++++++-------------- src/nm-activation-request.h | 35 +- src/nm-agent-manager.c | 231 ++++++++- src/nm-agent-manager.h | 26 +- src/nm-device-bt.c | 75 +-- src/nm-device-ethernet.c | 94 ++-- src/nm-device-modem.c | 67 +-- src/nm-device-wifi.c | 68 ++- src/nm-device.c | 33 -- src/nm-device.h | 5 - src/nm-manager.c | 228 +-------- src/nm-secrets-provider-interface.c | 224 --------- src/nm-secrets-provider-interface.h | 90 ---- src/ppp-manager/nm-ppp-manager.c | 216 +++++---- src/ppp-manager/nm-ppp-manager.h | 8 +- src/vpn-manager/nm-vpn-connection.c | 75 +-- src/vpn-manager/nm-vpn-connection.h | 3 +- 21 files changed, 1036 insertions(+), 1371 deletions(-) delete mode 100644 src/nm-secrets-provider-interface.c delete mode 100644 src/nm-secrets-provider-interface.h diff --git a/src/Makefile.am b/src/Makefile.am index 9e27f7e93..66be644c4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,8 +116,6 @@ NetworkManager_SOURCES = \ nm-ip4-config.h \ nm-ip6-config.c \ nm-ip6-config.h \ - nm-secrets-provider-interface.c \ - nm-secrets-provider-interface.h \ nm-active-connection.h \ nm-active-connection.c \ main.c \ diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c index abb96db1f..9a79535eb 100644 --- a/src/modem-manager/nm-modem-gsm.c +++ b/src/modem-manager/nm-modem-gsm.c @@ -177,12 +177,10 @@ ask_for_pin (NMModemGsm *self, gboolean always_ask) if (!always_ask) tries = priv->pin_tries++; - g_signal_emit_by_name (self, NM_MODEM_NEED_AUTH, - NM_SETTING_GSM_SETTING_NAME, - (tries || always_ask) ? TRUE : FALSE, - SECRETS_CALLER_MOBILE_BROADBAND, - NM_SETTING_GSM_PIN, - NULL); + nm_modem_get_secrets (NM_MODEM (self), + NM_SETTING_GSM_SETTING_NAME, + (tries || always_ask) ? TRUE : FALSE, + NM_SETTING_GSM_PIN); } static void diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index e07b818bb..6f62eab49 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -62,7 +62,9 @@ typedef struct { char *device; char *iface; + NMActRequest *act_request; guint32 secrets_tries; + guint32 secrets_id; DBusGProxyCall *call; @@ -78,7 +80,8 @@ enum { PPP_FAILED, PREPARE_RESULT, IP4_CONFIG_RESULT, - NEED_AUTH, + AUTH_REQUESTED, + AUTH_RESULT, LAST_SIGNAL }; @@ -475,67 +478,58 @@ nm_modem_stage4_get_ip4_config (NMModem *self, return ret; } -gboolean -nm_modem_connection_secrets_updated (NMModem *self, - NMActRequest *req, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller) +static void +cancel_get_secrets (NMModem *self) { - NMModemPrivate *priv; - gboolean found = FALSE; - const char *setting_name; - GSList *iter; + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (NM_IS_MODEM (self), FALSE); - g_return_val_if_fail (req != NULL, FALSE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); - - priv = NM_MODEM_GET_PRIVATE (self); - - if (caller == SECRETS_CALLER_PPP) { - const char *user = NULL; - const char *pass = NULL; - - g_return_val_if_fail (priv->ppp_manager != NULL, FALSE); - - if (!NM_MODEM_GET_CLASS (self)->get_user_pass (self, connection, &user, &pass)) { - /* Shouldn't ever happen */ - nm_ppp_manager_update_secrets (priv->ppp_manager, - priv->iface, - NULL, - NULL, - "missing GSM/CDMA setting; no secrets could be found."); - } else { - nm_ppp_manager_update_secrets (priv->ppp_manager, - priv->iface, - user ? user : "", - pass ? pass : "", - NULL); - } - return TRUE; + if (priv->secrets_id) { + nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + priv->secrets_id = 0; } +} - g_return_val_if_fail (caller == SECRETS_CALLER_MOBILE_BROADBAND, FALSE); +static void +modem_secrets_cb (NMActRequest *req, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + NMModem *self = NM_MODEM (user_data); + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - g_assert (NM_MODEM_GET_CLASS (self)->get_setting_name); - setting_name = NM_MODEM_GET_CLASS (self)->get_setting_name (self); + g_return_if_fail (call_id == priv->secrets_id); - for (iter = updated_settings; iter; iter = g_slist_next (iter)) { - const char *candidate_setting_name = (const char *) iter->data; + priv->secrets_id = 0; - if (!strcmp (candidate_setting_name, setting_name)) - found = TRUE; - else { - nm_log_warn (LOGD_MB, "ignoring updated secrets for setting '%s'.", - candidate_setting_name); - } - } + if (error) + nm_log_warn (LOGD_MB, "%s", error->message); - return found; + g_signal_emit (self, signals[AUTH_RESULT], 0, error); +} + +gboolean +nm_modem_get_secrets (NMModem *self, + const char *setting_name, + gboolean request_new, + const char *hint) +{ + NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + + cancel_get_secrets (self); + + priv->secrets_id = nm_act_request_get_secrets (priv->act_request, + NULL, + setting_name, + request_new, + hint, + modem_secrets_cb, + self); + if (priv->secrets_id) + g_signal_emit (self, signals[AUTH_REQUESTED], 0); + + return !!(priv->secrets_id); } static NMActStageReturn @@ -559,29 +553,30 @@ nm_modem_act_stage1_prepare (NMModem *self, GPtrArray *hints = NULL; const char *setting_name = NULL; + if (priv->act_request) + g_object_unref (priv->act_request); + priv->act_request = g_object_ref (req); + ret = NM_MODEM_GET_CLASS (self)->act_stage1_prepare (self, req, &hints, &setting_name, reason); if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) { - const char *hint1 = NULL, *hint2 = NULL; - - /* Need some secrets */ - if (hints) { - if (hints->len > 0) - hint1 = g_ptr_array_index (hints, 0); - if (hints->len > 1) - hint2 = g_ptr_array_index (hints, 1); + priv->secrets_id = nm_act_request_get_secrets (req, + NULL, + setting_name, + priv->secrets_tries++ ? TRUE : FALSE, + hints ? g_ptr_array_index (hints, 0) : NULL, + modem_secrets_cb, + self); + if (priv->secrets_id) + g_signal_emit (self, signals[AUTH_REQUESTED], 0); + else { + *reason = NM_DEVICE_STATE_REASON_NO_SECRETS; + ret = NM_ACT_STAGE_RETURN_FAILURE; } - g_signal_emit (self, signals[NEED_AUTH], 0, - setting_name, - priv->secrets_tries++ ? TRUE : FALSE, - SECRETS_CALLER_MOBILE_BROADBAND, - hint1, - hint2); - if (hints) g_ptr_array_free (hints, TRUE); } @@ -639,6 +634,12 @@ real_deactivate_quickly (NMModem *self, NMDevice *device) priv->secrets_tries = 0; + if (priv->act_request) { + cancel_get_secrets (self); + g_object_unref (priv->act_request); + priv->act_request = NULL; + } + if (priv->call) { dbus_g_proxy_cancel_call (priv->proxy, priv->call); priv->call = NULL; @@ -697,6 +698,7 @@ nm_modem_device_state_changed (NMModem *self, NMDeviceStateReason reason) { gboolean was_connected = FALSE; + NMModemPrivate *priv; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_MODEM (self)); @@ -704,16 +706,26 @@ nm_modem_device_state_changed (NMModem *self, if (IS_ACTIVATING_STATE (old_state) || (old_state == NM_DEVICE_STATE_ACTIVATED)) was_connected = TRUE; + priv = NM_MODEM_GET_PRIVATE (self); + /* Make sure we don't leave the serial device open */ switch (new_state) { case NM_DEVICE_STATE_NEED_AUTH: - if (NM_MODEM_GET_PRIVATE (self)->ppp_manager) + if (priv->ppp_manager) break; /* else fall through */ case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: case NM_DEVICE_STATE_FAILED: case NM_DEVICE_STATE_DISCONNECTED: + if (new_state != NM_DEVICE_STATE_NEED_AUTH) { + if (priv->act_request) { + cancel_get_secrets (self); + g_object_unref (priv->act_request); + priv->act_request = NULL; + } + } + if (was_connected) { dbus_g_proxy_begin_call (nm_modem_get_proxy (self, MM_DBUS_INTERFACE_MODEM), "Disconnect", @@ -1016,6 +1028,9 @@ finalize (GObject *object) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (object); + if (priv->act_request) + g_object_unref (priv->act_request); + if (priv->proxy) g_object_unref (priv->proxy); @@ -1128,15 +1143,23 @@ nm_modem_class_init (NMModemClass *klass) _nm_marshal_VOID__BOOLEAN_UINT, G_TYPE_NONE, 2, G_TYPE_BOOLEAN, G_TYPE_UINT); - signals[NEED_AUTH] = - g_signal_new (NM_MODEM_NEED_AUTH, + signals[AUTH_REQUESTED] = + g_signal_new (NM_MODEM_AUTH_REQUESTED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMModemClass, need_auth), + G_STRUCT_OFFSET (NMModemClass, auth_requested), NULL, NULL, - _nm_marshal_VOID__STRING_BOOLEAN_UINT_STRING_STRING, - G_TYPE_NONE, 5, - G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[AUTH_RESULT] = + g_signal_new (NM_MODEM_AUTH_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMModemClass, auth_result), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); } const DBusGObjectInfo * diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h index a2aed57e0..15933e49d 100644 --- a/src/modem-manager/nm-modem.h +++ b/src/modem-manager/nm-modem.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 Red Hat, Inc. + * Copyright (C) 2009 - 2010 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ @@ -46,7 +46,8 @@ G_BEGIN_DECLS #define NM_MODEM_PPP_FAILED "ppp-failed" #define NM_MODEM_PREPARE_RESULT "prepare-result" #define NM_MODEM_IP4_CONFIG_RESULT "ip4-config-result" -#define NM_MODEM_NEED_AUTH "need-auth" +#define NM_MODEM_AUTH_REQUESTED "auth-requested" +#define NM_MODEM_AUTH_RESULT "auth-result" typedef struct { GObject parent; @@ -85,12 +86,8 @@ typedef struct { void (*prepare_result) (NMModem *self, gboolean success, NMDeviceStateReason reason); void (*ip4_config_result) (NMModem *self, const char *iface, NMIP4Config *config, GError *error); - void (*need_auth) (NMModem *self, - const char *setting_name, - gboolean retry, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2); + void (*auth_requested) (NMModem *self); + void (*auth_result) (NMModem *self, GError *error); } NMModemClass; GType nm_modem_get_type (void); @@ -129,6 +126,11 @@ NMActStageReturn nm_modem_stage4_get_ip4_config (NMModem *modem, NMIP4Config **config, NMDeviceStateReason *reason); +gboolean nm_modem_get_secrets (NMModem *modem, + const char *setting_name, + gboolean request_new, + const char *hint); + void nm_modem_deactivate_quickly (NMModem *modem, NMDevice *device); void nm_modem_device_state_changed (NMModem *modem, @@ -140,12 +142,6 @@ gboolean nm_modem_hw_is_up (NMModem *modem, NMDevice *device); gboolean nm_modem_hw_bring_up (NMModem *modem, NMDevice *device, gboolean *no_firmware); -gboolean nm_modem_connection_secrets_updated (NMModem *modem, - NMActRequest *req, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller); - const DBusGObjectInfo *nm_modem_get_serial_dbus_info (void); gboolean nm_modem_get_mm_enabled (NMModem *self); diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 4d8d0d860..57b199b50 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -37,22 +37,16 @@ #include "nm-dbus-glib-types.h" -static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class); +G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) -G_DEFINE_TYPE_EXTENDED (NMActRequest, nm_act_request, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE, - secrets_provider_interface_init)) - -#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_ACT_REQUEST, NMActRequestPrivate)) +#define NM_ACT_REQUEST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_ACT_REQUEST, \ + NMActRequestPrivate)) enum { - CONNECTION_SECRETS_UPDATED, - CONNECTION_SECRETS_FAILED, PROPERTIES_CHANGED, - LAST_SIGNAL }; - static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { @@ -64,7 +58,9 @@ typedef struct { gboolean disposed; NMConnection *connection; - guint32 secrets_call_id; + + NMAgentManager *agent_mgr; + GSList *secrets_calls; char *specific_object; NMDevice *device; @@ -94,292 +90,9 @@ enum { LAST_PROP }; +/*******************************************************************/ -static void -device_state_changed (NMDevice *device, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) -{ - NMActRequest *self = NM_ACT_REQUEST (user_data); - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); - NMActiveConnectionState new_ac_state; - gboolean new_default = FALSE, new_default6 = FALSE; - - /* Set NMActiveConnection state based on the device's state */ - switch (new_state) { - case NM_DEVICE_STATE_PREPARE: - case NM_DEVICE_STATE_CONFIG: - case NM_DEVICE_STATE_NEED_AUTH: - case NM_DEVICE_STATE_IP_CONFIG: - new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING; - break; - case NM_DEVICE_STATE_ACTIVATED: - new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED; - new_default = priv->is_default; - new_default6 = priv->is_default6; - break; - default: - new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - break; - } - - if (new_ac_state != priv->state) { - priv->state = new_ac_state; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE); - } - - if (new_default != priv->is_default) { - priv->is_default = new_default; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT); - } - - if (new_default6 != priv->is_default6) { - priv->is_default6 = new_default6; - g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6); - } -} - -NMActRequest * -nm_act_request_new (NMConnection *connection, - const char *specific_object, - gboolean user_requested, - gboolean assumed, - gpointer *device) -{ - GObject *object; - NMActRequestPrivate *priv; - - g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (NM_DEVICE (device), NULL); - - object = g_object_new (NM_TYPE_ACT_REQUEST, NULL); - if (!object) - return NULL; - - priv = NM_ACT_REQUEST_GET_PRIVATE (object); - - priv->connection = g_object_ref (connection); - if (specific_object) - priv->specific_object = g_strdup (specific_object); - - priv->device = NM_DEVICE (device); - g_signal_connect (device, "state-changed", - G_CALLBACK (device_state_changed), - NM_ACT_REQUEST (object)); - - priv->user_requested = user_requested; - priv->assumed = assumed; - - return NM_ACT_REQUEST (object); -} - -static void -nm_act_request_init (NMActRequest *req) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); - NMDBusManager *dbus_mgr; - - priv->ac_path = nm_active_connection_get_next_object_path (); - priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; - - dbus_mgr = nm_dbus_manager_get (); - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), - priv->ac_path, - G_OBJECT (req)); - g_object_unref (dbus_mgr); -} - -static void -dispose (GObject *object) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - - if (priv->disposed) { - G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); - return; - } - priv->disposed = TRUE; - - g_assert (priv->connection); - - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device), - G_CALLBACK (device_state_changed), - NM_ACT_REQUEST (object)); - - /* Clear any share rules */ - nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE); - - g_object_unref (priv->connection); - - G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); -} - -static void -clear_share_rules (NMActRequest *req) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); - GSList *iter; - - for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) { - ShareRule *rule = (ShareRule *) iter->data; - - g_free (rule->table); - g_free (rule->rule); - g_free (rule); - } - - g_slist_free (priv->share_rules); - priv->share_rules = NULL; -} - -static void -finalize (GObject *object) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - - g_free (priv->specific_object); - g_free (priv->ac_path); - - clear_share_rules (NM_ACT_REQUEST (object)); - - G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object); -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); - GPtrArray *devices; - - switch (prop_id) { - case PROP_CONNECTION: - g_value_set_boxed (value, nm_connection_get_path (priv->connection)); - break; - case PROP_SPECIFIC_OBJECT: - if (priv->specific_object) - g_value_set_boxed (value, priv->specific_object); - else - g_value_set_boxed (value, "/"); - break; - case PROP_DEVICES: - devices = g_ptr_array_sized_new (1); - g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device))); - g_value_take_boxed (value, devices); - break; - case PROP_STATE: - g_value_set_uint (value, priv->state); - break; - case PROP_DEFAULT: - g_value_set_boolean (value, priv->is_default); - break; - case PROP_DEFAULT6: - g_value_set_boolean (value, priv->is_default6); - break; - case PROP_VPN: - g_value_set_boolean (value, FALSE); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_act_request_class_init (NMActRequestClass *req_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (req_class); - - g_type_class_add_private (req_class, sizeof (NMActRequestPrivate)); - - /* virtual methods */ - object_class->get_property = get_property; - object_class->dispose = dispose; - object_class->finalize = finalize; - - /* properties */ - g_object_class_install_property - (object_class, PROP_CONNECTION, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, - "Connection", - "Connection", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - g_object_class_install_property - (object_class, PROP_SPECIFIC_OBJECT, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, - "Specific object", - "Specific object", - DBUS_TYPE_G_OBJECT_PATH, - G_PARAM_READABLE)); - g_object_class_install_property - (object_class, PROP_DEVICES, - g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, - "Devices", - "Devices", - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, - G_PARAM_READABLE)); - g_object_class_install_property - (object_class, PROP_STATE, - g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, - "State", - "State", - NM_ACTIVE_CONNECTION_STATE_UNKNOWN, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NM_ACTIVE_CONNECTION_STATE_UNKNOWN, - G_PARAM_READABLE)); - g_object_class_install_property - (object_class, PROP_DEFAULT, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, - "Default", - "Is the default IPv4 active connection", - FALSE, - G_PARAM_READABLE)); - g_object_class_install_property - (object_class, PROP_DEFAULT6, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, - "Default6", - "Is the default IPv6 active connection", - FALSE, - G_PARAM_READABLE)); - g_object_class_install_property - (object_class, PROP_VPN, - g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, - "VPN", - "Is a VPN connection", - FALSE, - G_PARAM_READABLE)); - - /* Signals */ - signals[CONNECTION_SECRETS_UPDATED] = - g_signal_new ("connection-secrets-updated", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMActRequestClass, secrets_updated), - NULL, NULL, - _nm_marshal_VOID__OBJECT_POINTER_UINT, - G_TYPE_NONE, 3, - G_TYPE_OBJECT, G_TYPE_POINTER, G_TYPE_UINT); - - signals[CONNECTION_SECRETS_FAILED] = - g_signal_new ("connection-secrets-failed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMActRequestClass, secrets_failed), - NULL, NULL, - _nm_marshal_VOID__OBJECT_STRING_UINT, - G_TYPE_NONE, 3, - G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_UINT); - - signals[PROPERTIES_CHANGED] = - nm_properties_changed_signal_new (object_class, - G_STRUCT_OFFSET (NMActRequestClass, properties_changed)); - - nm_active_connection_install_type_info (object_class); -} - +#if 0 static gboolean secrets_update_setting (NMSecretsProviderInterface *interface, const char *setting_name, @@ -434,55 +147,83 @@ secrets_update_setting (NMSecretsProviderInterface *interface, return TRUE; } +#endif static void -secrets_result (NMSecretsProviderInterface *interface, - const char *setting_name, - RequestSecretsCaller caller, - const GSList *updated, - GError *error) +get_secrets_cb (NMAgentManager *manager, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data, + gpointer user_data2, + gpointer user_data3) { - NMActRequest *self = NM_ACT_REQUEST (interface); + NMActRequest *self = NM_ACT_REQUEST (user_data); NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + NMActRequestSecretsFunc callback = user_data2; - g_return_if_fail (priv->connection != NULL); + priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id)); - if (error) { - g_signal_emit (self, signals[CONNECTION_SECRETS_FAILED], 0, - priv->connection, setting_name, caller); - } else { - g_signal_emit (self, signals[CONNECTION_SECRETS_UPDATED], 0, - priv->connection, updated, caller); + callback (self, call_id, connection, error, user_data3); +} + +guint32 +nm_act_request_get_secrets (NMActRequest *self, + NMConnection *connection, + const char *setting_name, + gboolean request_new, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data) +{ + NMActRequestPrivate *priv; + guint32 call_id; + + g_return_val_if_fail (self, 0); + g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); + + priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + /* If given a connection (ie, called from an NMVpnConnection) then + * use that, otherwise use the private connection. + * + * FIXME: this is icky, and should go away when NMVPNConnection finally + * uses NMActRequest for activation tracking instead of impersonating one + * itself. + */ + call_id = nm_agent_manager_get_secrets (priv->agent_mgr, + connection ? connection : priv->connection, + setting_name, + request_new, + hint, + get_secrets_cb, + self, + callback, + callback_data); + if (call_id > 0) + priv->secrets_calls = g_slist_append (priv->secrets_calls, GUINT_TO_POINTER (call_id)); + + return call_id; +} + +void +nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) +{ + NMActRequestPrivate *priv; + + g_return_if_fail (self); + g_return_if_fail (NM_IS_ACT_REQUEST (self)); + g_return_if_fail (call_id > 0); + + priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + if (g_slist_find (priv->secrets_calls, GUINT_TO_POINTER (call_id))) { + priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id)); + nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); } } -static void -secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class) -{ - /* interface implementation */ - sp_interface_class->update_setting = secrets_update_setting; - sp_interface_class->result = secrets_result; -} - -gboolean -nm_act_request_get_secrets (NMActRequest *self, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2) -{ - g_return_val_if_fail (self, FALSE); - g_return_val_if_fail (NM_IS_ACT_REQUEST (self), FALSE); - - return nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self), - nm_act_request_get_connection (self), - setting_name, - request_new, - caller, - hint1, - hint2); -} +/*******************************************************************/ NMConnection * nm_act_request_get_connection (NMActRequest *req) @@ -578,6 +319,42 @@ nm_act_request_get_default6 (NMActRequest *req) return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default6; } +GObject * +nm_act_request_get_device (NMActRequest *req) +{ + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); + + return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device); +} + +gboolean +nm_act_request_get_assumed (NMActRequest *req) +{ + g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); + + return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed; +} + +/********************************************************************/ + +static void +clear_share_rules (NMActRequest *req) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); + GSList *iter; + + for (iter = priv->share_rules; iter; iter = g_slist_next (iter)) { + ShareRule *rule = (ShareRule *) iter->data; + + g_free (rule->table); + g_free (rule->rule); + g_free (rule); + } + + g_slist_free (priv->share_rules); + priv->share_rules = NULL; +} + static void share_child_setup (gpointer user_data G_GNUC_UNUSED) { @@ -664,26 +441,273 @@ nm_act_request_add_share_rule (NMActRequest *req, g_return_if_fail (NM_IS_ACT_REQUEST (req)); g_return_if_fail (table != NULL); g_return_if_fail (table_rule != NULL); - + rule = g_malloc0 (sizeof (ShareRule)); rule->table = g_strdup (table); rule->rule = g_strdup (table_rule); priv->share_rules = g_slist_append (priv->share_rules, rule); } -GObject * -nm_act_request_get_device (NMActRequest *req) -{ - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); +/********************************************************************/ - return G_OBJECT (NM_ACT_REQUEST_GET_PRIVATE (req)->device); +static void +device_state_changed (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + NMActRequest *self = NM_ACT_REQUEST (user_data); + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + NMActiveConnectionState new_ac_state; + gboolean new_default = FALSE, new_default6 = FALSE; + + /* Set NMActiveConnection state based on the device's state */ + switch (new_state) { + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + case NM_DEVICE_STATE_IP_CONFIG: + new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATING; + break; + case NM_DEVICE_STATE_ACTIVATED: + new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED; + new_default = priv->is_default; + new_default6 = priv->is_default6; + break; + default: + new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; + break; + } + + if (new_ac_state != priv->state) { + priv->state = new_ac_state; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_STATE); + } + + if (new_default != priv->is_default) { + priv->is_default = new_default; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT); + } + + if (new_default6 != priv->is_default6) { + priv->is_default6 = new_default6; + g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6); + } } -gboolean -nm_act_request_get_assumed (NMActRequest *req) -{ - g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE); +/********************************************************************/ - return NM_ACT_REQUEST_GET_PRIVATE (req)->assumed; +NMActRequest * +nm_act_request_new (NMConnection *connection, + const char *specific_object, + NMAgentManager *agent_mgr, + gboolean user_requested, + gboolean assumed, + gpointer *device) +{ + GObject *object; + NMActRequestPrivate *priv; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_AGENT_MANAGER (agent_mgr), NULL); + g_return_val_if_fail (NM_DEVICE (device), NULL); + + object = g_object_new (NM_TYPE_ACT_REQUEST, NULL); + if (!object) + return NULL; + + priv = NM_ACT_REQUEST_GET_PRIVATE (object); + + priv->connection = g_object_ref (connection); + if (specific_object) + priv->specific_object = g_strdup (specific_object); + + priv->agent_mgr = g_object_ref (agent_mgr); + + priv->device = NM_DEVICE (device); + g_signal_connect (device, "state-changed", + G_CALLBACK (device_state_changed), + NM_ACT_REQUEST (object)); + + priv->user_requested = user_requested; + priv->assumed = assumed; + + return NM_ACT_REQUEST (object); +} + +static void +nm_act_request_init (NMActRequest *req) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); + NMDBusManager *dbus_mgr; + + priv->ac_path = nm_active_connection_get_next_object_path (); + priv->state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN; + + dbus_mgr = nm_dbus_manager_get (); + dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), + priv->ac_path, + G_OBJECT (req)); + g_object_unref (dbus_mgr); +} + +static void +get_property (GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); + GPtrArray *devices; + + switch (prop_id) { + case PROP_CONNECTION: + g_value_set_boxed (value, nm_connection_get_path (priv->connection)); + break; + case PROP_SPECIFIC_OBJECT: + if (priv->specific_object) + g_value_set_boxed (value, priv->specific_object); + else + g_value_set_boxed (value, "/"); + break; + case PROP_DEVICES: + devices = g_ptr_array_sized_new (1); + g_ptr_array_add (devices, g_strdup (nm_device_get_path (priv->device))); + g_value_take_boxed (value, devices); + break; + case PROP_STATE: + g_value_set_uint (value, priv->state); + break; + case PROP_DEFAULT: + g_value_set_boolean (value, priv->is_default); + break; + case PROP_DEFAULT6: + g_value_set_boolean (value, priv->is_default6); + break; + case PROP_VPN: + g_value_set_boolean (value, FALSE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); + GSList *iter; + + if (priv->disposed) { + G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); + return; + } + priv->disposed = TRUE; + + g_assert (priv->connection); + + g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device), + G_CALLBACK (device_state_changed), + NM_ACT_REQUEST (object)); + + /* Clear any share rules */ + nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE); + + g_object_unref (priv->connection); + + for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { + nm_agent_manager_cancel_secrets (priv->agent_mgr, + GPOINTER_TO_UINT (iter->data)); + } + g_slist_free (priv->secrets_calls); + g_object_unref (priv->agent_mgr); + + G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (object); + + g_free (priv->specific_object); + g_free (priv->ac_path); + + clear_share_rules (NM_ACT_REQUEST (object)); + + G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object); +} + +static void +nm_act_request_class_init (NMActRequestClass *req_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (req_class); + + g_type_class_add_private (req_class, sizeof (NMActRequestPrivate)); + + /* virtual methods */ + object_class->get_property = get_property; + object_class->dispose = dispose; + object_class->finalize = finalize; + + /* properties */ + g_object_class_install_property + (object_class, PROP_CONNECTION, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, + "Connection", + "Connection", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_SPECIFIC_OBJECT, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, + "Specific object", + "Specific object", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, + "Devices", + "Devices", + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_STATE, + g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE, + "State", + "State", + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + NM_ACTIVE_CONNECTION_STATE_UNKNOWN, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_DEFAULT, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, + "Default", + "Is the default IPv4 active connection", + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_DEFAULT6, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6, + "Default6", + "Is the default IPv6 active connection", + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_VPN, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, + "VPN", + "Is a VPN connection", + FALSE, + G_PARAM_READABLE)); + + /* Signals */ + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMActRequestClass, properties_changed)); + + nm_active_connection_install_type_info (object_class); } diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index a24369452..172ebf39a 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -25,7 +25,7 @@ #include #include "nm-connection.h" #include "nm-active-connection.h" -#include "nm-secrets-provider-interface.h" +#include "nm-agent-manager.h" #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) @@ -42,15 +42,6 @@ typedef struct { GObjectClass parent; /* Signals */ - void (*secrets_updated) (NMActRequest *req, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller); - void (*secrets_failed) (NMActRequest *req, - NMConnection *connection, - const char *setting, - RequestSecretsCaller caller); - void (*properties_changed) (NMActRequest *req, GHashTable *properties); } NMActRequestClass; @@ -58,6 +49,7 @@ GType nm_act_request_get_type (void); NMActRequest *nm_act_request_new (NMConnection *connection, const char *specific_object, + NMAgentManager *agent_mgr, gboolean user_requested, gboolean assumed, gpointer *device); /* An NMDevice */ @@ -92,12 +84,23 @@ GObject * nm_act_request_get_device (NMActRequest *req); gboolean nm_act_request_get_assumed (NMActRequest *req); -gboolean nm_act_request_get_secrets (NMActRequest *req, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2); +/* Secrets handling */ + +typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data); + +guint32 nm_act_request_get_secrets (NMActRequest *req, + NMConnection *connection, /* NULL == use activation request's connection */ + const char *setting_name, + gboolean request_new, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data); + +void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id); #endif /* NM_ACTIVATION_REQUEST_H */ diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 378143bfe..b92c8971e 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -31,6 +31,7 @@ #include "nm-agent-manager.h" #include "nm-secret-agent.h" #include "nm-manager-auth.h" +#include "nm-sysconfig-connection.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -48,6 +49,8 @@ typedef struct { * sessions can use the same identifier. */ GHashTable *agents; + + GHashTable *requests; } NMAgentManagerPrivate; @@ -296,6 +299,222 @@ done: /*************************************************************/ +typedef struct _Request Request; + +typedef void (*RequestNextFunc) (Request *req, gpointer user_data); +typedef void (*RequestCompleteFunc) (Request *req, + GHashTable *secrets, + GError *error, + gpointer user_data); + +struct _Request { + guint32 reqid; + + NMConnection *connection; + char *setting_name; + gboolean request_new; + char *hint; + + guint32 idle_id; + + NMAgentSecretsResultFunc callback; + gpointer callback_data; + gpointer other_data2; + gpointer other_data3; + + RequestNextFunc next_callback; + RequestCompleteFunc complete_callback; + gpointer req_callback_data; +}; + +static Request * +request_new (NMConnection *connection, + const char *setting_name, + gboolean get_new, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3) +{ + Request *req; + static guint32 next_id = 1; + + req = g_malloc0 (sizeof (Request)); + req->reqid = next_id++; + req->connection = g_object_ref (connection); + req->setting_name = g_strdup (setting_name); + req->request_new = get_new; + req->hint = g_strdup (hint); + req->callback = callback; + req->callback_data = callback_data; + req->other_data2 = other_data2; + req->other_data3 = other_data3; + + return req; +} + +static void +request_free (Request *req) +{ + if (req->idle_id) + g_source_remove (req->idle_id); + + g_object_unref (req->connection); + g_free (req->setting_name); + g_free (req->hint); + memset (req, 0, sizeof (Request)); + g_free (req); +} + +static void +request_set_callbacks (Request *req, + RequestNextFunc next_func, + RequestCompleteFunc complete_func, + gpointer user_data) +{ + req->next_callback = next_func; + req->complete_callback = complete_func; + req->req_callback_data = user_data; +} + +static gboolean +request_start_secrets (gpointer user_data) +{ + Request *req = user_data; + GHashTable *secrets; + GError *error = NULL; + + req->idle_id = 0; + + secrets = nm_sysconfig_connection_get_secrets (NM_SYSCONFIG_CONNECTION (req->connection), + req->setting_name, + req->hint, + req->request_new, + &error); + if (secrets) { + /* The connection already had secrets, no need to get any */ + req->complete_callback (req, secrets, NULL, req->req_callback_data); + g_hash_table_destroy (secrets); + } else if (error) + req->complete_callback (req, NULL, error, req->req_callback_data); + else { + /* Couldn't get secrets from system settings, so now we ask the + * agents for secrets. Let the Agent Manager handle which agents + * we'll ask and in which order. + */ + req->next_callback (req, req->req_callback_data); + } + + g_clear_error (&error); + return FALSE; +} + +/*************************************************************/ + +static void +mgr_req_next_cb (Request *req, gpointer user_data) +{ +#if 0 + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + /* Look for the next agent to call for secrets based on whether that + * agent's user is in the connection's ACL. + */ +#endif +} + +static void +mgr_req_complete_cb (Request *req, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + GError *local = NULL; + + if (error) + local = g_error_copy (error); + else { + /* Save the secrets into the connection */ + nm_connection_update_secrets (req->connection, + req->setting_name, + secrets, + &local); + } + + if (local) { + nm_log_warn (LOGD_SETTINGS, + "Failed to %s connection secrets: (%d) %s", + error ? "get" : "update", + local->code, + local->message ? local->message : "(none)"); + } + + /* Call the activation requests' secrets callback */ + req->callback (self, + req->reqid, + req->connection, + local, + req->callback_data, + req->other_data2, + req->other_data3); + + g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); + g_clear_error (&local); +} + +guint32 +nm_agent_manager_get_secrets (NMAgentManager *self, + NMConnection *connection, + const char *setting_name, + gboolean get_new, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + Request *req; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), 0); + g_return_val_if_fail (callback != NULL, 0); + + req = request_new (connection, + setting_name, + get_new, + hint, + callback, + callback_data, + other_data2, + other_data3); + request_set_callbacks (req, mgr_req_next_cb, mgr_req_complete_cb, self); + + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + + req->idle_id = g_idle_add (request_start_secrets, req); + + return req->reqid; +} + +void +nm_agent_manager_cancel_secrets (NMAgentManager *self, + guint32 request_id) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (request_id > 0); + + g_hash_table_remove (NM_AGENT_MANAGER_GET_PRIVATE (self)->requests, + GUINT_TO_POINTER (request_id)); +} + +/*************************************************************/ + static void name_owner_changed_cb (NMDBusManager *dbus_mgr, const char *name, @@ -312,7 +531,7 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr, /*************************************************************/ NMAgentManager * -nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor) +nm_agent_manager_new (NMDBusManager *dbus_mgr) { NMAgentManager *self; NMAgentManagerPrivate *priv; @@ -324,7 +543,7 @@ nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor if (self) { priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - priv->session_monitor = g_object_ref (session_monitor); + priv->session_monitor = nm_session_monitor_get (); priv->dbus_mgr = g_object_ref (dbus_mgr); connection = nm_dbus_manager_get_connection (dbus_mgr); dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_AGENT_MANAGER, G_OBJECT (self)); @@ -341,6 +560,13 @@ nm_agent_manager_new (NMDBusManager *dbus_mgr, NMSessionMonitor *session_monitor static void nm_agent_manager_init (NMAgentManager *self) { + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + priv->requests = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify) request_free); } static void @@ -356,6 +582,7 @@ dispose (GObject *object) g_object_unref (priv->dbus_mgr); g_hash_table_destroy (priv->agents); + g_hash_table_destroy (priv->requests); G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); } diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h index 59a31bdd9..4ddd6165d 100644 --- a/src/nm-agent-manager.h +++ b/src/nm-agent-manager.h @@ -24,6 +24,8 @@ #include #include +#include + #include "nm-dbus-manager.h" #include "nm-session-monitor.h" @@ -44,7 +46,27 @@ typedef struct { GType nm_agent_manager_get_type (void); -NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr, - NMSessionMonitor *session_monitor); +NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr); + +typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data, + gpointer user_data2, + gpointer user_data3); + +guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, + NMConnection *connection, + const char *setting_name, + gboolean get_new, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3); + +void nm_agent_manager_cancel_secrets (NMAgentManager *manager, + guint32 request_id); #endif /* NM_AGENT_MANAGER_H */ diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c index 3ef08de8b..f6bd284cc 100644 --- a/src/nm-device-bt.c +++ b/src/nm-device-bt.c @@ -46,6 +46,8 @@ G_DEFINE_TYPE (NMDeviceBt, nm_device_bt, NM_TYPE_DEVICE) #define NM_DEVICE_BT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_BT, NMDeviceBtPrivate)) +static gboolean modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason); + typedef struct { char *bdaddr; char *name; @@ -291,22 +293,30 @@ ppp_failed (NMModem *modem, NMDeviceStateReason reason, gpointer user_data) } static void -modem_need_auth (NMModem *modem, - const char *setting_name, - gboolean retry, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2, - gpointer user_data) +modem_auth_requested (NMModem *modem, gpointer user_data) { - NMDeviceBt *self = NM_DEVICE_BT (user_data); - NMActRequest *req; + nm_device_state_changed (NM_DEVICE (user_data), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NONE); +} - req = nm_device_get_act_request (NM_DEVICE (self)); - g_assert (req); +static void +modem_auth_result (NMModem *modem, GError *error, gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); + NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - nm_act_request_get_secrets (req, setting_name, retry, caller, hint1, hint2); + if (error) { + nm_device_state_changed (device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_NO_SECRETS); + } else { + /* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */ + g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); + if (!modem_stage1 (NM_DEVICE_BT (device), priv->modem, &reason)) + nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); + } } static void @@ -412,41 +422,6 @@ modem_stage1 (NMDeviceBt *self, NMModem *modem, NMDeviceStateReason *reason) return FALSE; } -static void -real_connection_secrets_updated (NMDevice *device, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller) -{ - NMDeviceBt *self = NM_DEVICE_BT (device); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - NMActRequest *req; - NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; - - g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (device))); - - req = nm_device_get_act_request (device); - g_assert (req); - - if (!nm_modem_connection_secrets_updated (priv->modem, - req, - connection, - updated_settings, - caller)) { - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } - - /* PPP handles stuff itself... */ - if (caller == SECRETS_CALLER_PPP) - return; - - /* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */ - g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); - if (!modem_stage1 (self, priv->modem, &reason)) - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, reason); -} - /*****************************************************************************/ gboolean @@ -511,7 +486,8 @@ nm_device_bt_modem_added (NMDeviceBt *self, g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); - g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self); + g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); + g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); /* Kick off the modem connection */ if (!modem_stage1 (self, modem, &reason)) @@ -1019,7 +995,6 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) device_class->get_best_auto_connection = real_get_best_auto_connection; device_class->get_generic_capabilities = real_get_generic_capabilities; - device_class->connection_secrets_updated = real_connection_secrets_updated; device_class->deactivate_quickly = real_deactivate_quickly; device_class->act_stage2_config = real_act_stage2_config; device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start; diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 13139542f..d759df290 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -883,67 +883,6 @@ real_get_best_auto_connection (NMDevice *dev, return NULL; } -static void -real_connection_secrets_updated (NMDevice *dev, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller) -{ - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (dev); - NMActRequest *req; - gboolean valid = FALSE; - GSList *iter; - - g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (dev))); - - /* PPPoE? */ - if (caller == SECRETS_CALLER_PPP) { - NMSettingPPPOE *s_pppoe; - - g_assert (priv->ppp_manager); - - s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); - if (!s_pppoe) { - nm_ppp_manager_update_secrets (priv->ppp_manager, - nm_device_get_iface (dev), - NULL, - NULL, - "missing PPPoE setting; no secrets could be found."); - } else { - const char *pppoe_username = nm_setting_pppoe_get_username (s_pppoe); - const char *pppoe_password = nm_setting_pppoe_get_password (s_pppoe); - - nm_ppp_manager_update_secrets (priv->ppp_manager, - nm_device_get_iface (dev), - pppoe_username ? pppoe_username : "", - pppoe_password ? pppoe_password : "", - NULL); - } - return; - } - - /* Only caller could be ourselves for 802.1x */ - g_return_if_fail (caller == SECRETS_CALLER_ETHERNET); - g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); - - for (iter = updated_settings; iter; iter = g_slist_next (iter)) { - const char *setting_name = (const char *) iter->data; - - if (!strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) { - valid = TRUE; - } else { - nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.", - setting_name); - } - } - - req = nm_device_get_act_request (dev); - g_assert (req); - - g_return_if_fail (nm_act_request_get_connection (req) == connection); - nm_device_activate_schedule_stage1_device_prepare (dev); -} - /* FIXME: Move it to nm-device.c and then get rid of all foo_device_get_setting() all around. It's here now to keep the patch short. */ static NMSetting * @@ -1019,6 +958,28 @@ supplicant_interface_release (NMDeviceEthernet *self) } } +static void +wired_secrets_cb (NMActRequest *req, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + NMDevice *dev = NM_DEVICE (user_data); + + g_return_if_fail (req == nm_device_get_act_request (dev)); + g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); + g_return_if_fail (nm_act_request_get_connection (req) == connection); + + if (error) { + nm_log_warn (LOGD_ETHER, "%s", error->message); + nm_device_state_changed (dev, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_NO_SECRETS); + } else + nm_device_activate_schedule_stage1_device_prepare (dev); +} + static gboolean link_timeout_cb (gpointer user_data) { @@ -1060,11 +1021,12 @@ link_timeout_cb (gpointer user_data) nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, + NULL, setting_name, TRUE, - SECRETS_CALLER_ETHERNET, NULL, - NULL); + wired_secrets_cb, + self); return FALSE; @@ -1249,11 +1211,12 @@ handle_auth_or_fail (NMDeviceEthernet *self, */ get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); nm_act_request_get_secrets (req, + NULL, setting_name, get_new, - SECRETS_CALLER_ETHERNET, NULL, - NULL); + wired_secrets_cb, + self); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else { @@ -1969,7 +1932,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) parent_class->update_initial_hw_address = real_update_initial_hw_address; parent_class->get_best_auto_connection = real_get_best_auto_connection; parent_class->is_available = real_is_available; - parent_class->connection_secrets_updated = real_connection_secrets_updated; parent_class->check_connection_compatible = real_check_connection_compatible; parent_class->act_stage1_prepare = real_act_stage1_prepare; diff --git a/src/nm-device-modem.c b/src/nm-device-modem.c index 441f92cec..440db82f2 100644 --- a/src/nm-device-modem.c +++ b/src/nm-device-modem.c @@ -107,22 +107,27 @@ modem_prepare_result (NMModem *modem, } static void -modem_need_auth (NMModem *modem, - const char *setting_name, - gboolean retry, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2, - gpointer user_data) +modem_auth_requested (NMModem *modem, gpointer user_data) { - NMDeviceModem *self = NM_DEVICE_MODEM (user_data); - NMActRequest *req; + nm_device_state_changed (NM_DEVICE (user_data), + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_REASON_NONE); +} - req = nm_device_get_act_request (NM_DEVICE (self)); - g_assert (req); +static void +modem_auth_result (NMModem *modem, GError *error, gpointer user_data) +{ + NMDevice *device = NM_DEVICE (user_data); - nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NONE); - nm_act_request_get_secrets (req, setting_name, retry, caller, hint1, hint2); + if (error) { + nm_device_state_changed (device, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_NO_SECRETS); + } else { + /* Otherwise, on success for modem secrets we need to schedule stage1 again */ + g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); + nm_device_activate_schedule_stage1_device_prepare (device); + } } static void @@ -205,38 +210,6 @@ real_get_best_auto_connection (NMDevice *device, return nm_modem_get_best_auto_connection (priv->modem, connections, specific_object); } -static void -real_connection_secrets_updated (NMDevice *device, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller) -{ - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); - NMActRequest *req; - - g_return_if_fail (IS_ACTIVATING_STATE (nm_device_get_state (device))); - - req = nm_device_get_act_request (device); - g_assert (req); - - if (!nm_modem_connection_secrets_updated (priv->modem, - req, - connection, - updated_settings, - caller)) { - nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); - return; - } - - /* PPP handles stuff itself... */ - if (caller == SECRETS_CALLER_PPP) - return; - - /* Otherwise, on success for modem secrets we need to schedule stage1 again */ - g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); - nm_device_activate_schedule_stage1_device_prepare (device); -} - static gboolean real_check_connection_compatible (NMDevice *device, NMConnection *connection, @@ -365,7 +338,8 @@ set_modem (NMDeviceModem *self, NMModem *modem) g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); - g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self); + g_signal_connect (modem, NM_MODEM_AUTH_REQUESTED, G_CALLBACK (modem_auth_requested), self); + g_signal_connect (modem, NM_MODEM_AUTH_RESULT, G_CALLBACK (modem_auth_result), self); g_signal_connect (modem, "notify::" NM_MODEM_ENABLED, G_CALLBACK (modem_enabled_cb), self); } @@ -426,7 +400,6 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->get_generic_capabilities = real_get_generic_capabilities; device_class->get_best_auto_connection = real_get_best_auto_connection; - device_class->connection_secrets_updated = real_connection_secrets_updated; device_class->check_connection_compatible = real_check_connection_compatible; device_class->hw_is_up = real_hw_is_up; device_class->hw_bring_up = real_hw_bring_up; diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 49529708b..784a14976 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2245,6 +2245,27 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect) nm_supplicant_interface_disconnect (priv->supplicant.iface); } +static void +wifi_secrets_cb (NMActRequest *req, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + NMDevice *dev = NM_DEVICE (user_data); + + g_return_if_fail (req == nm_device_get_act_request (dev)); + g_return_if_fail (nm_device_get_state (dev) == NM_DEVICE_STATE_NEED_AUTH); + g_return_if_fail (nm_act_request_get_connection (req) == connection); + + if (error) { + nm_log_warn (LOGD_WIFI, "%s", error->message); + nm_device_state_changed (dev, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_NO_SECRETS); + } else + nm_device_activate_schedule_stage1_device_prepare (dev); +} static void remove_link_timeout (NMDeviceWifi *self) @@ -2340,11 +2361,12 @@ link_timeout_cb (gpointer user_data) cleanup_association_attempt (self, TRUE); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, + NULL, setting_name, TRUE, - SECRETS_CALLER_WIFI, NULL, - NULL); + wifi_secrets_cb, + self); return FALSE; } @@ -2586,11 +2608,12 @@ handle_auth_or_fail (NMDeviceWifi *self, */ get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); nm_act_request_get_secrets (req, + NULL, setting_name, get_new, - SECRETS_CALLER_WIFI, NULL, - NULL); + wifi_secrets_cb, + self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else { @@ -2966,42 +2989,6 @@ done: return NM_ACT_STAGE_RETURN_SUCCESS; } - -static void -real_connection_secrets_updated (NMDevice *dev, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller) -{ - NMActRequest *req; - gboolean valid = FALSE; - GSList *iter; - - g_return_if_fail (caller == SECRETS_CALLER_WIFI); - - if (nm_device_get_state (dev) != NM_DEVICE_STATE_NEED_AUTH) - return; - - for (iter = updated_settings; iter; iter = g_slist_next (iter)) { - const char *setting_name = (const char *) iter->data; - - if ( !strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) - || !strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME)) { - valid = TRUE; - } else { - nm_log_warn (LOGD_DEVICE, "Ignoring updated secrets for setting '%s'.", - setting_name); - } - } - - req = nm_device_get_act_request (dev); - g_assert (req); - - g_return_if_fail (nm_act_request_get_connection (req) == connection); - - nm_device_activate_schedule_stage1_device_prepare (dev); -} - static NMActStageReturn real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) { @@ -3712,7 +3699,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->update_initial_hw_address = real_update_initial_hw_address; parent_class->get_best_auto_connection = real_get_best_auto_connection; parent_class->is_available = real_is_available; - parent_class->connection_secrets_updated = real_connection_secrets_updated; parent_class->check_connection_compatible = real_check_connection_compatible; parent_class->act_stage1_prepare = real_act_stage1_prepare; diff --git a/src/nm-device.c b/src/nm-device.c index 27604e523..2765a5de3 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -2849,31 +2849,6 @@ check_connection_compatible (NMDeviceInterface *dev_iface, return TRUE; } -static void -connection_secrets_updated_cb (NMActRequest *req, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - - if (NM_DEVICE_GET_CLASS (self)->connection_secrets_updated) - NM_DEVICE_GET_CLASS (self)->connection_secrets_updated (self, connection, updated_settings, caller); -} - -static void -connection_secrets_failed_cb (NMActRequest *req, - NMConnection *connection, - const char *setting_name, - RequestSecretsCaller caller, - gpointer user_data) -{ - NMDevice *self = NM_DEVICE (user_data); - - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); -} - static gboolean device_activation_precheck (NMDevice *self, NMConnection *connection, GError **error) { @@ -2916,14 +2891,6 @@ nm_device_activate (NMDeviceInterface *device, } priv->act_request = g_object_ref (req); - priv->secrets_updated_id = g_signal_connect (req, - "connection-secrets-updated", - G_CALLBACK (connection_secrets_updated_cb), - device); - priv->secrets_failed_id = g_signal_connect (req, - "connection-secrets-failed", - G_CALLBACK (connection_secrets_failed_cb), - device); if (!nm_act_request_get_assumed (req)) { /* HACK: update the state a bit early to avoid a race between the diff --git a/src/nm-device.h b/src/nm-device.h index db2b1b7db..e7d347cbc 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -84,11 +84,6 @@ typedef struct { GSList *connections, char **specific_object); - void (* connection_secrets_updated) (NMDevice *self, - NMConnection *connection, - GSList *updated_settings, - RequestSecretsCaller caller); - gboolean (* check_connection_compatible) (NMDevice *self, NMConnection *connection, GError **error); diff --git a/src/nm-manager.c b/src/nm-manager.c index 3002debf6..23551d381 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -54,8 +54,8 @@ #include "nm-bluez-common.h" #include "nm-settings.h" #include "nm-sysconfig-connection.h" -#include "nm-secrets-provider-interface.h" #include "nm-manager-auth.h" +#include "nm-agent-manager.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" #define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd" @@ -202,8 +202,7 @@ typedef struct { NMSettings *settings; char *hostname; - - GSList *secrets_calls; + NMAgentManager *agent_mgr; RadioState radio_states[RFKILL_TYPE_MAX]; gboolean sleeping; @@ -1718,194 +1717,6 @@ nm_manager_get_act_request_by_path (NMManager *manager, return NULL; } -typedef struct GetSecretsInfo { - NMManager *manager; - NMSecretsProviderInterface *provider; - - char *setting_name; - RequestSecretsCaller caller; - gboolean request_new; - - /* User connection bits */ - DBusGProxy *proxy; - DBusGProxyCall *call; - - /* System connection bits */ - guint32 idle_id; - char *hint1; - char *hint2; - char *connection_path; -} GetSecretsInfo; - -static void -free_get_secrets_info (gpointer data) -{ - GetSecretsInfo *info = data; - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); - - g_object_weak_unref (G_OBJECT (info->provider), (GWeakNotify) free_get_secrets_info, info); - - priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); - - if (info->proxy) { - if (info->call) - dbus_g_proxy_cancel_call (info->proxy, info->call); - g_object_unref (info->proxy); - } - - if (info->idle_id) - g_source_remove (info->idle_id); - - g_free (info->hint1); - g_free (info->hint2); - g_free (info->setting_name); - g_free (info->connection_path); - memset (info, 0, sizeof (GetSecretsInfo)); - g_free (info); -} - -static void -provider_cancel_secrets (NMSecretsProviderInterface *provider, gpointer user_data) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (user_data); - GSList *iter; - - for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { - GetSecretsInfo *candidate = iter->data; - - if (candidate->provider == provider) { - free_get_secrets_info (candidate); - break; - } - } -} - -static void -system_get_secrets_reply_cb (NMSysconfigConnection *connection, - GHashTable *secrets, - GError *error, - gpointer user_data) -{ - GetSecretsInfo *info = user_data; - GObject *provider; - - provider = g_object_ref (info->provider); - - nm_secrets_provider_interface_get_secrets_result (info->provider, - info->setting_name, - info->caller, - error ? NULL : secrets, - error); - free_get_secrets_info (info); - g_object_unref (provider); -} - -static gboolean -system_get_secrets_idle_cb (gpointer user_data) -{ - GetSecretsInfo *info = user_data; - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (info->manager); - NMSysconfigConnection *connection; - GError *error = NULL; - const char *hints[3] = { NULL, NULL, NULL }; - - info->idle_id = 0; - - connection = nm_settings_get_connection_by_path (priv->settings, info->connection_path); - if (!connection) { - error = g_error_new_literal (NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "unknown connection (not exported by system settings)"); - nm_secrets_provider_interface_get_secrets_result (info->provider, - info->setting_name, - info->caller, - NULL, - error); - g_error_free (error); - free_get_secrets_info (info); - return FALSE; - } - - hints[0] = info->hint1; - hints[1] = info->hint2; - nm_sysconfig_connection_get_secrets (connection, - info->setting_name, - hints, - info->request_new, - system_get_secrets_reply_cb, - info); - return FALSE; -} - -static GetSecretsInfo * -system_get_secrets (NMManager *self, - NMSecretsProviderInterface *provider, - NMConnection *connection, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller_id, - const char *hint1, - const char *hint2) -{ - GetSecretsInfo *info; - - info = g_malloc0 (sizeof (GetSecretsInfo)); - info->manager = self; - info->provider = provider; - info->caller = caller_id; - info->setting_name = g_strdup (setting_name); - info->hint1 = hint1 ? g_strdup (hint1) : NULL; - info->hint2 = hint2 ? g_strdup (hint2) : NULL; - info->connection_path = g_strdup (nm_connection_get_path (connection)); - info->request_new = request_new; - - g_object_weak_ref (G_OBJECT (provider), (GWeakNotify) free_get_secrets_info, info); - - info->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - system_get_secrets_idle_cb, - info, - NULL); - return info; -} - -static gboolean -provider_get_secrets (NMSecretsProviderInterface *provider, - NMConnection *connection, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller_id, - const char *hint1, - const char *hint2, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GetSecretsInfo *info = NULL; - GSList *iter; - - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (setting_name != NULL, FALSE); - - /* Tear down any pending secrets requests for this secrets provider */ - for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { - GetSecretsInfo *candidate = iter->data; - - if (provider == candidate->provider) { - free_get_secrets_info (candidate); - break; - } - } - - /* Build up the new secrets request */ - info = system_get_secrets (self, provider, connection, setting_name, - request_new, caller_id, hint1, hint2); - - if (info) - priv->secrets_calls = g_slist_append (priv->secrets_calls, info); - - return !!info; -} - static const char * internal_activate_device (NMManager *manager, NMDevice *device, @@ -1936,9 +1747,12 @@ internal_activate_device (NMManager *manager, NM_DEVICE_STATE_REASON_NONE); } - req = nm_act_request_new (connection, specific_object, user_requested, assumed, (gpointer) device); - g_signal_connect (req, "manager-get-secrets", G_CALLBACK (provider_get_secrets), manager); - g_signal_connect (req, "manager-cancel-secrets", G_CALLBACK (provider_cancel_secrets), manager); + req = nm_act_request_new (connection, + specific_object, + NM_MANAGER_GET_PRIVATE (manager)->agent_mgr, + user_requested, + assumed, + (gpointer) device); success = nm_device_interface_activate (dev_iface, req, error); g_object_unref (req); @@ -1970,15 +1784,15 @@ nm_manager_activate_connection (NMManager *manager, g_assert (s_con); if (!strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_VPN_SETTING_NAME)) { - NMActRequest *req = NULL; + NMActRequest *parent_req = NULL; NMVPNManager *vpn_manager; /* VPN connection */ if (specific_object) { /* Find the specifc connection the client requested we use */ - req = nm_manager_get_act_request_by_path (manager, specific_object, &device); - if (!req) { + parent_req = nm_manager_get_act_request_by_path (manager, specific_object, &device); + if (!parent_req) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "%s", "Base connection for VPN connection not active."); @@ -1995,13 +1809,13 @@ nm_manager_activate_connection (NMManager *manager, candidate_req = nm_device_get_act_request (candidate); if (candidate_req && nm_act_request_get_default (candidate_req)) { device = candidate; - req = candidate_req; + parent_req = candidate_req; break; } } } - if (!device || !req) { + if (!device || !parent_req) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, "%s", "Could not find source connection, or the source connection had no active device."); @@ -2011,16 +1825,11 @@ nm_manager_activate_connection (NMManager *manager, vpn_manager = nm_vpn_manager_get (); vpn_connection = nm_vpn_manager_activate_connection (vpn_manager, connection, - req, + parent_req, device, error); - if (vpn_connection) { - g_signal_connect (vpn_connection, "manager-get-secrets", - G_CALLBACK (provider_get_secrets), manager); - g_signal_connect (vpn_connection, "manager-cancel-secrets", - G_CALLBACK (provider_cancel_secrets), manager); + if (vpn_connection) path = nm_vpn_connection_get_active_connection_path (vpn_connection); - } g_object_unref (vpn_manager); } else { NMDeviceState state; @@ -3072,6 +2881,8 @@ nm_manager_get (NMSettings *settings, priv->settings = g_object_ref (settings); + priv->agent_mgr = nm_agent_manager_new (priv->dbus_mgr); + priv->config_file = g_strdup (config_file); priv->state_file = g_strdup (state_file); @@ -3142,9 +2953,6 @@ dispose (GObject *object) g_slist_free (priv->auth_chains); g_object_unref (priv->authority); - while (g_slist_length (priv->secrets_calls)) - free_get_secrets_info ((GetSecretsInfo *) priv->secrets_calls->data); - while (g_slist_length (priv->devices)) { priv->devices = remove_one_device (manager, priv->devices, @@ -3157,6 +2965,8 @@ dispose (GObject *object) g_object_unref (priv->settings); + g_object_unref (priv->agent_mgr); + if (priv->vpn_manager_id) { g_source_remove (priv->vpn_manager_id); priv->vpn_manager_id = 0; diff --git a/src/nm-secrets-provider-interface.c b/src/nm-secrets-provider-interface.c deleted file mode 100644 index 47b8e57ef..000000000 --- a/src/nm-secrets-provider-interface.c +++ /dev/null @@ -1,224 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 Red Hat, Inc. - */ - -#include - -#include "nm-marshal.h" -#include "nm-secrets-provider-interface.h" - -#include -#include -#include "nm-logging.h" - -static void -nm_secrets_provider_interface_init (gpointer g_iface) -{ - GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); - static gboolean initialized = FALSE; - - if (initialized) - return; - initialized = TRUE; - - /* Signals */ - g_signal_new ("manager-get-secrets", - iface_type, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_get_secrets), - NULL, NULL, - _nm_marshal_BOOLEAN__POINTER_STRING_BOOLEAN_UINT_STRING_STRING, - G_TYPE_BOOLEAN, 6, - G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); - - g_signal_new ("manager-cancel-secrets", - iface_type, - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSecretsProviderInterface, manager_cancel_secrets), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - - -GType -nm_secrets_provider_interface_get_type (void) -{ - static GType interface_type = 0; - - if (!interface_type) { - const GTypeInfo interface_info = { - sizeof (NMSecretsProviderInterface), /* class_size */ - nm_secrets_provider_interface_init, /* base_init */ - NULL, /* base_finalize */ - NULL, - NULL, /* class_finalize */ - NULL, /* class_data */ - 0, - 0, /* n_preallocs */ - NULL - }; - - interface_type = g_type_register_static (G_TYPE_INTERFACE, - "NMSecretsProviderInterface", - &interface_info, 0); - - g_type_interface_add_prerequisite (interface_type, G_TYPE_OBJECT); - } - - return interface_type; -} - -gboolean -nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self, - NMConnection *connection, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2) -{ - guint success = FALSE; - - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self), FALSE); - g_return_val_if_fail (connection != NULL, FALSE); - g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - g_return_val_if_fail (setting_name != NULL, FALSE); - - nm_secrets_provider_interface_cancel_get_secrets (self); - - g_signal_emit_by_name (self, "manager-get-secrets", - connection, setting_name, request_new, caller, hint1, hint2, - &success); - if (!success) { - nm_log_warn (LOGD_CORE, "failed to get connection secrets."); - return FALSE; - } - - return TRUE; -} - -void -nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self) -{ - g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self)); - - g_signal_emit_by_name (self, "manager-cancel-secrets"); -} - - -static void -add_one_key_to_list (gpointer key, gpointer data, gpointer user_data) -{ - GSList **list = (GSList **) user_data; - - *list = g_slist_append (*list, key); -} - -static gint -settings_order_func (gconstpointer a, gconstpointer b) -{ - /* Just ensure the 802.1x setting gets processed _before_ the - * wireless-security one. - */ - - if ( !strcmp (a, NM_SETTING_802_1X_SETTING_NAME) - && !strcmp (b, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME)) - return -1; - - if ( !strcmp (a, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) - && !strcmp (b, NM_SETTING_802_1X_SETTING_NAME)) - return 1; - - return 0; -} - -void -nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self, - const char *setting_name, - RequestSecretsCaller caller, - GHashTable *settings, - GError *error) -{ - GSList *keys = NULL, *iter; - GSList *updated = NULL; - GError *tmp_error = NULL; - - g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_SECRETS_PROVIDER_INTERFACE (self)); - - if (error) { - NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, - setting_name, - caller, - NULL, - error); - return; - } - - if (g_hash_table_size (settings) == 0) { - g_set_error (&tmp_error, 0, 0, "%s", "no secrets were received!"); - NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, - setting_name, - caller, - NULL, - tmp_error); - g_clear_error (&tmp_error); - return; - } - - g_hash_table_foreach (settings, add_one_key_to_list, &keys); - keys = g_slist_sort (keys, settings_order_func); - for (iter = keys; iter; iter = g_slist_next (iter)) { - GHashTable *hash; - const char *name = (const char *) iter->data; - - hash = g_hash_table_lookup (settings, name); - if (!hash) { - nm_log_warn (LOGD_CORE, "couldn't get setting secrets for '%s'", name); - continue; - } - - if (NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->update_setting (self, name, hash)) - updated = g_slist_append (updated, (gpointer) setting_name); - } - g_slist_free (keys); - - if (g_slist_length (updated)) { - NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, - setting_name, - caller, - updated, - NULL); - } else { - g_set_error (&tmp_error, 0, 0, "%s", "no secrets updated because no valid " - "settings were received!"); - NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE (self)->result (self, - setting_name, - caller, - NULL, - tmp_error); - g_clear_error (&tmp_error); - } - - g_slist_free (updated); -} - diff --git a/src/nm-secrets-provider-interface.h b/src/nm-secrets-provider-interface.h deleted file mode 100644 index 3d9e08b18..000000000 --- a/src/nm-secrets-provider-interface.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2009 Red Hat, Inc. - */ - -#ifndef NM_SECRETS_PROVIDER_INTERFACE_H -#define NM_SECRETS_PROVIDER_INTERFACE_H - -#include -#include - -typedef enum { - SECRETS_CALLER_NONE = 0, - SECRETS_CALLER_ETHERNET, - SECRETS_CALLER_WIFI, - SECRETS_CALLER_MOBILE_BROADBAND, - SECRETS_CALLER_PPP, - SECRETS_CALLER_VPN -} RequestSecretsCaller; - -#define NM_TYPE_SECRETS_PROVIDER_INTERFACE (nm_secrets_provider_interface_get_type ()) -#define NM_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface)) -#define NM_IS_SECRETS_PROVIDER_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE)) -#define NM_SECRETS_PROVIDER_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SECRETS_PROVIDER_INTERFACE, NMSecretsProviderInterface)) - -typedef struct _NMSecretsProviderInterface NMSecretsProviderInterface; - -struct _NMSecretsProviderInterface { - GTypeInterface g_iface; - - /* Methods */ - void (*result) (NMSecretsProviderInterface *self, - const char *setting_name, - RequestSecretsCaller caller, - const GSList *updated, - GError *error); - - gboolean (*update_setting) (NMSecretsProviderInterface *self, - const char *setting_name, - GHashTable *new); - - /* Signals */ - void (*manager_get_secrets) (NMSecretsProviderInterface *self, - NMConnection *connection, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2); - - void (*manager_cancel_secrets) (NMSecretsProviderInterface *self); -}; - -GType nm_secrets_provider_interface_get_type (void); - -/* For callers */ -gboolean nm_secrets_provider_interface_get_secrets (NMSecretsProviderInterface *self, - NMConnection *connection, - const char *setting_name, - gboolean request_new, - RequestSecretsCaller caller, - const char *hint1, - const char *hint2); - -void nm_secrets_provider_interface_cancel_get_secrets (NMSecretsProviderInterface *self); - -/* For NMManager */ -void nm_secrets_provider_interface_get_secrets_result (NMSecretsProviderInterface *self, - const char *setting_name, - RequestSecretsCaller caller, - GHashTable *settings, - GError *error); - -#endif /* NM_SECRETS_PROVIDER_INTERFACE_H */ - diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index efa660b03..369466825 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -78,6 +78,7 @@ typedef struct { NMActRequest *act_req; DBusGMethodInvocation *pending_secrets_context; + guint32 secrets_id; guint32 ppp_watch_id; guint32 ppp_timeout_handler; @@ -334,19 +335,29 @@ remove_timeout_handler (NMPPPManager *manager) } static void -impl_ppp_manager_need_secrets (NMPPPManager *manager, - DBusGMethodInvocation *context) +cancel_get_secrets (NMPPPManager *self) { - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); - NMConnection *connection; - NMSettingConnection *s_con; - const char *connection_type; - const char *setting_name; - guint32 tries; - GPtrArray *hints = NULL; - const char *hint1 = NULL, *hint2 = NULL; + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); - connection = nm_act_request_get_connection (priv->act_req); + if (priv->secrets_id) { + nm_act_request_cancel_secrets (priv->act_req, priv->secrets_id); + priv->secrets_id = 0; + } +} + +static gboolean +extract_details_from_connection (NMConnection *connection, + const char **username, + const char **password, + GError **error) +{ + NMSettingConnection *s_con; + NMSetting *setting; + const char *connection_type; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (username != NULL, FALSE); + g_return_val_if_fail (password != NULL, FALSE); s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); @@ -354,67 +365,114 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, connection_type = nm_setting_connection_get_connection_type (s_con); g_assert (connection_type); + setting = nm_connection_get_setting_by_name (connection, connection_type); + if (!setting) { + g_set_error_literal (error, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, + "Missing type-specific setting; no secrets could be found."); + return FALSE; + } + + /* FIXME: push this down to the settings and keep PPP manager generic */ + if (NM_IS_SETTING_PPPOE (setting)) { + *username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting)); + *password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting)); + } else if (NM_IS_SETTING_GSM (setting)) { + *username = nm_setting_gsm_get_username (NM_SETTING_GSM (setting)); + *password = nm_setting_gsm_get_password (NM_SETTING_GSM (setting)); + } else if (NM_IS_SETTING_CDMA (setting)) { + *username = nm_setting_cdma_get_username (NM_SETTING_CDMA (setting)); + *password = nm_setting_cdma_get_password (NM_SETTING_CDMA (setting)); + } + + return TRUE; +} + +static void +ppp_secrets_cb (NMActRequest *req, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + NMPPPManager *self = NM_PPP_MANAGER (user_data); + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); + const char *username = NULL; + const char *password = NULL; + GError *local = NULL; + + g_return_if_fail (priv->pending_secrets_context != NULL); + g_return_if_fail (req == priv->act_req); + g_return_if_fail (call_id == priv->secrets_id); + + if (error) { + nm_log_warn (LOGD_PPP, "%s", error->message); + dbus_g_method_return_error (priv->pending_secrets_context, error); + goto out; + } + + if (!extract_details_from_connection (connection, &username, &password, &local)) { + nm_log_warn (LOGD_PPP, "%s", local->message); + dbus_g_method_return_error (priv->pending_secrets_context, local); + g_clear_error (&local); + goto out; + } + + /* This is sort of a hack but... + * pppd plugin only ever needs username and password. Passing the full + * connection there would mean some bloat: the plugin would need to link + * against libnm-util just to parse this. So instead, let's just send what + * it needs. + */ + dbus_g_method_return (priv->pending_secrets_context, username, password); + +out: + priv->pending_secrets_context = NULL; + priv->secrets_id = 0; +} + +static void +impl_ppp_manager_need_secrets (NMPPPManager *manager, + DBusGMethodInvocation *context) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + NMConnection *connection; + const char *setting_name; + const char *username = NULL; + const char *password = NULL; + guint32 tries; + GPtrArray *hints = NULL; + GError *error = NULL; + + connection = nm_act_request_get_connection (priv->act_req); + nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, &hints); if (!setting_name) { - NMSetting *setting; - - setting = nm_connection_get_setting_by_name (connection, connection_type); - if (setting) { - const char *username = NULL; - const char *password = NULL; - - /* FIXME: push this down to the settings and keep PPP manager generic */ - if (NM_IS_SETTING_PPPOE (setting)) { - username = nm_setting_pppoe_get_username (NM_SETTING_PPPOE (setting)); - password = nm_setting_pppoe_get_password (NM_SETTING_PPPOE (setting)); - } else if (NM_IS_SETTING_GSM (setting)) { - username = nm_setting_gsm_get_username (NM_SETTING_GSM (setting)); - password = nm_setting_gsm_get_password (NM_SETTING_GSM (setting)); - } else if (NM_IS_SETTING_CDMA (setting)) { - username = nm_setting_cdma_get_username (NM_SETTING_CDMA (setting)); - password = nm_setting_cdma_get_password (NM_SETTING_CDMA (setting)); - } - - /* If secrets are not required, send the existing username and password - * back to the PPP plugin immediately. - */ + /* Use existing secrets from the connection */ + if (extract_details_from_connection (connection, &username, &password, &error)) { + /* Send existing secrets to the PPP plugin */ priv->pending_secrets_context = context; - nm_ppp_manager_update_secrets (manager, - priv->parent_iface, - username ? username : "", - password ? password : "", - NULL); + ppp_secrets_cb (priv->act_req, priv->secrets_id, connection, NULL, manager); } else { - GError *err = NULL; - - g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, - "Missing type-specific setting; no secrets could be found."); - nm_log_warn (LOGD_PPP, "%s", err->message); - dbus_g_method_return_error (context, err); + nm_log_warn (LOGD_PPP, "%s", error->message); + dbus_g_method_return_error (priv->pending_secrets_context, error); + g_clear_error (&error); } return; } - /* Extract hints */ - if (hints) { - if (hints->len > 0) - hint1 = g_ptr_array_index (hints, 0); - if (hints->len > 1) - hint2 = g_ptr_array_index (hints, 1); - } - tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); /* Only ask for completely new secrets after retrying them once; some PPP * servers (T-Mobile USA) appear to ask a few times when they actually don't * even care what you pass back. */ - nm_act_request_get_secrets (priv->act_req, - setting_name, - tries > 1 ? TRUE : FALSE, - SECRETS_CALLER_PPP, - hint1, - hint2); + priv->secrets_id = nm_act_request_get_secrets (priv->act_req, + NULL, + setting_name, + tries > 1 ? TRUE : FALSE, + hints ? g_ptr_array_index (hints, 0) : NULL, + ppp_secrets_cb, + manager); g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, GUINT_TO_POINTER (++tries)); priv->pending_secrets_context = context; @@ -955,46 +1013,6 @@ nm_ppp_manager_start (NMPPPManager *manager, return priv->pid > 0; } -void -nm_ppp_manager_update_secrets (NMPPPManager *manager, - const char *device, - const char *username, - const char *password, - const char *error_message) -{ - NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); - - g_return_if_fail (NM_IS_PPP_MANAGER (manager)); - g_return_if_fail (device != NULL); - g_return_if_fail (priv->pending_secrets_context != NULL); - - if (error_message) { - g_return_if_fail (username == NULL); - g_return_if_fail (password == NULL); - } else { - g_return_if_fail (username != NULL); - g_return_if_fail (password != NULL); - } - - if (error_message) { - GError *err = NULL; - - g_set_error (&err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, "%s", error_message); - nm_log_warn (LOGD_PPP, "%s", error_message); - dbus_g_method_return_error (priv->pending_secrets_context, err); - g_error_free (err); - } else { - /* This is sort of a hack but... - pppd plugin only ever needs username and password. - Passing the full connection there would mean some bloat: - the plugin would need to link against libnm-util just to parse this. - So instead, let's just send what it needs */ - - dbus_g_method_return (priv->pending_secrets_context, username, password); - } - priv->pending_secrets_context = NULL; -} - static gboolean ensure_killed (gpointer data) { @@ -1020,6 +1038,8 @@ nm_ppp_manager_stop (NMPPPManager *manager) priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + cancel_get_secrets (manager); + if (priv->monitor_id) { g_source_remove (priv->monitor_id); priv->monitor_id = 0; diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index a0200973f..5a8c73e4c 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2010 Red Hat, Inc. */ #ifndef NM_PPP_MANAGER_H @@ -63,12 +63,6 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager, guint32 timeout_secs, GError **err); -void nm_ppp_manager_update_secrets (NMPPPManager *manager, - const char *device, - const char *username, - const char *password, - const char *error_message); - void nm_ppp_manager_stop (NMPPPManager *manager); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 7b47b18da..a5d04a500 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -50,11 +50,7 @@ #include "nm-vpn-connection-glue.h" -static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class); - -G_DEFINE_TYPE_EXTENDED (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE, - secrets_provider_interface_init)) +G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT) typedef struct { gboolean disposed; @@ -63,6 +59,7 @@ typedef struct { NMActRequest *act_request; char *ac_path; + guint32 secrets_id; NMDevice *parent_dev; gulong device_monitor; @@ -784,6 +781,7 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, /******************************************************************************/ +#if 0 static gboolean secrets_update_setting (NMSecretsProviderInterface *interface, const char *setting_name, @@ -807,19 +805,33 @@ secrets_update_setting (NMSecretsProviderInterface *interface, } return TRUE; } +#endif static void -secrets_result (NMSecretsProviderInterface *interface, - const char *setting_name, - RequestSecretsCaller caller, - const GSList *updated, - GError *error) +cancel_get_secrets (NMVPNConnection *self) { - NMVPNConnection *self = NM_VPN_CONNECTION (interface); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - g_return_if_fail (priv->connection != NULL); - g_return_if_fail (caller == SECRETS_CALLER_VPN); + if (priv->secrets_id) { + nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + priv->secrets_id = 0; + } +} + +static void +vpn_secrets_cb (NMActRequest *req, + guint32 call_id, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + NMVPNConnection *self = NM_VPN_CONNECTION (user_data); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (req == priv->act_request); + g_return_if_fail (call_id == priv->secrets_id); + + priv->secrets_id = 0; if (error) nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); @@ -827,14 +839,6 @@ secrets_result (NMSecretsProviderInterface *interface, really_activate (self); } -static void -secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class) -{ - /* interface implementation */ - sp_interface_class->update_setting = secrets_update_setting; - sp_interface_class->result = secrets_result; -} - static void connection_need_secrets_cb (DBusGProxy *proxy, char *setting_name, @@ -858,14 +862,14 @@ connection_need_secrets_cb (DBusGProxy *proxy, return; } - /* Get the secrets the VPN plugin wants */ - if (!nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self), - priv->connection, - setting_name, - FALSE, - SECRETS_CALLER_VPN, - NULL, - NULL)) + priv->secrets_id = nm_act_request_get_secrets (priv->act_request, + priv->connection, + setting_name, + FALSE, + NULL, + vpn_secrets_cb, + self); + if (!priv->secrets_id) nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); } @@ -944,17 +948,17 @@ vpn_cleanup (NMVPNConnection *connection) } static void -connection_state_changed (NMVPNConnection *connection, +connection_state_changed (NMVPNConnection *self, NMVPNConnectionState state, NMVPNConnectionStateReason reason) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (priv->act_request)); + cancel_get_secrets (self); switch (state) { case NM_VPN_CONNECTION_STATE_NEED_AUTH: - call_need_secrets (connection); + call_need_secrets (self); break; case NM_VPN_CONNECTION_STATE_DISCONNECTED: case NM_VPN_CONNECTION_STATE_FAILED: @@ -970,7 +974,7 @@ connection_state_changed (NMVPNConnection *connection, g_object_unref (priv->proxy); priv->proxy = NULL; } - vpn_cleanup (connection); + vpn_cleanup (self); break; default: break; @@ -1025,6 +1029,9 @@ dispose (GObject *object) if (priv->proxy) g_object_unref (priv->proxy); + if (priv->secrets_id) + nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + g_object_unref (priv->act_request); g_object_unref (priv->connection); diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index d69674db9..6101e74f0 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2008 Red Hat, Inc. + * Copyright (C) 2005 - 2010 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -27,7 +27,6 @@ #include "NetworkManagerVPN.h" #include "nm-device.h" #include "nm-activation-request.h" -#include "nm-secrets-provider-interface.h" #define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) #define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) From 1496f8056fa3a9ad7008504433f5cfb51f963147 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 00:03:22 -0600 Subject: [PATCH 110/264] libnm-glib: add secret agent base class --- include/NetworkManager.h | 3 + introspection/nm-secret-agent.xml | 106 +++++ libnm-glib/Makefile.am | 12 +- libnm-glib/nm-secret-agent.c | 638 ++++++++++++++++++++++++++++++ libnm-glib/nm-secret-agent.h | 119 ++++++ 5 files changed, 875 insertions(+), 3 deletions(-) create mode 100644 introspection/nm-secret-agent.xml create mode 100644 libnm-glib/nm-secret-agent.c create mode 100644 libnm-glib/nm-secret-agent.h diff --git a/include/NetworkManager.h b/include/NetworkManager.h index ea05c1f49..558eb3e40 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -55,6 +55,9 @@ #define NM_DBUS_INTERFACE_AGENT_MANAGER NM_DBUS_INTERFACE ".AgentManager" #define NM_DBUS_PATH_AGENT_MANAGER "/org/freedesktop/NetworkManager/AgentManager" +#define NM_DBUS_INTERFACE_SECRET_AGENT NM_DBUS_INTERFACE ".SecretAgent" +#define NM_DBUS_PATH_SECRET_AGENT "/org/freedesktop/NetworkManager/SecretAgent" + /* * Types of NetworkManager states */ diff --git a/introspection/nm-secret-agent.xml b/introspection/nm-secret-agent.xml new file mode 100644 index 000000000..bfab5852c --- /dev/null +++ b/introspection/nm-secret-agent.xml @@ -0,0 +1,106 @@ + + + + + + + Private D-Bus interface used by secret agents that store and provide + secrets to NetworkManager. + + + + + Retrieve and return stored secrets, if any, or request new + secrets from the agent's user. + + + + + + Nested settings maps containing the connection for which + secrets are being requested. + + + + + Object path of the connection for which secrets are being + requested. + + + + + Setting name for which secrets are being requested. + + + + + Array of strings of key names in the requested setting for + which NetworkManager thinks a secrets may be required. The + Agent should return any secrets it has, or that it thinks + are required, regardless of what hints NetworkManager sends + in this request. + + + + + If true, new secrets are assumed to be invalid or incorrect, + and the agent should ask the user for new secrets. If false, + existing secrets should be retrieved from storage and + returned without interrupting the user. + + + + + + Nested settings maps containing secrets. Each setting MUST + contain at least the 'name' field, containing the name of + the setting, and one or more secrets. + + + + + + + Save given secrets to backing storage. + + + + + + Nested settings maps containing the entire connection + (including secrets), for which the agent should save the + secrets to backing storage. + + + + + Object path of the connection for which the agent should + save secrets to backing storage. + + + + + + + Delete secrets from backing storage. + + + + + + Nested settings maps containing the entire connection + (including secrets), for which the agent should delete the + secrets from backing storage. + + + + + Object path of the connection for which the agent should + delete secrets from backing storage. + + + + + + + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index aa6f95960..5a6045ebc 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -18,7 +18,8 @@ BUILT_SOURCES = \ nm-ip4-config-bindings.h \ nm-dhcp4-config-bindings.h \ nm-ip6-config-bindings.h \ - nm-dhcp6-config-bindings.h + nm-dhcp6-config-bindings.h \ + nm-secret-agent-glue.h ##################################################### # Deprecated original libnm_glib bits @@ -76,7 +77,8 @@ libnminclude_HEADERS = \ nm-ip6-config.h \ nm-dhcp6-config.h \ nm-remote-connection.h \ - nm-remote-settings.h + nm-remote-settings.h \ + nm-secret-agent.h libnm_glib_la_SOURCES = \ nm-object.c \ @@ -105,7 +107,8 @@ libnm_glib_la_SOURCES = \ nm-dhcp6-config.c \ nm-remote-connection.c \ nm-remote-connection-private.h \ - nm-remote-settings.c + nm-remote-settings.c \ + nm-secret-agent.c libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ @@ -178,6 +181,9 @@ nm-ip6-config-bindings.h: $(top_srcdir)/introspection/nm-ip6-config.xml nm-dhcp6-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_dhcp6_config --mode=glib-client --output=$@ $< +nm-secret-agent-glue.h: $(top_srcdir)/introspection/nm-secret-agent.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_secret_agent --mode=glib-server --output=$@ $< + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-glib.pc libnm-glib-vpn.pc diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c new file mode 100644 index 000000000..68d6af9cf --- /dev/null +++ b/libnm-glib/nm-secret-agent.c @@ -0,0 +1,638 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Red Hat, Inc. + */ + +#include +#include +#include +#include +#include + +#include "nm-secret-agent.h" +#include "nm-marshal.h" +#include "NetworkManager.h" + +static void impl_secret_agent_get_secrets (NMSecretAgent *self, + GHashTable *connection_hash, + const char *connection_path, + const char *setting_name, + const char **hints, + gboolean request_new, + DBusGMethodInvocation *context); + +static void impl_secret_agent_save_secrets (NMSecretAgent *self, + GHashTable *connection_hash, + const char *connection_path, + DBusGMethodInvocation *context); + +static void impl_secret_agent_delete_secrets (NMSecretAgent *self, + GHashTable *connection_hash, + const char *connection_path, + DBusGMethodInvocation *context); + +#include "nm-secret-agent-glue.h" + +G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) + +#define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SECRET_AGENT, \ + NMSecretAgentPrivate)) + +typedef struct { + gboolean registered; + + DBusGConnection *bus; + DBusGProxy *dbus_proxy; + DBusGProxy *manager_proxy; + DBusGProxyCall *reg_call; + + char *nm_owner; + + char *identifier; + + gboolean disposed; +} NMSecretAgentPrivate; + +enum { + PROP_0, + PROP_IDENTIFIER, + + LAST_PROP +}; + +enum { + REGISTRATION_RESULT, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + + +/********************************************************************/ + +GQuark +nm_secret_agent_error_quark (void) +{ + static GQuark ret = 0; + + if (G_UNLIKELY (ret == 0)) + ret = g_quark_from_static_string ("nm-secret-agent-error"); + return ret; +} + +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_secret_agent_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* Sender is not authorized to make this request */ + ENUM_ENTRY (NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, "NotAuthorized"), + /* Given connection details do not make a valid connection */ + ENUM_ENTRY (NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "InvalidConnection"), + /* The request was canceled explicitly by the user */ + ENUM_ENTRY (NM_SECRET_AGENT_ERROR_USER_CANCELED, "UserCanceled"), + /* The request was canceled, but not by the user */ + ENUM_ENTRY (NM_SECRET_AGENT_ERROR_AGENT_CANCELED, "AgentCanceled"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMSecretAgentError", values); + } + return etype; +} + +/*************************************************************/ + +static const char * +get_nm_owner (NMSecretAgent *self) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GError *error = NULL; + char *owner; + + if (!priv->nm_owner) { + if (!dbus_g_proxy_call_with_timeout (priv->dbus_proxy, + "GetNameOwner", 2000, &error, + G_TYPE_STRING, NM_DBUS_SERVICE, + G_TYPE_INVALID, + G_TYPE_STRING, &owner, + G_TYPE_INVALID)) + return NULL; + + priv->nm_owner = g_strdup (owner); + g_free (owner); + } + + return priv->nm_owner; +} + +static void +name_owner_changed (DBusGProxy *proxy, + const char *name, + const char *old_owner, + const char *new_owner, + gpointer user_data) +{ + NMSecretAgent *self = NM_SECRET_AGENT (user_data); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + if (strcmp (name, NM_DBUS_SERVICE) == 0) { + g_free (priv->nm_owner); + priv->nm_owner = g_strdup (new_owner); + } +} + +static NMConnection * +verify_request (NMSecretAgent *self, + DBusGMethodInvocation *context, + GHashTable *connection_hash, + GError **error) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + NMConnection *connection = NULL; + DBusConnection *bus; + char *sender; + const char *nm_owner; + DBusError dbus_error; + uid_t sender_uid = G_MAXUINT; + GError *local = NULL; + + g_return_val_if_fail (context != NULL, NULL); + g_return_val_if_fail (connection_hash != NULL, NULL); + + /* Verify the sender's UID is 0, and that the sender is the same as + * NetworkManager's bus name owner. + */ + + nm_owner = get_nm_owner (self); + if (!nm_owner) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, + "NetworkManager bus name owner unknown."); + return FALSE; + } + + bus = dbus_g_connection_get_connection (priv->bus); + if (!bus) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, + "Failed to get DBus connection."); + return FALSE; + } + + sender = dbus_g_method_get_sender (context); + if (!sender) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, + "Failed to get request sender."); + return FALSE; + } + + /* Check that the sender matches the current NM bus name owner */ + if (strcmp (sender, nm_owner) != 0) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, + "Request sender does not match NetworkManager bus name owner."); + goto out; + } + + dbus_error_init (&dbus_error); + sender_uid = dbus_bus_get_unix_user (bus, sender, &dbus_error); + if (dbus_error_is_set (&dbus_error)) { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, + "Failed to get request unix user: (%s) %s.", + dbus_error.name, dbus_error.message); + dbus_error_free (&dbus_error); + goto out; + } + + if (0 != sender_uid) { + g_set_error_literal (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED, + "Request sender is not root."); + goto out; + } + + /* And make sure the connection is actually valid */ + connection = nm_connection_new_from_hash (connection_hash, &local); + if (!connection) { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: (%d) %s", + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); + g_clear_error (&local); + } + + +out: + g_free (sender); + return connection; +} + +static void +impl_secret_agent_get_secrets (NMSecretAgent *self, + GHashTable *connection_hash, + const char *connection_path, + const char *setting_name, + const char **hints, + gboolean request_new, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + NMConnection *connection; + + /* Make sure the request comes from NetworkManager and is valid */ + connection = verify_request (self, context, connection_hash, &error); + if (!connection) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + return; + } + + NM_SECRET_AGENT_GET_CLASS (self)->get_secrets (self, + connection, + connection_path, + setting_name, + hints, + request_new, + context); + g_object_unref (connection); +} + +static void +impl_secret_agent_save_secrets (NMSecretAgent *self, + GHashTable *connection_hash, + const char *connection_path, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + NMConnection *connection; + + /* Make sure the request comes from NetworkManager and is valid */ + connection = verify_request (self, context, connection_hash, &error); + if (!connection) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + return; + } + + NM_SECRET_AGENT_GET_CLASS (self)->save_secrets (self, + connection, + connection_path, + context); + g_object_unref (connection); +} + +static void +impl_secret_agent_delete_secrets (NMSecretAgent *self, + GHashTable *connection_hash, + const char *connection_path, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + NMConnection *connection; + + /* Make sure the request comes from NetworkManager and is valid */ + connection = verify_request (self, context, connection_hash, &error); + if (!connection) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + return; + } + + NM_SECRET_AGENT_GET_CLASS (self)->delete_secrets (self, + connection, + connection_path, + context); + g_object_unref (connection); +} + +/**************************************************************/ + +static void +reg_request_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + NMSecretAgent *self = NM_SECRET_AGENT (user_data); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GError *error = NULL; + + priv->reg_call = NULL; + + if (dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) + priv->registered = TRUE; + else { + /* If registration failed we shouldn't expose ourselves on the bus */ + dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self)); + } + + g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error); + g_clear_error (&error); +} + +/** + * nm_secret_agent_register: + * + * Registers the #NMSecretAgent with the NetworkManager secret manager, + * indicating to NetworkManager that the agent is able to provide and save + * secrets for connections on behalf of its user. Registration is an + * asynchronous operation and its success or failure is indicated via the + * 'registration-result' signal. + * + * Returns: a new %TRUE if registration was successfully requested (this does + * not mean registration itself was successful), %FALSE if registration was not + * successfully requested. + **/ +gboolean +nm_secret_agent_register (NMSecretAgent *self) +{ + NMSecretAgentPrivate *priv; + NMSecretAgentClass *class; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); + + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + g_return_val_if_fail (priv->registered == FALSE, FALSE); + g_return_val_if_fail (priv->reg_call == NULL, FALSE); + g_return_val_if_fail (priv->bus != NULL, FALSE); + g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + + /* Also make sure the subclass can actually respond to secrets requests */ + class = NM_SECRET_AGENT_GET_CLASS (self); + g_return_val_if_fail (class->get_secrets != NULL, FALSE); + g_return_val_if_fail (class->save_secrets != NULL, FALSE); + g_return_val_if_fail (class->delete_secrets != NULL, FALSE); + + /* Export our secret agent interface before registering with the manager */ + dbus_g_connection_register_g_object (priv->bus, + NM_DBUS_PATH_SECRET_AGENT, + G_OBJECT (self)); + + priv->reg_call = dbus_g_proxy_begin_call_with_timeout (priv->manager_proxy, + "Register", + reg_request_cb, + self, + NULL, + G_USEC_PER_SEC * 5, + G_TYPE_STRING, priv->identifier, + G_TYPE_INVALID); + + return TRUE; +} + +/** + * nm_secret_agent_unregister: + * + * Unregisters the #NMSecretAgent with the NetworkManager secret manager, + * indicating to NetworkManager that the agent is will no longer provide or + * store secrets on behalf of this user. + * + * Returns: a new %TRUE if unregistration was successful, %FALSE if it was not. + **/ +gboolean +nm_secret_agent_unregister (NMSecretAgent *self) +{ + NMSecretAgentPrivate *priv; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SECRET_AGENT (self), FALSE); + + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + g_return_val_if_fail (priv->registered == TRUE, FALSE); + g_return_val_if_fail (priv->bus != NULL, FALSE); + g_return_val_if_fail (priv->manager_proxy != NULL, FALSE); + + dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID); + + return TRUE; +} + +/**************************************************************/ + +static gboolean +validate_identifier (const char *identifier) +{ + const char *p = identifier; + size_t id_len; + + /* Length between 3 and 255 characters inclusive */ + id_len = strlen (identifier); + if (id_len < 3 || id_len > 255) + return FALSE; + + if ((identifier[0] == '.') || (identifier[id_len - 1] == '.')) + return FALSE; + + /* FIXME: do complete validation here */ + while (p && *p) { + if (!isalnum (*p) && (*p != '_') && (*p != '-')) + return FALSE; + if ((*p == '.') && (*(p + 1) == '.')) + return FALSE; + } + + return TRUE; +} + +static void +nm_secret_agent_init (NMSecretAgent *self) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GError *error = NULL; + + priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (!priv->bus) { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + return; + } + + priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + if (!priv->dbus_proxy) { + g_warning ("Couldn't create messagebus proxy."); + return; + } + + dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING_STRING, + G_TYPE_NONE, + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged", + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->dbus_proxy, + "NameOwnerChanged", + G_CALLBACK (name_owner_changed), + self, NULL); + + priv->manager_proxy = dbus_g_proxy_new_for_name (priv->bus, + NM_DBUS_SERVICE, + NM_DBUS_PATH_AGENT_MANAGER, + NM_DBUS_INTERFACE_AGENT_MANAGER); + if (!priv->manager_proxy) { + g_warning ("Couldn't create NM agent manager proxy."); + return; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object); + + switch (prop_id) { + case PROP_IDENTIFIER: + g_value_set_string (value, priv->identifier); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object); + const char *identifier; + + switch (prop_id) { + case PROP_IDENTIFIER: + identifier = g_value_get_string (value); + + g_return_if_fail (validate_identifier (identifier)); + + g_free (priv->identifier); + priv->identifier = g_strdup (identifier); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +dispose (GObject *object) +{ + NMSecretAgent *self = NM_SECRET_AGENT (object); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + if (!priv->disposed) { + priv->disposed = TRUE; + + if (priv->registered) + nm_secret_agent_unregister (self); + + g_free (priv->identifier); + g_free (priv->nm_owner); + + if (priv->dbus_proxy) + g_object_unref (priv->dbus_proxy); + + if (priv->manager_proxy) + g_object_unref (priv->manager_proxy); + + if (priv->bus) + dbus_g_connection_unref (priv->bus); + } + + G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); +} + +static void +nm_secret_agent_class_init (NMSecretAgentClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + g_type_class_add_private (class, sizeof (NMSecretAgentPrivate)); + + /* Virtual methods */ + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + /** + * NMSecretAgent:identifier: + * + * Identifies this agent; only one agent in each user session may use the + * same identifier. Identifier formatting follows the same rules as + * D-Bus bus names with the exception that the ':' character is not + * allowed. The valid set of characters is "[A-Z][a-z][0-9]_-." and the + * identifier is limited in length to 255 characters with a minimum + * of 3 characters. An example valid identifier is 'org.gnome.nm-applet' + * (without quotes). + **/ + g_object_class_install_property + (object_class, PROP_IDENTIFIER, + g_param_spec_string (NM_SECRET_AGENT_IDENTIFIER, + "Identifier", + "Identifier", + NULL, + G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); + + /** + * NMSecretAgent::registration-result: + * @agent: the agent that received the signal + * @error: the error, if any, that occured while registering + * + * Indicates the result of a registration request; if @error is NULL the + * request was successful. + **/ + signals[REGISTRATION_RESULT] = + g_signal_new (REGISTRATION_RESULT, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), + &dbus_glib_nm_secret_agent_object_info); + + dbus_g_error_domain_register (NM_SECRET_AGENT_ERROR, + NM_DBUS_INTERFACE_SECRET_AGENT, + NM_TYPE_SECRET_AGENT_ERROR); +} + diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h new file mode 100644 index 000000000..b9f0fd727 --- /dev/null +++ b/libnm-glib/nm-secret-agent.h @@ -0,0 +1,119 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2010 Red Hat, Inc. + */ + +#ifndef NM_SECRET_AGENT_H +#define NM_SECRET_AGENT_H + +#include +#include +#include + +G_BEGIN_DECLS + +#define NM_SECRET_AGENT_ERROR (nm_secret_agent_error_quark ()) +#define NM_TYPE_SECRET_AGENT_ERROR (nm_secret_agent_error_get_type ()) + +GQuark nm_secret_agent_error_quark (void); +GType nm_secret_agent_error_get_type (void); + +typedef enum { + NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED = 0, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + NM_SECRET_AGENT_ERROR_USER_CANCELED, + NM_SECRET_AGENT_ERROR_AGENT_CANCELED +} NMSecretAgentError; + + +#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) +#define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) +#define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) +#define NM_IS_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SECRET_AGENT)) +#define NM_IS_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SECRET_AGENT)) +#define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) + +#define NM_SECRET_AGENT_IDENTIFIER "identifier" + +#define NM_SECRET_AGENT_REGISTRATION_RESULT "registration-result" + +typedef struct { + GObject parent; +} NMSecretAgent; + +typedef struct { + GObjectClass parent; + + /* Virtual methods for subclasses */ + + /* Called when the subclass should retrieve and return secrets. Subclass + * must copy or reference any arguments it may require after returning from + * this method, as the arguments will freed (except for 'agent' and + * 'context' of course). + */ + void (*get_secrets) (NMSecretAgent *agent, + NMConnection *connection, + const char *connection_path, + const char *setting_name, + const char **hints, + gboolean request_new, + DBusGMethodInvocation *context); + + /* Called when the subclass should save the secrets contained in the + * connection to backing storage. Subclass must copy or reference any + * arguments it may require after returning from this method, as the + * arguments will freed (except for 'agent' and 'context' of course). + */ + void (*save_secrets) (NMSecretAgent *agent, + NMConnection *connection, + const char *connection_path, + DBusGMethodInvocation *context); + + /* Called when the subclass should delete the secrets contained in the + * connection from backing storage. Subclass must copy or reference any + * arguments it may require after returning from this method, as the + * arguments will freed (except for 'agent' and 'context' of course). + */ + void (*delete_secrets) (NMSecretAgent *agent, + NMConnection *connection, + const char *connection_path, + DBusGMethodInvocation *context); + + /* Signals */ + void (*registration_result) (NMSecretAgent *agent, GError *error); + + /* Padding for future expansion */ + void (*_reserved1) (void); + void (*_reserved2) (void); + void (*_reserved3) (void); + void (*_reserved4) (void); + void (*_reserved5) (void); + void (*_reserved6) (void); +} NMSecretAgentClass; + +GType nm_secret_agent_get_type (void); + +NMSecretAgent *nm_secret_agent_new (const char *identifier); + +gboolean nm_secret_agent_register (NMSecretAgent *self); + +gboolean nm_secret_agent_unregister (NMSecretAgent *self); + +G_END_DECLS + +#endif /* NM_SECRET_AGENT_H */ From 85fa487a48427962571f222ba447e68448d7fd69 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 10:51:00 -0600 Subject: [PATCH 111/264] tests: fix missing Makefile dep --- src/tests/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 62612a0e1..42f9c95a3 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -41,7 +41,7 @@ test_policy_hosts_LDADD = \ if WITH_TESTS -check-local: test-dhcp-options +check-local: test-dhcp-options test-policy-hosts $(abs_builddir)/test-dhcp-options $(abs_builddir)/test-policy-hosts From 84abb135540dddb8f3512631aef87f1573aaf7d7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 11:12:24 -0600 Subject: [PATCH 112/264] libnm-glib: fix infinite loop checking agent identifier --- libnm-glib/nm-secret-agent.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 68d6af9cf..a8c73213f 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -462,6 +462,7 @@ validate_identifier (const char *identifier) return FALSE; if ((*p == '.') && (*(p + 1) == '.')) return FALSE; + p++; } return TRUE; From 585a4a13511bf3a1d3900e109846cd85d298589d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 11:12:56 -0600 Subject: [PATCH 113/264] agent: actually register D-Bus introspection So that the agent manager can get exported on the bus. --- src/nm-agent-manager.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index b92c8971e..4faef41f4 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -588,15 +588,18 @@ dispose (GObject *object) } static void -nm_agent_manager_class_init (NMAgentManagerClass *config_class) +nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class) { - GObjectClass *object_class = G_OBJECT_CLASS (config_class); + GObjectClass *object_class = G_OBJECT_CLASS (agent_manager_class); - g_type_class_add_private (config_class, sizeof (NMAgentManagerPrivate)); + g_type_class_add_private (agent_manager_class, sizeof (NMAgentManagerPrivate)); /* virtual methods */ object_class->dispose = dispose; + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (agent_manager_class), + &dbus_glib_nm_agent_manager_object_info); + dbus_g_error_domain_register (NM_AGENT_MANAGER_ERROR, NM_DBUS_INTERFACE_AGENT_MANAGER, NM_TYPE_AGENT_MANAGER_ERROR); From ffac6b33c644397e7ea41c8f1b55792af54b5273 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 11:14:24 -0600 Subject: [PATCH 114/264] agent: fix infinite loop checking agent identifier --- src/nm-agent-manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 4faef41f4..d31df7054 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -192,6 +192,7 @@ validate_identifier (const char *identifier, GError **error) "Identifier contains two '.' characters in sequence"); return FALSE; } + p++; } return TRUE; From 81bc9c857217e7dcdf5e369b91b684ee63373bb8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 11:19:19 -0600 Subject: [PATCH 115/264] libnm-glib: allow the '.' character in agent identifiers --- libnm-glib/nm-secret-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index a8c73213f..f10a2584b 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -458,7 +458,7 @@ validate_identifier (const char *identifier) /* FIXME: do complete validation here */ while (p && *p) { - if (!isalnum (*p) && (*p != '_') && (*p != '-')) + if (!isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.')) return FALSE; if ((*p == '.') && (*(p + 1) == '.')) return FALSE; From fc82bbc412938a4ceb8c3bb6de7ecbd3ae460cb8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 11:19:39 -0600 Subject: [PATCH 116/264] agent: allow the '.' character in agent identifiers --- src/nm-agent-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index d31df7054..9bdc72d39 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -177,7 +177,7 @@ validate_identifier (const char *identifier, GError **error) /* FIXME: do complete validation here */ while (p && *p) { - if (!isalnum (*p) && (*p != '_') && (*p != '-')) { + if (!isalnum (*p) && (*p != '_') && (*p != '-') && (*p != '.')) { g_set_error (error, NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, From ca1338007c066dd40c5105711816559ffceccab6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 15:04:14 -0600 Subject: [PATCH 117/264] tests: add secret agent API test tool --- src/tests/Makefile.am | 6 +++ src/tests/test-secret-agent.py | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100755 src/tests/test-secret-agent.py diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 42f9c95a3..88c4c683f 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -39,6 +39,12 @@ test_policy_hosts_LDADD = \ $(top_builddir)/src/libtest-policy-hosts.la \ $(GLIB_LIBS) +####### secret agent interface test ####### + +EXTRA_DIST = test-secret-agent.py + +########################################### + if WITH_TESTS check-local: test-dhcp-options test-policy-hosts diff --git a/src/tests/test-secret-agent.py b/src/tests/test-secret-agent.py new file mode 100755 index 000000000..a6ae6fd77 --- /dev/null +++ b/src/tests/test-secret-agent.py @@ -0,0 +1,68 @@ +#!/bin/env python +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +import glib +import gobject +import sys +import dbus +import dbus.service +import dbus.mainloop.glib + +IFACE_SECRET_AGENT = 'org.freedesktop.NetworkManager.SecretAgent' +IFACE_AGENT_MANAGER = 'org.freedesktop.NetworkManager.AgentManager' + +class NotAuthorizedException(dbus.DBusException): + _dbus_error_name = IFACE_SECRET_AGENT + '.NotAuthorized' + +class Agent(dbus.service.Object): + def __init__(self, bus, object_path): + self.agents = {} + self.bus = bus + dbus.service.Object.__init__(self, bus, object_path) + + @dbus.service.method(IFACE_SECRET_AGENT, + in_signature='a{sa{sv}}osasb', + out_signature='a{sa{sv}}', + sender_keyword='sender') + def GetSecrets(self, connection_hash, connection_path, setting_name, hints, request_new, sender=None): + if not sender: + raise NotAuthorizedException("Internal error: couldn't get sender") + uid = self.bus.get_unix_user(sender) + if uid != 0: + raise NotAuthorizedException("UID %d not authorized" % uid) + + print "Secrets requested path '%s' setting '%s' hints '%s' new %d" % (connection_path, setting_name, str(hints), request_new) + + # return some random GSM secrets + s_gsm = dbus.Dictionary({'password': 'asdfadfasdfaf'}) + con = dbus.Dictionary({'gsm': s_gsm}) + return con + +def register(proxy): + proxy.Register("test.agent.id", dbus_interface=IFACE_AGENT_MANAGER) + print "Registered!" + return False + +def unregister(proxy, loop): + proxy.Unregister(dbus_interface=IFACE_AGENT_MANAGER) + loop.quit() + return False + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + bus = dbus.SystemBus() + obj = Agent(bus, "/org/freedesktop/NetworkManager/SecretAgent") + proxy = bus.get_object("org.freedesktop.NetworkManager", + "/org/freedesktop/NetworkManager/AgentManager") + + mainloop = gobject.MainLoop() + + gobject.idle_add(register, proxy) + gobject.timeout_add_seconds(10, unregister, proxy, mainloop) + print "Running test secret agent" + mainloop.run() + +if __name__ == '__main__': + main() + From 16a8a951e9835fb88c0143acdffe887f138c8bee Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 15:26:40 -0600 Subject: [PATCH 118/264] ifcfg-rh: PSK isn't necessary for valid WPA connection We'll ask secret agents for it if it's not stored in the connection. --- system-settings/plugins/ifcfg-rh/reader.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index f25acc892..68f7141cf 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -1895,11 +1895,8 @@ parse_wpa_psk (shvarFile *ifcfg, if (!psk) psk = svGetValue (ifcfg, "WPA_PSK", TRUE); - if (!psk) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing WPA_PSK for WPA-PSK key management"); + if (!psk) return NULL; - } p = psk; @@ -2516,10 +2513,10 @@ make_wpa_setting (shvarFile *ifcfg, if (!strcmp (value, "WPA-PSK")) { psk = parse_wpa_psk (ifcfg, file, ssid, error); - if (!psk) - goto error; - g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); - g_free (psk); + if (psk) { + g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); + g_free (psk); + } if (adhoc) g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL); From 9df9abb06f25ea7eb07afeccbbbc24b4cc991c98 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 15:31:53 -0600 Subject: [PATCH 119/264] tests: make agent tester stick around until Ctl+C --- src/tests/test-secret-agent.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tests/test-secret-agent.py b/src/tests/test-secret-agent.py index a6ae6fd77..6b9e676b3 100755 --- a/src/tests/test-secret-agent.py +++ b/src/tests/test-secret-agent.py @@ -59,9 +59,15 @@ def main(): mainloop = gobject.MainLoop() gobject.idle_add(register, proxy) - gobject.timeout_add_seconds(10, unregister, proxy, mainloop) print "Running test secret agent" - mainloop.run() + + try: + mainloop.run() + except KeyboardInterrupt, e: + pass + + print "Unregistering..." + unregister(proxy, mainloop); if __name__ == '__main__': main() From 5e19b02f0bad3e425546c80d70f35348717a9f65 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 15:32:12 -0600 Subject: [PATCH 120/264] dbus: allow NetworkManager to talk to secret agents --- src/NetworkManager.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf index fbbeb935d..c7ea5f735 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -8,6 +8,8 @@ + + @@ -54,6 +56,9 @@ + + @@ -84,6 +89,9 @@ + + From 4f058e2dc4562b39ed271680a26f5307d869ef19 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 14 Dec 2010 15:34:34 -0600 Subject: [PATCH 121/264] agent: ask secret agents for secrets when connection doesn't have any Filter registered agents for each secrets request to ensure that the connection for which secrets are requested is visible to that agent, and add that agent to the queue. Ask each agent in the queue until one returns usable secrets. Ensure that if new agents register or existing agents quit during the secrets request, that the queue is updated accordingly, and ensure that an agent that's already been asked for secrets, unregisters, and re-registers before the secrets request is comple, isn't asked for secrets twice. --- src/nm-activation-request.c | 57 ----- src/nm-agent-manager.c | 316 ++++++++++++++++++++++++---- src/nm-secret-agent.c | 105 ++++++++- src/nm-secret-agent.h | 23 +- src/vpn-manager/nm-vpn-connection.c | 26 --- 5 files changed, 400 insertions(+), 127 deletions(-) diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 57b199b50..dbc65b4d4 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -92,63 +92,6 @@ enum { /*******************************************************************/ -#if 0 -static gboolean -secrets_update_setting (NMSecretsProviderInterface *interface, - const char *setting_name, - GHashTable *new) -{ - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (interface); - NMSetting *setting = NULL; - GError *error = NULL; - GType type; - - g_return_val_if_fail (priv->connection != NULL, FALSE); - - /* Check whether a complete & valid NMSetting object was returned. If - * yes, replace the setting object in the connection. If not, just try - * updating the secrets. - */ - type = nm_connection_lookup_setting_type (setting_name); - if (type == 0) - return FALSE; - - setting = nm_setting_new_from_hash (type, new); - if (setting) { - NMSetting *s_8021x = NULL; - GSList *all_settings = NULL; - - /* The wireless-security setting might need the 802.1x setting in - * the all_settings argument of the verify function. Ugh. - */ - s_8021x = nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_802_1X); - if (s_8021x) - all_settings = g_slist_append (all_settings, s_8021x); - - if (!nm_setting_verify (setting, all_settings, NULL)) { - /* Just try updating secrets */ - g_object_unref (setting); - setting = NULL; - } - - g_slist_free (all_settings); - } - - if (setting) - nm_connection_add_setting (priv->connection, setting); - else { - if (!nm_connection_update_secrets (priv->connection, setting_name, new, &error)) { - nm_log_warn (LOGD_DEVICE, "Failed to update connection secrets: %d %s", - error ? error->code : -1, - error && error->message ? error->message : "(none)"); - g_clear_error (&error); - } - } - - return TRUE; -} -#endif - static void get_secrets_cb (NMAgentManager *manager, guint32 call_id, diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 9bdc72d39..7fb9ce4a5 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -32,6 +32,7 @@ #include "nm-secret-agent.h" #include "nm-manager-auth.h" #include "nm-sysconfig-connection.h" +#include "nm-dbus-glib-types.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -53,6 +54,13 @@ typedef struct { GHashTable *requests; } NMAgentManagerPrivate; +typedef struct _Request Request; + +static void request_add_agent (Request *req, + NMSecretAgent *agent, + NMSessionMonitor *session_monitor); + +static void request_remove_agent (Request *req, NMSecretAgent *agent); static void impl_agent_manager_register (NMAgentManager *self, const char *identifier, @@ -74,7 +82,8 @@ typedef enum { NM_AGENT_MANAGER_ERROR_SESSION_NOT_FOUND, NM_AGENT_MANAGER_ERROR_INVALID_IDENTIFIER, NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, - NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR + NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, + NM_AGENT_MANAGER_ERROR_NO_SECRETS } NMAgentManagerError; static GQuark @@ -108,6 +117,8 @@ nm_agent_manager_error_get_type (void) ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"), /* Some internal error occurred */ ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, "InternalError"), + /* No secrets were available */ + ENUM_ENTRY (NM_AGENT_MANAGER_ERROR_NO_SECRETS, "NoSecrets"), { 0, 0, 0 } }; @@ -123,20 +134,25 @@ remove_agent (NMAgentManager *self, const char *owner) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); NMSecretAgent *agent; + GHashTableIter iter; + gpointer data; g_return_val_if_fail (owner != NULL, FALSE); + /* Make sure this agent has already registered */ agent = g_hash_table_lookup (priv->agents, owner); if (!agent) return FALSE; - /* FIXME: signal agent removal */ + nm_log_dbg (LOGD_AGENTS, "(%s) agent unregistered", + nm_secret_agent_get_description (agent)); - nm_log_dbg (LOGD_AGENTS, "(%s/%s) agent unregistered for UID %ld", - nm_secret_agent_get_dbus_owner (agent), - nm_secret_agent_get_identifier (agent), - nm_secret_agent_get_owner_uid (agent)); + /* Remove this agent to any in-progress secrets requests */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_remove_agent ((Request *) data, agent); + /* And dispose of the agent */ g_hash_table_remove (priv->agents, owner); return TRUE; } @@ -208,6 +224,8 @@ impl_agent_manager_register (NMAgentManager *self, gulong sender_uid = G_MAXULONG; GError *error = NULL, *local = NULL; NMSecretAgent *agent; + GHashTableIter iter; + gpointer data; if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, @@ -243,7 +261,7 @@ impl_agent_manager_register (NMAgentManager *self, goto done; /* Success, add the new agent */ - agent = nm_secret_agent_new (sender, identifier, sender_uid); + agent = nm_secret_agent_new (priv->dbus_mgr, sender, identifier, sender_uid); if (!agent) { error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_INTERNAL_ERROR, @@ -252,12 +270,15 @@ impl_agent_manager_register (NMAgentManager *self, } g_hash_table_insert (priv->agents, g_strdup (sender), agent); - nm_log_dbg (LOGD_AGENTS, "(%s/%s) agent registered for UID %ld", - nm_secret_agent_get_dbus_owner (agent), - nm_secret_agent_get_identifier (agent), - nm_secret_agent_get_owner_uid (agent)); + nm_log_dbg (LOGD_AGENTS, "(%s) agent registered", + nm_secret_agent_get_description (agent)); dbus_g_method_return (context); + /* Add this agent to any in-progress secrets requests */ + g_hash_table_iter_init (&iter, priv->requests); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_add_agent ((Request *) data, agent, priv->session_monitor); + done: if (error) dbus_g_method_return_error (context, error); @@ -300,9 +321,6 @@ done: /*************************************************************/ -typedef struct _Request Request; - -typedef void (*RequestNextFunc) (Request *req, gpointer user_data); typedef void (*RequestCompleteFunc) (Request *req, GHashTable *secrets, GError *error, @@ -316,6 +334,21 @@ struct _Request { gboolean request_new; char *hint; + /* Current agent being asked for secrets */ + NMSecretAgent *current; + gpointer current_call_id; + + /* Stores the sorted list of NMSecretAgents which will be + * asked for secrets. + */ + GSList *pending; + + /* Stores the list of NMSecretAgent hashes that we've already + * asked for secrets, so that we don't ask the same agent twice + * if it quits and re-registers during this secrets request. + */ + GSList *asked; + guint32 idle_id; NMAgentSecretsResultFunc callback; @@ -323,9 +356,8 @@ struct _Request { gpointer other_data2; gpointer other_data3; - RequestNextFunc next_callback; RequestCompleteFunc complete_callback; - gpointer req_callback_data; + gpointer complete_callback_data; }; static Request * @@ -336,7 +368,9 @@ request_new (NMConnection *connection, NMAgentSecretsResultFunc callback, gpointer callback_data, gpointer other_data2, - gpointer other_data3) + gpointer other_data3, + RequestCompleteFunc complete_callback, + gpointer complete_callback_data) { Request *req; static guint32 next_id = 1; @@ -351,6 +385,8 @@ request_new (NMConnection *connection, req->callback_data = callback_data; req->other_data2 = other_data2; req->other_data3 = other_data3; + req->complete_callback = complete_callback; + req->complete_callback_data = complete_callback_data; return req; } @@ -361,6 +397,11 @@ request_free (Request *req) if (req->idle_id) g_source_remove (req->idle_id); + if (req->current && req->current_call_id) + nm_secret_agent_cancel_secrets (req->current, req->current_call_id); + + g_slist_free (req->pending); + g_slist_free (req->asked); g_object_unref (req->connection); g_free (req->setting_name); g_free (req->hint); @@ -368,15 +409,97 @@ request_free (Request *req) g_free (req); } +static void request_next (Request *req); + static void -request_set_callbacks (Request *req, - RequestNextFunc next_func, - RequestCompleteFunc complete_func, - gpointer user_data) +request_secrets_done_cb (DBusGProxy *proxy, + DBusGProxyCall *call_id, + void *user_data) { - req->next_callback = next_func; - req->complete_callback = complete_func; - req->req_callback_data = user_data; + Request *req = user_data; + GError *error = NULL; + GHashTable *secrets = NULL; + GHashTable *setting_secrets; + NMSecretAgent *agent = NM_SECRET_AGENT (req->current); + + if (call_id != req->current_call_id) + return; + + req->current = NULL; + req->current_call_id = NULL; + + if (!dbus_g_proxy_end_call (proxy, call_id, &error, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, + G_TYPE_INVALID)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + + /* Try the next agent */ + request_next (req); + return; + } + + /* Ensure the setting we wanted secrets for got returned and has something in it */ + setting_secrets = g_hash_table_lookup (secrets, req->setting_name); + if (!setting_secrets || !g_hash_table_size (setting_secrets)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + g_hash_table_destroy (secrets); + + /* Try the next agent */ + request_next (req); + return; + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent returned secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + /* Success! */ + req->complete_callback (req, secrets, NULL, req->complete_callback_data); + g_hash_table_destroy (secrets); +} + +static void +request_next (Request *req) +{ + GError *error = NULL; + + if (req->pending == NULL) { + /* No more secret agents are available to fulfill this secrets request */ + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NO_SECRETS, + "No secrets were available for this request."); + req->complete_callback (req, NULL, error, req->complete_callback_data); + g_error_free (error); + return; + } + + /* Send a secrets request to the next agent */ + req->current = req->pending->data; + req->pending = g_slist_remove (req->pending, req->current); + + nm_log_dbg (LOGD_AGENTS, "(%s) agent getting secrets for request %p/%s", + nm_secret_agent_get_description (req->current), + req, req->setting_name); + + req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), + req->connection, + req->setting_name, + req->hint, + req->request_new, + request_secrets_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current = NULL; + request_next (req); + } } static gboolean @@ -393,39 +516,135 @@ request_start_secrets (gpointer user_data) req->hint, req->request_new, &error); - if (secrets) { + if (secrets && g_hash_table_size (secrets)) { /* The connection already had secrets, no need to get any */ - req->complete_callback (req, secrets, NULL, req->req_callback_data); - g_hash_table_destroy (secrets); - } else if (error) - req->complete_callback (req, NULL, error, req->req_callback_data); - else { + req->complete_callback (req, secrets, NULL, req->complete_callback_data); + } else if (error) { + /* Errors from the system settings are hard errors; we don't go on + * to ask agents for secrets if the settings service failed. + */ + req->complete_callback (req, NULL, error, req->complete_callback_data); + g_error_free (error); + } else { /* Couldn't get secrets from system settings, so now we ask the * agents for secrets. Let the Agent Manager handle which agents * we'll ask and in which order. */ - req->next_callback (req, req->req_callback_data); + request_next (req); } - g_clear_error (&error); + if (secrets) + g_hash_table_destroy (secrets); + return FALSE; } -/*************************************************************/ +static gint +agent_compare_func (NMSecretAgent *a, NMSecretAgent *b, gpointer user_data) +{ + NMSessionMonitor *session_monitor = NM_SESSION_MONITOR (user_data); + gboolean a_active, b_active; + + if (a && !b) + return -1; + else if (a == b) + return 0; + else if (!a && b) + return 1; + + /* Prefer agents in active sessions */ + a_active = nm_session_monitor_uid_active (session_monitor, + nm_secret_agent_get_owner_uid (a), + NULL); + b_active = nm_session_monitor_uid_active (session_monitor, + nm_secret_agent_get_owner_uid (b), + NULL); + if (a_active && !b_active) + return -1; + else if (a_active == b_active) + return 0; + else if (!a_active && b_active) + return 1; + + return 0; +} static void -mgr_req_next_cb (Request *req, gpointer user_data) +request_add_agent (Request *req, + NMSecretAgent *agent, + NMSessionMonitor *session_monitor) { -#if 0 - NMAgentManager *self = NM_AGENT_MANAGER (user_data); - NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + uid_t agent_uid; - /* Look for the next agent to call for secrets based on whether that - * agent's user is in the connection's ACL. + g_return_if_fail (req != NULL); + g_return_if_fail (agent != NULL); + + if (g_slist_find (req->asked, GUINT_TO_POINTER (nm_secret_agent_get_hash (agent)))) + return; + + /* Ensure the caller's username exists in the connection's permissions, + * or that the permissions is empty (ie, visible by everyone). */ -#endif + agent_uid = nm_secret_agent_get_owner_uid (agent); + if (0 != agent_uid) { + if (!nm_auth_uid_in_acl (req->connection, session_monitor, agent_uid, NULL)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + /* Connection not visible to this agent's user */ + return; + } + /* Caller is allowed to add this connection */ + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent allowed for secrets request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + /* Add this agent to the list, preferring active sessions */ + req->pending = g_slist_insert_sorted_with_data (req->pending, + agent, + (GCompareDataFunc) agent_compare_func, + session_monitor); } +static void +request_remove_agent (Request *req, NMSecretAgent *agent) +{ + gboolean try_next = FALSE; + const char *detail = ""; + + g_return_if_fail (req != NULL); + g_return_if_fail (agent != NULL); + + if (!g_slist_find (req->pending, agent)) + return; + + /* If this agent is being asked right now, cancel the request */ + if (agent == req->current) { + nm_secret_agent_cancel_secrets (req->current, req->current_call_id); + req->current = NULL; + req->current_call_id = NULL; + try_next = TRUE; + detail = " current"; + } + + nm_log_dbg (LOGD_AGENTS, "(%s)%s agent removed from secrets request %p/%s", + nm_secret_agent_get_description (agent), + detail, req, req->setting_name); + + req->pending = g_slist_remove (req->pending, agent); + + if (try_next) { + /* If the agent serving the in-progress secrets request went away then + * we need to ask the next agent for secrets. + */ + request_next (req); + } +} + +/*************************************************************/ + static void mgr_req_complete_cb (Request *req, GHashTable *secrets, @@ -480,12 +699,19 @@ nm_agent_manager_get_secrets (NMAgentManager *self, { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); Request *req; + GHashTableIter iter; + gpointer data; g_return_val_if_fail (self != NULL, 0); g_return_val_if_fail (connection != NULL, 0); g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), 0); g_return_val_if_fail (callback != NULL, 0); + nm_log_dbg (LOGD_SETTINGS, + "Secrets requested for connection %s (%s)", + nm_connection_get_path (connection), + setting_name); + req = request_new (connection, setting_name, get_new, @@ -493,11 +719,17 @@ nm_agent_manager_get_secrets (NMAgentManager *self, callback, callback_data, other_data2, - other_data3); - request_set_callbacks (req, mgr_req_next_cb, mgr_req_complete_cb, self); + other_data3, + mgr_req_complete_cb, + self); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + /* Add agents to the request */ + g_hash_table_iter_init (&iter, priv->agents); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_add_agent (req, NM_SECRET_AGENT (data), priv->session_monitor); + req->idle_id = g_idle_add (request_start_secrets, req); return req->reqid; diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c index 0a1c8b723..7951c5065 100644 --- a/src/nm-secret-agent.c +++ b/src/nm-secret-agent.c @@ -24,7 +24,9 @@ #include #include +#include "NetworkManager.h" #include "nm-secret-agent.h" +#include "nm-dbus-glib-types.h" G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) @@ -35,13 +37,37 @@ G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) typedef struct { gboolean disposed; + char *description; char *owner; char *identifier; uid_t owner_uid; + guint32 hash; + + NMDBusManager *dbus_mgr; + DBusGProxy *proxy; } NMSecretAgentPrivate; /*************************************************************/ +const char * +nm_secret_agent_get_description (NMSecretAgent *agent) +{ + NMSecretAgentPrivate *priv; + + g_return_val_if_fail (agent != NULL, NULL); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE (agent); + if (!priv->description) { + priv->description = g_strdup_printf ("%s/%s/%u", + priv->owner, + priv->identifier, + priv->owner_uid); + } + + return priv->description; +} + const char * nm_secret_agent_get_dbus_owner (NMSecretAgent *agent) { @@ -69,10 +95,68 @@ nm_secret_agent_get_owner_uid (NMSecretAgent *agent) return NM_SECRET_AGENT_GET_PRIVATE (agent)->owner_uid; } +guint32 +nm_secret_agent_get_hash (NMSecretAgent *agent) +{ + g_return_val_if_fail (agent != NULL, 0); + g_return_val_if_fail (NM_IS_SECRET_AGENT (agent), 0); + + return NM_SECRET_AGENT_GET_PRIVATE (agent)->hash; +} + +/*************************************************************/ + +gpointer +nm_secret_agent_get_secrets (NMSecretAgent *self, + NMConnection *connection, + const char *setting_name, + const char *hint, + gboolean request_new, + DBusGProxyCallNotify done_callback, + gpointer done_callback_data) +{ + NMSecretAgentPrivate *priv; + DBusGProxyCall *call; + GHashTable *hash; + const char *hints[2] = { hint, NULL }; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (setting_name != NULL, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + hash = nm_connection_to_hash (connection); + call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "GetSecrets", + done_callback, + done_callback_data, + NULL, + 120000, /* 120 seconds */ + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), + G_TYPE_STRING, setting_name, + G_TYPE_STRV, hints, + G_TYPE_BOOLEAN, request_new, + G_TYPE_INVALID); + g_hash_table_destroy (hash); + + return call; +} + +void +nm_secret_agent_cancel_secrets (NMSecretAgent *self, gpointer call_id) +{ + g_return_if_fail (self != NULL); + + dbus_g_proxy_cancel_call (NM_SECRET_AGENT_GET_PRIVATE (self)->proxy, call_id); +} + /*************************************************************/ NMSecretAgent * -nm_secret_agent_new (const char *owner, +nm_secret_agent_new (NMDBusManager *dbus_mgr, + const char *owner, const char *identifier, uid_t owner_uid) { @@ -84,11 +168,26 @@ nm_secret_agent_new (const char *owner, self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL); if (self) { + DBusGConnection *bus; + char *hash_str; + priv = NM_SECRET_AGENT_GET_PRIVATE (self); priv->owner = g_strdup (owner); priv->identifier = g_strdup (identifier); priv->owner_uid = owner_uid; + + hash_str = g_strdup_printf ("%08u%s", owner_uid, identifier); + priv->hash = g_str_hash (hash_str); + g_free (hash_str); + + priv->dbus_mgr = g_object_ref (dbus_mgr); + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); + priv->proxy = dbus_g_proxy_new_for_name (bus, + owner, + NM_DBUS_PATH_SECRET_AGENT, + NM_DBUS_INTERFACE_SECRET_AGENT); + g_assert (priv->proxy); } return self; @@ -108,9 +207,13 @@ dispose (GObject *object) return; priv->disposed = TRUE; + g_free (priv->description); g_free (priv->owner); g_free (priv->identifier); + g_object_unref (priv->proxy); + g_object_unref (priv->dbus_mgr); + G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); } diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h index d5fb6b246..3aebf27f9 100644 --- a/src/nm-secret-agent.h +++ b/src/nm-secret-agent.h @@ -23,6 +23,11 @@ #include #include +#include +#include + +#include +#include "nm-dbus-manager.h" #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) @@ -41,14 +46,30 @@ typedef struct { GType nm_secret_agent_get_type (void); -NMSecretAgent *nm_secret_agent_new (const char *owner, +NMSecretAgent *nm_secret_agent_new (NMDBusManager *dbus_mgr, + const char *owner, const char *identifier, uid_t owner_uid); +const char *nm_secret_agent_get_description (NMSecretAgent *agent); + const char *nm_secret_agent_get_dbus_owner (NMSecretAgent *agent); const char *nm_secret_agent_get_identifier (NMSecretAgent *agent); uid_t nm_secret_agent_get_owner_uid (NMSecretAgent *agent); +guint32 nm_secret_agent_get_hash (NMSecretAgent *agent); + +gpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, + NMConnection *connection, + const char *setting_name, + const char *hint, + gboolean request_new, + DBusGProxyCallNotify done_callback, + gpointer done_callback_data); + +void nm_secret_agent_cancel_secrets (NMSecretAgent *agent, + gpointer call_id); + #endif /* NM_SECRET_AGENT_H */ diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index a5d04a500..e835aa692 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -781,32 +781,6 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, /******************************************************************************/ -#if 0 -static gboolean -secrets_update_setting (NMSecretsProviderInterface *interface, - const char *setting_name, - GHashTable *new) -{ - NMVPNConnection *self = NM_VPN_CONNECTION (interface); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - GError *error = NULL; - - g_return_val_if_fail (priv->connection != NULL, FALSE); - - if (strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME)) - return FALSE; - - if (!nm_connection_update_secrets (priv->connection, NM_SETTING_VPN_SETTING_NAME, new, &error)) { - nm_log_warn (LOGD_VPN, "Failed to update VPN secrets: %d %s", - error ? error->code : -1, - error && error->message ? error->message : "(none)"); - g_clear_error (&error); - return FALSE; - } - return TRUE; -} -#endif - static void cancel_get_secrets (NMVPNConnection *self) { From f7e27ea2390d79fa8ef4e8acc97bdf5fef92ad39 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 22 Dec 2010 15:12:12 -0600 Subject: [PATCH 122/264] settings: allow settings service to return partial secrets This allows the admin to define generic secrets for all users the connection is visible to, but allows user-specific secrets as well. --- src/nm-agent-manager.c | 106 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 7 deletions(-) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 7fb9ce4a5..3b6262110 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -351,6 +351,8 @@ struct _Request { guint32 idle_id; + GHashTable *settings_secrets; + NMAgentSecretsResultFunc callback; gpointer callback_data; gpointer other_data2; @@ -405,12 +407,60 @@ request_free (Request *req) g_object_unref (req->connection); g_free (req->setting_name); g_free (req->hint); + if (req->settings_secrets) + g_hash_table_unref (req->settings_secrets); memset (req, 0, sizeof (Request)); g_free (req); } static void request_next (Request *req); +static void +destroy_gvalue (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +static void +merge_secrets (GHashTable *src, GHashTable *dest) +{ + GHashTableIter iter; + gpointer key, data; + + g_hash_table_iter_init (&iter, src); + while (g_hash_table_iter_next (&iter, &key, &data)) { + const char *setting_name = key; + GHashTable *dstsetting; + GHashTableIter subiter; + gpointer subkey, subval; + + /* Find the corresponding setting in the merged secrets hash, or create + * it if it doesn't exist. + */ + dstsetting = g_hash_table_lookup (dest, setting_name); + if (!dstsetting) { + dstsetting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) destroy_gvalue); + g_hash_table_insert (dest, (gpointer) setting_name, dstsetting); + } + + /* And copy in each secret from src */ + g_hash_table_iter_init (&subiter, (GHashTable *) data); + while (g_hash_table_iter_next (&subiter, &subkey, &subval)) { + const char *keyname = subkey; + GValue *srcval = subval, *dstval; + + dstval = g_slice_new0 (GValue); + g_value_init (dstval, G_VALUE_TYPE (srcval)); + g_value_copy (srcval, dstval); + + g_hash_table_insert (dstsetting, (gpointer) keyname, dstval); + } + } +} + static void request_secrets_done_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, @@ -459,8 +509,23 @@ request_secrets_done_cb (DBusGProxy *proxy, nm_secret_agent_get_description (agent), req, req->setting_name); - /* Success! */ - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + /* Success! If we got some secrets from the settings service, merge those + * with the ones from the secret agent. + */ + if (req->settings_secrets) { + GHashTable *merged; + + merged = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_unref); + + /* Copy agent secrets first, then overwrite with settings secrets */ + merge_secrets (secrets, merged); + merge_secrets (req->settings_secrets, merged); + + req->complete_callback (req, merged, NULL, req->complete_callback_data); + g_hash_table_destroy (merged); + } else + req->complete_callback (req, secrets, NULL, req->complete_callback_data); + g_hash_table_destroy (secrets); } @@ -506,7 +571,7 @@ static gboolean request_start_secrets (gpointer user_data) { Request *req = user_data; - GHashTable *secrets; + GHashTable *secrets, *setting_secrets = NULL; GError *error = NULL; req->idle_id = 0; @@ -516,9 +581,36 @@ request_start_secrets (gpointer user_data) req->hint, req->request_new, &error); - if (secrets && g_hash_table_size (secrets)) { - /* The connection already had secrets, no need to get any */ - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + if (secrets) + setting_secrets = g_hash_table_lookup (secrets, req->setting_name); + + if (setting_secrets && g_hash_table_size (setting_secrets)) { + NMConnection *tmp; + + /* The connection already had secrets; check if any more are required. + * If no more are required, we're done. If secrets are still needed, + * ask a secret agent for more. This allows admins to provide generic + * secrets but allow additional user-specific ones as well. + */ + tmp = nm_connection_duplicate (req->connection); + g_assert (tmp); + + if (!nm_connection_update_secrets (tmp, req->setting_name, secrets, &error)) { + req->complete_callback (req, NULL, error, req->complete_callback_data); + g_clear_error (&error); + } else { + /* Do we have everything we need? */ + /* FIXME: handle second check for VPN connections */ + if (nm_connection_need_secrets (tmp, NULL) == NULL) { + /* Got everything, we're done */ + req->complete_callback (req, secrets, NULL, req->complete_callback_data); + } else { + /* We don't, so ask some agents for additional secrets */ + req->settings_secrets = g_hash_table_ref (secrets); + request_next (req); + } + } + g_object_unref (tmp); } else if (error) { /* Errors from the system settings are hard errors; we don't go on * to ask agents for secrets if the settings service failed. @@ -534,7 +626,7 @@ request_start_secrets (gpointer user_data) } if (secrets) - g_hash_table_destroy (secrets); + g_hash_table_unref (secrets); return FALSE; } From 136139f699c00901755189b99bfac0c74819dc6e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 23 Dec 2010 07:52:41 -0600 Subject: [PATCH 123/264] policy: only autoactivate connections visible to some user If the connection is restricted to certain users, don't auto-activate that connection unless at least one of those users is logged in. --- src/nm-policy.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 6bad928cf..6ee493cc1 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -756,27 +756,35 @@ auto_activate_device (gpointer user_data) if (nm_device_get_act_request (data->device)) goto out; - connections = nm_settings_get_connections (policy->settings); + iter = connections = nm_settings_get_connections (policy->settings); - /* Remove connections that have INVALID_TAG and shouldn't be retried any more. */ - iter = connections; + /* Remove connections that shouldn't be auto-activated */ while (iter) { - NMConnection *iter_connection = NM_CONNECTION (iter->data); - GSList *next = g_slist_next (iter); + NMConnection *candidate = NM_CONNECTION (iter->data); + gboolean ignore = FALSE; - if (g_object_get_data (G_OBJECT (iter_connection), INVALID_TAG)) { - guint retries = get_connection_auto_retries (iter_connection); + /* Ignore connecitons that were tried too many times */ + if (g_object_get_data (G_OBJECT (candidate), INVALID_TAG)) { + guint retries = get_connection_auto_retries (candidate); if (retries == 0) - connections = g_slist_remove (connections, iter_connection); + ignore = TRUE; else if (retries > 0) - set_connection_auto_retries (iter_connection, retries - 1); + set_connection_auto_retries (candidate, retries - 1); } else { /* Set the initial # of retries for auto-connection */ - set_connection_auto_retries (iter_connection, RETRIES_DEFAULT); + set_connection_auto_retries (candidate, RETRIES_DEFAULT); } - iter = next; + /* Ignore connections that aren't visible to any logged-in users */ + if (ignore == FALSE) { + if (!nm_sysconfig_connection_is_visible (NM_SYSCONFIG_CONNECTION (candidate))) + ignore = TRUE; + } + + iter = g_slist_next (iter); + if (ignore) + connections = g_slist_remove (connections, candidate); } best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object); From 77f3d6c81cabf7ab899ed3f12002ef1c09015680 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 23 Dec 2010 09:09:13 -0600 Subject: [PATCH 124/264] libnm-glib: add signal prototype to class definition --- libnm-glib/nm-client.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 69847fdcc..95f8de983 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -84,6 +84,9 @@ typedef struct { /* Signals */ void (*device_added) (NMClient *client, NMDevice *device); void (*device_removed) (NMClient *client, NMDevice *device); + void (*permission_changed) (NMClient *client, + NMClientPermission permission, + NMClientPermissionResult result); /* Padding for future expansion */ void (*_reserved1) (void); From eb27406fdc58c40c5b6a43deea4502f7c1042c63 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 23 Dec 2010 09:59:57 -0600 Subject: [PATCH 125/264] libnm-glib: handle visibility changes for updated connections --- libnm-glib/nm-remote-connection.c | 63 ++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 9f52570cb..0887b725f 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -242,44 +242,36 @@ nm_remote_connection_get_secrets (NMRemoteConnection *self, /****************************************************************/ -static gboolean +static void replace_settings (NMRemoteConnection *self, GHashTable *new_settings) { GError *error = NULL; - if (!nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) { + if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, &error)) + g_signal_emit (self, signals[UPDATED], 0, new_settings); + else { g_warning ("%s: error updating connection %s settings: (%d) %s", __func__, nm_connection_get_path (NM_CONNECTION (self)), error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - return FALSE; - } - /* Emit update irregardless to let listeners figure out what to do with - * the connection; whether to delete / ignore it or not. - */ - g_signal_emit (self, signals[UPDATED], 0, new_settings); - return TRUE; + g_signal_emit (self, signals[REMOVED], 0); + } } static void -get_settings_cb (DBusGProxy *proxy, - GHashTable *new_settings, - GError *error, - gpointer user_data) +init_get_settings_cb (DBusGProxy *proxy, + GHashTable *new_settings, + GError *error, + gpointer user_data) { NMRemoteConnection *self = user_data; NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); if (error) { - g_warning ("%s: error getting connection %s settings: (%d) %s", - __func__, - nm_connection_get_path (NM_CONNECTION (self)), - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); - g_error_free (error); + /* Connection doesn't exist, or isn't visible to this user */ priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_ERROR; g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_INIT_RESULT); } else { @@ -291,9 +283,34 @@ get_settings_cb (DBusGProxy *proxy, } static void -updated_cb (DBusGProxy *proxy, GHashTable *settings, gpointer user_data) +updated_get_settings_cb (DBusGProxy *proxy, + GHashTable *new_settings, + GError *error, + gpointer user_data) { - replace_settings (NM_REMOTE_CONNECTION (user_data), settings); + NMRemoteConnection *self = user_data; + + if (error) { + /* The connection no longer exists, or is no longer visible to this + * user; we must remove it. + */ + g_signal_emit (self, signals[REMOVED], 0); + } else { + replace_settings (self, new_settings); + g_hash_table_destroy (new_settings); + } +} + +static void +updated_cb (DBusGProxy *proxy, gpointer user_data) +{ + NMRemoteConnection *self = NM_REMOTE_CONNECTION (user_data); + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); + + /* The connection got updated; request the replacement settings */ + org_freedesktop_NetworkManager_Settings_Connection_get_settings_async (priv->proxy, + updated_get_settings_cb, + self); } static void @@ -356,14 +373,14 @@ constructor (GType type, g_assert (priv->secrets_proxy); dbus_g_proxy_set_default_timeout (priv->secrets_proxy, G_MAXINT); - dbus_g_proxy_add_signal (priv->proxy, "Updated", DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->proxy, "Updated", G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "Updated", G_CALLBACK (updated_cb), object, NULL); dbus_g_proxy_add_signal (priv->proxy, "Removed", G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "Removed", G_CALLBACK (removed_cb), object, NULL); org_freedesktop_NetworkManager_Settings_Connection_get_settings_async (priv->proxy, - get_settings_cb, + init_get_settings_cb, object); return object; } From 8bb9394e9236ec6cc7f5ca8a6438ced03730e1e1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 24 Dec 2010 07:02:35 -0600 Subject: [PATCH 126/264] trivial: whitespace fixes --- libnm-glib/nm-client.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 95f8de983..e528af426 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -107,11 +107,11 @@ NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_ typedef void (*NMClientActivateDeviceFn) (gpointer user_data, const char *object_path, GError *error); void nm_client_activate_connection (NMClient *client, - const char *connection_path, - NMDevice *device, - const char *specific_object, - NMClientActivateDeviceFn callback, - gpointer user_data); + const char *connection_path, + NMDevice *device, + const char *specific_object, + NMClientActivateDeviceFn callback, + gpointer user_data); void nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active); From ad9270da79a571bdb7e3e6c69ed24dc1d396c536 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 27 Dec 2010 15:03:44 -0600 Subject: [PATCH 127/264] libnm-glib: ensure connection is initialized before AddConnection callback --- libnm-glib/nm-remote-settings.c | 169 ++++++++++++++++++++++++++++---- libnm-glib/nm-remote-settings.h | 24 +++++ 2 files changed, 175 insertions(+), 18 deletions(-) diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 7b614854a..872babeb4 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -42,6 +42,9 @@ typedef struct { GHashTable *connections; GHashTable *pending; /* Connections we don't have settings for yet */ gboolean service_running; + + /* AddConnectionInfo objects that are waiting for the connection to become initialized */ + GSList *add_list; DBusGProxy *props_proxy; char *hostname; @@ -73,6 +76,89 @@ enum { }; static guint signals[LAST_SIGNAL] = { 0 }; +/**********************************************************************/ + +/** + * nm_remote_settings_error_quark: + * + * Registers an error quark for #NMRemoteSettings if necessary. + * + * Returns: the error quark used for #NMRemoteSettings errors. + **/ +GQuark +nm_remote_settings_error_quark (void) +{ + static GQuark quark; + + if (G_UNLIKELY (!quark)) + quark = g_quark_from_static_string ("nm-remote-settings-error-quark"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +GType +nm_remote_settings_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + ENUM_ENTRY (NM_REMOTE_SETTINGS_ERROR_UNKNOWN, "UnknownError"), + ENUM_ENTRY (NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED, "ConnectionRemoved"), + ENUM_ENTRY (NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, "ConnectionUnavailable"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMRemoteSettingsError", values); + } + return etype; +} + +/**********************************************************************/ + +typedef struct { + NMRemoteSettings *self; + NMRemoteSettingsAddConnectionFunc callback; + gpointer callback_data; + NMRemoteConnection *connection; +} AddConnectionInfo; + +static AddConnectionInfo * +add_connection_info_find (NMRemoteSettings *self, NMRemoteConnection *connection) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->add_list; iter; iter = g_slist_next (iter)) { + AddConnectionInfo *info = iter->data; + + if (info->connection == connection) + return info; + } + + return NULL; +} + +static void +add_connection_info_dispose (NMRemoteSettings *self, AddConnectionInfo *info) +{ + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + + priv->add_list = g_slist_remove (priv->add_list, info); + + g_free (info); +} + +static void +add_connection_info_complete (NMRemoteSettings *self, + AddConnectionInfo *info, + GError *error) +{ + info->callback (info->self, error ? NULL : info->connection, error, info->callback_data); + add_connection_info_dispose (self, info); +} + /** * nm_remote_settings_get_connection_by_path: * @settings: the %NMRemoteSettings @@ -98,8 +184,20 @@ connection_removed_cb (NMRemoteConnection *remote, gpointer user_data) { NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + AddConnectionInfo *addinfo; + GError *add_error; const char *path; + /* Might have been removed while it was waiting to be initialized */ + addinfo = add_connection_info_find (self, remote); + if (addinfo) { + add_error = g_error_new_literal (NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED, + "Connection removed before it was initialized"); + add_connection_info_complete (self, addinfo, add_error); + g_error_free (add_error); + } + path = nm_connection_get_path (NM_CONNECTION (remote)); g_hash_table_remove (priv->connections, path); g_hash_table_remove (priv->pending, path); @@ -113,7 +211,9 @@ connection_init_result_cb (NMRemoteConnection *remote, NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); guint32 init_result = NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN; + AddConnectionInfo *addinfo; const char *path; + GError *add_error = NULL; /* Disconnect from the init-result signal just to be safe */ g_signal_handlers_disconnect_matched (remote, @@ -130,6 +230,8 @@ connection_init_result_cb (NMRemoteConnection *remote, NM_REMOTE_CONNECTION_INIT_RESULT, &init_result, NULL); + addinfo = add_connection_info_find (self, remote); + switch (init_result) { case NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS: /* ref it when adding to ->connections, since removing it from ->pending @@ -137,12 +239,26 @@ connection_init_result_cb (NMRemoteConnection *remote, */ g_hash_table_insert (priv->connections, g_strdup (path), g_object_ref (remote)); + /* If there's a pending AddConnection request, complete that here before + * signaling new-connection. + */ + add_connection_info_complete (self, addinfo, NULL); + /* Finally, let users know of the new connection now that it has all * its settings and is valid. */ g_signal_emit (self, signals[NEW_CONNECTION], 0, remote); break; case NM_REMOTE_CONNECTION_INIT_RESULT_ERROR: + /* Complete pending AddConnection callbacks */ + if (addinfo) { + add_error = g_error_new_literal (NM_REMOTE_SETTINGS_ERROR, + NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, + "Connection not visible or not available"); + add_connection_info_complete (self, addinfo, add_error); + g_error_free (add_error); + } + break; default: break; } @@ -161,6 +277,15 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); NMRemoteConnection *connection = NULL; + /* Make double-sure we don't already have it */ + connection = g_hash_table_lookup (priv->pending, path); + if (connection) + return connection; + connection = g_hash_table_lookup (priv->connections, path); + if (connection) + return connection; + + /* Create a new connection object for it */ connection = nm_remote_connection_new (priv->bus, path); if (connection) { g_signal_connect (connection, "removed", @@ -261,12 +386,6 @@ nm_remote_settings_list_connections (NMRemoteSettings *settings) return list; } -typedef struct { - NMRemoteSettings *self; - NMRemoteSettingsAddConnectionFunc callback; - gpointer callback_data; -} AddConnectionInfo; - static void add_connection_done (DBusGProxy *proxy, char *path, @@ -274,13 +393,12 @@ add_connection_done (DBusGProxy *proxy, gpointer user_data) { AddConnectionInfo *info = user_data; - NMRemoteConnection *connection; - connection = new_connection_cb (proxy, path, info->self); - g_assert (connection); - info->callback (info->self, connection, error, info->callback_data); + info->connection = new_connection_cb (proxy, path, info->self); + g_assert (info->connection); + + /* Wait until this connection is fully initialized before calling the callback */ - g_free (info); g_free (path); } /** @@ -325,14 +443,15 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, add_connection_done, info); g_hash_table_destroy (new_settings); + + priv->add_list = g_slist_append (priv->add_list, info); + return TRUE; } -static gboolean -remove_connections (gpointer user_data) +static void +clear_one_hash (GHashTable *table) { - NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); GHashTableIter iter; gpointer value; GSList *list = NULL, *list_iter; @@ -342,7 +461,7 @@ remove_connections (gpointer user_data) * that explicitly removes the the connection from the hash table somewhere * else. */ - g_hash_table_iter_init (&iter, priv->connections); + g_hash_table_iter_init (&iter, table); while (g_hash_table_iter_next (&iter, NULL, &value)) list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value)); @@ -350,7 +469,17 @@ remove_connections (gpointer user_data) g_signal_emit_by_name (NM_REMOTE_CONNECTION (list_iter->data), "removed"); g_slist_free (list); - g_hash_table_remove_all (priv->connections); + g_hash_table_remove_all (table); +} + +static gboolean +remove_connections (gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + + clear_one_hash (priv->pending); + clear_one_hash (priv->connections); return FALSE; } @@ -626,7 +755,8 @@ constructor (GType type, static void dispose (GObject *object) { - NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (object); + NMRemoteSettings *self = NM_REMOTE_SETTINGS (object); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); if (priv->disposed) return; @@ -636,6 +766,9 @@ dispose (GObject *object) if (priv->fetch_id) g_source_remove (priv->fetch_id); + while (g_slist_length (priv->add_list)) + add_connection_info_dispose (self, (AddConnectionInfo *) priv->add_list->data); + if (priv->connections) g_hash_table_destroy (priv->connections); diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index 78c7e827f..b38266d9d 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -38,6 +38,30 @@ G_BEGIN_DECLS #define NM_IS_REMOTE_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_SETTINGS)) #define NM_REMOTE_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_SETTINGS, NMRemoteSettingsClass)) +/** + * NMRemoteSettingsError: + * @NM_REMOTE_SETTINGS_ERROR_UNKNOWN: unknown or unclassified error + * @NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED: the #NMRemoteConnection object + * was removed before it was completely initialized + * @NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE: the #NMRemoteConnection object + * is not visible or otherwise unreadable + * + * Describes errors that may result from operations involving a #NMRemoteSettings. + * + **/ +typedef enum { + NM_REMOTE_SETTINGS_ERROR_UNKNOWN = 0, + NM_REMOTE_SETTINGS_ERROR_CONNECTION_REMOVED, + NM_REMOTE_SETTINGS_ERROR_CONNECTION_UNAVAILABLE, +} NMRemoteSettingsError; + +#define NM_TYPE_REMOTE_SETTINGS_ERROR (nm_remote_settings_error_get_type ()) +GType nm_remote_settings_error_get_type (void); + +#define NM_REMOTE_SETTINGS_ERROR nm_remote_settings_error_quark () +GQuark nm_remote_settings_error_quark (void); + + #define NM_REMOTE_SETTINGS_BUS "bus" #define NM_REMOTE_SETTINGS_SERVICE_RUNNING "service-running" #define NM_REMOTE_SETTINGS_HOSTNAME "hostname" From dd6d72d6a13267033dfd6d36519118b901a36e4e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 28 Dec 2010 16:40:07 -0600 Subject: [PATCH 128/264] libnm-glib: handle errors on AddConnection reply --- libnm-glib/nm-remote-settings.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 872babeb4..3369860e8 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -394,10 +394,13 @@ add_connection_done (DBusGProxy *proxy, { AddConnectionInfo *info = user_data; - info->connection = new_connection_cb (proxy, path, info->self); - g_assert (info->connection); - - /* Wait until this connection is fully initialized before calling the callback */ + if (error) { + add_connection_info_complete (info->self, info, error); + } else { + info->connection = new_connection_cb (proxy, path, info->self); + g_assert (info->connection); + /* Wait until this connection is fully initialized before calling the callback */ + } g_free (path); } From ad80a58c15f7d30f2c035323f35f782607dd7bfb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 28 Dec 2010 17:11:27 -0600 Subject: [PATCH 129/264] libnm-glib: add testcases and testing infrastructure Tests for addition and removal of connections. --- .gitignore | 1 + configure.ac | 1 + libnm-glib/Makefile.am | 26 ++ libnm-glib/nm-client.c | 4 + libnm-glib/tests/Makefile.am | 34 +++ .../tests/test-remote-settings-client.c | 258 ++++++++++++++++++ .../tests/test-remote-settings-service.py | 116 ++++++++ 7 files changed, 440 insertions(+) create mode 100644 libnm-glib/tests/Makefile.am create mode 100644 libnm-glib/tests/test-remote-settings-client.c create mode 100755 libnm-glib/tests/test-remote-settings-service.py diff --git a/.gitignore b/.gitignore index 033eaada1..980764198 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ libnm-util/tests/test-settings-defaults libnm-util/tests/test-general libnm-util/tests/test-need-secrets libnm-util/tests/test-setting-8021x +libnm-glib/tests/test-remote-settings-client src/tests/test-dhcp-options src/tests/test-policy-hosts diff --git a/configure.ac b/configure.ac index 3306c6da2..bc9733036 100644 --- a/configure.ac +++ b/configure.ac @@ -547,6 +547,7 @@ libnm-util/tests/certs/Makefile libnm-glib/libnm-glib.pc libnm-glib/libnm-glib-vpn.pc libnm-glib/Makefile +libnm-glib/tests/Makefile callouts/Makefile tools/Makefile system-settings/Makefile diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 5a6045ebc..571b6bf96 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS=. tests + INCLUDES = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libnm-util \ @@ -135,6 +137,30 @@ libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ -version-info "1:0:0" +##################################################### +# Test libnm-glib stuff +##################################################### + +noinst_LTLIBRARIES = libnm-glib-test.la + +libnm_glib_test_la_CFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GUDEV_CFLAGS) \ + -DLIBNM_GLIB_TEST + +libnm_glib_test_la_SOURCES = \ + $(libnminclude_HEADERS) \ + $(libnm_glib_la_SOURCES) + +libnm_glib_test_la_LIBADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) \ + $(GUDEV_LIBS) + +##################################################### nm-client-bindings.h: $(top_srcdir)/introspection/nm-manager-client.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_client --mode=glib-client --output=$@ $< diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index e7770df64..a2be1f795 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -817,7 +817,11 @@ nm_client_new (void) DBusGConnection *connection; GError *err = NULL; +#ifdef LIBNM_GLIB_TEST + connection = dbus_g_bus_get (DBUS_BUS_SESSION, &err); +#else connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); +#endif if (!connection) { g_warning ("Couldn't connect to system bus: %s", err->message); g_error_free (err); diff --git a/libnm-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am new file mode 100644 index 000000000..a22a2d35d --- /dev/null +++ b/libnm-glib/tests/Makefile.am @@ -0,0 +1,34 @@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/libnm-util \ + -I$(top_srcdir)/libnm-glib + +noinst_PROGRAMS = test-remote-settings-client + +####### remote settings client test ####### + +test_remote_settings_client_SOURCES = \ + test-remote-settings-client.c + +test_remote_settings_client_CPPFLAGS = \ + -DSERVICEDIR=\"$(builddir)\" \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) + +test_remote_settings_client_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib-test.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) + +########################################### + +EXTRA_DIST = test-remote-settings-service.py + +if WITH_TESTS + +check-local: test-remote-settings-client + $(abs_builddir)/test-remote-settings-client + +endif + diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c new file mode 100644 index 000000000..328573573 --- /dev/null +++ b/libnm-glib/tests/test-remote-settings-client.c @@ -0,0 +1,258 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2010 Red Hat, Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "nm-remote-settings.h" + +#define SERVICE_FILE "test-remote-settings-service.py" + +static GPid spid = 0; +static NMRemoteSettings *settings = NULL; + +/*******************************************************************/ + +static void +cleanup (void) +{ + if (settings) + g_object_unref (settings); + kill (spid, SIGTERM); +} + +#define test_assert(condition) \ +do { \ + if (!G_LIKELY (condition)) \ + cleanup (); \ + g_assert (condition); \ +} while (0) + +/*******************************************************************/ + +typedef struct { + gboolean done; + NMRemoteConnection *connection; +} AddInfo; + +static void +add_cb (NMRemoteSettings *s, + NMRemoteConnection *connection, + GError *error, + gpointer user_data) +{ + AddInfo *info = user_data; + + if (error) + g_warning ("Add error: %s", error->message); + + info->done = TRUE; + info->connection = connection; +} + +static void +test_add_connection (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + char *uuid; + gboolean success; + time_t start, now; + AddInfo info = { FALSE, NULL }; + + connection = nm_connection_new (); + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_ID, "blahblahblah", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + s_wired = (NMSettingWired *) nm_setting_wired_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + success = nm_remote_settings_add_connection (settings, + connection, + add_cb, + &info); + test_assert (success == TRUE); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((info.done == FALSE) && (now - start < 5)); + test_assert (info.done == TRUE); + test_assert (info.connection != NULL); + + /* Make sure the connection is the same as what we added */ + test_assert (nm_connection_compare (connection, + NM_CONNECTION (info.connection), + NM_SETTING_COMPARE_FLAG_EXACT) == TRUE); +} + +/*******************************************************************/ + +static void +deleted_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + GError *error = NULL; + gboolean success; + + success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + if (!success) + g_warning ("Failed to delete connection: %s", error->message); + test_assert (success == TRUE); + test_assert (error == NULL); +} + +static void +removed_cb (NMRemoteConnection *connection, gpointer user_data) +{ + gboolean *done = user_data; + + *done = TRUE; +} + +static void +test_remove_connection (DBusGConnection *bus) +{ + NMRemoteConnection *connection; + time_t start, now; + GSList *list, *iter; + DBusGProxy *proxy; + gboolean done = FALSE; + char *path; + + /* Find a connection to delete */ + list = nm_remote_settings_list_connections (settings); + test_assert (g_slist_length (list) > 0); + + connection = NM_REMOTE_CONNECTION (list->data); + path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); + g_signal_connect (connection, "removed", G_CALLBACK (removed_cb), &done); + + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + test_assert (proxy != NULL); + + /* Bypass the NMRemoteSettings object so we can test it independently */ + dbus_g_proxy_begin_call (proxy, "Delete", deleted_cb, NULL, NULL, G_TYPE_INVALID); + + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + test_assert (done == TRUE); + + /* Ensure NMRemoteSettings no longer has the connection */ + list = nm_remote_settings_list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + test_assert ((gpointer) connection != (gpointer) candidate); + test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + } + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +#if GLIB_CHECK_VERSION(2,25,12) +typedef GTestFixtureFunc TCFunc; +#else +typedef void (*TCFunc)(void); +#endif + +#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) + +int main (int argc, char **argv) +{ + GTestSuite *suite; + char *service_argv[3] = { SERVICEDIR "/" SERVICE_FILE, SERVICE_FILE, NULL }; + int ret; + GError *error = NULL; + DBusGConnection *bus; + int i = 100; + + g_type_init (); + + g_test_init (&argc, &argv, NULL); + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + if (!bus) { + g_warning ("Error connecting to D-Bus: %s", error->message); + g_assert (error == NULL); + } + + if (!g_spawn_async (SERVICEDIR, service_argv, NULL, 0, NULL, NULL, &spid, &error)) { + g_warning ("Error spawning " SERVICE_FILE ": %s", error->message); + g_assert (error == NULL); + } + + /* Wait until the service is registered on the bus */ + while (i > 0) { + g_usleep (G_USEC_PER_SEC / 50); + if (dbus_bus_name_has_owner (dbus_g_connection_get_connection (bus), + "org.freedesktop.NetworkManager", + NULL)) + break; + i--; + } + test_assert (i > 0); + + settings = nm_remote_settings_new (bus); + test_assert (settings != NULL); + + suite = g_test_get_root (); + + g_test_suite_add (suite, TESTCASE (test_add_connection, NULL)); + g_test_suite_add (suite, TESTCASE (test_remove_connection, bus)); + + ret = g_test_run (); + + cleanup (); + + return ret; +} + diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py new file mode 100755 index 000000000..1f4f9af07 --- /dev/null +++ b/libnm-glib/tests/test-remote-settings-service.py @@ -0,0 +1,116 @@ +#!/bin/env python +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +import glib +import gobject +import sys +import dbus +import dbus.service +import dbus.mainloop.glib + +IFACE_SETTINGS = 'org.freedesktop.NetworkManager.Settings' +IFACE_CONNECTION = 'org.freedesktop.NetworkManager.Settings.Connection' +IFACE_DBUS = 'org.freedesktop.DBus' + +class UnknownInterfaceException(dbus.DBusException): + _dbus_error_name = IFACE_DBUS + '.UnknownInterface' + +class UnknownPropertyException(dbus.DBusException): + _dbus_error_name = IFACE_DBUS + '.UnknownProperty' + +mainloop = gobject.MainLoop() + +class Connection(dbus.service.Object): + def __init__(self, bus, object_path, settings, remove_func): + dbus.service.Object.__init__(self, bus, object_path) + self.path = object_path + self.settings = settings + self.remove_func = remove_func + + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') + def GetSettings(self): + return self.settings + + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='') + def Delete(self): + self.remove_func(self) + self.Removed() + + @dbus.service.signal(IFACE_CONNECTION, signature='') + def Removed(self): + pass + +class Settings(dbus.service.Object): + def __init__(self, bus, object_path): + dbus.service.Object.__init__(self, bus, object_path) + self.connections = {} + self.bus = bus + self.counter = 1 + self.props = {} + self.props['Hostname'] = "foobar.baz" + self.props['CanModify'] = True + + @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='', out_signature='ao') + def ListConnections(self): + connections = [] + return self.connections.keys() + + @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='a{sa{sv}}', out_signature='o') + def AddConnection(self, settings): + path = "/org/freedesktop/NetworkManager/Settings/Connection/%d" % self.counter + self.counter = self.counter + 1 + self.connections[path] = Connection(self.bus, path, settings, self.delete_connection) + print "Added connection %s" % path + return path + + def delete_connection(self, connection): + del self.connections[connection.path] + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, iface): + if iface != IFACE_SETTINGS: + raise UnknownInterfaceException() + return self.props + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, iface, name): + if iface != IFACE_SETTINGS: + raise UnknownInterfaceException() + if not name in self.props.keys(): + raise UnknownPropertyException() + return self.props[name] + + @dbus.service.signal(IFACE_SETTINGS, signature='o') + def NewConnection(self, path): + pass + + @dbus.service.method(IFACE_SETTINGS, in_signature='', out_signature='') + def Quit(self): + mainloop.quit() + +def quit_cb(user_data): + mainloop.quit() + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + bus = dbus.SessionBus() + obj = Settings(bus, "/org/freedesktop/NetworkManager/Settings") + if not bus.request_name("org.freedesktop.NetworkManager"): + sys.exit(1) + + print "Service started" + + gobject.timeout_add_seconds(20, quit_cb, None) + + try: + mainloop.run() + except Exception, e: + pass + + print "Service stopped" + sys.exit(0) + +if __name__ == '__main__': + main() + From 694571a5c6bca5dfaa4e9a7391f34bd5488721df Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 9 Jan 2011 02:00:29 -0600 Subject: [PATCH 130/264] libnm-util: add defines for wifi modes --- libnm-util/nm-setting-wireless.c | 2 +- libnm-util/nm-setting-wireless.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libnm-util/nm-setting-wireless.c b/libnm-util/nm-setting-wireless.c index ec7d53ad7..f645e9d8a 100644 --- a/libnm-util/nm-setting-wireless.c +++ b/libnm-util/nm-setting-wireless.c @@ -446,7 +446,7 @@ static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingWirelessPrivate *priv = NM_SETTING_WIRELESS_GET_PRIVATE (setting); - const char *valid_modes[] = { "infrastructure", "adhoc", NULL }; + const char *valid_modes[] = { NM_SETTING_WIRELESS_MODE_INFRA, NM_SETTING_WIRELESS_MODE_ADHOC, NULL }; const char *valid_bands[] = { "a", "bg", NULL }; GSList *iter; diff --git a/libnm-util/nm-setting-wireless.h b/libnm-util/nm-setting-wireless.h index 2216a246a..728a05e2c 100644 --- a/libnm-util/nm-setting-wireless.h +++ b/libnm-util/nm-setting-wireless.h @@ -68,6 +68,9 @@ GQuark nm_setting_wireless_error_quark (void); #define NM_SETTING_WIRELESS_SEEN_BSSIDS "seen-bssids" #define NM_SETTING_WIRELESS_SEC "security" +#define NM_SETTING_WIRELESS_MODE_ADHOC "adhoc" +#define NM_SETTING_WIRELESS_MODE_INFRA "infrastructure" + typedef struct { NMSetting parent; } NMSettingWireless; From bf98469b8d7b9efe0dfd6e8117e1bcff30ef2c16 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 9 Jan 2011 02:00:51 -0600 Subject: [PATCH 131/264] include: fix BT capability docs --- include/NetworkManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 558eb3e40..95f065353 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -152,7 +152,7 @@ typedef enum { * NMBluetoothCapabilities: * @NM_BT_CAPABILITY_NONE: device has no usable capabilities * @NM_BT_CAPABILITY_DUN: device provides Dial-Up Networking capability - * @NM_BT_CAPABILITY_PAN: device provides Personal Area Networking capability + * @NM_BT_CAPABILITY_NAP: device provides Network Access Point capability * * #NMBluetoothCapabilities values indicate the usable capabilities of a * Bluetooth device. From 215306f5a1e4dc38ec02a484c31470bb048d668b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Jan 2011 23:39:12 -0600 Subject: [PATCH 132/264] core: add AddAndActivate D-Bus method Given connection details, complete the connection as well as possible using the given specific object and device, add it to system settings, and activate it all in one method. --- .gitignore | 1 + introspection/nm-manager.xml | 49 ++ src/Makefile.am | 23 +- src/modem-manager/nm-modem-cdma.c | 48 +- src/modem-manager/nm-modem-gsm.c | 53 +- src/modem-manager/nm-modem.c | 11 + src/modem-manager/nm-modem.h | 10 + src/nm-device-bt.c | 158 ++++- src/nm-device-ethernet.c | 64 +- src/nm-device-modem.c | 13 + src/nm-device-modem.h | 2 +- src/nm-device-olpc-mesh.c | 47 +- src/nm-device-private.h | 8 +- src/nm-device-wifi.c | 226 ++++++- src/nm-device.c | 149 ++++- src/nm-device.h | 14 +- src/nm-manager.c | 217 +++++-- src/nm-wifi-ap-utils.c | 699 +++++++++++++++++++++ src/nm-wifi-ap-utils.h | 43 ++ src/nm-wifi-ap.c | 22 + src/nm-wifi-ap.h | 7 +- src/settings/nm-settings.c | 71 ++- src/settings/nm-settings.h | 12 + src/tests/Makefile.am | 20 +- src/tests/test-wifi-ap-utils.c | 973 ++++++++++++++++++++++++++++++ 25 files changed, 2839 insertions(+), 101 deletions(-) create mode 100644 src/nm-wifi-ap-utils.c create mode 100644 src/nm-wifi-ap-utils.h create mode 100644 src/tests/test-wifi-ap-utils.c diff --git a/.gitignore b/.gitignore index 980764198..848da36b5 100644 --- a/.gitignore +++ b/.gitignore @@ -94,6 +94,7 @@ libnm-util/tests/test-setting-8021x libnm-glib/tests/test-remote-settings-client src/tests/test-dhcp-options src/tests/test-policy-hosts +src/tests/test-wifi-ap-utils system-settings/plugins/keyfile/tests/test-keyfile system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 92a78b349..5e087a263 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -66,6 +66,55 @@ + + + + + Adds a new connection using the given details (if any) as a template + (automatically filling in missing settings with the capabilities of the + given device and specific object), then activate the new connection. + Cannot be used for VPN connections at this time. + + + + Connection settings and properties; if incomplete missing settings will + be automatically completed using the given device and specific object. + + + + + The object path of device to be activated using the given connection. + + + + + The path of a connection-type-specific object this activation should use. + This parameter is currently ignored for wired and mobile broadband connections, + and the value of "/" should be used (ie, no specific object). For WiFi + connections, pass the object path of a specific AP from the card's scan + list, which will be used to complete the details of the newly added + connection. + + + + + Object path of the new connection that was just added. + + + + + The path of the active connection object representing this active connection. + + + + + + + The connection is invalid for this device. + + + + Deactivate an active connection. diff --git a/src/Makefile.am b/src/Makefile.am index 66be644c4..5f1b63c23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -35,7 +35,10 @@ INCLUDES = -I${top_srcdir} \ # Test libraries ########################################### -noinst_LTLIBRARIES = libtest-dhcp.la libtest-policy-hosts.la +noinst_LTLIBRARIES = \ + libtest-dhcp.la \ + libtest-policy-hosts.la \ + libtest-wifi-ap-utils.la ########################################### # DHCP test library @@ -76,6 +79,22 @@ libtest_policy_hosts_la_LIBADD = \ $(GLIB_LIBS) +########################################### +# Wifi ap utils +########################################### + +libtest_wifi_ap_utils_la_SOURCES = \ + nm-wifi-ap-utils.c \ + nm-wifi-ap-utils.h + +libtest_wifi_ap_utils_la_CPPFLAGS = \ + $(GLIB_CFLAGS) + +libtest_wifi_ap_utils_la_LIBADD = \ + ${top_builddir}/libnm-util/libnm-util.la \ + $(GLIB_LIBS) + + ########################################### # NetworkManager ########################################### @@ -106,6 +125,8 @@ NetworkManager_SOURCES = \ nm-device-gsm.h \ nm-wifi-ap.c \ nm-wifi-ap.h \ + nm-wifi-ap-utils.c \ + nm-wifi-ap-utils.h \ nm-dbus-manager.h \ nm-dbus-manager.c \ nm-udev-manager.c \ diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c index c32c18222..63b2d66fd 100644 --- a/src/modem-manager/nm-modem-cdma.c +++ b/src/modem-manager/nm-modem-cdma.c @@ -15,19 +15,23 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ #include +#include #include "nm-dbus-glib-types.h" #include "nm-modem-cdma.h" #include "nm-modem-types.h" #include "nm-device.h" +#include "nm-device-private.h" #include "nm-dbus-manager.h" #include "nm-setting-connection.h" #include "nm-setting-cdma.h" +#include "nm-setting-serial.h" +#include "nm-setting-ppp.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" @@ -269,6 +273,47 @@ real_check_connection_compatible (NMModem *modem, return TRUE; } +static gboolean +real_complete_connection (NMModem *modem, + NMConnection *connection, + const GSList *existing_connections, + GError **error) +{ + NMSettingCdma *s_cdma; + NMSettingSerial *s_serial; + NMSettingPPP *s_ppp; + + s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); + s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL); + s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + + if (!s_cdma) { + s_cdma = (NMSettingCdma *) nm_setting_cdma_new (); + nm_connection_add_setting (connection, NM_SETTING (s_cdma)); + } + + if (!nm_setting_cdma_get_number (s_cdma)) + g_object_set (G_OBJECT (s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); + + /* Need serial and PPP settings at least */ + if (!s_serial) { + s_serial = (NMSettingSerial *) nm_setting_serial_new (); + nm_connection_add_setting (connection, NM_SETTING (s_serial)); + } + if (!s_ppp) { + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + } + + nm_device_complete_generic (connection, + NM_SETTING_CDMA_SETTING_NAME, + existing_connections, + _("CDMA connection %d"), + NULL); + + return TRUE; +} + static gboolean real_get_user_pass (NMModem *modem, NMConnection *connection, @@ -344,6 +389,7 @@ nm_modem_cdma_class_init (NMModemCdmaClass *klass) modem_class->get_setting_name = real_get_setting_name; modem_class->get_best_auto_connection = real_get_best_auto_connection; modem_class->check_connection_compatible = real_check_connection_compatible; + modem_class->complete_connection = real_complete_connection; modem_class->act_stage1_prepare = real_act_stage1_prepare; modem_class->deactivate_quickly = real_deactivate_quickly; diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c index 9a79535eb..4672f4cee 100644 --- a/src/modem-manager/nm-modem-gsm.c +++ b/src/modem-manager/nm-modem-gsm.c @@ -15,16 +15,21 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ #include +#include + #include "nm-dbus-glib-types.h" #include "nm-modem-gsm.h" #include "nm-device.h" +#include "nm-device-private.h" #include "nm-setting-connection.h" #include "nm-setting-gsm.h" +#include "nm-setting-serial.h" +#include "nm-setting-ppp.h" #include "nm-modem-types.h" #include "nm-logging.h" #include "NetworkManagerUtils.h" @@ -467,6 +472,51 @@ real_check_connection_compatible (NMModem *modem, return TRUE; } +static gboolean +real_complete_connection (NMModem *modem, + NMConnection *connection, + const GSList *existing_connections, + GError **error) +{ + NMSettingGsm *s_gsm; + NMSettingSerial *s_serial; + NMSettingPPP *s_ppp; + + s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); + s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL); + s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + + if (!s_gsm || !nm_setting_gsm_get_apn (s_gsm)) { + /* Need an APN at least */ + g_set_error_literal (error, + NM_SETTING_GSM_ERROR, + NM_SETTING_GSM_ERROR_MISSING_PROPERTY, + NM_SETTING_GSM_APN); + return FALSE; + } + + if (!nm_setting_gsm_get_number (s_gsm)) + g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); + + /* Need serial and PPP settings at least */ + if (!s_serial) { + s_serial = (NMSettingSerial *) nm_setting_serial_new (); + nm_connection_add_setting (connection, NM_SETTING (s_serial)); + } + if (!s_ppp) { + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + } + + nm_device_complete_generic (connection, + NM_SETTING_GSM_SETTING_NAME, + existing_connections, + _("GSM connection %d"), + NULL); + + return TRUE; +} + static gboolean real_get_user_pass (NMModem *modem, NMConnection *connection, @@ -545,6 +595,7 @@ nm_modem_gsm_class_init (NMModemGsmClass *klass) modem_class->get_setting_name = real_get_setting_name; modem_class->get_best_auto_connection = real_get_best_auto_connection; modem_class->check_connection_compatible = real_check_connection_compatible; + modem_class->complete_connection = real_complete_connection; modem_class->act_stage1_prepare = real_act_stage1_prepare; modem_class->deactivate_quickly = real_deactivate_quickly; diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 6f62eab49..5bba7030b 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -619,6 +619,17 @@ nm_modem_check_connection_compatible (NMModem *self, return FALSE; } +gboolean +nm_modem_complete_connection (NMModem *self, + NMConnection *connection, + const GSList *existing_connections, + GError **error) +{ + if (NM_MODEM_GET_CLASS (self)->complete_connection) + return NM_MODEM_GET_CLASS (self)->complete_connection (self, connection, existing_connections, error); + return FALSE; +} + static void real_deactivate_quickly (NMModem *self, NMDevice *device) { diff --git a/src/modem-manager/nm-modem.h b/src/modem-manager/nm-modem.h index 15933e49d..f4f7be798 100644 --- a/src/modem-manager/nm-modem.h +++ b/src/modem-manager/nm-modem.h @@ -67,6 +67,11 @@ typedef struct { NMConnection *connection, GError **error); + gboolean (*complete_connection) (NMModem *modem, + NMConnection *connection, + const GSList *existing_connections, + GError **error); + NMConnection * (*get_best_auto_connection) (NMModem *modem, GSList *connections, char **specific_object); @@ -107,6 +112,11 @@ gboolean nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection, GError **error); +gboolean nm_modem_complete_connection (NMModem *self, + NMConnection *connection, + const GSList *existing_connections, + GError **error); + NMActStageReturn nm_modem_act_stage1_prepare (NMModem *modem, NMActRequest *req, NMDeviceStateReason *reason); diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c index f6bd284cc..f2ce78e63 100644 --- a/src/nm-device-bt.c +++ b/src/nm-device-bt.c @@ -15,12 +15,15 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. */ #include #include #include +#include + +#include #include "nm-glib-compat.h" #include "nm-bluez-common.h" @@ -36,6 +39,8 @@ #include "nm-setting-bluetooth.h" #include "nm-setting-cdma.h" #include "nm-setting-gsm.h" +#include "nm-setting-serial.h" +#include "nm-setting-ppp.h" #include "nm-device-bt-glue.h" #include "NetworkManagerUtils.h" @@ -250,6 +255,156 @@ real_check_connection_compatible (NMDevice *device, return addr_match; } +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); + NMSettingBluetooth *s_bt; + const GByteArray *setting_bdaddr; + struct ether_addr *devaddr = ether_aton (priv->bdaddr); + const char *ctype; + gboolean is_dun = FALSE, is_pan = FALSE; + NMSettingGsm *s_gsm; + NMSettingCdma *s_cdma; + NMSettingSerial *s_serial; + NMSettingPPP *s_ppp; + const char *format = NULL, *preferred = NULL; + + s_gsm = (NMSettingGsm *) nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM); + s_cdma = (NMSettingCdma *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA); + s_serial = (NMSettingSerial *) nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL); + s_ppp = (NMSettingPPP *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPP); + + s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH); + if (!s_bt) { + s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new (); + nm_connection_add_setting (connection, NM_SETTING (s_bt)); + } + + ctype = nm_setting_bluetooth_get_connection_type (s_bt); + if (ctype) { + if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_DUN)) + is_dun = TRUE; + else if (!strcmp (ctype, NM_SETTING_BLUETOOTH_TYPE_PANU)) + is_pan = TRUE; + } else { + if (s_gsm || s_cdma) + is_dun = TRUE; + else if (priv->capabilities & NM_BT_CAPABILITY_NAP) + is_pan = TRUE; + } + + if (is_pan) { + /* Make sure the device supports PAN */ + if (!(priv->capabilities & NM_BT_CAPABILITY_NAP)) { + g_set_error_literal (error, + NM_SETTING_BLUETOOTH_ERROR, + NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, + "PAN required but Bluetooth device does not support NAP"); + return FALSE; + } + + /* PAN can't use any DUN-related settings */ + if (s_gsm || s_cdma || s_serial) { + g_set_error_literal (error, + NM_SETTING_BLUETOOTH_ERROR, + NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, + "PAN incompatible with GSM, CDMA, or serial settings"); + return FALSE; + } + + g_object_set (G_OBJECT (s_bt), + NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_PANU, + NULL); + + format = _("PAN connection %d"); + } else if (is_dun) { + /* Make sure the device supports PAN */ + if (!(priv->capabilities & NM_BT_CAPABILITY_DUN)) { + g_set_error_literal (error, + NM_SETTING_BLUETOOTH_ERROR, + NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, + "DUN required but Bluetooth device does not support DUN"); + return FALSE; + } + + /* Need at least a GSM or a CDMA setting */ + if (!s_gsm && !s_cdma) { + g_set_error_literal (error, + NM_SETTING_BLUETOOTH_ERROR, + NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, + "Setting requires DUN but no GSM or CDMA setting is present"); + return FALSE; + } + + g_object_set (G_OBJECT (s_bt), + NM_SETTING_BLUETOOTH_TYPE, NM_SETTING_BLUETOOTH_TYPE_DUN, + NULL); + + if (s_gsm) { + format = _("GSM connection %d"); + if (!nm_setting_gsm_get_number (s_gsm)) + g_object_set (G_OBJECT (s_gsm), NM_SETTING_GSM_NUMBER, "*99#", NULL); + } else if (s_cdma) { + format = _("CDMA connection %d"); + if (!nm_setting_cdma_get_number (s_cdma)) + g_object_set (G_OBJECT (s_cdma), NM_SETTING_GSM_NUMBER, "#777", NULL); + } else + format = _("DUN connection %d"); + + /* Need serial and PPP settings */ + if (!s_serial) { + s_serial = (NMSettingSerial *) nm_setting_serial_new (); + nm_connection_add_setting (connection, NM_SETTING (s_serial)); + } + if (!s_ppp) { + s_ppp = (NMSettingPPP *) nm_setting_ppp_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ppp)); + } + } else { + g_set_error_literal (error, + NM_SETTING_BLUETOOTH_ERROR, + NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, + "Unknown/unhandled Bluetooth connection type"); + return FALSE; + } + + nm_device_complete_generic (connection, + NM_SETTING_BLUETOOTH_SETTING_NAME, + existing_connections, + format, + preferred); + + setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); + if (setting_bdaddr) { + /* Make sure the setting BT Address (if any) matches the device's */ + if (memcmp (setting_bdaddr->data, devaddr->ether_addr_octet, ETH_ALEN)) { + g_set_error_literal (error, + NM_SETTING_BLUETOOTH_ERROR, + NM_SETTING_BLUETOOTH_ERROR_INVALID_PROPERTY, + NM_SETTING_BLUETOOTH_BDADDR); + return FALSE; + } + } else { + GByteArray *bdaddr; + const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + /* Lock the connection to this device by default */ + if (memcmp (devaddr->ether_addr_octet, null_mac, ETH_ALEN)) { + bdaddr = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (bdaddr, devaddr->ether_addr_octet, ETH_ALEN); + g_object_set (G_OBJECT (s_bt), NM_SETTING_BLUETOOTH_BDADDR, bdaddr, NULL); + g_byte_array_free (bdaddr, TRUE); + } + } + + return TRUE; +} + static guint32 real_get_generic_capabilities (NMDevice *dev) { @@ -1000,6 +1155,7 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) device_class->act_stage3_ip4_config_start = real_act_stage3_ip4_config_start; device_class->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; device_class->check_connection_compatible = real_check_connection_compatible; + device_class->complete_connection = real_complete_connection; /* Properties */ g_object_class_install_property diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index d759df290..e38d58576 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -1624,6 +1624,67 @@ real_check_connection_compatible (NMDevice *device, return TRUE; } +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device); + NMSettingWired *s_wired; + NMSettingPPPOE *s_pppoe; + const GByteArray *setting_mac; + + s_pppoe = (NMSettingPPPOE *) nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE); + + /* We can't telepathically figure out the service name or username, so if + * those weren't given, we can't complete the connection. + */ + if (s_pppoe && !nm_setting_verify (NM_SETTING (s_pppoe), NULL, error)) + return FALSE; + + /* Default to an ethernet-only connection, but if a PPPoE setting was given + * then PPPoE should be our connection type. + */ + nm_device_complete_generic (connection, + s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_CONNECTION_SETTING_NAME, + existing_connections, + s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"), + NULL); + + s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + if (!s_wired) { + s_wired = (NMSettingWired *) nm_setting_wired_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + } + + setting_mac = nm_setting_wired_get_mac_address (s_wired); + if (setting_mac) { + /* Make sure the setting MAC (if any) matches the device's permanent MAC */ + if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { + g_set_error_literal (error, + NM_SETTING_WIRED_ERROR, + NM_SETTING_WIRED_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRED_MAC_ADDRESS); + return FALSE; + } + } else { + GByteArray *mac; + const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + /* Lock the connection to this device by default */ + if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { + mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); + g_object_set (G_OBJECT (s_wired), NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL); + g_byte_array_free (mac, TRUE); + } + } + + return TRUE; +} + static gboolean spec_match_list (NMDevice *device, const GSList *specs) { @@ -1933,6 +1994,7 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) parent_class->get_best_auto_connection = real_get_best_auto_connection; parent_class->is_available = real_is_available; parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; parent_class->act_stage1_prepare = real_act_stage1_prepare; parent_class->act_stage2_config = real_act_stage2_config; diff --git a/src/nm-device-modem.c b/src/nm-device-modem.c index 440db82f2..362ff8575 100644 --- a/src/nm-device-modem.c +++ b/src/nm-device-modem.c @@ -220,6 +220,18 @@ real_check_connection_compatible (NMDevice *device, return nm_modem_check_connection_compatible (priv->modem, connection, error); } +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); + + return nm_modem_complete_connection (priv->modem, connection, existing_connections, error); +} + static gboolean real_hw_is_up (NMDevice *device) { @@ -401,6 +413,7 @@ nm_device_modem_class_init (NMDeviceModemClass *mclass) device_class->get_generic_capabilities = real_get_generic_capabilities; device_class->get_best_auto_connection = real_get_best_auto_connection; device_class->check_connection_compatible = real_check_connection_compatible; + device_class->complete_connection = real_complete_connection; device_class->hw_is_up = real_hw_is_up; device_class->hw_bring_up = real_hw_bring_up; device_class->deactivate_quickly = real_deactivate_quickly; diff --git a/src/nm-device-modem.h b/src/nm-device-modem.h index c6ef4d218..806676e5b 100644 --- a/src/nm-device-modem.h +++ b/src/nm-device-modem.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef NM_DEVICE_MODEM_H diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index 36b968ed8..e0a05df95 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -19,7 +19,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2010 Red Hat, Inc. + * (C) Copyright 2005 - 2011 Red Hat, Inc. * (C) Copyright 2008 Collabora Ltd. * (C) Copyright 2009 One Laptop per Child */ @@ -381,6 +381,50 @@ real_check_connection_compatible (NMDevice *device, return TRUE; } +#define DEFAULT_SSID "olpc-mesh" + +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMSettingOlpcMesh *s_mesh; + GByteArray *tmp; + + s_mesh = (NMSettingOlpcMesh *) nm_connection_get_setting (connection, NM_TYPE_SETTING_OLPC_MESH); + if (!s_mesh) { + s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new (); + nm_connection_add_setting (connection, NM_SETTING (s_mesh)); + } + + if (!nm_setting_olpc_mesh_get_ssid (s_mesh)) { + tmp = g_byte_array_sized_new (strlen (DEFAULT_SSID)); + g_byte_array_append (tmp, (const guint8 *) DEFAULT_SSID, strlen (DEFAULT_SSID)); + g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_SSID, tmp, NULL); + g_byte_array_free (tmp, TRUE); + } + + if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) { + const guint8 anycast[ETH_ALEN] = { 0xC0, 0x27, 0xC0, 0x27, 0xC0, 0x27 }; + + tmp = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (tmp, anycast, sizeof (anycast)); + g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_DHCP_ANYCAST_ADDRESS, tmp, NULL); + g_byte_array_free (tmp, TRUE); + + } + + nm_device_complete_generic (connection, + NM_SETTING_OLPC_MESH_SETTING_NAME, + existing_connections, + _("Mesh %d"), + NULL); + + return TRUE; +} + /* * nm_device_olpc_mesh_get_address * @@ -722,6 +766,7 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) parent_class->take_down = real_take_down; parent_class->update_hw_address = real_update_hw_address; parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; parent_class->act_stage1_prepare = real_act_stage1_prepare; parent_class->act_stage2_config = real_act_stage2_config; diff --git a/src/nm-device-private.h b/src/nm-device-private.h index f4f968a94..82f429fc6 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2008 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #ifndef NM_DEVICE_PRIVATE_H @@ -46,4 +46,10 @@ gboolean nm_device_get_firmware_missing (NMDevice *self); void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); +void nm_device_complete_generic (NMConnection *connection, + const char *ctype, + const GSList *existing, + const char *format, + const char *preferred); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 784a14976..a86890b91 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -104,15 +104,6 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -typedef enum { - NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0, - NM_WIFI_ERROR_CONNECTION_INVALID, - NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, -} NMWifiError; - -#define NM_WIFI_ERROR (nm_wifi_error_quark ()) -#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ()) - #define SUP_SIG_ID_LEN 5 typedef struct Supplicant { @@ -208,6 +199,18 @@ static guint32 nm_device_wifi_get_bitrate (NMDeviceWifi *self); static void cull_scan_list (NMDeviceWifi *self); +/*****************************************************************/ + +typedef enum { + NM_WIFI_ERROR_CONNECTION_NOT_WIRELESS = 0, + NM_WIFI_ERROR_CONNECTION_INVALID, + NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, + NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, +} NMWifiError; + +#define NM_WIFI_ERROR (nm_wifi_error_quark ()) +#define NM_TYPE_WIFI_ERROR (nm_wifi_error_get_type ()) + static GQuark nm_wifi_error_quark (void) { @@ -233,6 +236,8 @@ nm_wifi_error_get_type (void) ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), /* Connection does not apply to this device. */ ENUM_ENTRY (NM_WIFI_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), + /* Given access point was not in this device's scan list. */ + ENUM_ENTRY (NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, "AccessPointNotFound"), { 0, 0, 0 } }; etype = g_enum_register_static ("NMWifiError", values); @@ -240,6 +245,8 @@ nm_wifi_error_get_type (void) return etype; } +/*****************************************************************/ + /* IPW rfkill handling (until 2.6.33) */ RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self) @@ -298,6 +305,8 @@ ipw_rfkill_state_work (gpointer user_data) return TRUE; } +/*****************************************************************/ + /* * nm_device_wifi_update_signal_strength * @@ -732,6 +741,20 @@ supplicant_interface_release (NMDeviceWifi *self) } } + +static NMAccessPoint * +get_ap_by_path (NMDeviceWifi *self, const char *path) +{ + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + GSList *iter; + + for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { + if (strcmp (path, nm_ap_get_dbus_path (NM_AP (iter->data))) == 0) + return NM_AP (iter->data); + } + return NULL; +} + static NMAccessPoint * get_active_ap (NMDeviceWifi *self, NMAccessPoint *ignore_ap, @@ -1222,6 +1245,174 @@ real_check_connection_compatible (NMDevice *device, return TRUE; } +/* + * List of manufacturer default SSIDs that are often unchanged by users. + * + * NOTE: this list should *not* contain networks that you would like to + * automatically roam to like "Starbucks" or "AT&T" or "T-Mobile HotSpot". + */ +static const char * +manf_defaults[] = { + "linksys", + "linksys-a", + "linksys-g", + "default", + "belkin54g", + "NETGEAR", + "o2DSL", + "WLAN", + "ALICE-WLAN", +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0])) + +static gboolean +is_manf_default_ssid (const GByteArray *ssid) +{ + int i; + + for (i = 0; i < ARRAY_SIZE (manf_defaults); i++) { + if (ssid->len == strlen (manf_defaults[i])) { + if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0) + return TRUE; + } + } + return FALSE; +} + +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMDeviceWifi *self = NM_DEVICE_WIFI (device); + NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + const GByteArray *setting_mac; + char *format, *str_ssid = NULL; + NMAccessPoint *ap = NULL; + const GByteArray *ssid = NULL; + GSList *iter; + char buf[33]; + int buf_len; + + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + + if (!specific_object) { + /* If not given a specific object, we need at minimum an SSID */ + if (!s_wifi) { + g_set_error_literal (error, + NM_WIFI_ERROR, + NM_WIFI_ERROR_CONNECTION_INVALID, + "A 'wireless' setting is required if no AP path was given."); + return FALSE; + } + + ssid = nm_setting_wireless_get_ssid (s_wifi); + if (!ssid || !ssid->len) { + g_set_error_literal (error, + NM_WIFI_ERROR, + NM_WIFI_ERROR_CONNECTION_INVALID, + "A 'wireless' setting with a valid SSID is required if no AP path was given."); + return FALSE; + } + + /* Find a compatible AP in the scan list */ + for (iter = priv->ap_list; iter; iter = g_slist_next (iter)) { + if (nm_ap_check_compatible (NM_AP (iter->data), connection)) { + ap = NM_AP (iter->data); + break; + } + } + + /* If we still don't have an AP, then the WiFI settings needs to be + * fully specified by the client. Might not be able to find an AP + * if the network isn't broadcasting the SSID for example. + */ + if (!ap) { + GSList *settings = NULL; + gboolean valid; + + settings = g_slist_prepend (settings, s_wifi); + settings = g_slist_prepend (settings, s_wsec); + settings = g_slist_prepend (settings, s_8021x); + valid = nm_setting_verify (NM_SETTING (s_wifi), settings, error); + g_slist_free (settings); + if (!valid) + return FALSE; + } + } else { + ap = get_ap_by_path (self, specific_object); + if (!ap) { + g_set_error (error, + NM_WIFI_ERROR, + NM_WIFI_ERROR_ACCESS_POINT_NOT_FOUND, + "The access point %s was not in the scan list.", + specific_object); + return FALSE; + } + } + + if (ap) { + ssid = nm_ap_get_ssid (ap); + + /* If the SSID is a well-known SSID, lock the connection to the AP's + * specific BSSID so NM doesn't autoconnect to some random wifi net. + */ + if (!nm_ap_complete_connection (ap, + connection, + is_manf_default_ssid (ssid), + error)) + return FALSE; + } + + g_assert (ssid); + memset (buf, 0, sizeof (buf)); + buf_len = MIN (ssid->len, sizeof (buf) - 1); + memcpy (buf, ssid->data, buf_len); + str_ssid = nm_utils_ssid_to_utf8 (buf, buf_len); + format = g_strdup_printf ("%s %%d", str_ssid); + + nm_device_complete_generic (connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + format, + str_ssid); + g_free (str_ssid); + g_free (format); + + setting_mac = nm_setting_wireless_get_mac_address (s_wifi); + if (setting_mac) { + /* Make sure the setting MAC (if any) matches the device's permanent MAC */ + if (memcmp (setting_mac->data, priv->perm_hw_addr, ETH_ALEN)) { + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_MAC_ADDRESS); + return FALSE; + } + } else { + GByteArray *mac; + const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + /* Lock the connection to this device by default */ + if (memcmp (priv->perm_hw_addr, null_mac, ETH_ALEN)) { + mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac, priv->perm_hw_addr, ETH_ALEN); + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MAC_ADDRESS, mac, NULL); + g_byte_array_free (mac, TRUE); + } + } + + return TRUE; +} + static gboolean real_is_available (NMDevice *dev) { @@ -3449,10 +3640,8 @@ device_state_changed (NMDevice *device, NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv; NMActRequest *req; const char *ap_path; - GSList * elt; g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NULL); @@ -3461,18 +3650,8 @@ nm_device_wifi_get_activation_ap (NMDeviceWifi *self) return NULL; ap_path = nm_act_request_get_specific_object (req); - if (!ap_path) - return NULL; - /* Find the AP by it's object path */ - priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - for (elt = priv->ap_list; elt; elt = g_slist_next (elt)) { - NMAccessPoint *ap = NM_AP (elt->data); - - if (!strcmp (ap_path, nm_ap_get_dbus_path (ap))) - return ap; - } - return NULL; + return ap_path ? get_ap_by_path (self, ap_path) : NULL; } static void @@ -3700,6 +3879,7 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) parent_class->get_best_auto_connection = real_get_best_auto_connection; parent_class->is_available = real_is_available; parent_class->check_connection_compatible = real_check_connection_compatible; + parent_class->complete_connection = real_complete_connection; parent_class->act_stage1_prepare = real_act_stage1_prepare; parent_class->act_stage2_config = real_act_stage2_config; diff --git a/src/nm-device.c b/src/nm-device.c index 2765a5de3..7c531c7bd 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -572,6 +572,153 @@ nm_device_get_best_auto_connection (NMDevice *dev, return NM_DEVICE_GET_CLASS (dev)->get_best_auto_connection (dev, connections, specific_object); } +gboolean +nm_device_complete_connection (NMDevice *self, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + gboolean success = FALSE; + + g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (connection != NULL, FALSE); + + if (!NM_DEVICE_GET_CLASS (self)->complete_connection) { + g_set_error (error, + NM_DEVICE_INTERFACE_ERROR, + NM_DEVICE_INTERFACE_ERROR_CONNECTION_INVALID, + "Device class %s had no complete_connection method", + G_OBJECT_TYPE_NAME (self)); + return FALSE; + } + + success = NM_DEVICE_GET_CLASS (self)->complete_connection (self, + connection, + specific_object, + existing_connections, + error); + if (success) + success = nm_connection_verify (connection, error); + + return success; +} + +static char * +nm_device_new_connection_name (const GSList *existing, + const char *format, + const char *preferred) +{ + GSList *names = NULL; + const GSList *iter; + char *cname = NULL; + int i = 0; + gboolean preferred_found = FALSE; + + for (iter = existing; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + const char *id; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION)); + id = nm_setting_connection_get_id (s_con); + g_assert (id); + names = g_slist_append (names, (gpointer) id); + + if (preferred && !preferred_found && (strcmp (preferred, id) == 0)) + preferred_found = TRUE; + } + + /* Return the preferred name if it was unique */ + if (preferred && !preferred_found) { + g_slist_free (names); + return g_strdup (preferred); + } + + /* Otherwise find the next available unique connection name using the given + * connection name template. + */ + while (!cname && (i++ < 10000)) { + char *temp; + gboolean found = FALSE; + + temp = g_strdup_printf (format, i); + for (iter = names; iter; iter = g_slist_next (iter)) { + if (!strcmp (iter->data, temp)) { + found = TRUE; + break; + } + } + if (!found) + cname = temp; + else + g_free (temp); + } + + g_slist_free (names); + return cname; +} + +void +nm_device_complete_generic (NMConnection *connection, + const char *ctype, + const GSList *existing, + const char *format, + const char *preferred) +{ + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + const char *method; + char *id, *uuid; + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (!s_con) { + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + } + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL); + + if (!nm_setting_connection_get_uuid (s_con)) { + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, uuid, NULL); + g_free (uuid); + } + + /* Add a connection ID if absent */ + if (!nm_setting_connection_get_id (s_con)) { + id = nm_device_new_connection_name (existing, format, preferred); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL); + g_free (id); + } + + /* Add an 'auto' IPv4 connection if present */ + s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + if (!s_ip4) { + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + } + method = nm_setting_ip4_config_get_method (s_ip4); + if (!method) { + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + } + + s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (!s_ip6) { + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + } + method = nm_setting_ip6_config_get_method (s_ip6); + if (!method) { + g_object_set (G_OBJECT (s_ip6), + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + } +} + static void dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data) { diff --git a/src/nm-device.h b/src/nm-device.h index e7d347cbc..b96da3302 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -88,6 +88,12 @@ typedef struct { NMConnection *connection, GError **error); + gboolean (* complete_connection) (NMDevice *self, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error); + NMActStageReturn (* act_stage1_prepare) (NMDevice *self, NMDeviceStateReason *reason); NMActStageReturn (* act_stage2_config) (NMDevice *self, @@ -157,6 +163,12 @@ NMConnection * nm_device_get_best_auto_connection (NMDevice *dev, GSList *connections, char **specific_object); +gboolean nm_device_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connection, + GError **error); + void nm_device_activate_schedule_stage1_device_prepare (NMDevice *device); void nm_device_activate_schedule_stage2_device_config (NMDevice *device); void nm_device_activate_schedule_stage4_ip4_config_get (NMDevice *device); diff --git a/src/nm-manager.c b/src/nm-manager.c index 23551d381..106757553 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2009 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #include @@ -69,6 +69,12 @@ static void impl_manager_activate_connection (NMManager *manager, const char *specific_object_path, DBusGMethodInvocation *context); +static void impl_manager_add_and_activate_connection (NMManager *manager, + GHashTable *settings, + const char *device_path, + const char *specific_object_path, + DBusGMethodInvocation *context); + static void impl_manager_deactivate_connection (NMManager *manager, const char *connection_path, DBusGMethodInvocation *context); @@ -170,9 +176,8 @@ struct PendingActivation { PendingActivationFunc callback; NMAuthChain *chain; - gboolean authorized; - char *connection_path; + NMConnection *connection; char *specific_object_path; char *device_path; }; @@ -270,8 +275,10 @@ enum { LAST_PROP }; -typedef enum -{ + +/************************************************************************/ + +typedef enum { NM_MANAGER_ERROR_UNKNOWN_CONNECTION = 0, NM_MANAGER_ERROR_UNKNOWN_DEVICE, NM_MANAGER_ERROR_UNMANAGED_DEVICE, @@ -327,6 +334,32 @@ nm_manager_error_get_type (void) return etype; } +/************************************************************************/ + +static NMDevice * +nm_manager_get_device_by_udi (NMManager *manager, const char *udi) +{ + GSList *iter; + + for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { + if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi)) + return NM_DEVICE (iter->data); + } + return NULL; +} + +static NMDevice * +nm_manager_get_device_by_path (NMManager *manager, const char *path) +{ + GSList *iter; + + for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { + if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path)) + return NM_DEVICE (iter->data); + } + return NULL; +} + static gboolean manager_sleeping (NMManager *self) { @@ -618,10 +651,17 @@ pending_activation_new (NMManager *manager, DBusGMethodInvocation *context, const char *device_path, const char *connection_path, + GHashTable *settings, const char *specific_object_path, - PendingActivationFunc callback) + PendingActivationFunc callback, + GError **error) { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); PendingActivation *pending; + NMDevice *device; + NMConnection *connection = NULL; + GSList *all_connections = NULL; + gboolean success; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (authority != NULL, NULL); @@ -629,6 +669,35 @@ pending_activation_new (NMManager *manager, g_return_val_if_fail (device_path != NULL, NULL); g_return_val_if_fail (connection_path != NULL, NULL); + /* Create the partial connection from the given settings */ + if (settings) { + device = nm_manager_get_device_by_path (manager, device_path); + if (!device) { + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "Device not found"); + return NULL; + } + + connection = nm_connection_new (); + nm_connection_replace_settings (connection, settings, NULL); + + /* Let each device subclass complete the connection */ + all_connections = nm_settings_get_connections (priv->settings); + success = nm_device_complete_connection (device, + connection, + specific_object_path, + all_connections, + error); + g_slist_free (all_connections); + + if (success == FALSE) { + g_object_unref (connection); + return NULL; + } + } + pending = g_slice_new0 (PendingActivation); pending->manager = manager; pending->authority = authority; @@ -637,6 +706,7 @@ pending_activation_new (NMManager *manager, pending->device_path = g_strdup (device_path); pending->connection_path = g_strdup (connection_path); + pending->connection = connection; /* "/" is special-cased to NULL to get through D-Bus */ if (specific_object_path && strcmp (specific_object_path, "/")) @@ -731,14 +801,22 @@ pending_activation_destroy (PendingActivation *pending, { g_return_if_fail (pending != NULL); + if (error) + dbus_g_method_return_error (pending->context, error); + else if (ac_path) { + if (pending->connection) { + dbus_g_method_return (pending->context, + pending->connection_path, + ac_path); + } else + dbus_g_method_return (pending->context, ac_path); + } + g_free (pending->connection_path); g_free (pending->specific_object_path); g_free (pending->device_path); - - if (error) - dbus_g_method_return_error (pending->context, error); - else if (ac_path) - dbus_g_method_return (pending->context, ac_path); + if (pending->connection) + g_object_unref (pending->connection); if (pending->chain) nm_auth_chain_unref (pending->chain); @@ -840,30 +918,6 @@ system_hostname_changed_cb (NMSettings *settings, /* General NMManager stuff */ /*******************************************************************/ -static NMDevice * -nm_manager_get_device_by_udi (NMManager *manager, const char *udi) -{ - GSList *iter; - - for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - if (!strcmp (nm_device_get_udi (NM_DEVICE (iter->data)), udi)) - return NM_DEVICE (iter->data); - } - return NULL; -} - -static NMDevice * -nm_manager_get_device_by_path (NMManager *manager, const char *path) -{ - GSList *iter; - - for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - if (!strcmp (nm_device_get_path (NM_DEVICE (iter->data)), path)) - return NM_DEVICE (iter->data); - } - return NULL; -} - /* Store value into key-file; supported types: boolean, int, string */ static gboolean write_value_to_state_file (const char *filename, @@ -1870,7 +1924,7 @@ nm_manager_activate_connection (NMManager *manager, * it. */ static void -check_pending_ready (NMManager *self, PendingActivation *pending) +pending_activate (NMManager *self, PendingActivation *pending) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMSysconfigConnection *connection; @@ -1907,14 +1961,10 @@ out: static void activation_auth_done (PendingActivation *pending, GError *error) { - if (error) { + if (error) pending_activation_destroy (pending, error, NULL); - return; - } else { - pending->authorized = TRUE; - - check_pending_ready (pending->manager, pending); - } + else + pending_activate (pending->manager, pending); } static void @@ -1926,6 +1976,7 @@ impl_manager_activate_connection (NMManager *self, { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); PendingActivation *pending; + GError *error = NULL; /* Need to check the caller's permissions and stuff before we can * activate the connection. @@ -1935,10 +1986,86 @@ impl_manager_activate_connection (NMManager *self, context, device_path, connection_path, + NULL, specific_object_path, - activation_auth_done); + activation_auth_done, + &error); + if (pending) + pending_activation_check_authorized (pending, priv->dbus_mgr); + else { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + } +} - pending_activation_check_authorized (pending, priv->dbus_mgr); +static void +activation_add_done (NMSettings *self, + NMSysconfigConnection *connection, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + PendingActivation *pending = user_data; + + if (error) + pending_activation_destroy (pending, error, NULL); + else { + /* Save the new connection's D-Bus path */ + pending->connection_path = g_strdup (nm_connection_get_path (NM_CONNECTION (connection))); + + /* And activate it */ + pending_activate (pending->manager, pending); + } +} + +static void +add_and_activate_auth_done (PendingActivation *pending, GError *error) +{ + if (error) + pending_activation_destroy (pending, error, NULL); + else { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (pending->manager); + + /* Basic sender auth checks performed; try to add the connection */ + nm_settings_add_connection (priv->settings, + pending->connection, + pending->context, + activation_add_done, + pending); + } +} + +static void +impl_manager_add_and_activate_connection (NMManager *self, + GHashTable *settings, + const char *device_path, + const char *specific_object_path, + DBusGMethodInvocation *context) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + PendingActivation *pending; + GError *error = NULL; + + /* Need to check the caller's permissions and stuff before we can + * activate the connection. + */ + pending = pending_activation_new (self, + priv->authority, + context, + device_path, + NULL, + settings, + specific_object_path, + add_and_activate_auth_done, + &error); + if (pending) + pending_activation_check_authorized (pending, priv->dbus_mgr); + else { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + } } gboolean diff --git a/src/nm-wifi-ap-utils.c b/src/nm-wifi-ap-utils.c new file mode 100644 index 000000000..a5bf190b8 --- /dev/null +++ b/src/nm-wifi-ap-utils.c @@ -0,0 +1,699 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#include + +#include "nm-wifi-ap-utils.h" + +static gboolean +verify_no_wep (NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) +{ + if ( nm_setting_wireless_security_get_wep_key (s_wsec, 0) + || nm_setting_wireless_security_get_wep_key (s_wsec, 1) + || nm_setting_wireless_security_get_wep_key (s_wsec, 2) + || nm_setting_wireless_security_get_wep_key (s_wsec, 3) + || nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) + || nm_setting_wireless_security_get_wep_key_type (s_wsec)) { + /* Dynamic WEP cannot have any WEP keys set */ + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "%s is incompatible with static WEP keys", tag); + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_leap (NMSettingWirelessSecurity *s_wsec, + NMSetting8021x *s_8021x, + gboolean adhoc, + GError **error) +{ + const char *key_mgmt, *auth_alg, *leap_username; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); + + /* One (or both) of two things indicates we want LEAP: + * 1) auth_alg == 'leap' + * 2) valid leap_username + * + * LEAP always requires a LEAP username. + */ + + if (auth_alg) { + if (!strcmp (auth_alg, "leap")) { + /* LEAP authentication requires at least a LEAP username */ + if (!leap_username) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, + "LEAP requires a LEAP username"); + return FALSE; + } + } else if (leap_username) { + /* Leap username requires 'leap' auth */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "LEAP requires 'leap' authentication"); + return FALSE; + } + } + + if (leap_username) { + if (key_mgmt && strcmp (key_mgmt, "ieee8021x")) { + /* LEAP requires ieee8021x key management */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_802_1X, + "LEAP requires IEEE 802.1x key management"); + return FALSE; + } + } + + /* At this point if auth_alg is set it must be 'leap', and if key_mgmt + * is set it must be 'ieee8021x'. + */ + if (leap_username) { + if (auth_alg) + g_assert (strcmp (auth_alg, "leap") == 0); + if (key_mgmt) + g_assert (strcmp (key_mgmt, "ieee8021x") == 0); + + if (adhoc) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "LEAP incompatible with Ad-Hoc mode"); + return FALSE; + } + + if (!verify_no_wep (s_wsec, "LEAP", error)) + return FALSE; + + if (s_8021x) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME, + "LEAP incompatible with 802.1x setting"); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +verify_no_wpa (NMSettingWirelessSecurity *s_wsec, + const char *tag, + GError **error) +{ + const char *key_mgmt; + int n, i; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + if (key_mgmt && !strncmp (key_mgmt, "wpa", 3)) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "%s incompatible with any WPA key management", tag); + return FALSE; + } + + if (nm_setting_wireless_security_get_num_protos (s_wsec)) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "%s incompatible with any 'proto' setting", tag); + return FALSE; + } + + n = nm_setting_wireless_security_get_num_pairwise (s_wsec); + for (i = 0; i < n; i++) { + const char *pw; + + pw = nm_setting_wireless_security_get_pairwise (s_wsec, i); + if (strcmp (pw, "wep40") && strcmp (pw, "wep104")) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "%s is incompatible with WPA pairwise ciphers", tag); + return FALSE; + } + } + + n = nm_setting_wireless_security_get_num_groups (s_wsec); + for (i = 0; i < n; i++) { + const char *gr; + + gr = nm_setting_wireless_security_get_group (s_wsec, i); + if (strcmp (gr, "wep40") && strcmp (gr, "wep104")) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "%s is incompatible with WPA group ciphers", tag); + return FALSE; + } + } + + if (nm_setting_wireless_security_get_psk (s_wsec)) { + g_set_error (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "%s is incompatible with a WPA Pre-Shared Key", tag); + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_dynamic_wep (NMSettingWirelessSecurity *s_wsec, + NMSetting8021x *s_8021x, + gboolean adhoc, + GError **error) +{ + const char *key_mgmt, *auth_alg, *leap_username; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); + + g_return_val_if_fail (leap_username == NULL, TRUE); + + if (key_mgmt) { + if (!strcmp (key_mgmt, "ieee8021x")) { + if (!s_8021x) { + /* 802.1x key management requires an 802.1x setting */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Dynamic WEP requires an 802.1x setting"); + return FALSE; + } + + if (auth_alg && strcmp (auth_alg, "open")) { + /* 802.1x key management must use "open" authentication */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Dynamic WEP requires 'open' authentication"); + return FALSE; + } + + /* Dynamic WEP incompatible with anything static WEP related */ + if (!verify_no_wep (s_wsec, "Dynamic WEP", error)) + return FALSE; + } else if (!strcmp (key_mgmt, "none")) { + if (s_8021x) { + /* 802.1x setting requires 802.1x key management */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Dynamic WEP requires 'ieee8021x' key management"); + return FALSE; + } + } + } else if (s_8021x) { + /* 802.1x setting incompatible with anything but 'open' auth */ + if (auth_alg && strcmp (auth_alg, "open")) { + /* 802.1x key management must use "open" authentication */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Dynamic WEP requires 'open' authentication"); + return FALSE; + } + + /* Dynamic WEP incompatible with anything static WEP related */ + if (!verify_no_wep (s_wsec, "Dynamic WEP", error)) + return FALSE; + } + + return TRUE; +} + +static gboolean +verify_wpa_psk (NMSettingWirelessSecurity *s_wsec, + NMSetting8021x *s_8021x, + gboolean adhoc, + guint32 wpa_flags, + guint32 rsn_flags, + GError **error) +{ + const char *key_mgmt, *auth_alg, *tmp; + int n; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + + if (key_mgmt) { + if (!strcmp (key_mgmt, "wpa-psk") || !strcmp (key_mgmt, "wpa-none")) { + if (s_8021x) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA-PSK incompatible with 802.1x"); + return FALSE; + } + + if (auth_alg && strcmp (auth_alg, "open")) { + /* WPA must use "open" authentication */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA-PSK requires 'open' authentication"); + return FALSE; + } + } + + if (!strcmp (key_mgmt, "wpa-none")) { + if (!adhoc) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA Ad-Hoc requires an Ad-Hoc mode AP"); + return FALSE; + } + + /* Ad-Hoc WPA requires 'wpa' proto, 'none' pairwise, and 'tkip' group */ + n = nm_setting_wireless_security_get_num_protos (s_wsec); + tmp = (n > 0) ? nm_setting_wireless_security_get_proto (s_wsec, 0) : NULL; + if (n > 1 || strcmp (tmp, "wpa")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA Ad-Hoc requires 'wpa' proto"); + return FALSE; + } + + n = nm_setting_wireless_security_get_num_pairwise (s_wsec); + tmp = (n > 0) ? nm_setting_wireless_security_get_pairwise (s_wsec, 0) : NULL; + if (n > 1 || strcmp (tmp, "none")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA Ad-Hoc requires 'none' pairwise cipher"); + return FALSE; + } + + n = nm_setting_wireless_security_get_num_groups (s_wsec); + tmp = (n > 0) ? nm_setting_wireless_security_get_group (s_wsec, 0) : NULL; + if (n > 1 || strcmp (tmp, "tkip")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA Ad-Hoc requires 'tkip' group cipher"); + return FALSE; + } + } + + if (!strcmp (key_mgmt, "wpa-psk")) { + /* Make sure the AP's capabilities support WPA-PSK */ + if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "AP does not support PSK but setting requires it"); + return FALSE; + } + } + } + + return TRUE; +} + +static gboolean +verify_wpa_eap (NMSettingWirelessSecurity *s_wsec, + NMSetting8021x *s_8021x, + guint32 wpa_flags, + guint32 rsn_flags, + GError **error) +{ + const char *key_mgmt, *auth_alg; + gboolean is_wpa_eap = FALSE; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + + if (key_mgmt) { + if (!strcmp (key_mgmt, "wpa-eap")) { + if (!s_8021x) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA-EAP requires an 802.1x setting"); + return FALSE; + } + + if (auth_alg && strcmp (auth_alg, "open")) { + /* WPA must use "open" authentication */ + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA-EAP requires 'open' authentication"); + return FALSE; + } + + is_wpa_eap = TRUE; + } else if (s_8021x) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Setting requires 802.1x but does not use 'wpa-eap' key management"); + return FALSE; + } + } + + if (is_wpa_eap || s_8021x) { + /* Make sure the AP's capabilities support WPA-EAP */ + if ( !(wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + && !(rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "AP does not support 802.1x but setting requires it"); + return FALSE; + } + } + + return TRUE; +} + +static gboolean +verify_adhoc (NMSettingWirelessSecurity *s_wsec, + NMSetting8021x *s_8021x, + gboolean adhoc, + GError **error) +{ + const char *key_mgmt = NULL, *leap_username = NULL, *auth_alg = NULL; + + if (s_wsec) { + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); + } + + if (adhoc) { + if (key_mgmt && strcmp (key_mgmt, "wpa-none") && strcmp (key_mgmt, "none")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "AP mode is Ad-Hoc but setting requires Infrastructure security"); + return FALSE; + } + + if (s_8021x) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Ad-Hoc mode incompatible with 802.1x security"); + return FALSE; + } + + if (leap_username) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Ad-Hoc mode incompatible with LEAP security"); + return FALSE; + } + + if (auth_alg && strcmp (auth_alg, "open")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Ad-Hoc mode requires 'open' authentication"); + return FALSE; + } + } else { + if (key_mgmt && !strcmp (key_mgmt, "wpa-none")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "AP mode is Infrastructure but setting requires Ad-Hoc security"); + return FALSE; + } + } + + return TRUE; +} + +gboolean +nm_ap_utils_complete_connection (const GByteArray *ap_ssid, + const guint8 ap_bssid[ETH_ALEN], + NM80211Mode ap_mode, + guint32 ap_flags, + guint32 ap_wpa_flags, + guint32 ap_rsn_flags, + NMConnection *connection, + gboolean lock_bssid, + GError **error) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + const GByteArray *ssid; + const char *mode, *key_mgmt, *leap_username; + gboolean adhoc = FALSE; + + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + } + + /* Fill in missing SSID */ + ssid = nm_setting_wireless_get_ssid (s_wifi); + if (!ssid) + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL); + else if ( ssid->len != ap_ssid->len + || memcmp (ssid->data, ap_ssid->data, ssid->len)) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + "Setting SSID did not match AP SSID"); + return FALSE; + } + + if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) { + GByteArray *bssid; + + bssid = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (bssid, ap_bssid, ETH_ALEN); + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); + g_byte_array_free (bssid, TRUE); + } + + /* And mode */ + mode = nm_setting_wireless_get_mode (s_wifi); + if (mode) { + gboolean valid = FALSE; + + /* Make sure the supplied mode matches the AP's */ + if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_INFRA)) { + if (ap_mode == NM_802_11_MODE_INFRA) + valid = TRUE; + } else if (!strcmp (mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { + if (ap_mode == NM_802_11_MODE_ADHOC) + valid = TRUE; + adhoc = TRUE; + } + + if (valid == FALSE) { + g_set_error (error, + NM_SETTING_WIRELESS_ERROR, + NM_SETTING_WIRELESS_ERROR_INVALID_PROPERTY, + NM_SETTING_WIRELESS_MODE); + return FALSE; + } + } else { + mode = NM_SETTING_WIRELESS_MODE_INFRA; + if (ap_mode == NM_802_11_MODE_ADHOC) { + mode = NM_SETTING_WIRELESS_MODE_ADHOC; + adhoc = TRUE; + } + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, mode, NULL); + } + + /* Security */ + + /* Open */ + if ( !(ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + && (ap_wpa_flags == NM_802_11_AP_SEC_NONE) + && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) { + /* Make sure the connection doesn't specify security */ + if (nm_setting_wireless_get_security (s_wifi) || s_wsec || s_8021x) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "AP is unencrypted but setting specifies security"); + return FALSE; + } + return TRUE; + } + + /* Everything else requires security */ + g_object_set (G_OBJECT (s_wifi), + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + } + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); + + /* Ad-Hoc checks */ + if (!verify_adhoc (s_wsec, s_8021x, adhoc, error)) + return FALSE; + + /* Static WEP, Dynamic WEP, or LEAP */ + if ( (ap_flags & NM_802_11_AP_FLAGS_PRIVACY) + && (ap_wpa_flags == NM_802_11_AP_SEC_NONE) + && (ap_rsn_flags == NM_802_11_AP_SEC_NONE)) { + const char *tag = "WEP"; + gboolean is_dynamic_wep = FALSE; + + if (!verify_leap (s_wsec, s_8021x, adhoc, error)) + return FALSE; + + if (leap_username) { + tag = "LEAP"; + } else { + /* Static or Dynamic WEP */ + if (!verify_dynamic_wep (s_wsec, s_8021x, adhoc, error)) + return FALSE; + + if (s_8021x || (key_mgmt && !strcmp (key_mgmt, "ieee8021x"))) { + is_dynamic_wep = TRUE; + tag = "Dynamic WEP"; + } + } + + /* Nothing WPA-related can be set */ + if (!verify_no_wpa (s_wsec, tag, error)) + return FALSE; + + if (leap_username) { + /* LEAP */ + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", + NULL); + } else if (is_dynamic_wep) { + /* Dynamic WEP */ + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", + NULL); + nm_setting_wireless_security_add_pairwise (s_wsec, "wep40"); + nm_setting_wireless_security_add_pairwise (s_wsec, "wep104"); + nm_setting_wireless_security_add_group (s_wsec, "wep40"); + nm_setting_wireless_security_add_group (s_wsec, "wep104"); + + if (s_8021x) { + /* Dynamic WEP requires a valid 802.1x setting since we can't + * autocomplete 802.1x. + */ + if (!nm_setting_verify (NM_SETTING (s_8021x), NULL, error)) + return FALSE; + } + } else { + /* Static WEP */ + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", + NULL); + } + + return TRUE; + } + + /* WPA/RSN */ + g_assert (ap_wpa_flags != NM_802_11_AP_SEC_NONE); + g_assert (ap_rsn_flags != NM_802_11_AP_SEC_NONE); + + if (leap_username) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA incompatible with non-EAP (original) LEAP"); + return FALSE; + } + + if (!verify_no_wep (s_wsec, "WPA", error)) + return FALSE; + + if (!verify_wpa_psk (s_wsec, s_8021x, adhoc, ap_wpa_flags, ap_rsn_flags, error)) + return FALSE; + + if (!adhoc && !verify_wpa_eap (s_wsec, s_8021x, ap_wpa_flags, ap_rsn_flags, error)) + return FALSE; + + + if (adhoc) { + g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL); + /* Ad-Hoc does not support RSN/WPA2 */ + nm_setting_wireless_security_add_proto (s_wsec, "wpa"); + nm_setting_wireless_security_add_pairwise (s_wsec, "none"); + nm_setting_wireless_security_add_group (s_wsec, "tkip"); + } else if (s_8021x) { + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", + NULL); + /* Leave proto/pairwise/group as client set them; if they are unset the + * supplicant will figure out the best combination at connect time. + */ + + /* 802.1x also requires the client to completely fill in the 8021x + * setting. Since there's so much configuration required for it, there's + * no way it can be automatically completed. + */ + } else if ( (key_mgmt && !strcmp (key_mgmt, "wpa-psk")) + || (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", + NULL); + /* Leave proto/pairwise/group as client set them; if they are unset the + * supplicant will figure out the best combination at connect time. + */ + } else { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "Failed to determine AP security information"); + return FALSE; + } + + return TRUE; +} + diff --git a/src/nm-wifi-ap-utils.h b/src/nm-wifi-ap-utils.h new file mode 100644 index 000000000..a464867b9 --- /dev/null +++ b/src/nm-wifi-ap-utils.h @@ -0,0 +1,43 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_WIFI_AP_UTILS_H +#define NM_WIFI_AP_UTILS_H + +#include + +#include +#include +#include +#include +#include + +gboolean nm_ap_utils_complete_connection (const GByteArray *ssid, + const guint8 bssid[ETH_ALEN], + NM80211Mode mode, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + NMConnection *connection, + gboolean lock_bssid, + GError **error); + +#endif /* NM_WIFI_AP_UTILS_H */ + diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index 7770b8bc4..e596a08b8 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -24,6 +24,7 @@ #include #include "nm-wifi-ap.h" +#include "nm-wifi-ap-utils.h" #include "NetworkManagerUtils.h" #include "nm-utils.h" #include "nm-logging.h" @@ -1275,6 +1276,27 @@ nm_ap_check_compatible (NMAccessPoint *self, nm_ap_get_mode (self)); } +gboolean +nm_ap_complete_connection (NMAccessPoint *self, + NMConnection *connection, + gboolean lock_bssid, + GError **error) +{ + NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (self); + + g_return_val_if_fail (connection != NULL, FALSE); + + return nm_ap_utils_complete_connection (priv->ssid, + priv->address.ether_addr_octet, + priv->mode, + priv->flags, + priv->wpa_flags, + priv->rsn_flags, + connection, + lock_bssid, + error); +} + static gboolean capabilities_compatible (guint32 a_flags, guint32 b_flags) { diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h index 86b785a31..62457765f 100644 --- a/src/nm-wifi-ap.h +++ b/src/nm-wifi-ap.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2004 - 2010 Red Hat, Inc. + * Copyright (C) 2004 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -117,6 +117,11 @@ guint32 nm_ap_add_security_from_ie (guint32 flags, gboolean nm_ap_check_compatible (NMAccessPoint *self, NMConnection *connection); +gboolean nm_ap_complete_connection (NMAccessPoint *self, + NMConnection *connection, + gboolean lock_bssid, + GError **error); + NMAccessPoint * nm_ap_match_in_list (NMAccessPoint *find_ap, GSList *ap_list, gboolean strict_match); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 7c2e7c2c2..2f47b7a62 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -776,9 +776,11 @@ pk_add_cb (NMAuthChain *chain, NMAuthCallResult result; GError *error = NULL, *add_error = NULL; NMConnection *connection; - NMSysconfigConnection *added; + NMSysconfigConnection *added = NULL; gulong caller_uid = G_MAXULONG; char *error_desc = NULL; + NMSettingsAddCallback callback; + gpointer callback_data; priv->auths = g_slist_remove (priv->auths, chain); @@ -830,9 +832,7 @@ pk_add_cb (NMAuthChain *chain, } added = add_new_connection (self, connection, &add_error); - if (added) - dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (added))); - else { + if (!added) { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_ADD_FAILED, "Saving connection failed: (%d) %s", @@ -842,37 +842,45 @@ pk_add_cb (NMAuthChain *chain, } done: - if (error) - dbus_g_method_return_error (context, error); + callback = nm_auth_chain_get_data (chain, "callback"); + callback_data = nm_auth_chain_get_data (chain, "callback-data"); + + callback (self, added, error, context, callback_data); g_clear_error (&error); nm_auth_chain_unref (chain); } static void -impl_settings_add_connection (NMSettings *self, - GHashTable *settings, - DBusGMethodInvocation *context) +add_cb (NMSettings *self, + NMSysconfigConnection *connection, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection))); +} + +void +nm_settings_add_connection (NMSettings *self, + NMConnection *connection, + DBusGMethodInvocation *context, + NMSettingsAddCallback callback, + gpointer user_data) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMAuthChain *chain; - NMConnection *connection; - GError *error = NULL; - - connection = nm_connection_new_from_hash (settings, &error); - if (!connection) { - g_assert (error); - dbus_g_method_return_error (context, error); - g_error_free (error); - return; - } + GError *error; /* Do any of the plugins support adding? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "None of the registered plugins support add."); - dbus_g_method_return_error (context, error); + callback (self, NULL, error, context, user_data); g_error_free (error); return; } @@ -882,7 +890,28 @@ impl_settings_add_connection (NMSettings *self, g_assert (chain); priv->auths = g_slist_append (priv->auths, chain); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); - nm_auth_chain_set_data (chain, "connection", connection, g_object_unref); + nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", user_data, NULL); +} + +static void +impl_settings_add_connection (NMSettings *self, + GHashTable *settings, + DBusGMethodInvocation *context) +{ + NMConnection *connection; + GError *error = NULL; + + connection = nm_connection_new_from_hash (settings, &error); + if (connection) { + nm_settings_add_connection (self, connection, context, add_cb, NULL); + g_object_unref (connection); + } else { + g_assert (error); + dbus_g_method_return_error (context, error); + g_error_free (error); + } } static void diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 51c454fd9..0ba3170d1 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -84,6 +84,18 @@ void nm_settings_for_each_connection (NMSettings *settings, NMSettingsForEachFunc for_each_func, gpointer user_data); +typedef void (*NMSettingsAddCallback) (NMSettings *settings, + NMSysconfigConnection *connection, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data); + +void nm_settings_add_connection (NMSettings *self, + NMConnection *connection, + DBusGMethodInvocation *context, + NMSettingsAddCallback callback, + gpointer user_data); + /* Returns a list of NMSysconfigConnections. Caller must free the list with * g_slist_free(). */ diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 88c4c683f..2b889cc31 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -6,7 +6,10 @@ INCLUDES = \ -I$(top_srcdir)/src \ -I$(top_builddir)/src -noinst_PROGRAMS = test-dhcp-options test-policy-hosts +noinst_PROGRAMS = \ + test-dhcp-options \ + test-policy-hosts \ + test-wifi-ap-utils ####### DHCP options test ####### @@ -39,6 +42,20 @@ test_policy_hosts_LDADD = \ $(top_builddir)/src/libtest-policy-hosts.la \ $(GLIB_LIBS) +####### wifi ap utils test ####### + +test_wifi_ap_utils_SOURCES = \ + test-wifi-ap-utils.c + +test_wifi_ap_utils_CPPFLAGS = \ + $(GLIB_CFLAGS) + +test_wifi_ap_utils_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/src/libtest-wifi-ap-utils.la \ + $(GLIB_LIBS) \ + $(DBUS_LIBS) + ####### secret agent interface test ####### EXTRA_DIST = test-secret-agent.py @@ -50,6 +67,7 @@ if WITH_TESTS check-local: test-dhcp-options test-policy-hosts $(abs_builddir)/test-dhcp-options $(abs_builddir)/test-policy-hosts + $(abs_builddir)/test-wifi-ap-utils endif diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c new file mode 100644 index 000000000..b2cd234ec --- /dev/null +++ b/src/tests/test-wifi-ap-utils.c @@ -0,0 +1,973 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + * + */ + +#include +#include + +#include "nm-wifi-ap-utils.h" + +#include "nm-setting-connection.h" +#include "nm-setting-wireless.h" +#include "nm-setting-wireless-security.h" +#include "nm-setting-8021x.h" + +#define DEBUG 1 + +/*******************************************/ + +#define COMPARE(src, expected, success, error, edomain, ecode) \ +{ \ + if (expected) { \ + if (!success) { \ + g_assert (error != NULL); \ + g_warning ("Failed to complete connection: (%d) %s", error->code, error->message); \ + } \ + g_assert (success == TRUE); \ + g_assert (error == NULL); \ +\ + success = nm_connection_compare (src, expected, NM_SETTING_COMPARE_FLAG_EXACT); \ + if (success == FALSE && DEBUG) { \ + g_message ("\n- COMPLETED ---------------------------------\n"); \ + nm_connection_dump (src); \ + g_message ("+ EXPECTED ++++++++++++++++++++++++++++++++++++\n"); \ + nm_connection_dump (expected); \ + g_message ("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"); \ + } \ + g_assert (success == TRUE); \ + } else { \ + if (success) { \ + g_message ("\n- COMPLETED ---------------------------------\n"); \ + nm_connection_dump (src); \ + } \ + g_assert (success == FALSE); \ + g_assert_error (error, edomain, ecode); \ + } \ + \ + g_clear_error (&error); \ +} + +static gboolean +complete_connection (const char *ssid, + const guint8 bssid[ETH_ALEN], + NM80211Mode mode, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + gboolean lock_bssid, + NMConnection *src, + GError **error) +{ + GByteArray *tmp; + gboolean success; + + tmp = g_byte_array_sized_new (strlen (ssid)); + g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid)); + + success = nm_ap_utils_complete_connection (tmp, + bssid, + mode, + flags, + wpa_flags, + rsn_flags, + src, + lock_bssid, + error); + g_byte_array_free (tmp, TRUE); + return success; +} + +static NMConnection * +create_expected (const char *ssid, + const guint8 *bssid, + NM80211Mode mode, + gboolean add_security, + gboolean add_8021x, + const char *key_mgmt, + const char *auth_alg, + NMSettingWireless **out_s_wifi, + NMSettingWirelessSecurity **out_s_wsec, + NMSetting8021x **out_s_8021x) +{ + NMConnection *connection; + NMSettingWireless *s_wifi = NULL; + NMSettingWirelessSecurity *s_wsec = NULL; + NMSetting8021x *s_8021x = NULL; + GByteArray *tmp; + + connection = nm_connection_new (); + + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + /* SSID */ + tmp = g_byte_array_sized_new (strlen (ssid)); + g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid)); + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, tmp, NULL); + g_byte_array_free (tmp, TRUE); + + /* BSSID */ + if (bssid) { + tmp = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (tmp, bssid, ETH_ALEN); + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, tmp, NULL); + g_byte_array_free (tmp, TRUE); + } + + if (mode == NM_802_11_MODE_INFRA) + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); + else if (mode == NM_802_11_MODE_ADHOC) + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL); + else + g_assert_not_reached (); + + if (add_security) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + g_object_set (G_OBJECT (s_wifi), + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + if (key_mgmt) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL); + if (auth_alg) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); + + if (add_8021x) { + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + } + } + + if (out_s_wifi) + *out_s_wifi = s_wifi; + if (out_s_wsec) + *out_s_wsec = s_wsec; + if (out_s_8021x) + *out_s_8021x = s_8021x; + return connection; +} + +static NMSettingWireless * +get_wifi_setting (NMConnection *connection, gboolean add_if_absent) +{ + NMSettingWireless *s_wifi; + + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + if (add_if_absent) { + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + } + g_object_set (G_OBJECT (s_wifi), + NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NULL); + } + return s_wifi; +} + +static void +fill_wep (NMConnection *connection, + const char *key0, + guint32 tx_keyidx, + const char *auth_alg, + gboolean set_s_wifi) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + + s_wifi = get_wifi_setting (connection, set_s_wifi); + + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + } + + if (key0) { + g_object_set (G_OBJECT (s_wsec), + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, key0, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, tx_keyidx, + NULL); + } + + if (auth_alg) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); +} + +static void +fill_leap (NMConnection *connection, + const char *leap_username, + gboolean set_auth_alg, + gboolean set_key_mgmt, + gboolean set_s_wifi) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + + s_wifi = get_wifi_setting (connection, set_s_wifi); + + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + } + + if (leap_username) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NULL); + + if (set_auth_alg) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL); + + if (set_key_mgmt) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); +} + +static void +fill_wpa_psk (NMConnection *connection, + const char *key_mgmt, + const char *psk, + const char *auth_alg, + gboolean set_s_wifi) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + + s_wifi = get_wifi_setting (connection, set_s_wifi); + + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + } + + if (key_mgmt) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL); + if (psk) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); + if (auth_alg) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); +} + +static void +fill_8021x (NMConnection *connection, + NMSetting8021x *s_8021x, + const char *key_mgmt, + const char *auth_alg, + gboolean set_s_wifi) +{ + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + + s_wifi = get_wifi_setting (connection, set_s_wifi); + + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + } + + if (key_mgmt) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL); + if (auth_alg) + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); + + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); +} + +/*******************************************/ + +static void +test_lock_bssid (void) +{ + NMConnection *src, *expected; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *ssid = "blahblah"; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + TRUE, + src, &error); + + expected = create_expected (ssid, bssid, NM_802_11_MODE_INFRA, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL); + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); + g_object_unref (expected); +} + +/*******************************************/ + +static void +test_open_ap_empty_connection (void) +{ + NMConnection *src, *expected; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *ssid = "blahblah"; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + + expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL); + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); + g_object_unref (expected); +} + +/*******************************************/ + +static void +test_open_ap_leap_connection_1 (gboolean fill_wifi) +{ + NMConnection *src; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + s_wifi = get_wifi_setting (src, fill_wifi); + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", NULL); + nm_connection_add_setting (src, NM_SETTING (s_wsec)); + + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + /* We expect failure */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_open_ap_leap_connection_2 (void) +{ + NMConnection *src; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + s_wifi = get_wifi_setting (src, TRUE); + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); + nm_connection_add_setting (src, NM_SETTING (s_wsec)); + + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + /* We expect failure */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_open_ap_wep_connection (gboolean fill_wifi) +{ + NMConnection *src; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_wep (src, "11111111111111111111111111", 0, "open", fill_wifi); + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + /* We expect failure */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_ap_wpa_psk_connection_base (const char *key_mgmt, + const char *auth_alg, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + gboolean fill_wifi) +{ + NMConnection *src; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_wpa_psk (src, key_mgmt, "asdfasdfasdfasdfasdfafs", auth_alg, fill_wifi); + success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, + flags, wpa_flags, rsn_flags, + FALSE, src, &error); + /* We expect failure */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +static void +test_open_ap_wpa_psk_connection_1 (void) +{ + test_ap_wpa_psk_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_open_ap_wpa_psk_connection_2 (void) +{ + test_ap_wpa_psk_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_open_ap_wpa_psk_connection_3 (void) +{ + test_ap_wpa_psk_connection_base (NULL, "open", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_open_ap_wpa_psk_connection_4 (void) +{ + test_ap_wpa_psk_connection_base (NULL, "shared", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_open_ap_wpa_psk_connection_5 (void) +{ + test_ap_wpa_psk_connection_base ("wpa-psk", "open", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +/*******************************************/ + +static void +test_ap_wpa_eap_connection_base (const char *key_mgmt, + const char *auth_alg, + guint32 flags, + guint32 wpa_flags, + guint32 rsn_flags, + gboolean fill_wifi, + guint error_domain, + guint error_code) +{ + NMConnection *src; + NMSetting8021x *s_8021x; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + gboolean success; + GError *error = NULL; + const char *ssid = "blahblah"; + + src = nm_connection_new (); + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + fill_8021x (src, s_8021x, key_mgmt, auth_alg, fill_wifi); + success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, + flags, wpa_flags, rsn_flags, + FALSE, src, &error); + if (!wpa_flags && !rsn_flags) { + if (!flags) { + /* Failure expected */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + } else if (flags & NM_802_11_AP_FLAGS_PRIVACY) { + COMPARE (src, NULL, success, error, error_domain, error_code); + } + } else + g_assert_not_reached (); + + g_object_unref (src); +} + +static void +test_open_ap_wpa_eap_connection_1 (void) +{ + test_ap_wpa_eap_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, 0, 0); +} + +static void +test_open_ap_wpa_eap_connection_2 (void) +{ + test_ap_wpa_eap_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE, 0, 0); +} + +static void +test_open_ap_wpa_eap_connection_3 (void) +{ + test_ap_wpa_eap_connection_base (NULL, "open", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, 0, 0); +} + +static void +test_open_ap_wpa_eap_connection_4 (void) +{ + test_ap_wpa_eap_connection_base (NULL, "shared", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, 0, 0); +} + +static void +test_open_ap_wpa_eap_connection_5 (void) +{ + test_ap_wpa_eap_connection_base ("wpa-eap", "open", + NM_802_11_AP_FLAGS_NONE, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, 0, 0); +} + +/*******************************************/ + +static void +test_priv_ap_empty_connection (void) +{ + NMConnection *src, *expected; + NMSettingWirelessSecurity *s_wsec; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *ssid = "blahblah"; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + + /* Static WEP connection expected */ + expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, FALSE, "none", NULL, NULL, &s_wsec, NULL); + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); + g_object_unref (expected); +} + +/*******************************************/ + +static void +test_priv_ap_leap_connection_1 (gboolean fill_wifi) +{ + NMConnection *src, *expected; + NMSettingWirelessSecurity *s_wsec; + const char *ssid = "blahblah"; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *leap_username = "Bill Smith"; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_leap (src, leap_username, TRUE, FALSE, TRUE); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + /* We expect success here; since LEAP APs just set the 'privacy' flag + * there's no way to determine from the AP's beacon whether it's static WEP, + * dynamic WEP, or LEAP. + */ + s_wsec = NULL; + expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, FALSE, "ieee8021x", "leap", NULL, &s_wsec, NULL); + g_assert (s_wsec); + g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NULL); + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_priv_ap_leap_connection_2 (void) +{ + NMConnection *src; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_leap (src, NULL, TRUE, TRUE, TRUE); + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + /* We expect failure here, we need a LEAP username */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_LEAP_REQUIRES_USERNAME); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_priv_ap_dynamic_wep_1 (void) +{ + NMConnection *src, *expected; + const char *ssid = "blahblah"; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + g_object_set (G_OBJECT (s_8021x), + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", + NULL); + fill_8021x (src, s_8021x, "ieee8021x", "open", TRUE); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + + /* We expect a completed Dynamic WEP connection */ + s_8021x = NULL; + expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, TRUE, "ieee8021x", "open", NULL, &s_wsec, &s_8021x); + nm_setting_wireless_security_add_pairwise (s_wsec, "wep40"); + nm_setting_wireless_security_add_pairwise (s_wsec, "wep104"); + nm_setting_wireless_security_add_group (s_wsec, "wep40"); + nm_setting_wireless_security_add_group (s_wsec, "wep104"); + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + g_object_set (G_OBJECT (s_8021x), + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", + NULL); + + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_priv_ap_dynamic_wep_2 (void) +{ + NMConnection *src, *expected; + const char *ssid = "blahblah"; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + NMSettingWirelessSecurity *s_wsec; + NMSetting8021x *s_8021x; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + g_object_set (G_OBJECT (s_8021x), + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", + NULL); + fill_8021x (src, s_8021x, NULL, "open", TRUE); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + + /* We expect a completed Dynamic WEP connection */ + s_8021x = NULL; + expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, TRUE, "ieee8021x", "open", NULL, &s_wsec, &s_8021x); + nm_setting_wireless_security_add_pairwise (s_wsec, "wep40"); + nm_setting_wireless_security_add_pairwise (s_wsec, "wep104"); + nm_setting_wireless_security_add_group (s_wsec, "wep40"); + nm_setting_wireless_security_add_group (s_wsec, "wep104"); + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + g_object_set (G_OBJECT (s_8021x), + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", + NULL); + + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_priv_ap_dynamic_wep_3 (void) +{ + NMConnection *src; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + NMSetting8021x *s_8021x; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_setting_802_1x_add_eap_method (s_8021x, "peap"); + g_object_set (G_OBJECT (s_8021x), + NM_SETTING_802_1X_IDENTITY, "Bill Smith", + NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", + NULL); + fill_8021x (src, s_8021x, "ieee8021x", "shared", TRUE); + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + FALSE, + src, &error); + /* Expect failure; shared is not compatible with dynamic WEP */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_priv_ap_wpa_psk_connection_1 (void) +{ + test_ap_wpa_psk_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_priv_ap_wpa_psk_connection_2 (void) +{ + test_ap_wpa_psk_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE); +} + +static void +test_priv_ap_wpa_psk_connection_3 (void) +{ + test_ap_wpa_psk_connection_base (NULL, "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_priv_ap_wpa_psk_connection_4 (void) +{ + test_ap_wpa_psk_connection_base (NULL, "shared", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +static void +test_priv_ap_wpa_psk_connection_5 (void) +{ + test_ap_wpa_psk_connection_base ("wpa-psk", "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE); +} + +/*******************************************/ + +static void +test_priv_ap_wpa_eap_connection_1 (void) +{ + test_ap_wpa_eap_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY); +} + +static void +test_priv_ap_wpa_eap_connection_2 (void) +{ + test_ap_wpa_eap_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY); +} + +static void +test_priv_ap_wpa_eap_connection_3 (void) +{ + test_ap_wpa_eap_connection_base (NULL, "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY); +} + +static void +test_priv_ap_wpa_eap_connection_4 (void) +{ + test_ap_wpa_eap_connection_base (NULL, "shared", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); +} + +static void +test_priv_ap_wpa_eap_connection_5 (void) +{ + test_ap_wpa_eap_connection_base ("wpa-eap", "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); +} + +/*******************************************/ + +#if GLIB_CHECK_VERSION(2,25,12) +typedef GTestFixtureFunc TCFunc; +#else +typedef void (*TCFunc)(void); +#endif + +#define TESTCASE(t, d) g_test_create_case (#t, 0, (gconstpointer) d, NULL, (TCFunc) t, NULL) + +int main (int argc, char **argv) +{ + GTestSuite *suite; + + g_type_init (); + g_test_init (&argc, &argv, NULL); + + suite = g_test_get_root (); + + g_test_suite_add (suite, TESTCASE (test_lock_bssid, NULL)); + + /* Open AP tests; make sure that connections to be completed that have + * various security-related settings already set cause the completion + * to fail. + */ + g_test_suite_add (suite, TESTCASE (test_open_ap_empty_connection, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_1, TRUE)); + g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_1, FALSE)); + g_test_suite_add (suite, TESTCASE (test_open_ap_leap_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wep_connection, TRUE)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wep_connection, FALSE)); + + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_3, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_4, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_5, NULL)); + + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_3, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_4, NULL)); + g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_5, NULL)); + + /* WEP AP tests */ + g_test_suite_add (suite, TESTCASE (test_priv_ap_empty_connection, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_leap_connection_1, FALSE)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_leap_connection_2, FALSE)); + + g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_dynamic_wep_3, NULL)); + + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_3, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_4, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_5, NULL)); + + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_3, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_4, NULL)); + g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_5, NULL)); + + return g_test_run (); +} + From aa88058a5eb3fc43843d46ea4513f57a1e002d5e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 11 Jan 2011 21:52:12 -0600 Subject: [PATCH 133/264] wifi: simplify AP connection completion testcase Make it clearer exactly what settings are added to the source connection, and what to the expected one. --- src/tests/test-wifi-ap-utils.c | 484 ++++++++++++++++----------------- 1 file changed, 235 insertions(+), 249 deletions(-) diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c index b2cd234ec..fd12ef5d5 100644 --- a/src/tests/test-wifi-ap-utils.c +++ b/src/tests/test-wifi-ap-utils.c @@ -93,22 +93,122 @@ complete_connection (const char *ssid, return success; } +typedef struct { + const char *key; + const char *str; + guint32 uint; +} KeyData; + +static void +set_items (NMSetting *setting, const KeyData *items) +{ + const KeyData *item; + GParamSpec *pspec; + + for (item = items; item && item->key; item++) { + g_assert (item->key); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), item->key); + g_assert (pspec); + + if (pspec->value_type == G_TYPE_STRING) { + g_assert (item->uint == 0); + if (item->str) + g_object_set (G_OBJECT (setting), item->key, item->str, NULL); + } else if (pspec->value_type == G_TYPE_UINT) { + g_assert (item->str == NULL); + g_object_set (G_OBJECT (setting), item->key, item->uint, NULL); + } else if (pspec->value_type == G_TYPE_INT) { + gint foo = (gint) item->uint; + + g_assert (item->str == NULL); + g_object_set (G_OBJECT (setting), item->key, foo, NULL); + } else if (pspec->value_type == G_TYPE_BOOLEAN) { + gboolean foo = !! (item->uint); + + g_assert (item->str == NULL); + g_object_set (G_OBJECT (setting), item->key, foo, NULL); + } else { + /* Special types, check based on property name */ + if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PROTO)) + nm_setting_wireless_security_add_proto (NM_SETTING_WIRELESS_SECURITY (setting), item->str); + else if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PAIRWISE)) + nm_setting_wireless_security_add_pairwise (NM_SETTING_WIRELESS_SECURITY (setting), item->str); + else if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_GROUP)) + nm_setting_wireless_security_add_group (NM_SETTING_WIRELESS_SECURITY (setting), item->str); + else if (!strcmp (item->key, NM_SETTING_802_1X_EAP)) + nm_setting_802_1x_add_eap_method (NM_SETTING_802_1X (setting), item->str); + } + } +} + +static NMSettingWireless * +fill_wifi_empty (NMConnection *connection) +{ + NMSettingWireless *s_wifi; + + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + } + return s_wifi; +} + +#if 0 +static NMSettingWireless * +fill_wifi (NMConnection *connection, const KeyData items[]) +{ + NMSettingWireless *s_wifi; + + s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); + if (!s_wifi) { + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + } + + set_items (NM_SETTING (s_wifi), items); + return s_wifi; +} +#endif + +static NMSettingWirelessSecurity * +fill_wsec (NMConnection *connection, const KeyData items[]) +{ + NMSettingWirelessSecurity *s_wsec; + + s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); + if (!s_wsec) { + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + } + + set_items (NM_SETTING (s_wsec), items); + return s_wsec; +} + +static NMSetting8021x * +fill_8021x (NMConnection *connection, const KeyData items[]) +{ + NMSetting8021x *s_8021x; + + s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); + if (!s_8021x) { + s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); + nm_connection_add_setting (connection, NM_SETTING (s_8021x)); + } + + set_items (NM_SETTING (s_8021x), items); + return s_8021x; +} + static NMConnection * -create_expected (const char *ssid, - const guint8 *bssid, - NM80211Mode mode, - gboolean add_security, - gboolean add_8021x, - const char *key_mgmt, - const char *auth_alg, - NMSettingWireless **out_s_wifi, - NMSettingWirelessSecurity **out_s_wsec, - NMSetting8021x **out_s_8021x) +create_basic (const char *ssid, + const guint8 *bssid, + NM80211Mode mode, + gboolean set_security) { NMConnection *connection; NMSettingWireless *s_wifi = NULL; - NMSettingWirelessSecurity *s_wsec = NULL; - NMSetting8021x *s_8021x = NULL; GByteArray *tmp; connection = nm_connection_new (); @@ -137,160 +237,12 @@ create_expected (const char *ssid, else g_assert_not_reached (); - if (add_security) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + if (set_security) + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL); - g_object_set (G_OBJECT (s_wifi), - NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NULL); - if (key_mgmt) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL); - if (auth_alg) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); - - if (add_8021x) { - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); - } - } - - if (out_s_wifi) - *out_s_wifi = s_wifi; - if (out_s_wsec) - *out_s_wsec = s_wsec; - if (out_s_8021x) - *out_s_8021x = s_8021x; return connection; } -static NMSettingWireless * -get_wifi_setting (NMConnection *connection, gboolean add_if_absent) -{ - NMSettingWireless *s_wifi; - - s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); - if (add_if_absent) { - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wifi)); - } - g_object_set (G_OBJECT (s_wifi), - NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, - NULL); - } - return s_wifi; -} - -static void -fill_wep (NMConnection *connection, - const char *key0, - guint32 tx_keyidx, - const char *auth_alg, - gboolean set_s_wifi) -{ - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - - s_wifi = get_wifi_setting (connection, set_s_wifi); - - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - } - - if (key0) { - g_object_set (G_OBJECT (s_wsec), - NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, key0, - NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, tx_keyidx, - NULL); - } - - if (auth_alg) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); -} - -static void -fill_leap (NMConnection *connection, - const char *leap_username, - gboolean set_auth_alg, - gboolean set_key_mgmt, - gboolean set_s_wifi) -{ - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - - s_wifi = get_wifi_setting (connection, set_s_wifi); - - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - } - - if (leap_username) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NULL); - - if (set_auth_alg) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", NULL); - - if (set_key_mgmt) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); -} - -static void -fill_wpa_psk (NMConnection *connection, - const char *key_mgmt, - const char *psk, - const char *auth_alg, - gboolean set_s_wifi) -{ - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - - s_wifi = get_wifi_setting (connection, set_s_wifi); - - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - } - - if (key_mgmt) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL); - if (psk) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_PSK, psk, NULL); - if (auth_alg) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); -} - -static void -fill_8021x (NMConnection *connection, - NMSetting8021x *s_8021x, - const char *key_mgmt, - const char *auth_alg, - gboolean set_s_wifi) -{ - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; - - s_wifi = get_wifi_setting (connection, set_s_wifi); - - s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wsec)); - } - - if (key_mgmt) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, NULL); - if (auth_alg) - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, NULL); - - nm_connection_add_setting (connection, NM_SETTING (s_8021x)); -} - /*******************************************/ static void @@ -308,8 +260,7 @@ test_lock_bssid (void) NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, TRUE, src, &error); - - expected = create_expected (ssid, bssid, NM_802_11_MODE_INFRA, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL); + expected = create_basic (ssid, bssid, NM_802_11_MODE_INFRA, FALSE); COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); @@ -333,8 +284,7 @@ test_open_ap_empty_connection (void) NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, FALSE, src, &error); - - expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, FALSE, FALSE, NULL, NULL, NULL, NULL, NULL); + expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, FALSE); COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); @@ -344,20 +294,18 @@ test_open_ap_empty_connection (void) /*******************************************/ static void -test_open_ap_leap_connection_1 (gboolean fill_wifi) +test_open_ap_leap_connection_1 (gboolean add_wifi) { NMConnection *src; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", 0 }, { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - s_wifi = get_wifi_setting (src, fill_wifi); - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "Bill Smith", NULL); - nm_connection_add_setting (src, NM_SETTING (s_wsec)); + if (add_wifi) + fill_wifi_empty (src); + fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, @@ -376,17 +324,14 @@ static void test_open_ap_leap_connection_2 (void) { NMConnection *src; - NMSettingWireless *s_wifi; - NMSettingWirelessSecurity *s_wsec; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - s_wifi = get_wifi_setting (src, TRUE); - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", NULL); - nm_connection_add_setting (src, NM_SETTING (s_wsec)); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, @@ -402,15 +347,22 @@ test_open_ap_leap_connection_2 (void) /*******************************************/ static void -test_open_ap_wep_connection (gboolean fill_wifi) +test_open_ap_wep_connection (gboolean add_wifi) { NMConnection *src; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "11111111111111111111111111", 0 }, + { NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, NULL, 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - fill_wep (src, "11111111111111111111111111", 0, "open", fill_wifi); + if (add_wifi) + fill_wifi_empty (src); + fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, @@ -430,15 +382,22 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, - gboolean fill_wifi) + gboolean add_wifi) { NMConnection *src; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 }, + { NM_SETTING_WIRELESS_SECURITY_PSK, "asdfasdfasdfasdfasdfafs", 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - fill_wpa_psk (src, key_mgmt, "asdfasdfasdfasdfasdfafs", auth_alg, fill_wifi); + if (add_wifi) + fill_wifi_empty (src); + fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, FALSE, src, &error); @@ -506,21 +465,26 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, - gboolean fill_wifi, + gboolean add_wifi, guint error_domain, guint error_code) { NMConnection *src; - NMSetting8021x *s_8021x; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_empty[] = { { NULL } }; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 }, + { NULL } }; gboolean success; GError *error = NULL; - const char *ssid = "blahblah"; src = nm_connection_new (); - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - fill_8021x (src, s_8021x, key_mgmt, auth_alg, fill_wifi); - success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, + if (add_wifi) + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + fill_8021x (src, src_empty); + success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, FALSE, src, &error); if (!wpa_flags && !rsn_flags) { @@ -592,9 +556,11 @@ static void test_priv_ap_empty_connection (void) { NMConnection *src, *expected; - NMSettingWirelessSecurity *s_wsec; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; const char *ssid = "blahblah"; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", 0 }, + { NULL } }; gboolean success; GError *error = NULL; @@ -606,7 +572,8 @@ test_priv_ap_empty_connection (void) src, &error); /* Static WEP connection expected */ - expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, FALSE, "none", NULL, NULL, &s_wsec, NULL); + expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); + fill_wsec (expected, exp_wsec); COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); @@ -616,18 +583,28 @@ test_priv_ap_empty_connection (void) /*******************************************/ static void -test_priv_ap_leap_connection_1 (gboolean fill_wifi) +test_priv_ap_leap_connection_1 (gboolean add_wifi) { NMConnection *src, *expected; - NMSettingWirelessSecurity *s_wsec; const char *ssid = "blahblah"; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; const char *leap_username = "Bill Smith"; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 }, + { NULL } }; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, + { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - fill_leap (src, leap_username, TRUE, FALSE, TRUE); + if (add_wifi) + fill_wifi_empty (src); + fill_wsec (src, src_wsec); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, @@ -637,10 +614,8 @@ test_priv_ap_leap_connection_1 (gboolean fill_wifi) * there's no way to determine from the AP's beacon whether it's static WEP, * dynamic WEP, or LEAP. */ - s_wsec = NULL; - expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, FALSE, "ieee8021x", "leap", NULL, &s_wsec, NULL); - g_assert (s_wsec); - g_object_set (G_OBJECT (s_wsec), NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, NULL); + expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); + fill_wsec (expected, exp_wsec); COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); @@ -653,11 +628,16 @@ test_priv_ap_leap_connection_2 (void) { NMConnection *src; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - fill_leap (src, NULL, TRUE, TRUE, TRUE); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, @@ -677,19 +657,30 @@ test_priv_ap_dynamic_wep_1 (void) NMConnection *src, *expected; const char *ssid = "blahblah"; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + const KeyData both_8021x[] = { + { NM_SETTING_802_1X_EAP, "peap", 0 }, + { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 }, + { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 }, + { NULL } }; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep40", 0 }, + { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep104", 0 }, + { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep40", 0 }, + { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep104", 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_setting_802_1x_add_eap_method (s_8021x, "peap"); - g_object_set (G_OBJECT (s_8021x), - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", - NULL); - fill_8021x (src, s_8021x, "ieee8021x", "open", TRUE); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + fill_8021x (src, both_8021x); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, @@ -697,18 +688,9 @@ test_priv_ap_dynamic_wep_1 (void) src, &error); /* We expect a completed Dynamic WEP connection */ - s_8021x = NULL; - expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, TRUE, "ieee8021x", "open", NULL, &s_wsec, &s_8021x); - nm_setting_wireless_security_add_pairwise (s_wsec, "wep40"); - nm_setting_wireless_security_add_pairwise (s_wsec, "wep104"); - nm_setting_wireless_security_add_group (s_wsec, "wep40"); - nm_setting_wireless_security_add_group (s_wsec, "wep104"); - nm_setting_802_1x_add_eap_method (s_8021x, "peap"); - g_object_set (G_OBJECT (s_8021x), - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", - NULL); - + expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); + fill_wsec (expected, exp_wsec); + fill_8021x (expected, both_8021x); COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); @@ -722,19 +704,29 @@ test_priv_ap_dynamic_wep_2 (void) NMConnection *src, *expected; const char *ssid = "blahblah"; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; - NMSettingWirelessSecurity *s_wsec; - NMSetting8021x *s_8021x; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + const KeyData both_8021x[] = { + { NM_SETTING_802_1X_EAP, "peap", 0 }, + { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 }, + { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 }, + { NULL } }; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep40", 0 }, + { NM_SETTING_WIRELESS_SECURITY_PAIRWISE, "wep104", 0 }, + { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep40", 0 }, + { NM_SETTING_WIRELESS_SECURITY_GROUP, "wep104", 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_setting_802_1x_add_eap_method (s_8021x, "peap"); - g_object_set (G_OBJECT (s_8021x), - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", - NULL); - fill_8021x (src, s_8021x, NULL, "open", TRUE); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + fill_8021x (src, both_8021x); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, @@ -742,18 +734,9 @@ test_priv_ap_dynamic_wep_2 (void) src, &error); /* We expect a completed Dynamic WEP connection */ - s_8021x = NULL; - expected = create_expected (ssid, NULL, NM_802_11_MODE_INFRA, TRUE, TRUE, "ieee8021x", "open", NULL, &s_wsec, &s_8021x); - nm_setting_wireless_security_add_pairwise (s_wsec, "wep40"); - nm_setting_wireless_security_add_pairwise (s_wsec, "wep104"); - nm_setting_wireless_security_add_group (s_wsec, "wep40"); - nm_setting_wireless_security_add_group (s_wsec, "wep104"); - nm_setting_802_1x_add_eap_method (s_8021x, "peap"); - g_object_set (G_OBJECT (s_8021x), - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", - NULL); - + expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); + fill_wsec (expected, exp_wsec); + fill_8021x (expected, both_8021x); COMPARE (src, expected, success, error, 0, 0); g_object_unref (src); @@ -766,18 +749,21 @@ test_priv_ap_dynamic_wep_3 (void) { NMConnection *src; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; - NMSetting8021x *s_8021x; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "shared", 0 }, + { NULL } }; + const KeyData src_8021x[] = { + { NM_SETTING_802_1X_EAP, "peap", 0 }, + { NM_SETTING_802_1X_IDENTITY, "Bill Smith", 0 }, + { NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", 0 }, + { NULL } }; gboolean success; GError *error = NULL; src = nm_connection_new (); - s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - nm_setting_802_1x_add_eap_method (s_8021x, "peap"); - g_object_set (G_OBJECT (s_8021x), - NM_SETTING_802_1X_IDENTITY, "Bill Smith", - NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", - NULL); - fill_8021x (src, s_8021x, "ieee8021x", "shared", TRUE); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + fill_8021x (src, src_8021x); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, From c4c02758e16229e4154f5f3e19a3a59966fe4565 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 11 Jan 2011 22:40:18 -0600 Subject: [PATCH 134/264] wifi: add more AP connection completion tests --- src/nm-wifi-ap-utils.c | 7 +- src/tests/Makefile.am | 3 +- src/tests/test-wifi-ap-utils.c | 293 +++++++++++++++++++++++++++++---- 3 files changed, 269 insertions(+), 34 deletions(-) diff --git a/src/nm-wifi-ap-utils.c b/src/nm-wifi-ap-utils.c index a5bf190b8..b862dd18a 100644 --- a/src/nm-wifi-ap-utils.c +++ b/src/nm-wifi-ap-utils.c @@ -636,14 +636,13 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, } /* WPA/RSN */ - g_assert (ap_wpa_flags != NM_802_11_AP_SEC_NONE); - g_assert (ap_rsn_flags != NM_802_11_AP_SEC_NONE); + g_assert (ap_wpa_flags || ap_rsn_flags); - if (leap_username) { + if ((key_mgmt && !strcmp (key_mgmt, "ieee8021x")) || leap_username) { g_set_error_literal (error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, - "WPA incompatible with non-EAP (original) LEAP"); + "WPA incompatible with non-EAP (original) LEAP or Dynamic WEP"); return FALSE; } diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 2b889cc31..33a7bb15a 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -48,7 +48,8 @@ test_wifi_ap_utils_SOURCES = \ test-wifi-ap-utils.c test_wifi_ap_utils_CPPFLAGS = \ - $(GLIB_CFLAGS) + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) test_wifi_ap_utils_LDADD = \ $(top_builddir)/libnm-util/libnm-util.la \ diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c index fd12ef5d5..a1467d814 100644 --- a/src/tests/test-wifi-ap-utils.c +++ b/src/tests/test-wifi-ap-utils.c @@ -22,6 +22,7 @@ #include #include "nm-wifi-ap-utils.h" +#include "nm-dbus-glib-types.h" #include "nm-setting-connection.h" #include "nm-setting-wireless.h" @@ -104,6 +105,7 @@ set_items (NMSetting *setting, const KeyData *items) { const KeyData *item; GParamSpec *pspec; + GByteArray *tmp; for (item = items; item && item->key; item++) { g_assert (item->key); @@ -127,6 +129,12 @@ set_items (NMSetting *setting, const KeyData *items) g_assert (item->str == NULL); g_object_set (G_OBJECT (setting), item->key, foo, NULL); + } else if (pspec->value_type == DBUS_TYPE_G_UCHAR_ARRAY) { + g_assert (item->str); + tmp = g_byte_array_sized_new (strlen (item->str)); + g_byte_array_append (tmp, (const guint8 *) item->str, strlen (item->str)); + g_object_set (G_OBJECT (setting), item->key, tmp, NULL); + g_byte_array_free (tmp, TRUE); } else { /* Special types, check based on property name */ if (!strcmp (item->key, NM_SETTING_WIRELESS_SECURITY_PROTO)) @@ -154,7 +162,6 @@ fill_wifi_empty (NMConnection *connection) return s_wifi; } -#if 0 static NMSettingWireless * fill_wifi (NMConnection *connection, const KeyData items[]) { @@ -169,7 +176,6 @@ fill_wifi (NMConnection *connection, const KeyData items[]) set_items (NM_SETTING (s_wifi), items); return s_wifi; } -#endif static NMSettingWirelessSecurity * fill_wsec (NMConnection *connection, const KeyData items[]) @@ -257,7 +263,7 @@ test_lock_bssid (void) src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, TRUE, src, &error); expected = create_basic (ssid, bssid, NM_802_11_MODE_INFRA, FALSE); @@ -281,7 +287,7 @@ test_open_ap_empty_connection (void) src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, FALSE); @@ -309,7 +315,7 @@ test_open_ap_leap_connection_1 (gboolean add_wifi) success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); /* We expect failure */ @@ -335,7 +341,7 @@ test_open_ap_leap_connection_2 (void) success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); /* We expect failure */ @@ -365,7 +371,7 @@ test_open_ap_wep_connection (gboolean add_wifi) fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); /* We expect failure */ @@ -382,11 +388,18 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, - gboolean add_wifi) + gboolean add_wifi, + NMConnection *expected) { NMConnection *src; + const char *ssid = "blahblah"; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; - const KeyData src_wsec[] = { + const KeyData exp_wifi[] = { + { NM_SETTING_WIRELESS_SSID, ssid, 0 }, + { NM_SETTING_WIRELESS_MODE, "infrastructure", 0 }, + { NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, 0 }, + { NULL } }; + const KeyData both_wsec[] = { { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, key_mgmt, 0 }, { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, auth_alg, 0 }, { NM_SETTING_WIRELESS_SECURITY_PSK, "asdfasdfasdfasdfasdfafs", 0 }, @@ -397,12 +410,15 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, src = nm_connection_new (); if (add_wifi) fill_wifi_empty (src); - fill_wsec (src, src_wsec); - success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, + fill_wsec (src, both_wsec); + success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, FALSE, src, &error); - /* We expect failure */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + if (expected) { + fill_wifi (expected, exp_wifi); + fill_wsec (expected, both_wsec); + } + COMPARE (src, expected, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); g_object_unref (src); } @@ -414,7 +430,7 @@ test_open_ap_wpa_psk_connection_1 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -424,7 +440,7 @@ test_open_ap_wpa_psk_connection_2 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -434,7 +450,7 @@ test_open_ap_wpa_psk_connection_3 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -444,7 +460,7 @@ test_open_ap_wpa_psk_connection_4 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -454,7 +470,7 @@ test_open_ap_wpa_psk_connection_5 (void) NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } /*******************************************/ @@ -567,7 +583,7 @@ test_priv_ap_empty_connection (void) src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); @@ -607,7 +623,7 @@ test_priv_ap_leap_connection_1 (gboolean add_wifi) fill_wsec (src, src_wsec); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); /* We expect success here; since LEAP APs just set the 'privacy' flag @@ -640,7 +656,7 @@ test_priv_ap_leap_connection_2 (void) fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); /* We expect failure here, we need a LEAP username */ @@ -683,7 +699,7 @@ test_priv_ap_dynamic_wep_1 (void) fill_8021x (src, both_8021x); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); @@ -729,7 +745,7 @@ test_priv_ap_dynamic_wep_2 (void) fill_8021x (src, both_8021x); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); @@ -766,7 +782,7 @@ test_priv_ap_dynamic_wep_3 (void) fill_8021x (src, src_8021x); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - NM_WIFI_DEVICE_CAP_NONE, NM_WIFI_DEVICE_CAP_NONE, + NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); /* Expect failure; shared is not compatible with dynamic WEP */ @@ -784,7 +800,7 @@ test_priv_ap_wpa_psk_connection_1 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -794,7 +810,7 @@ test_priv_ap_wpa_psk_connection_2 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - TRUE); + TRUE, NULL); } static void @@ -804,7 +820,7 @@ test_priv_ap_wpa_psk_connection_3 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -814,7 +830,7 @@ test_priv_ap_wpa_psk_connection_4 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } static void @@ -824,7 +840,7 @@ test_priv_ap_wpa_psk_connection_5 (void) NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE); + FALSE, NULL); } /*******************************************/ @@ -891,6 +907,212 @@ test_priv_ap_wpa_eap_connection_5 (void) /*******************************************/ +#define WPA_PSK_CAPS (NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK) + +static void +test_wpa_ap_empty_connection (void) +{ + NMConnection *src, *expected; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *ssid = "blahblah"; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + FALSE, + src, &error); + + /* Static WEP connection expected */ + expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); + fill_wsec (expected, exp_wsec); + COMPARE (src, expected, success, error, 0, 0); + + g_object_unref (src); + g_object_unref (expected); +} + +/*******************************************/ + +static void +test_wpa_ap_leap_connection_1 (void) +{ + NMConnection *src; + const char *ssid = "blahblah"; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const char *leap_username = "Bill Smith"; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, leap_username, 0 }, + { NULL } }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + success = complete_connection (ssid, bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + FALSE, + src, &error); + /* Expect failure here; WPA APs don't support old-school LEAP */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_wpa_ap_leap_connection_2 (void) +{ + NMConnection *src; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "leap", 0 }, + { NULL } }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + FALSE, + src, &error); + /* We expect failure here, we need a LEAP username */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_wpa_ap_dynamic_wep_connection (void) +{ + NMConnection *src; + const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; + const KeyData src_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "ieee8021x", 0 }, + { NULL } }; + gboolean success; + GError *error = NULL; + + src = nm_connection_new (); + fill_wifi_empty (src); + fill_wsec (src, src_wsec); + success = complete_connection ("blahblah", bssid, + NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, + WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + FALSE, + src, &error); + /* We expect failure here since Dynamic WEP is incompatible with WPA */ + COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); + + g_object_unref (src); +} + +/*******************************************/ + +static void +test_wpa_ap_wpa_psk_connection_1 (void) +{ + NMConnection *expected; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + + expected = nm_connection_new (); + fill_wsec (expected, exp_wsec); + test_ap_wpa_psk_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_PRIVACY, + WPA_PSK_CAPS, + NM_802_11_AP_SEC_NONE, + FALSE, expected); + g_object_unref (expected); +} + +static void +test_wpa_ap_wpa_psk_connection_2 (void) +{ + NMConnection *expected; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + + expected = nm_connection_new (); + fill_wsec (expected, exp_wsec); + test_ap_wpa_psk_connection_base (NULL, NULL, + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + TRUE, NULL); + g_object_unref (expected); +} + +static void +test_wpa_ap_wpa_psk_connection_3 (void) +{ + NMConnection *expected; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + + expected = nm_connection_new (); + fill_wsec (expected, exp_wsec); + test_ap_wpa_psk_connection_base (NULL, "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, NULL); + g_object_unref (expected); +} + +static void +test_wpa_ap_wpa_psk_connection_4 (void) +{ + test_ap_wpa_psk_connection_base (NULL, "shared", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, NULL); +} + +static void +test_wpa_ap_wpa_psk_connection_5 (void) +{ + NMConnection *expected; + const KeyData exp_wsec[] = { + { NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", 0 }, + { NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", 0 }, + { NULL } }; + + expected = nm_connection_new (); + fill_wsec (expected, exp_wsec); + test_ap_wpa_psk_connection_base ("wpa-psk", "open", + NM_802_11_AP_FLAGS_PRIVACY, + NM_802_11_AP_SEC_NONE, + NM_802_11_AP_SEC_NONE, + FALSE, NULL); + g_object_unref (expected); +} + +/*******************************************/ + #if GLIB_CHECK_VERSION(2,25,12) typedef GTestFixtureFunc TCFunc; #else @@ -954,6 +1176,19 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_4, NULL)); g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_5, NULL)); + /* WPA-PSK tests */ + g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_2, NULL)); + + g_test_suite_add (suite, TESTCASE (test_wpa_ap_dynamic_wep_connection, NULL)); + + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_1, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_3, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, NULL)); + return g_test_run (); } From 54c58bcf1f0324f73c6876945479e8a9bd3c71bf Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 00:11:29 -0600 Subject: [PATCH 135/264] wifi: add more AP connection completion tests for EAP --- src/tests/test-wifi-ap-utils.c | 243 ++++++++++++++++++--------------- 1 file changed, 135 insertions(+), 108 deletions(-) diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c index a1467d814..625cb4386 100644 --- a/src/tests/test-wifi-ap-utils.c +++ b/src/tests/test-wifi-ap-utils.c @@ -503,67 +503,150 @@ test_ap_wpa_eap_connection_base (const char *key_mgmt, success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, FALSE, src, &error); - if (!wpa_flags && !rsn_flags) { - if (!flags) { - /* Failure expected */ - COMPARE (src, NULL, success, error, NM_SETTING_WIRELESS_SECURITY_ERROR, NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); - } else if (flags & NM_802_11_AP_FLAGS_PRIVACY) { - COMPARE (src, NULL, success, error, error_domain, error_code); - } - } else - g_assert_not_reached (); + /* Failure expected */ + COMPARE (src, NULL, success, error, error_domain, error_code); g_object_unref (src); } -static void -test_open_ap_wpa_eap_connection_1 (void) +enum { + IDX_NONE = 0, + IDX_OPEN, + IDX_PRIV, + IDX_WPA_PSK, + IDX_RSN_PSK, + IDX_WPA_8021X, + IDX_RSN_8021X +}; + +static guint32 +flags_for_idx (guint32 idx) { - test_ap_wpa_eap_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, 0, 0); + if (idx == IDX_OPEN) + return NM_802_11_AP_FLAGS_NONE; + else if (idx == IDX_PRIV || idx == IDX_WPA_PSK || idx == IDX_RSN_PSK + || idx == IDX_WPA_8021X || idx == IDX_RSN_8021X) + return NM_802_11_AP_FLAGS_PRIVACY; + else + g_assert_not_reached (); +} + +static guint32 +wpa_flags_for_idx (guint32 idx) +{ + if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_RSN_PSK || idx == IDX_RSN_8021X) + return NM_802_11_AP_SEC_NONE; + else if (idx == IDX_WPA_PSK) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_WPA_8021X) + return NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_KEY_MGMT_802_1X; + else + g_assert_not_reached (); +} + +static guint32 +rsn_flags_for_idx (guint32 idx) +{ + if (idx == IDX_OPEN || idx == IDX_PRIV || idx == IDX_WPA_PSK || idx == IDX_WPA_8021X) + return NM_802_11_AP_SEC_NONE; + else if (idx == IDX_RSN_PSK) + return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (idx == IDX_RSN_8021X) + return NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_CCMP | NM_802_11_AP_SEC_KEY_MGMT_802_1X; + else + g_assert_not_reached (); +} + +static guint32 +error_domain_for_idx (guint32 idx, guint num) +{ + if (idx == IDX_OPEN) + return NM_SETTING_WIRELESS_SECURITY_ERROR; + else if (idx == IDX_PRIV) { + if (num <= 3) + return NM_SETTING_802_1X_ERROR; + else + return NM_SETTING_WIRELESS_SECURITY_ERROR; + } else if (idx == IDX_WPA_PSK) + return NM_SETTING_WIRELESS_SECURITY_ERROR; + else + g_assert_not_reached (); +} + +static guint32 +error_code_for_idx (guint32 idx, guint num) +{ + if (idx == IDX_OPEN) + return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + else if (idx == IDX_PRIV) { + if (num <= 3) + return NM_SETTING_802_1X_ERROR_MISSING_PROPERTY; + else + return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + } else if (idx == IDX_WPA_PSK) { + return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; + } else + g_assert_not_reached (); } static void -test_open_ap_wpa_eap_connection_2 (void) +test_ap_wpa_eap_connection_1 (guint32 idx) { test_ap_wpa_eap_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - TRUE, 0, 0); + flags_for_idx (idx), + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, + error_domain_for_idx (idx, 1), + error_code_for_idx (idx, 1)); } static void -test_open_ap_wpa_eap_connection_3 (void) +test_ap_wpa_eap_connection_2 (guint idx) +{ + test_ap_wpa_eap_connection_base (NULL, NULL, + flags_for_idx (idx), + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + TRUE, + error_domain_for_idx (idx, 2), + error_code_for_idx (idx, 2)); +} + +static void +test_ap_wpa_eap_connection_3 (guint idx) { test_ap_wpa_eap_connection_base (NULL, "open", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, 0, 0); + flags_for_idx (idx), + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, + error_domain_for_idx (idx, 3), + error_code_for_idx (idx, 3)); } static void -test_open_ap_wpa_eap_connection_4 (void) +test_ap_wpa_eap_connection_4 (guint idx) { test_ap_wpa_eap_connection_base (NULL, "shared", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, 0, 0); + flags_for_idx (idx), + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, + error_domain_for_idx (idx, 4), + error_code_for_idx (idx, 4)); } static void -test_open_ap_wpa_eap_connection_5 (void) +test_ap_wpa_eap_connection_5 (guint idx) { test_ap_wpa_eap_connection_base ("wpa-eap", "open", - NM_802_11_AP_FLAGS_NONE, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, 0, 0); + flags_for_idx (idx), + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, + error_domain_for_idx (idx, 5), + error_code_for_idx (idx, 5)); } /*******************************************/ @@ -845,68 +928,6 @@ test_priv_ap_wpa_psk_connection_5 (void) /*******************************************/ -static void -test_priv_ap_wpa_eap_connection_1 (void) -{ - test_ap_wpa_eap_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_MISSING_PROPERTY); -} - -static void -test_priv_ap_wpa_eap_connection_2 (void) -{ - test_ap_wpa_eap_connection_base (NULL, NULL, - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - TRUE, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_MISSING_PROPERTY); -} - -static void -test_priv_ap_wpa_eap_connection_3 (void) -{ - test_ap_wpa_eap_connection_base (NULL, "open", - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_SETTING_802_1X_ERROR, - NM_SETTING_802_1X_ERROR_MISSING_PROPERTY); -} - -static void -test_priv_ap_wpa_eap_connection_4 (void) -{ - test_ap_wpa_eap_connection_base (NULL, "shared", - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); -} - -static void -test_priv_ap_wpa_eap_connection_5 (void) -{ - test_ap_wpa_eap_connection_base ("wpa-eap", "open", - NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, - NM_SETTING_WIRELESS_SECURITY_ERROR, - NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY); -} - -/*******************************************/ - #define WPA_PSK_CAPS (NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK) static void @@ -1149,11 +1170,11 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_4, NULL)); g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_psk_connection_5, NULL)); - g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_1, NULL)); - g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_2, NULL)); - g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_3, NULL)); - g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_4, NULL)); - g_test_suite_add (suite, TESTCASE (test_open_ap_wpa_eap_connection_5, NULL)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_OPEN)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_OPEN)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, IDX_OPEN)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_OPEN)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_OPEN)); /* WEP AP tests */ g_test_suite_add (suite, TESTCASE (test_priv_ap_empty_connection, NULL)); @@ -1170,11 +1191,11 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_4, NULL)); g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_psk_connection_5, NULL)); - g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_1, NULL)); - g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_2, NULL)); - g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_3, NULL)); - g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_4, NULL)); - g_test_suite_add (suite, TESTCASE (test_priv_ap_wpa_eap_connection_5, NULL)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_PRIV)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_PRIV)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, IDX_PRIV)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_PRIV)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_PRIV)); /* WPA-PSK tests */ g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, NULL)); @@ -1189,6 +1210,12 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, NULL)); g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, NULL)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_WPA_PSK)); + return g_test_run (); } From f7a8d53ac453d9702d1afccf209fb6d137d23713 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 00:24:41 -0600 Subject: [PATCH 136/264] wifi: ensure shared auth is rejected for WPA APs when completing connections --- src/nm-wifi-ap-utils.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/nm-wifi-ap-utils.c b/src/nm-wifi-ap-utils.c index b862dd18a..15e176a12 100644 --- a/src/nm-wifi-ap-utils.c +++ b/src/nm-wifi-ap-utils.c @@ -476,7 +476,7 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; const GByteArray *ssid; - const char *mode, *key_mgmt, *leap_username; + const char *mode, *key_mgmt, *auth_alg, *leap_username; gboolean adhoc = FALSE; s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); @@ -568,6 +568,7 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, } key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wsec); + auth_alg = nm_setting_wireless_security_get_auth_alg (s_wsec); leap_username = nm_setting_wireless_security_get_leap_username (s_wsec); /* Ad-Hoc checks */ @@ -638,6 +639,7 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, /* WPA/RSN */ g_assert (ap_wpa_flags || ap_rsn_flags); + /* Ensure key management is valid for WPA */ if ((key_mgmt && !strcmp (key_mgmt, "ieee8021x")) || leap_username) { g_set_error_literal (error, NM_SETTING_WIRELESS_SECURITY_ERROR, @@ -646,6 +648,15 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, return FALSE; } + /* 'shared' auth incompatible with any type of WPA */ + if (auth_alg && strcmp (auth_alg, "open")) { + g_set_error_literal (error, + NM_SETTING_WIRELESS_SECURITY_ERROR, + NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY, + "WPA incompatible with Shared Key authentication"); + return FALSE; + } + if (!verify_no_wep (s_wsec, "WPA", error)) return FALSE; @@ -655,7 +666,6 @@ nm_ap_utils_complete_connection (const GByteArray *ap_ssid, if (!adhoc && !verify_wpa_eap (s_wsec, s_8021x, ap_wpa_flags, ap_rsn_flags, error)) return FALSE; - if (adhoc) { g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-none", NULL); /* Ad-Hoc does not support RSN/WPA2 */ From 3a160af5abc89de843aaa97be99058ed942b93e7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 00:25:07 -0600 Subject: [PATCH 137/264] wifi: add RSN connection completion tests --- src/tests/test-wifi-ap-utils.c | 102 ++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c index 625cb4386..b1c7c9bc0 100644 --- a/src/tests/test-wifi-ap-utils.c +++ b/src/tests/test-wifi-ap-utils.c @@ -567,7 +567,7 @@ error_domain_for_idx (guint32 idx, guint num) return NM_SETTING_802_1X_ERROR; else return NM_SETTING_WIRELESS_SECURITY_ERROR; - } else if (idx == IDX_WPA_PSK) + } else if (idx == IDX_WPA_PSK || idx == IDX_RSN_PSK) return NM_SETTING_WIRELESS_SECURITY_ERROR; else g_assert_not_reached (); @@ -583,7 +583,7 @@ error_code_for_idx (guint32 idx, guint num) return NM_SETTING_802_1X_ERROR_MISSING_PROPERTY; else return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; - } else if (idx == IDX_WPA_PSK) { + } else if (idx == IDX_WPA_PSK || idx == IDX_RSN_PSK) { return NM_SETTING_WIRELESS_SECURITY_ERROR_INVALID_PROPERTY; } else g_assert_not_reached (); @@ -928,10 +928,8 @@ test_priv_ap_wpa_psk_connection_5 (void) /*******************************************/ -#define WPA_PSK_CAPS (NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_KEY_MGMT_PSK) - static void -test_wpa_ap_empty_connection (void) +test_wpa_ap_empty_connection (guint idx) { NMConnection *src, *expected; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; @@ -946,9 +944,9 @@ test_wpa_ap_empty_connection (void) src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, - FALSE, - src, &error); + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, src, &error); /* Static WEP connection expected */ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); @@ -962,7 +960,7 @@ test_wpa_ap_empty_connection (void) /*******************************************/ static void -test_wpa_ap_leap_connection_1 (void) +test_wpa_ap_leap_connection_1 (guint idx) { NMConnection *src; const char *ssid = "blahblah"; @@ -980,7 +978,8 @@ test_wpa_ap_leap_connection_1 (void) fill_wsec (src, src_wsec); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), FALSE, src, &error); /* Expect failure here; WPA APs don't support old-school LEAP */ @@ -992,7 +991,7 @@ test_wpa_ap_leap_connection_1 (void) /*******************************************/ static void -test_wpa_ap_leap_connection_2 (void) +test_wpa_ap_leap_connection_2 (guint idx) { NMConnection *src; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; @@ -1008,7 +1007,8 @@ test_wpa_ap_leap_connection_2 (void) fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), FALSE, src, &error); /* We expect failure here, we need a LEAP username */ @@ -1020,7 +1020,7 @@ test_wpa_ap_leap_connection_2 (void) /*******************************************/ static void -test_wpa_ap_dynamic_wep_connection (void) +test_wpa_ap_dynamic_wep_connection (guint idx) { NMConnection *src; const guint8 bssid[ETH_ALEN] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 }; @@ -1035,7 +1035,8 @@ test_wpa_ap_dynamic_wep_connection (void) fill_wsec (src, src_wsec); success = complete_connection ("blahblah", bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, - WPA_PSK_CAPS, NM_802_11_AP_SEC_NONE, + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), FALSE, src, &error); /* We expect failure here since Dynamic WEP is incompatible with WPA */ @@ -1047,7 +1048,7 @@ test_wpa_ap_dynamic_wep_connection (void) /*******************************************/ static void -test_wpa_ap_wpa_psk_connection_1 (void) +test_wpa_ap_wpa_psk_connection_1 (guint idx) { NMConnection *expected; const KeyData exp_wsec[] = { @@ -1059,14 +1060,14 @@ test_wpa_ap_wpa_psk_connection_1 (void) fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, - WPA_PSK_CAPS, - NM_802_11_AP_SEC_NONE, + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), FALSE, expected); g_object_unref (expected); } static void -test_wpa_ap_wpa_psk_connection_2 (void) +test_wpa_ap_wpa_psk_connection_2 (guint idx) { NMConnection *expected; const KeyData exp_wsec[] = { @@ -1078,14 +1079,14 @@ test_wpa_ap_wpa_psk_connection_2 (void) fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - TRUE, NULL); + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + TRUE, expected); g_object_unref (expected); } static void -test_wpa_ap_wpa_psk_connection_3 (void) +test_wpa_ap_wpa_psk_connection_3 (guint idx) { NMConnection *expected; const KeyData exp_wsec[] = { @@ -1097,24 +1098,24 @@ test_wpa_ap_wpa_psk_connection_3 (void) fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base (NULL, "open", NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, NULL); + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, expected); g_object_unref (expected); } static void -test_wpa_ap_wpa_psk_connection_4 (void) +test_wpa_ap_wpa_psk_connection_4 (guint idx) { test_ap_wpa_psk_connection_base (NULL, "shared", NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), FALSE, NULL); } static void -test_wpa_ap_wpa_psk_connection_5 (void) +test_wpa_ap_wpa_psk_connection_5 (guint idx) { NMConnection *expected; const KeyData exp_wsec[] = { @@ -1126,9 +1127,9 @@ test_wpa_ap_wpa_psk_connection_5 (void) fill_wsec (expected, exp_wsec); test_ap_wpa_psk_connection_base ("wpa-psk", "open", NM_802_11_AP_FLAGS_PRIVACY, - NM_802_11_AP_SEC_NONE, - NM_802_11_AP_SEC_NONE, - FALSE, NULL); + wpa_flags_for_idx (idx), + rsn_flags_for_idx (idx), + FALSE, expected); g_object_unref (expected); } @@ -1198,17 +1199,17 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_PRIV)); /* WPA-PSK tests */ - g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, NULL)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_1, NULL)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_2, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_1, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_2, IDX_WPA_PSK)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_dynamic_wep_connection, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_dynamic_wep_connection, IDX_WPA_PSK)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_1, NULL)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_2, NULL)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_3, NULL)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, NULL)); - g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, NULL)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_1, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_2, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_3, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, IDX_WPA_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, IDX_WPA_PSK)); g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_WPA_PSK)); g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_WPA_PSK)); @@ -1216,6 +1217,25 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_WPA_PSK)); g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_WPA_PSK)); + /* RSN-PSK tests */ + g_test_suite_add (suite, TESTCASE (test_wpa_ap_empty_connection, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_1, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_leap_connection_2, IDX_RSN_PSK)); + + g_test_suite_add (suite, TESTCASE (test_wpa_ap_dynamic_wep_connection, IDX_RSN_PSK)); + + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_1, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_2, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_3, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_4, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_wpa_ap_wpa_psk_connection_5, IDX_RSN_PSK)); + + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_1, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_2, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_3, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_4, IDX_RSN_PSK)); + g_test_suite_add (suite, TESTCASE (test_ap_wpa_eap_connection_5, IDX_RSN_PSK)); + return g_test_run (); } From 063859ba66715c6cb239ac49dc8f75cb77213964 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 00:39:34 -0600 Subject: [PATCH 138/264] libnm-glib: add nm_client_add_and_activate_connection() --- introspection/nm-manager-client.xml | 10 ++++ libnm-glib/nm-client.c | 78 +++++++++++++++++++++++++++-- libnm-glib/nm-client.h | 16 +++++- 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/introspection/nm-manager-client.xml b/introspection/nm-manager-client.xml index 540aff378..9dde9ddfb 100644 --- a/introspection/nm-manager-client.xml +++ b/introspection/nm-manager-client.xml @@ -28,6 +28,16 @@ object. dbus-glib generates the same bound function names for D-Bus the methods + + + + + + + + + + diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index a2be1f795..32a6c972d 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -990,7 +990,8 @@ nm_client_get_device_by_path (NMClient *client, const char *object_path) } typedef struct { - NMClientActivateDeviceFn fn; + NMClientActivateDeviceFn act_fn; + NMClientAddActivateFn add_act_fn; gpointer user_data; } ActivateDeviceInfo; @@ -1002,8 +1003,8 @@ activate_cb (DBusGProxy *proxy, { ActivateDeviceInfo *info = (ActivateDeviceInfo *) user_data; - if (info->fn) - info->fn (info->user_data, path, error); + if (info->act_fn) + info->act_fn (info->user_data, path, error); else if (error) nm_warning ("Device activation failed: (%d) %s", error->code, error->message); @@ -1044,7 +1045,7 @@ nm_client_activate_connection (NMClient *client, internal_so = "/"; info = g_slice_new (ActivateDeviceInfo); - info->fn = callback; + info->act_fn = callback; info->user_data = user_data; org_freedesktop_NetworkManager_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->client_proxy, @@ -1055,6 +1056,75 @@ nm_client_activate_connection (NMClient *client, info); } +static void +add_activate_cb (DBusGProxy *proxy, + char *connection_path, + char *active_path, + GError *error, + gpointer user_data) +{ + ActivateDeviceInfo *info = (ActivateDeviceInfo *) user_data; + + if (info->add_act_fn) + info->add_act_fn (info->user_data, connection_path, active_path, error); + else if (error) + nm_warning ("Connection add and activate failed: (%d) %s", error->code, error->message); + + g_slice_free (ActivateDeviceInfo, info); +} + +/** + * nm_client_add_and_activate_connection: + * @client: a #NMClient + * @partial: an #NMConnection to add; the connection may be partially filled + * and will be completed by NetworkManager using the given @device and + * @specific_object before being added + * @device: the #NMDevice + * @specific_object: the object path of a connection-type-specific object this + * activation should use. This parameter is currently ignored for wired and + * mobile broadband connections, and the value of NULL should be used (ie, no + * specific object). For WiFi connections, pass the object path of a specific + * AP from the card's scan list, which will be used to complete the details of + * the newly added connection. + * @callback: the function to call when the call is done + * @user_data: user data to pass to the callback function + * + * Adds a new connection using the given details (if any) as a template + * (automatically filling in missing settings with the capabilities of the + * given device and specific object), then activate the new connection. + * Cannot be used for VPN connections at this time. + **/ +void +nm_client_add_and_activate_connection (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + NMClientAddActivateFn callback, + gpointer user_data) +{ + ActivateDeviceInfo *info; + GHashTable *hash = NULL; + + g_return_if_fail (NM_IS_CLIENT (client)); + g_return_if_fail (NM_IS_DEVICE (device)); + + info = g_slice_new (ActivateDeviceInfo); + info->add_act_fn = callback; + info->user_data = user_data; + + if (partial) + hash = nm_connection_to_hash (partial); + else + hash = g_hash_table_new (g_str_hash, g_str_equal); + org_freedesktop_NetworkManager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->client_proxy, + hash, + nm_object_get_path (NM_OBJECT (device)), + specific_object ? specific_object : "/", + add_activate_cb, + info); + g_hash_table_unref (hash); +} + /** * nm_client_deactivate_connection: * @client: a #NMClient diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index e528af426..b28afd8c3 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -104,7 +104,9 @@ NMClient *nm_client_new (void); const GPtrArray *nm_client_get_devices (NMClient *client); NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_path); -typedef void (*NMClientActivateDeviceFn) (gpointer user_data, const char *object_path, GError *error); +typedef void (*NMClientActivateDeviceFn) (gpointer user_data, + const char *object_path, + GError *error); void nm_client_activate_connection (NMClient *client, const char *connection_path, @@ -113,6 +115,18 @@ void nm_client_activate_connection (NMClient *client, NMClientActivateDeviceFn callback, gpointer user_data); +typedef void (*NMClientAddActivateFn) (gpointer user_data, + const char *connection_path, + const char *active_path, + GError *error); + +void nm_client_add_and_activate_connection (NMClient *client, + NMConnection *partial, + NMDevice *device, + const char *specific_object, + NMClientAddActivateFn callback, + gpointer user_data); + void nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active); gboolean nm_client_networking_get_enabled (NMClient *client); From c1ee4fce68bb28e9474e247f87d00cf012e9fbb5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 13:20:37 -0600 Subject: [PATCH 139/264] tests: add some comments to the wifi connection completion tests --- src/tests/test-wifi-ap-utils.c | 107 ++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/src/tests/test-wifi-ap-utils.c b/src/tests/test-wifi-ap-utils.c index b1c7c9bc0..da46b8cd6 100644 --- a/src/tests/test-wifi-ap-utils.c +++ b/src/tests/test-wifi-ap-utils.c @@ -284,6 +284,10 @@ test_open_ap_empty_connection (void) gboolean success; GError *error = NULL; + /* Test that an empty source connection is correctly filled with the + * SSID and Infra modes of the given AP details. + */ + src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, @@ -308,6 +312,11 @@ test_open_ap_leap_connection_1 (gboolean add_wifi) gboolean success; GError *error = NULL; + /* Test that a basic connection filled with a LEAP username is + * rejected when completion is attempted with an open AP. LEAP requires + * the AP to have the Privacy bit set. + */ + src = nm_connection_new (); if (add_wifi) fill_wifi_empty (src); @@ -335,6 +344,10 @@ test_open_ap_leap_connection_2 (void) gboolean success; GError *error = NULL; + /* Test that a basic connection specifying IEEE8021x security (ie, Dynamic + * WEP or LEAP) is rejected when completion is attempted with an open AP. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -365,6 +378,10 @@ test_open_ap_wep_connection (gboolean add_wifi) gboolean success; GError *error = NULL; + /* Test that a static WEP connection is rejected when completion is + * attempted with an open AP. + */ + src = nm_connection_new (); if (add_wifi) fill_wifi_empty (src); @@ -426,6 +443,10 @@ test_ap_wpa_psk_connection_base (const char *key_mgmt, static void test_open_ap_wpa_psk_connection_1 (void) { + /* Test that a WPA-PSK connection filling only the PSK itself and *not* + * filling the wifi setting is rejected when completion is attempted with + * an open AP. + */ test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, @@ -436,16 +457,23 @@ test_open_ap_wpa_psk_connection_1 (void) static void test_open_ap_wpa_psk_connection_2 (void) { + /* Test that a WPA-PSK connection filling only the PSK itself and also + * filling the wifi setting is rejected when completion is attempted with + * an open AP. + */ test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, - FALSE, NULL); + TRUE, NULL); } static void test_open_ap_wpa_psk_connection_3 (void) { + /* Test that a WPA-PSK connection filling the PSK and setting the auth alg + * to 'open' is rejected when completion is attempted with an open AP. + */ test_ap_wpa_psk_connection_base (NULL, "open", NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, @@ -456,6 +484,10 @@ test_open_ap_wpa_psk_connection_3 (void) static void test_open_ap_wpa_psk_connection_4 (void) { + /* Test that a WPA-PSK connection filling the PSK and setting the auth alg + * to 'shared' is rejected when completion is attempted with an open AP. + * Shared auth cannot be used with WPA. + */ test_ap_wpa_psk_connection_base (NULL, "shared", NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, @@ -466,6 +498,9 @@ test_open_ap_wpa_psk_connection_4 (void) static void test_open_ap_wpa_psk_connection_5 (void) { + /* Test that a WPA-PSK connection filling the PSK, the auth algorithm, and + * key management is rejected when completion is attempted with an open AP. + */ test_ap_wpa_psk_connection_base ("wpa-psk", "open", NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, @@ -663,6 +698,10 @@ test_priv_ap_empty_connection (void) gboolean success; GError *error = NULL; + /* Test that an empty connection is completed to a valid Static WEP + * connection when completed with an AP with the Privacy bit set. + */ + src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, @@ -700,6 +739,11 @@ test_priv_ap_leap_connection_1 (gboolean add_wifi) gboolean success; GError *error = NULL; + /* Test that an minimal LEAP connection specifying only key management and + * the LEAP username is completed to a full LEAP connection when completed + * with an AP with the Privacy bit set. + */ + src = nm_connection_new (); if (add_wifi) fill_wifi_empty (src); @@ -734,6 +778,11 @@ test_priv_ap_leap_connection_2 (void) gboolean success; GError *error = NULL; + /* Test that an minimal LEAP connection specifying only key management and + * the LEAP auth alg is completed to a full LEAP connection when completed + * with an AP with the Privacy bit set. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -776,6 +825,11 @@ test_priv_ap_dynamic_wep_1 (void) gboolean success; GError *error = NULL; + /* Test that an minimal Dynamic WEP connection specifying key management, + * the auth algorithm, and valid 802.1x setting is completed to a valid + * Dynamic WEP connection when completed with an AP with the Privacy bit set. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -822,6 +876,11 @@ test_priv_ap_dynamic_wep_2 (void) gboolean success; GError *error = NULL; + /* Test that an minimal Dynamic WEP connection specifying only the auth + * algorithm and a valid 802.1x setting is completed to a valid Dynamic + * WEP connection when completed with an AP with the Privacy bit set. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -859,6 +918,10 @@ test_priv_ap_dynamic_wep_3 (void) gboolean success; GError *error = NULL; + /* Ensure that a basic connection specifying 'shared' auth and an 802.1x + * setting is rejected, as 802.1x is incompatible with 'shared' auth. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -879,6 +942,10 @@ test_priv_ap_dynamic_wep_3 (void) static void test_priv_ap_wpa_psk_connection_1 (void) { + /* Test that a basic WPA-PSK connection is rejected when completion is + * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN + * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA. + */ test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, @@ -889,6 +956,10 @@ test_priv_ap_wpa_psk_connection_1 (void) static void test_priv_ap_wpa_psk_connection_2 (void) { + /* Test that a basic WPA-PSK connection is rejected when completion is + * attempted with an AP with just the Privacy bit set. Lack of WPA/RSN + * flags means the AP provides Static/Dynamic WEP or LEAP, not WPA. + */ test_ap_wpa_psk_connection_base (NULL, NULL, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, @@ -899,6 +970,11 @@ test_priv_ap_wpa_psk_connection_2 (void) static void test_priv_ap_wpa_psk_connection_3 (void) { + /* Test that a basic WPA-PSK connection specifying only the auth algorithm + * is rejected when completion is attempted with an AP with just the Privacy + * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP + * or LEAP, not WPA. + */ test_ap_wpa_psk_connection_base (NULL, "open", NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, @@ -909,6 +985,11 @@ test_priv_ap_wpa_psk_connection_3 (void) static void test_priv_ap_wpa_psk_connection_4 (void) { + /* Test that a basic WPA-PSK connection specifying only the auth algorithm + * is rejected when completion is attempted with an AP with just the Privacy + * bit set. Lack of WPA/RSN flags means the AP provides Static/Dynamic WEP + * or LEAP, not WPA. Second, 'shared' auth is incompatible with WPA. + */ test_ap_wpa_psk_connection_base (NULL, "shared", NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, @@ -919,6 +1000,11 @@ test_priv_ap_wpa_psk_connection_4 (void) static void test_priv_ap_wpa_psk_connection_5 (void) { + /* Test that a WPA-PSK connection specifying both the key management and + * auth algorithm is rejected when completion is attempted with an AP with + * just the Privacy bit set. Lack of WPA/RSN flags means the AP provides + * Static/Dynamic WEP or LEAP, not WPA. + */ test_ap_wpa_psk_connection_base ("wpa-psk", "open", NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, @@ -941,6 +1027,11 @@ test_wpa_ap_empty_connection (guint idx) gboolean success; GError *error = NULL; + /* Test that a basic WPA-PSK connection specifying just key management and + * the auth algorithm is completed successfully when given an AP with WPA + * or RSN flags. + */ + src = nm_connection_new (); success = complete_connection (ssid, bssid, NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, @@ -948,7 +1039,7 @@ test_wpa_ap_empty_connection (guint idx) rsn_flags_for_idx (idx), FALSE, src, &error); - /* Static WEP connection expected */ + /* WPA connection expected */ expected = create_basic (ssid, NULL, NM_802_11_MODE_INFRA, TRUE); fill_wsec (expected, exp_wsec); COMPARE (src, expected, success, error, 0, 0); @@ -973,6 +1064,10 @@ test_wpa_ap_leap_connection_1 (guint idx) gboolean success; GError *error = NULL; + /* Test that completion of a LEAP connection with a WPA-enabled AP is + * rejected since WPA APs (usually) do not support LEAP. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -1002,6 +1097,10 @@ test_wpa_ap_leap_connection_2 (guint idx) gboolean success; GError *error = NULL; + /* Test that completion of a LEAP connection with a WPA-enabled AP is + * rejected since WPA APs (usually) do not support LEAP. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); @@ -1030,6 +1129,10 @@ test_wpa_ap_dynamic_wep_connection (guint idx) gboolean success; GError *error = NULL; + /* Test that completion of a Dynamic WEP connection with a WPA-enabled AP is + * rejected since WPA APs (usually) do not support Dynamic WEP. + */ + src = nm_connection_new (); fill_wifi_empty (src); fill_wsec (src, src_wsec); From 7de13fa58dca796493b623fcba00d468f3aaa9f6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 13:24:22 -0600 Subject: [PATCH 140/264] libnm-glib: fix library builds Duh, don't specify noinst_LTLIBRARIES twice... --- libnm-glib/Makefile.am | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 571b6bf96..55c994adf 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -23,12 +23,15 @@ BUILT_SOURCES = \ nm-dhcp6-config-bindings.h \ nm-secret-agent-glue.h + +noinst_LTLIBRARIES = \ + libdeprecated-nm-glib.la \ + libnm-glib-test.la + ##################################################### # Deprecated original libnm_glib bits ##################################################### -noinst_LTLIBRARIES = libdeprecated-nm-glib.la - libdeprecated_nm_glib_la_SOURCES = \ libnm_glib.h \ libnm_glib.c @@ -141,8 +144,6 @@ libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ # Test libnm-glib stuff ##################################################### -noinst_LTLIBRARIES = libnm-glib-test.la - libnm_glib_test_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ From 2b65dcdf9258458e4763feab5e4e5da1d4d45229 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 15:54:56 -0600 Subject: [PATCH 141/264] libnm-util: WiMAX setting requires a non-zero-length NSP name --- libnm-util/nm-setting-wimax.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libnm-util/nm-setting-wimax.c b/libnm-util/nm-setting-wimax.c index 349a3ae8e..c37af8cdc 100644 --- a/libnm-util/nm-setting-wimax.c +++ b/libnm-util/nm-setting-wimax.c @@ -16,11 +16,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * + * (C) Copyright 2011 Red Hat, Inc. * (C) Copyright 2009 Novell, Inc. */ +#include #include #include + #include "nm-setting-wimax.h" #include "nm-param-spec-specialized.h" @@ -111,6 +114,15 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (!strlen (priv->network_name)) { + g_set_error (error, + NM_SETTING_WIMAX_ERROR, + NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, + NM_SETTING_WIMAX_NETWORK_NAME); + + return FALSE; + } + if (priv->mac_address && priv->mac_address->len != ETH_ALEN) { g_set_error (error, NM_SETTING_WIMAX_ERROR, From 8259b35ee5e5d346fe928003011fb124f667b9b9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 17:46:43 -0600 Subject: [PATCH 142/264] wimax: add connection completion function --- src/wimax/nm-device-wimax.c | 115 ++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index fba108f5b..ad57458ba 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -114,6 +114,7 @@ typedef enum NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0, NM_WIMAX_ERROR_CONNECTION_INVALID, NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, + NM_WIMAX_ERROR_NSP_NOT_FOUND, } NMWimaxError; #define NM_WIMAX_ERROR (nm_wimax_error_quark ()) @@ -144,6 +145,8 @@ nm_wimax_error_get_type (void) ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), /* Connection does not apply to this device. */ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"), + /* NSP not found in the scan list. */ + ENUM_ENTRY (NM_WIMAX_ERROR_NSP_NOT_FOUND, "NspNotFound"), { 0, 0, 0 } }; etype = g_enum_register_static ("NMWimaxError", values); @@ -479,6 +482,117 @@ real_check_connection_compatible (NMDevice *device, return TRUE; } +static gboolean +real_complete_connection (NMDevice *device, + NMConnection *connection, + const char *specific_object, + const GSList *existing_connections, + GError **error) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (device); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + NMSettingWimax *s_wimax; + const GByteArray *setting_mac; + char *format; + const char *nsp_name = NULL; + NMWimaxNsp *nsp = NULL; + GSList *iter; + + s_wimax = (NMSettingWimax *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX); + + if (!specific_object) { + /* If not given a specific object, we need at minimum an NSP name */ + if (!s_wimax) { + g_set_error_literal (error, + NM_WIMAX_ERROR, + NM_WIMAX_ERROR_CONNECTION_INVALID, + "A 'wimax' setting is required if no NSP path was given."); + return FALSE; + } + + nsp_name = nm_setting_wimax_get_network_name (s_wimax); + if (!nsp_name || !strlen (nsp_name)) { + g_set_error_literal (error, + NM_WIMAX_ERROR, + NM_WIMAX_ERROR_CONNECTION_INVALID, + "A 'wimax' setting with a valid network name is required if no NSP path was given."); + return FALSE; + } + + /* Find a compatible NSP in the list */ + nsp = get_nsp_by_name (self, nsp_name); + + /* If we still don't have an NSP, then the WiMAX settings needs to be + * fully specified by the client. Might not be able to find the NSP + * if the scan didn't find the NSP yet. + */ + if (!nsp) { + if (!nm_setting_verify (NM_SETTING (s_wimax), NULL, error)) + return FALSE; + } + } else { + /* Find a compatible NSP in the list */ + for (iter = priv->nsp_list; iter; iter = g_slist_next (iter)) { + if (!strcmp (specific_object, nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data)))) { + nsp = NM_WIMAX_NSP (iter->data); + break; + } + } + + if (!nsp) { + g_set_error (error, + NM_WIMAX_ERROR, + NM_WIMAX_ERROR_NSP_NOT_FOUND, + "The NSP %s was not in the scan list.", + specific_object); + return FALSE; + } + + nsp_name = nm_wimax_nsp_get_name (nsp); + } + + /* Add a WiMAX setting if one doesn't exist */ + if (!s_wimax) { + s_wimax = (NMSettingWimax *) nm_setting_wimax_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wimax)); + } + + g_assert (nsp_name); + format = g_strdup_printf ("%s %%d", nsp_name); + nm_device_complete_generic (connection, + NM_SETTING_WIMAX_SETTING_NAME, + existing_connections, + format, + nsp_name); + g_free (format); + g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); + + setting_mac = nm_setting_wimax_get_mac_address (s_wimax); + if (setting_mac) { + /* Make sure the setting MAC (if any) matches the device's permanent MAC */ + if (memcmp (setting_mac->data, &priv->hw_addr.ether_addr_octet, ETH_ALEN)) { + g_set_error (error, + NM_SETTING_WIMAX_ERROR, + NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, + NM_SETTING_WIMAX_MAC_ADDRESS); + return FALSE; + } + } else { + GByteArray *mac; + const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; + + /* Lock the connection to this device by default */ + if (memcmp (&priv->hw_addr.ether_addr_octet, null_mac, ETH_ALEN)) { + mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac, priv->hw_addr.ether_addr_octet, ETH_ALEN); + g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, mac, NULL); + g_byte_array_free (mac, TRUE); + } + } + + return TRUE; +} + static NMConnection * real_get_best_auto_connection (NMDevice *device, GSList *connections, @@ -1349,6 +1463,7 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) device_class->hw_take_down = real_hw_take_down; device_class->update_hw_address = real_update_hw_address; device_class->check_connection_compatible = real_check_connection_compatible; + device_class->complete_connection = real_complete_connection; device_class->get_best_auto_connection = real_get_best_auto_connection; device_class->get_generic_capabilities = real_get_generic_capabilities; device_class->is_available = real_is_available; From b38f39cfc624d6b793f2e93abbba8ffd903b879c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 12 Jan 2011 18:12:23 -0600 Subject: [PATCH 143/264] core: build keyfile plugin into NetworkManager Since settings storage is now handled by NetworkManager, we must have the ability to read/write all connection types at all times. Since the 'keyfile' plugin is the only plugin that can handle all connection types, build it into NetworkManager. --- Makefile.am | 6 +++--- src/settings/Makefile.am | 4 +--- src/settings/nm-settings.c | 15 +++++++++++++-- system-settings/plugins/keyfile/Makefile.am | 15 +++++++++------ system-settings/plugins/keyfile/plugin.c | 4 ++-- system-settings/plugins/keyfile/plugin.h | 2 ++ 6 files changed, 30 insertions(+), 16 deletions(-) diff --git a/Makefile.am b/Makefile.am index 64be5c852..c3eb4e151 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,12 +1,12 @@ SUBDIRS = \ marshallers \ + include \ libnm-util \ libnm-glib \ - src \ - include \ introspection \ - callouts \ system-settings \ + src \ + callouts \ cli \ tools \ policy \ diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am index 0fc8b1fb5..927169cc2 100644 --- a/src/settings/Makefile.am +++ b/src/settings/Makefile.am @@ -1,7 +1,6 @@ INCLUDES = -I${top_srcdir} \ -I${top_srcdir}/include \ -I${top_srcdir}/libnm-util \ - -I${top_srcdir}/libnm-glib \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src \ -I${top_builddir}/marshallers @@ -44,9 +43,9 @@ libsettings_la_CPPFLAGS = \ libsettings_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/system-settings/plugins/keyfile/libnm-settings-plugin-keyfile.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ @@ -54,7 +53,6 @@ libsettings_la_LIBADD = \ libsettings_la_LDFLAGS = -rdynamic - nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 2f47b7a62..2f299c8d6 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -62,6 +62,7 @@ #include "nm-dbus-manager.h" #include "nm-manager-auth.h" #include "nm-session-monitor.h" +#include "system-settings/plugins/keyfile/plugin.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -520,6 +521,10 @@ load_plugins (NMSettings *self, const char *plugins, GError **error) GObject *obj; GObject * (*factory_func) (void); + /* keyfile plugin built in now */ + if (!strcmp (pname, "keyfile")) + continue; + /* ifcfg-fedora was renamed ifcfg-rh; handle old configs here */ if (!strcmp (pname, "ifcfg-fedora")) pname = "ifcfg-rh"; @@ -1328,11 +1333,12 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device) NMSettings * nm_settings_new (const char *config_file, - const char *plugins, - GError **error) + const char *plugins, + GError **error) { NMSettings *self; NMSettingsPrivate *priv; + GObject *keyfile_plugin; self = g_object_new (NM_TYPE_SETTINGS, NULL); if (!self) @@ -1353,6 +1359,11 @@ nm_settings_new (const char *config_file, unmanaged_specs_changed (NULL, self); } + /* Add the keyfile plugin last */ + keyfile_plugin = nm_settings_keyfile_plugin_new (); + g_assert (keyfile_plugin); + add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin)); + dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); return self; } diff --git a/system-settings/plugins/keyfile/Makefile.am b/system-settings/plugins/keyfile/Makefile.am index ea2f18c23..3b2421422 100644 --- a/system-settings/plugins/keyfile/Makefile.am +++ b/system-settings/plugins/keyfile/Makefile.am @@ -3,12 +3,13 @@ SUBDIRS=. tests INCLUDES = \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ - -I$(top_srcdir)/libnm-util \ - -I$(top_srcdir)/libnm-glib + -I$(top_srcdir)/libnm-util -pkglib_LTLIBRARIES = libnm-settings-plugin-keyfile.la +noinst_LTLIBRARIES = \ + libkeyfile-io.la \ + libnm-settings-plugin-keyfile.la -noinst_LTLIBRARIES = libkeyfile-io.la +##### I/O library for testcases ##### libkeyfile_io_la_SOURCES = \ reader.c \ @@ -28,6 +29,8 @@ libkeyfile_io_la_CPPFLAGS = \ libkeyfile_io_la_LIBADD = $(GLIB_LIBS) +##################################### + libnm_settings_plugin_keyfile_la_SOURCES = \ nm-keyfile-connection.c \ nm-keyfile-connection.h \ @@ -41,16 +44,16 @@ libnm_settings_plugin_keyfile_la_CPPFLAGS = \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -DG_DISABLE_DEPRECATED -libnm_settings_plugin_keyfile_la_LDFLAGS = -module -avoid-version libnm_settings_plugin_keyfile_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ - $(top_builddir)/libnm-glib/libnm-glib.la \ libkeyfile-io.la \ $(GLIB_LIBS) \ $(GMODULE_LIBS) \ $(DBUS_LIBS) \ $(GIO_LIBS) +libnm_settings_plugin_keyfile_la_LDFLAGS = -rdynamic + keyfiledir=$(sysconfdir)/NetworkManager/system-connections install-data-hook: diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index a1c654245..27ddb299f 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -662,8 +662,8 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; } -G_MODULE_EXPORT GObject * -nm_system_config_factory (void) +GObject * +nm_settings_keyfile_plugin_new (void) { static SCPluginKeyfile *singleton = NULL; diff --git a/system-settings/plugins/keyfile/plugin.h b/system-settings/plugins/keyfile/plugin.h index 71496c074..af5147ef1 100644 --- a/system-settings/plugins/keyfile/plugin.h +++ b/system-settings/plugins/keyfile/plugin.h @@ -43,4 +43,6 @@ GType sc_plugin_keyfile_get_type (void); GQuark keyfile_plugin_error_quark (void); +GObject *nm_settings_keyfile_plugin_new (void); + #endif /* _PLUGIN_H_ */ From 2d9cd80c870d6eb209605d927c0b4144c85a25cb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 12:42:52 -0600 Subject: [PATCH 144/264] wifi: use less memory converting SSID nm_utils_ssid_to_utf8() handles null termination for us, so no need to copy the SSID to a buffer first. --- src/nm-device-wifi.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 4a9e50214..9f821be8c 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -1385,8 +1385,6 @@ real_complete_connection (NMDevice *device, NMAccessPoint *ap = NULL; const GByteArray *ssid = NULL; GSList *iter; - char buf[33]; - int buf_len; s_wifi = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS); s_wsec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); @@ -1461,10 +1459,7 @@ real_complete_connection (NMDevice *device, } g_assert (ssid); - memset (buf, 0, sizeof (buf)); - buf_len = MIN (ssid->len, sizeof (buf) - 1); - memcpy (buf, ssid->data, buf_len); - str_ssid = nm_utils_ssid_to_utf8 (buf, buf_len); + str_ssid = nm_utils_ssid_to_utf8 ((const char *) ssid, ssid->len); format = g_strdup_printf ("%s %%d", str_ssid); nm_device_complete_generic (connection, From b5f3aa7120c2cff17d515087e675b5f16f1a06c7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 13:03:02 -0600 Subject: [PATCH 145/264] libnm-glib: pass NMClient as first callback argument to activation callbacks Better matches glib style. --- cli/src/connections.c | 6 +++--- libnm-glib/nm-client.c | 26 +++++++++++--------------- libnm-glib/nm-client.h | 12 +++++++----- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index 50c1373f8..0e08b3750 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -144,7 +144,7 @@ static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection const char *nsp, NMDevice **device, const char **spec_object, GError **error); static const char *active_connection_state_to_string (NMActiveConnectionState state); static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data); -static void activate_connection_cb (gpointer user_data, const char *path, GError *error); +static void activate_connection_cb (NMClient *client, const char *path, GError *error, gpointer user_data); static void get_connections_cb (NMRemoteSettings *settings, gpointer user_data); static NMCResultCode do_connections_list (NmCli *nmc, int argc, char **argv); static NMCResultCode do_connections_status (NmCli *nmc, int argc, char **argv); @@ -1267,11 +1267,11 @@ foo_active_connections_changed_cb (NMClient *client, /* Call again activate_connection_cb with dummy arguments; * the correct ones are taken from its first call. */ - activate_connection_cb (NULL, NULL, NULL); + activate_connection_cb (NULL, NULL, NULL, NULL); } static void -activate_connection_cb (gpointer user_data, const char *path, GError *error) +activate_connection_cb (NMClient *client, const char *path, GError *error, gpointer user_data) { NmCli *nmc = (NmCli *) user_data; NMActiveConnection *active; diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index b00f65b69..ff8b999e6 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #include @@ -1080,6 +1080,7 @@ nm_client_get_device_by_path (NMClient *client, const char *object_path) } typedef struct { + NMClient *client; NMClientActivateDeviceFn act_fn; NMClientAddActivateFn add_act_fn; gpointer user_data; @@ -1094,7 +1095,7 @@ activate_cb (DBusGProxy *proxy, ActivateDeviceInfo *info = (ActivateDeviceInfo *) user_data; if (info->act_fn) - info->act_fn (info->user_data, path, error); + info->act_fn (info->client, path, error, info->user_data); else if (error) nm_warning ("Device activation failed: (%d) %s", error->code, error->message); @@ -1122,28 +1123,22 @@ nm_client_activate_connection (NMClient *client, gpointer user_data) { ActivateDeviceInfo *info; - char *internal_so = (char *) specific_object; g_return_if_fail (NM_IS_CLIENT (client)); g_return_if_fail (NM_IS_DEVICE (device)); g_return_if_fail (connection_path != NULL); - /* NULL specific object must be translated into "/" because D-Bus does - * not have any idea of NULL object paths. - */ - if (internal_so == NULL) - internal_so = "/"; - info = g_slice_new (ActivateDeviceInfo); info->act_fn = callback; info->user_data = user_data; + info->client = client; org_freedesktop_NetworkManager_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->client_proxy, - connection_path, - nm_object_get_path (NM_OBJECT (device)), - internal_so, - activate_cb, - info); + connection_path, + nm_object_get_path (NM_OBJECT (device)), + specific_object ? specific_object : "/", + activate_cb, + info); } static void @@ -1156,7 +1151,7 @@ add_activate_cb (DBusGProxy *proxy, ActivateDeviceInfo *info = (ActivateDeviceInfo *) user_data; if (info->add_act_fn) - info->add_act_fn (info->user_data, connection_path, active_path, error); + info->add_act_fn (info->client, connection_path, active_path, error, info->user_data); else if (error) nm_warning ("Connection add and activate failed: (%d) %s", error->code, error->message); @@ -1201,6 +1196,7 @@ nm_client_add_and_activate_connection (NMClient *client, info = g_slice_new (ActivateDeviceInfo); info->add_act_fn = callback; info->user_data = user_data; + info->client = client; if (partial) hash = nm_connection_to_hash (partial); diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index eae04c5d2..bdc5ab81f 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #ifndef NM_CLIENT_H @@ -107,9 +107,10 @@ NMClient *nm_client_new (void); const GPtrArray *nm_client_get_devices (NMClient *client); NMDevice *nm_client_get_device_by_path (NMClient *client, const char *object_path); -typedef void (*NMClientActivateDeviceFn) (gpointer user_data, +typedef void (*NMClientActivateDeviceFn) (NMClient *client, const char *object_path, - GError *error); + GError *error, + gpointer user_data); void nm_client_activate_connection (NMClient *client, const char *connection_path, @@ -118,10 +119,11 @@ void nm_client_activate_connection (NMClient *client, NMClientActivateDeviceFn callback, gpointer user_data); -typedef void (*NMClientAddActivateFn) (gpointer user_data, +typedef void (*NMClientAddActivateFn) (NMClient *client, const char *connection_path, const char *active_path, - GError *error); + GError *error, + gpointer user_data); void nm_client_add_and_activate_connection (NMClient *client, NMConnection *partial, From 53766ae2915197bc2b511d7930c8838c106d2007 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 13:28:52 -0600 Subject: [PATCH 146/264] core: move generic connection complete function to a generic location Out of NMDevice specific places to the utils code, so it can be used more easily from everywhere. There's nothing device-specific about it anyway. --- src/NetworkManagerUtils.c | 118 ++++++++++++++++++++++++++++++ src/NetworkManagerUtils.h | 6 ++ src/modem-manager/nm-modem-cdma.c | 10 +-- src/modem-manager/nm-modem-gsm.c | 10 +-- src/nm-device-bt.c | 10 +-- src/nm-device-ethernet.c | 10 +-- src/nm-device-olpc-mesh.c | 10 +-- src/nm-device-private.h | 6 -- src/nm-device-wifi.c | 10 +-- src/nm-device.c | 115 ----------------------------- src/wimax/nm-device-wimax.c | 10 +-- 11 files changed, 159 insertions(+), 156 deletions(-) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 0f6788971..ee8c61f37 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -36,6 +36,9 @@ #include "nm-dbus-manager.h" #include "nm-dispatcher-action.h" #include "nm-dbus-glib-types.h" +#include "nm-setting-connection.h" +#include "nm-setting-ip4-config.h" +#include "nm-setting-ip6-config.h" #include #include @@ -708,3 +711,118 @@ nm_utils_get_proc_sys_net_value (const char *path, return success; } +static char * +get_new_connection_name (const GSList *existing, + const char *format, + const char *preferred) +{ + GSList *names = NULL; + const GSList *iter; + char *cname = NULL; + int i = 0; + gboolean preferred_found = FALSE; + + for (iter = existing; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + NMSettingConnection *s_con; + const char *id; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION)); + id = nm_setting_connection_get_id (s_con); + g_assert (id); + names = g_slist_append (names, (gpointer) id); + + if (preferred && !preferred_found && (strcmp (preferred, id) == 0)) + preferred_found = TRUE; + } + + /* Return the preferred name if it was unique */ + if (preferred && !preferred_found) { + g_slist_free (names); + return g_strdup (preferred); + } + + /* Otherwise find the next available unique connection name using the given + * connection name template. + */ + while (!cname && (i++ < 10000)) { + char *temp; + gboolean found = FALSE; + + temp = g_strdup_printf (format, i); + for (iter = names; iter; iter = g_slist_next (iter)) { + if (!strcmp (iter->data, temp)) { + found = TRUE; + break; + } + } + if (!found) + cname = temp; + else + g_free (temp); + } + + g_slist_free (names); + return cname; +} + +void +nm_utils_complete_generic (NMConnection *connection, + const char *ctype, + const GSList *existing, + const char *format, + const char *preferred) +{ + NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + const char *method; + char *id, *uuid; + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (!s_con) { + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + } + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL); + + if (!nm_setting_connection_get_uuid (s_con)) { + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, uuid, NULL); + g_free (uuid); + } + + /* Add a connection ID if absent */ + if (!nm_setting_connection_get_id (s_con)) { + id = get_new_connection_name (existing, format, preferred); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL); + g_free (id); + } + + /* Add an 'auto' IPv4 connection if present */ + s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + if (!s_ip4) { + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + } + method = nm_setting_ip4_config_get_method (s_ip4); + if (!method) { + g_object_set (G_OBJECT (s_ip4), + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + } + + s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (!s_ip6) { + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + } + method = nm_setting_ip6_config_get_method (s_ip6); + if (!method) { + g_object_set (G_OBJECT (s_ip6), + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, + NULL); + } +} + diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 72c0e532b..1edd87746 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -78,4 +78,10 @@ gboolean nm_utils_get_proc_sys_net_value (const char *path, const char *iface, guint32 *out_value); +void nm_utils_complete_generic (NMConnection *connection, + const char *ctype, + const GSList *existing, + const char *format, + const char *preferred); + #endif /* NETWORK_MANAGER_UTILS_H */ diff --git a/src/modem-manager/nm-modem-cdma.c b/src/modem-manager/nm-modem-cdma.c index 63b2d66fd..7000c5de8 100644 --- a/src/modem-manager/nm-modem-cdma.c +++ b/src/modem-manager/nm-modem-cdma.c @@ -305,11 +305,11 @@ real_complete_connection (NMModem *modem, nm_connection_add_setting (connection, NM_SETTING (s_ppp)); } - nm_device_complete_generic (connection, - NM_SETTING_CDMA_SETTING_NAME, - existing_connections, - _("CDMA connection %d"), - NULL); + nm_utils_complete_generic (connection, + NM_SETTING_CDMA_SETTING_NAME, + existing_connections, + _("CDMA connection %d"), + NULL); return TRUE; } diff --git a/src/modem-manager/nm-modem-gsm.c b/src/modem-manager/nm-modem-gsm.c index 4672f4cee..525aa55b0 100644 --- a/src/modem-manager/nm-modem-gsm.c +++ b/src/modem-manager/nm-modem-gsm.c @@ -508,11 +508,11 @@ real_complete_connection (NMModem *modem, nm_connection_add_setting (connection, NM_SETTING (s_ppp)); } - nm_device_complete_generic (connection, - NM_SETTING_GSM_SETTING_NAME, - existing_connections, - _("GSM connection %d"), - NULL); + nm_utils_complete_generic (connection, + NM_SETTING_GSM_SETTING_NAME, + existing_connections, + _("GSM connection %d"), + NULL); return TRUE; } diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c index f2ce78e63..8c8545b4b 100644 --- a/src/nm-device-bt.c +++ b/src/nm-device-bt.c @@ -373,11 +373,11 @@ real_complete_connection (NMDevice *device, return FALSE; } - nm_device_complete_generic (connection, - NM_SETTING_BLUETOOTH_SETTING_NAME, - existing_connections, - format, - preferred); + nm_utils_complete_generic (connection, + NM_SETTING_BLUETOOTH_SETTING_NAME, + existing_connections, + format, + preferred); setting_bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); if (setting_bdaddr) { diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 90137b49a..c318f0869 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1647,11 +1647,11 @@ real_complete_connection (NMDevice *device, /* Default to an ethernet-only connection, but if a PPPoE setting was given * then PPPoE should be our connection type. */ - nm_device_complete_generic (connection, - s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_CONNECTION_SETTING_NAME, - existing_connections, - s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"), - NULL); + nm_utils_complete_generic (connection, + s_pppoe ? NM_SETTING_PPPOE_SETTING_NAME : NM_SETTING_CONNECTION_SETTING_NAME, + existing_connections, + s_pppoe ? _("PPPoE connection %d") : _("Wired connection %d"), + NULL); s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); if (!s_wired) { diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index f9d0eb446..36b056e8f 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -416,11 +416,11 @@ real_complete_connection (NMDevice *device, } - nm_device_complete_generic (connection, - NM_SETTING_OLPC_MESH_SETTING_NAME, - existing_connections, - _("Mesh %d"), - NULL); + nm_utils_complete_generic (connection, + NM_SETTING_OLPC_MESH_SETTING_NAME, + existing_connections, + _("Mesh %d"), + NULL); return TRUE; } diff --git a/src/nm-device-private.h b/src/nm-device-private.h index 82f429fc6..a7d238b10 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -46,10 +46,4 @@ gboolean nm_device_get_firmware_missing (NMDevice *self); void nm_device_set_firmware_missing (NMDevice *self, gboolean missing); -void nm_device_complete_generic (NMConnection *connection, - const char *ctype, - const GSList *existing, - const char *format, - const char *preferred); - #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 9f821be8c..c19557b00 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -1462,11 +1462,11 @@ real_complete_connection (NMDevice *device, str_ssid = nm_utils_ssid_to_utf8 ((const char *) ssid, ssid->len); format = g_strdup_printf ("%s %%d", str_ssid); - nm_device_complete_generic (connection, - NM_SETTING_WIRELESS_SETTING_NAME, - existing_connections, - format, - str_ssid); + nm_utils_complete_generic (connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + format, + str_ssid); g_free (str_ssid); g_free (format); diff --git a/src/nm-device.c b/src/nm-device.c index c3e5c75b5..2fae4adaa 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -604,121 +604,6 @@ nm_device_complete_connection (NMDevice *self, return success; } -static char * -nm_device_new_connection_name (const GSList *existing, - const char *format, - const char *preferred) -{ - GSList *names = NULL; - const GSList *iter; - char *cname = NULL; - int i = 0; - gboolean preferred_found = FALSE; - - for (iter = existing; iter; iter = g_slist_next (iter)) { - NMConnection *candidate = NM_CONNECTION (iter->data); - NMSettingConnection *s_con; - const char *id; - - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION)); - id = nm_setting_connection_get_id (s_con); - g_assert (id); - names = g_slist_append (names, (gpointer) id); - - if (preferred && !preferred_found && (strcmp (preferred, id) == 0)) - preferred_found = TRUE; - } - - /* Return the preferred name if it was unique */ - if (preferred && !preferred_found) { - g_slist_free (names); - return g_strdup (preferred); - } - - /* Otherwise find the next available unique connection name using the given - * connection name template. - */ - while (!cname && (i++ < 10000)) { - char *temp; - gboolean found = FALSE; - - temp = g_strdup_printf (format, i); - for (iter = names; iter; iter = g_slist_next (iter)) { - if (!strcmp (iter->data, temp)) { - found = TRUE; - break; - } - } - if (!found) - cname = temp; - else - g_free (temp); - } - - g_slist_free (names); - return cname; -} - -void -nm_device_complete_generic (NMConnection *connection, - const char *ctype, - const GSList *existing, - const char *format, - const char *preferred) -{ - NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; - NMSettingIP6Config *s_ip6; - const char *method; - char *id, *uuid; - - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); - if (!s_con) { - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - } - g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_TYPE, ctype, NULL); - - if (!nm_setting_connection_get_uuid (s_con)) { - uuid = nm_utils_uuid_generate (); - g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_UUID, uuid, NULL); - g_free (uuid); - } - - /* Add a connection ID if absent */ - if (!nm_setting_connection_get_id (s_con)) { - id = nm_device_new_connection_name (existing, format, preferred); - g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_ID, id, NULL); - g_free (id); - } - - /* Add an 'auto' IPv4 connection if present */ - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (!s_ip4) { - s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - } - method = nm_setting_ip4_config_get_method (s_ip4); - if (!method) { - g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); - } - - s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (!s_ip6) { - s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - } - method = nm_setting_ip6_config_get_method (s_ip6); - if (!method) { - g_object_set (G_OBJECT (s_ip6), - NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_MAY_FAIL, TRUE, - NULL); - } -} - static void dnsmasq_state_changed_cb (NMDnsMasqManager *manager, guint32 status, gpointer user_data) { diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index ad57458ba..4b35a1cf4 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -559,11 +559,11 @@ real_complete_connection (NMDevice *device, g_assert (nsp_name); format = g_strdup_printf ("%s %%d", nsp_name); - nm_device_complete_generic (connection, - NM_SETTING_WIMAX_SETTING_NAME, - existing_connections, - format, - nsp_name); + nm_utils_complete_generic (connection, + NM_SETTING_WIMAX_SETTING_NAME, + existing_connections, + format, + nsp_name); g_free (format); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); From bba24a0e00b9b4cb9f182333aeb737db4f688a7a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 13:30:30 -0600 Subject: [PATCH 147/264] core: allow minimal completion of VPN connections for AddAndActivate We can at least fill in the connection setting if we're just given the VPN setting. --- po/POTFILES.in | 3 ++- src/nm-manager.c | 62 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 94bb473ed..65008b27f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -12,7 +12,6 @@ libnm-util/crypto_gnutls.c libnm-util/crypto_nss.c libnm-util/nm-utils.c policy/org.freedesktop.NetworkManager.policy.in -src/nm-netlink-monitor.c src/main.c src/dhcp-manager/nm-dhcp-dhclient.c src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -24,6 +23,8 @@ src/modem-manager/nm-modem-gsm.c src/nm-device-bt.c src/nm-device-ethernet.c src/nm-device-olpc-mesh.c +src/nm-manager.c +src/nm-netlink-monitor.c src/settings/nm-default-wired-connection.c system-settings/plugins/ifcfg-rh/reader.c system-settings/plugins/ifnet/connection_parser.c diff --git a/src/nm-manager.c b/src/nm-manager.c index c75b89332..1fbaa03f0 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "nm-glib-compat.h" #include "nm-manager.h" @@ -59,6 +60,7 @@ #include "nm-sysconfig-connection.h" #include "nm-manager-auth.h" #include "nm-agent-manager.h" +#include "NetworkManagerUtils.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" #define NM_AUTOIP_DBUS_IFACE "org.freedesktop.nm_avahi_autoipd" @@ -292,6 +294,7 @@ typedef enum { NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, + NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, } NMManagerError; #define NM_MANAGER_ERROR (nm_manager_error_quark ()) @@ -332,6 +335,8 @@ nm_manager_error_get_type (void) ENUM_ENTRY (NM_MANAGER_ERROR_ALREADY_ASLEEP_OR_AWAKE, "AlreadyAsleepOrAwake"), /* The manager is already in the requested enabled/disabled state */ ENUM_ENTRY (NM_MANAGER_ERROR_ALREADY_ENABLED_OR_DISABLED, "AlreadyEnabledOrDisabled"), + /* The requested operation is unsupported for this type of connection */ + ENUM_ENTRY (NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, "UnsupportedConnectionType"), { 0, 0, 0 }, }; etype = g_enum_register_static ("NMManagerError", values); @@ -650,6 +655,45 @@ nm_manager_get_state (NMManager *manager) return NM_MANAGER_GET_PRIVATE (manager)->state; } +static gboolean +might_be_vpn (NMConnection *connection) +{ + NMSettingConnection *s_con; + const char *ctype = NULL; + + if (nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN)) + return TRUE; + + /* Make sure it's not a VPN, which we can't autocomplete yet */ + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (s_con) + ctype = nm_setting_connection_get_connection_type (s_con); + + return (g_strcmp0 (ctype, NM_SETTING_VPN_SETTING_NAME) == 0); +} + +static gboolean +try_complete_vpn (NMConnection *connection, GSList *existing, GError **error) +{ + g_assert (might_be_vpn (connection) == TRUE); + + if (!nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN)) { + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNSUPPORTED_CONNECTION_TYPE, + "VPN connections require a 'vpn' setting"); + return FALSE; + } + + nm_utils_complete_generic (connection, + NM_SETTING_VPN_SETTING_NAME, + existing, + _("VPN connection %d"), + NULL); + + return TRUE; +} + static PendingActivation * pending_activation_new (NMManager *manager, PolkitAuthority *authority, @@ -688,13 +732,19 @@ pending_activation_new (NMManager *manager, connection = nm_connection_new (); nm_connection_replace_settings (connection, settings, NULL); - /* Let each device subclass complete the connection */ all_connections = nm_settings_get_connections (priv->settings); - success = nm_device_complete_connection (device, - connection, - specific_object_path, - all_connections, - error); + + if (might_be_vpn (connection)) { + /* Try to fill the VPN's connection setting and name at least */ + success = try_complete_vpn (connection, all_connections, error); + } else { + /* Let each device subclass complete the connection */ + success = nm_device_complete_connection (device, + connection, + specific_object_path, + all_connections, + error); + } g_slist_free (all_connections); if (success == FALSE) { From a3d4688431cdefa8f128a5e90cd8b57652a18408 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 13:42:01 -0600 Subject: [PATCH 148/264] libnm-glib: add NM_SECRET_AGENT_ERROR_INTERNAL_ERROR --- libnm-glib/nm-secret-agent.c | 2 ++ libnm-glib/nm-secret-agent.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index f10a2584b..4e6f56f8e 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -114,6 +114,8 @@ nm_secret_agent_error_get_type (void) ENUM_ENTRY (NM_SECRET_AGENT_ERROR_USER_CANCELED, "UserCanceled"), /* The request was canceled, but not by the user */ ENUM_ENTRY (NM_SECRET_AGENT_ERROR_AGENT_CANCELED, "AgentCanceled"), + /* Some internal error prevented returning secrets */ + ENUM_ENTRY (NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, "InternalError"), { 0, 0, 0 } }; etype = g_enum_register_static ("NMSecretAgentError", values); diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index b9f0fd727..8d3497aac 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -37,7 +37,8 @@ typedef enum { NM_SECRET_AGENT_ERROR_NOT_AUTHORIZED = 0, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, NM_SECRET_AGENT_ERROR_USER_CANCELED, - NM_SECRET_AGENT_ERROR_AGENT_CANCELED + NM_SECRET_AGENT_ERROR_AGENT_CANCELED, + NM_SECRET_AGENT_ERROR_INTERNAL_ERROR } NMSecretAgentError; From 7779a3f1516fd1cce230462354bab275867d9cc1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 13:43:26 -0600 Subject: [PATCH 149/264] libnm-glib: add NM_SECRET_AGENT_ERROR_NO_SECRETS --- libnm-glib/nm-secret-agent.c | 2 ++ libnm-glib/nm-secret-agent.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 4e6f56f8e..07a36cdc3 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -116,6 +116,8 @@ nm_secret_agent_error_get_type (void) ENUM_ENTRY (NM_SECRET_AGENT_ERROR_AGENT_CANCELED, "AgentCanceled"), /* Some internal error prevented returning secrets */ ENUM_ENTRY (NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, "InternalError"), + /* No secrets could be found to fulfill the request */ + ENUM_ENTRY (NM_SECRET_AGENT_ERROR_NO_SECRETS, "NoSecrets"), { 0, 0, 0 } }; etype = g_enum_register_static ("NMSecretAgentError", values); diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index 8d3497aac..e8a417e0c 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -38,7 +38,8 @@ typedef enum { NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, NM_SECRET_AGENT_ERROR_USER_CANCELED, NM_SECRET_AGENT_ERROR_AGENT_CANCELED, - NM_SECRET_AGENT_ERROR_INTERNAL_ERROR + NM_SECRET_AGENT_ERROR_INTERNAL_ERROR, + NM_SECRET_AGENT_ERROR_NO_SECRETS, } NMSecretAgentError; From acd16ceeede7ef3ffe5718b94082bd94d6d3761d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 14:08:36 -0600 Subject: [PATCH 150/264] api: fix argument direction for SecretAgent API calls --- introspection/nm-secret-agent.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/introspection/nm-secret-agent.xml b/introspection/nm-secret-agent.xml index bfab5852c..ec1ac687b 100644 --- a/introspection/nm-secret-agent.xml +++ b/introspection/nm-secret-agent.xml @@ -15,7 +15,7 @@ - + Nested settings maps containing the connection for which secrets are being requested. @@ -65,7 +65,7 @@ - + Nested settings maps containing the entire connection (including secrets), for which the agent should save the @@ -86,7 +86,7 @@ - + Nested settings maps containing the entire connection (including secrets), for which the agent should delete the From 24915553fdee563b5ae9c00bc2cbd16bf648fcf1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 14:18:03 -0600 Subject: [PATCH 151/264] libnm-glib: keep symbol visibility list alphabetized --- libnm-glib/libnm-glib.ver | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 6a6cea4c2..57435825a 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -92,6 +92,17 @@ global: nm_device_wifi_get_mode; nm_device_wifi_get_type; nm_device_wifi_new; + nm_device_wimax_get_bsid; + nm_device_wimax_get_center_frequency; + nm_device_wimax_get_cinr; + nm_device_wimax_get_hw_address; + nm_device_wimax_get_active_nsp; + nm_device_wimax_get_nsp_by_path; + nm_device_wimax_get_nsps; + nm_device_wimax_get_rssi; + nm_device_wimax_get_tx_power; + nm_device_wimax_get_type; + nm_device_wimax_new; nm_dhcp4_config_get_one_option; nm_dhcp4_config_get_options; nm_dhcp4_config_get_type; @@ -149,17 +160,6 @@ global: nm_vpn_connection_get_type; nm_vpn_connection_get_vpn_state; nm_vpn_connection_new; - nm_device_wimax_get_bsid; - nm_device_wimax_get_center_frequency; - nm_device_wimax_get_cinr; - nm_device_wimax_get_hw_address; - nm_device_wimax_get_active_nsp; - nm_device_wimax_get_nsp_by_path; - nm_device_wimax_get_nsps; - nm_device_wimax_get_rssi; - nm_device_wimax_get_tx_power; - nm_device_wimax_get_type; - nm_device_wimax_new; nm_wimax_nsp_get_name; nm_wimax_nsp_get_network_type; nm_wimax_nsp_get_signal_quality; From 61cc2494adb4405dfb6d0ecff5ba06270074cf02 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 14:18:29 -0600 Subject: [PATCH 152/264] libnm-glib: add helper functions and callbacks to Secret Agent API First, remove anything dbus-glib related from the public API and use callbacks to handle returning secrets requested by D-Bus. Second, add helper functions so local code can use the same API to request secrets. --- libnm-glib/libnm-glib.ver | 7 +++ libnm-glib/nm-secret-agent.c | 112 +++++++++++++++++++++++++++++++++++ libnm-glib/nm-secret-agent.h | 55 ++++++++++++++--- 3 files changed, 165 insertions(+), 9 deletions(-) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 57435825a..bafa0bd3a 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -146,6 +146,13 @@ global: nm_remote_settings_save_hostname; nm_remote_settings_get_type; nm_remote_settings_new; + nm_secret_agent_delete_secrets; + nm_secret_agent_get_secrets; + nm_secret_agent_get_type; + nm_secret_agent_new; + nm_secret_agent_register; + nm_secret_agent_save_secrets; + nm_secret_agent_unregister; nm_serial_device_get_bytes_received; nm_serial_device_get_bytes_sent; nm_serial_device_get_type; diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 07a36cdc3..5308759d0 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -262,6 +262,21 @@ out: return connection; } +static void +get_secrets_cb (NMSecretAgent *self, + NMConnection *connection, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context, secrets); +} + static void impl_secret_agent_get_secrets (NMSecretAgent *self, GHashTable *connection_hash, @@ -288,10 +303,25 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, setting_name, hints, request_new, + get_secrets_cb, context); g_object_unref (connection); } +static void +save_secrets_cb (NMSecretAgent *self, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + static void impl_secret_agent_save_secrets (NMSecretAgent *self, GHashTable *connection_hash, @@ -312,10 +342,25 @@ impl_secret_agent_save_secrets (NMSecretAgent *self, NM_SECRET_AGENT_GET_CLASS (self)->save_secrets (self, connection, connection_path, + save_secrets_cb, context); g_object_unref (connection); } +static void +delete_secrets_cb (NMSecretAgent *self, + NMConnection *connection, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = user_data; + + if (error) + dbus_g_method_return_error (context, error); + else + dbus_g_method_return (context); +} + static void impl_secret_agent_delete_secrets (NMSecretAgent *self, GHashTable *connection_hash, @@ -336,6 +381,7 @@ impl_secret_agent_delete_secrets (NMSecretAgent *self, NM_SECRET_AGENT_GET_CLASS (self)->delete_secrets (self, connection, connection_path, + delete_secrets_cb, context); g_object_unref (connection); } @@ -444,6 +490,72 @@ nm_secret_agent_unregister (NMSecretAgent *self) return TRUE; } +void +nm_secret_agent_get_secrets (NMSecretAgent *self, + NMConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + NMSecretAgentGetSecretsFunc callback, + gpointer callback_data) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SECRET_AGENT (self)); + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (connection)); + g_return_if_fail (setting_name != NULL); + g_return_if_fail (strlen (setting_name) > 0); + g_return_if_fail (callback != NULL); + + NM_SECRET_AGENT_GET_CLASS (self)->get_secrets (self, + connection, + nm_connection_get_path (connection), + setting_name, + hints, + request_new, + callback, + callback_data); +} + +void +nm_secret_agent_save_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentSaveSecretsFunc callback, + gpointer callback_data) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SECRET_AGENT (self)); + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (connection)); + + NM_SECRET_AGENT_GET_CLASS (self)->save_secrets (self, + connection, + nm_connection_get_path (connection), + callback, + callback_data); +} + +void +nm_secret_agent_delete_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentDeleteSecretsFunc callback, + gpointer callback_data) +{ + g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SECRET_AGENT (self)); + g_return_if_fail (connection != NULL); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (nm_connection_get_path (connection)); + + NM_SECRET_AGENT_GET_CLASS (self)->delete_secrets (self, + connection, + nm_connection_get_path (connection), + callback, + callback_data); +} + /**************************************************************/ static gboolean diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index e8a417e0c..98c90114d 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -21,8 +21,6 @@ #ifndef NM_SECRET_AGENT_H #define NM_SECRET_AGENT_H -#include -#include #include G_BEGIN_DECLS @@ -58,6 +56,22 @@ typedef struct { GObject parent; } NMSecretAgent; +typedef void (*NMSecretAgentGetSecretsFunc) (NMSecretAgent *agent, + NMConnection *connection, + GHashTable *secrets, + GError *error, + gpointer user_data); + +typedef void (*NMSecretAgentSaveSecretsFunc) (NMSecretAgent *agent, + NMConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMSecretAgentDeleteSecretsFunc) (NMSecretAgent *agent, + NMConnection *connection, + GError *error, + gpointer user_data); + typedef struct { GObjectClass parent; @@ -65,8 +79,8 @@ typedef struct { /* Called when the subclass should retrieve and return secrets. Subclass * must copy or reference any arguments it may require after returning from - * this method, as the arguments will freed (except for 'agent' and - * 'context' of course). + * this method, as the arguments will freed (except for 'agent', 'callback', + * and 'callback_data' of course). */ void (*get_secrets) (NMSecretAgent *agent, NMConnection *connection, @@ -74,27 +88,32 @@ typedef struct { const char *setting_name, const char **hints, gboolean request_new, - DBusGMethodInvocation *context); + NMSecretAgentGetSecretsFunc callback, + gpointer callback_data); /* Called when the subclass should save the secrets contained in the * connection to backing storage. Subclass must copy or reference any * arguments it may require after returning from this method, as the - * arguments will freed (except for 'agent' and 'context' of course). + * arguments will freed (except for 'agent', 'callback', and 'callback_data' + * of course). */ void (*save_secrets) (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, - DBusGMethodInvocation *context); + NMSecretAgentSaveSecretsFunc callback, + gpointer callback_data); /* Called when the subclass should delete the secrets contained in the * connection from backing storage. Subclass must copy or reference any * arguments it may require after returning from this method, as the - * arguments will freed (except for 'agent' and 'context' of course). + * arguments will freed (except for 'agent', 'callback', and 'callback_data' + * of course). */ void (*delete_secrets) (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, - DBusGMethodInvocation *context); + NMSecretAgentDeleteSecretsFunc callback, + gpointer callback_data); /* Signals */ void (*registration_result) (NMSecretAgent *agent, GError *error); @@ -116,6 +135,24 @@ gboolean nm_secret_agent_register (NMSecretAgent *self); gboolean nm_secret_agent_unregister (NMSecretAgent *self); +void nm_secret_agent_get_secrets (NMSecretAgent *self, + NMConnection *connection, + const char *setting_name, + const char **hints, + gboolean request_new, + NMSecretAgentGetSecretsFunc callback, + gpointer callback_data); + +void nm_secret_agent_save_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentSaveSecretsFunc callback, + gpointer callback_data); + +void nm_secret_agent_delete_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentDeleteSecretsFunc callback, + gpointer callback_data); + G_END_DECLS #endif /* NM_SECRET_AGENT_H */ From bb35e0a9e2daf48b9c2d6e74ec8ef771b567677a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 13 Jan 2011 17:29:54 -0600 Subject: [PATCH 153/264] libnm-glib: make a few forgotten functions visible Oops. --- libnm-glib/libnm-glib.ver | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index bafa0bd3a..c31dc798d 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -27,6 +27,7 @@ global: nm_cdma_device_get_type; nm_cdma_device_new; nm_client_activate_connection; + nm_client_add_and_activate_connection; nm_client_deactivate_connection; nm_client_get_active_connections; nm_client_get_device_by_path; @@ -147,6 +148,7 @@ global: nm_remote_settings_get_type; nm_remote_settings_new; nm_secret_agent_delete_secrets; + nm_secret_agent_error_quark; nm_secret_agent_get_secrets; nm_secret_agent_get_type; nm_secret_agent_new; From 3e8547ff1b3e030c4b337b4148937829dbfe9772 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 17 Jan 2011 23:11:51 -0600 Subject: [PATCH 154/264] ifcfg-rh: fix crash on ignored file change Don't crash when a file we don't care about changes. --- system-settings/plugins/ifcfg-rh/plugin.c | 34 +++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 24a4d115d..f99348df9 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -343,24 +343,24 @@ dir_changed (GFileMonitor *monitor, /* Given any ifcfg, keys, or routes file, get the ifcfg file path */ name = utils_get_ifcfg_path (path); g_free (path); - - connection = g_hash_table_lookup (priv->connections, name); - switch (event_type) { - case G_FILE_MONITOR_EVENT_DELETED: - PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name); - if (connection) - remove_connection (plugin, connection); - break; - case G_FILE_MONITOR_EVENT_CREATED: - case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - /* Update or new */ - connection_new_or_changed (plugin, name, connection); - break; - default: - break; + if (name) { + connection = g_hash_table_lookup (priv->connections, name); + switch (event_type) { + case G_FILE_MONITOR_EVENT_DELETED: + PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "removed %s.", name); + if (connection) + remove_connection (plugin, connection); + break; + case G_FILE_MONITOR_EVENT_CREATED: + case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: + /* Update or new */ + connection_new_or_changed (plugin, name, connection); + break; + default: + break; + } + g_free (name); } - - g_free (name); } static void From e041fabcfddea83966d677f81954bfb602a87aa1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 17 Jan 2011 23:12:24 -0600 Subject: [PATCH 155/264] ifcfg-rh: don't try to parse non-ifcfg files at startup --- system-settings/plugins/ifcfg-rh/plugin.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index f99348df9..b718574a1 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -181,7 +181,8 @@ read_connections (SCPluginIfcfg *plugin) continue; full_path = g_build_filename (IFCFG_DIR, item, NULL); - _internal_new_connection (plugin, full_path, NULL, NULL); + if (utils_get_ifcfg_name (full_path, TRUE)) + _internal_new_connection (plugin, full_path, NULL, NULL); g_free (full_path); } From 7fa1a62cd351a3e50bdc49788c560b6f76164c3c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 17 Jan 2011 23:19:25 -0600 Subject: [PATCH 156/264] libnm-glib: don't crash when adding new connections that aren't waited upon If we're not waiting for this connection to show up after an AddConnection operation, we don't need to touch anything addinfo-related. --- libnm-glib/nm-remote-settings.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 3369860e8..e4b0bc55b 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -155,6 +155,8 @@ add_connection_info_complete (NMRemoteSettings *self, AddConnectionInfo *info, GError *error) { + g_return_if_fail (info != NULL); + info->callback (info->self, error ? NULL : info->connection, error, info->callback_data); add_connection_info_dispose (self, info); } @@ -242,7 +244,8 @@ connection_init_result_cb (NMRemoteConnection *remote, /* If there's a pending AddConnection request, complete that here before * signaling new-connection. */ - add_connection_info_complete (self, addinfo, NULL); + if (addinfo) + add_connection_info_complete (self, addinfo, NULL); /* Finally, let users know of the new connection now that it has all * its settings and is valid. From a2f36e8bd4afd52c3fa3831b7f843633fc08f8fa Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 13:19:29 -0600 Subject: [PATCH 157/264] agent: add CancelGetSecrets D-Bus API Allows NM to signal to an agent that an in-progress secrets request is no longer needed. This could happen if the device for which the request was started was removed, disabled, or the network being connected to changed, or whatever. --- introspection/nm-secret-agent.xml | 21 +++++ src/nm-agent-manager.c | 27 ++---- src/nm-secret-agent.c | 148 +++++++++++++++++++++++------- src/nm-secret-agent.h | 14 ++- 4 files changed, 155 insertions(+), 55 deletions(-) diff --git a/introspection/nm-secret-agent.xml b/introspection/nm-secret-agent.xml index ec1ac687b..9ac6950fa 100644 --- a/introspection/nm-secret-agent.xml +++ b/introspection/nm-secret-agent.xml @@ -59,6 +59,27 @@ + + + Cancel a pending GetSecrets request for secrets of the given + connection. Any matching request should be canceled. + + + + + + Object path of the connection for which, if secrets are being + requested, the request should be canceled. + + + + + Setting name for which secrets for this connection were + originally being requested. + + + + Save given secrets to backing storage. diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 3b6262110..ddefc877b 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -336,7 +336,7 @@ struct _Request { /* Current agent being asked for secrets */ NMSecretAgent *current; - gpointer current_call_id; + gconstpointer current_call_id; /* Stores the sorted list of NMSecretAgents which will be * asked for secrets. @@ -462,25 +462,21 @@ merge_secrets (GHashTable *src, GHashTable *dest) } static void -request_secrets_done_cb (DBusGProxy *proxy, - DBusGProxyCall *call_id, - void *user_data) +request_secrets_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) { Request *req = user_data; - GError *error = NULL; - GHashTable *secrets = NULL; - GHashTable *setting_secrets; - NMSecretAgent *agent = NM_SECRET_AGENT (req->current); + GHashTable *setting_secrets, *merged; - if (call_id != req->current_call_id) - return; + g_return_if_fail (call_id == req->current_call_id); req->current = NULL; req->current_call_id = NULL; - if (!dbus_g_proxy_end_call (proxy, call_id, &error, - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, - G_TYPE_INVALID)) { + if (error) { nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s", nm_secret_agent_get_description (agent), req, req->setting_name, @@ -498,7 +494,6 @@ request_secrets_done_cb (DBusGProxy *proxy, nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s", nm_secret_agent_get_description (agent), req, req->setting_name); - g_hash_table_destroy (secrets); /* Try the next agent */ request_next (req); @@ -513,8 +508,6 @@ request_secrets_done_cb (DBusGProxy *proxy, * with the ones from the secret agent. */ if (req->settings_secrets) { - GHashTable *merged; - merged = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_unref); /* Copy agent secrets first, then overwrite with settings secrets */ @@ -525,8 +518,6 @@ request_secrets_done_cb (DBusGProxy *proxy, g_hash_table_destroy (merged); } else req->complete_callback (req, secrets, NULL, req->complete_callback_data); - - g_hash_table_destroy (secrets); } static void diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c index 7951c5065..e1755d26a 100644 --- a/src/nm-secret-agent.c +++ b/src/nm-secret-agent.c @@ -45,10 +45,49 @@ typedef struct { NMDBusManager *dbus_mgr; DBusGProxy *proxy; + + GHashTable *requests; } NMSecretAgentPrivate; /*************************************************************/ +typedef struct { + NMSecretAgent *agent; + DBusGProxyCall *call; + char *path; + char *setting_name; + NMSecretAgentCallback callback; + gpointer callback_data; +} Request; + +static Request * +request_new (NMSecretAgent *agent, + const char *path, + const char *setting_name, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + Request *r; + + r = g_slice_new0 (Request); + r->agent = agent; + r->path = g_strdup (path); + r->setting_name = g_strdup (setting_name); + r->callback = callback; + r->callback_data = callback_data; + return r; +} + +static void +request_free (Request *r) +{ + g_free (r->path); + g_free (r->setting_name); + g_slice_free (Request, r); +} + +/*************************************************************/ + const char * nm_secret_agent_get_description (NMSecretAgent *agent) { @@ -106,19 +145,41 @@ nm_secret_agent_get_hash (NMSecretAgent *agent) /*************************************************************/ -gpointer +static void +secrets_callback (DBusGProxy *proxy, + DBusGProxyCall *call, + void *user_data) +{ + Request *r = user_data; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); + GError *error = NULL; + GHashTable *secrets = NULL; + + g_return_if_fail (call == r->call); + + dbus_g_proxy_end_call (proxy, call, &error, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, + G_TYPE_INVALID); + r->callback (r->agent, r, secrets, error, r->callback_data); + if (secrets) + g_hash_table_unref (secrets); + g_clear_error (&error); + g_hash_table_remove (priv->requests, call); +} + +gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *self, NMConnection *connection, const char *setting_name, const char *hint, - gboolean request_new, - DBusGProxyCallNotify done_callback, - gpointer done_callback_data) + gboolean get_new, + NMSecretAgentCallback callback, + gpointer callback_data) { NMSecretAgentPrivate *priv; - DBusGProxyCall *call; GHashTable *hash; const char *hints[2] = { hint, NULL }; + Request *r; g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); @@ -127,29 +188,46 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, priv = NM_SECRET_AGENT_GET_PRIVATE (self); hash = nm_connection_to_hash (connection); - call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, - "GetSecrets", - done_callback, - done_callback_data, - NULL, - 120000, /* 120 seconds */ - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, - DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), - G_TYPE_STRING, setting_name, - G_TYPE_STRV, hints, - G_TYPE_BOOLEAN, request_new, - G_TYPE_INVALID); - g_hash_table_destroy (hash); - return call; + r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); + r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "GetSecrets", + secrets_callback, + r, + NULL, + 120000, /* 120 seconds */ + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), + G_TYPE_STRING, setting_name, + G_TYPE_STRV, hints, + G_TYPE_BOOLEAN, get_new, + G_TYPE_INVALID); + g_hash_table_insert (priv->requests, r->call, r); + + g_hash_table_destroy (hash); + return r->call; } void -nm_secret_agent_cancel_secrets (NMSecretAgent *self, gpointer call_id) +nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call) { - g_return_if_fail (self != NULL); + NMSecretAgentPrivate *priv; + Request *r; - dbus_g_proxy_cancel_call (NM_SECRET_AGENT_GET_PRIVATE (self)->proxy, call_id); + g_return_if_fail (self != NULL); + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + r = g_hash_table_lookup (priv->requests, call); + g_return_if_fail (r != NULL); + + dbus_g_proxy_cancel_call (NM_SECRET_AGENT_GET_PRIVATE (self)->proxy, (gpointer) call); + + dbus_g_proxy_call_no_reply (priv->proxy, + "CancelGetSecrets", + G_TYPE_STRING, r->path, + G_TYPE_STRING, r->setting_name, + G_TYPE_INVALID); + g_hash_table_remove (priv->requests, call); } /*************************************************************/ @@ -162,15 +240,14 @@ nm_secret_agent_new (NMDBusManager *dbus_mgr, { NMSecretAgent *self; NMSecretAgentPrivate *priv; + DBusGConnection *bus; + char *hash_str; g_return_val_if_fail (owner != NULL, NULL); g_return_val_if_fail (identifier != NULL, NULL); self = (NMSecretAgent *) g_object_new (NM_TYPE_SECRET_AGENT, NULL); if (self) { - DBusGConnection *bus; - char *hash_str; - priv = NM_SECRET_AGENT_GET_PRIVATE (self); priv->owner = g_strdup (owner); @@ -196,6 +273,10 @@ nm_secret_agent_new (NMDBusManager *dbus_mgr, static void nm_secret_agent_init (NMSecretAgent *self) { + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->requests = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) request_free); } static void @@ -203,16 +284,17 @@ dispose (GObject *object) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object); - if (priv->disposed) - return; - priv->disposed = TRUE; + if (!priv->disposed) { + priv->disposed = TRUE; - g_free (priv->description); - g_free (priv->owner); - g_free (priv->identifier); + g_free (priv->description); + g_free (priv->owner); + g_free (priv->identifier); - g_object_unref (priv->proxy); - g_object_unref (priv->dbus_mgr); + g_hash_table_destroy (priv->requests); + g_object_unref (priv->proxy); + g_object_unref (priv->dbus_mgr); + } G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); } diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h index 3aebf27f9..7241ecb92 100644 --- a/src/nm-secret-agent.h +++ b/src/nm-secret-agent.h @@ -61,15 +61,21 @@ uid_t nm_secret_agent_get_owner_uid (NMSecretAgent *agent); guint32 nm_secret_agent_get_hash (NMSecretAgent *agent); -gpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, +typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent, + gconstpointer call, + GHashTable *secrets, + GError *error, + gpointer user_data); + +gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, NMConnection *connection, const char *setting_name, const char *hint, gboolean request_new, - DBusGProxyCallNotify done_callback, - gpointer done_callback_data); + NMSecretAgentCallback callback, + gpointer callback_data); void nm_secret_agent_cancel_secrets (NMSecretAgent *agent, - gpointer call_id); + gconstpointer call_id); #endif /* NM_SECRET_AGENT_H */ From 30c7308e9d9f6db72023ecc6ccb8ea964fb563d9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 13:20:34 -0600 Subject: [PATCH 158/264] libnm-glib: implement agent secrets request cancelation --- libnm-glib/nm-secret-agent.c | 73 ++++++++++++++++++++++++------------ libnm-glib/nm-secret-agent.h | 13 ++++++- 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index 5308759d0..d1c8b4498 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -36,6 +36,11 @@ static void impl_secret_agent_get_secrets (NMSecretAgent *self, gboolean request_new, DBusGMethodInvocation *context); +static void impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, + const char *connection_path, + const char *setting_name, + DBusGMethodInvocation *context); + static void impl_secret_agent_save_secrets (NMSecretAgent *self, GHashTable *connection_hash, const char *connection_path, @@ -166,10 +171,12 @@ name_owner_changed (DBusGProxy *proxy, } } -static NMConnection * +static gboolean verify_request (NMSecretAgent *self, DBusGMethodInvocation *context, GHashTable *connection_hash, + const char *connection_path, + NMConnection **out_connection, GError **error) { NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); @@ -181,8 +188,7 @@ verify_request (NMSecretAgent *self, uid_t sender_uid = G_MAXUINT; GError *local = NULL; - g_return_val_if_fail (context != NULL, NULL); - g_return_val_if_fail (connection_hash != NULL, NULL); + g_return_val_if_fail (context != NULL, FALSE); /* Verify the sender's UID is 0, and that the sender is the same as * NetworkManager's bus name owner. @@ -245,21 +251,27 @@ verify_request (NMSecretAgent *self, } /* And make sure the connection is actually valid */ - connection = nm_connection_new_from_hash (connection_hash, &local); - if (!connection) { - g_set_error (error, - NM_SECRET_AGENT_ERROR, - NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, - "Invalid connection: (%d) %s", - local ? local->code : -1, - (local && local->message) ? local->message : "(unknown)"); - g_clear_error (&local); + if (connection_hash) { + connection = nm_connection_new_from_hash (connection_hash, &local); + if (connection && connection_path) { + nm_connection_set_path (connection, connection_path); + } else { + g_set_error (error, + NM_SECRET_AGENT_ERROR, + NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, + "Invalid connection: (%d) %s", + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); + g_clear_error (&local); + } } - out: + if (out_connection) + *out_connection = connection; g_free (sender); - return connection; + + return !!connection; } static void @@ -287,11 +299,10 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, DBusGMethodInvocation *context) { GError *error = NULL; - NMConnection *connection; + NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - connection = verify_request (self, context, connection_hash, &error); - if (!connection) { + if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); return; @@ -308,6 +319,24 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, g_object_unref (connection); } +static void +impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, + const char *connection_path, + const char *setting_name, + DBusGMethodInvocation *context) +{ + GError *error = NULL; + + /* Make sure the request comes from NetworkManager and is valid */ + if (!verify_request (self, context, NULL, NULL, NULL, &error)) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + } else { + NM_SECRET_AGENT_GET_CLASS (self)->cancel_get_secrets (self, connection_path, setting_name); + dbus_g_method_return (context); + } +} + static void save_secrets_cb (NMSecretAgent *self, NMConnection *connection, @@ -329,11 +358,10 @@ impl_secret_agent_save_secrets (NMSecretAgent *self, DBusGMethodInvocation *context) { GError *error = NULL; - NMConnection *connection; + NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - connection = verify_request (self, context, connection_hash, &error); - if (!connection) { + if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); return; @@ -368,11 +396,10 @@ impl_secret_agent_delete_secrets (NMSecretAgent *self, DBusGMethodInvocation *context) { GError *error = NULL; - NMConnection *connection; + NMConnection *connection = NULL; /* Make sure the request comes from NetworkManager and is valid */ - connection = verify_request (self, context, connection_hash, &error); - if (!connection) { + if (!verify_request (self, context, connection_hash, connection_path, &connection, &error)) { dbus_g_method_return_error (context, error); g_clear_error (&error); return; diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index 98c90114d..f62ebacd0 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -15,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 Red Hat, Inc. + * (C) Copyright 2010 - 2011 Red Hat, Inc. */ #ifndef NM_SECRET_AGENT_H @@ -80,7 +80,9 @@ typedef struct { /* Called when the subclass should retrieve and return secrets. Subclass * must copy or reference any arguments it may require after returning from * this method, as the arguments will freed (except for 'agent', 'callback', - * and 'callback_data' of course). + * and 'callback_data' of course). If the request is canceled, the callback + * should still be called, but with the NM_SECRET_AGENT_ERROR_AGENT_CANCELED + * error. */ void (*get_secrets) (NMSecretAgent *agent, NMConnection *connection, @@ -91,6 +93,13 @@ typedef struct { NMSecretAgentGetSecretsFunc callback, gpointer callback_data); + /* Called when the subclass should cancel an outstanding request to + * get secrets for a given connection. + */ + void (*cancel_get_secrets) (NMSecretAgent *agent, + const char *connection_path, + const char *setting_name); + /* Called when the subclass should save the secrets contained in the * connection to backing storage. Subclass must copy or reference any * arguments it may require after returning from this method, as the From cc88e4e51c0a6aa6d6bf40caef14a53e3a2b0396 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 13:21:02 -0600 Subject: [PATCH 159/264] trivial: fix a few small issues in the NMSecretAgent class --- libnm-glib/nm-secret-agent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index d1c8b4498..c5b80dc72 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -754,7 +754,7 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) "Identifier", "Identifier", NULL, - G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); /** * NMSecretAgent::registration-result: @@ -765,7 +765,7 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) * request was successful. **/ signals[REGISTRATION_RESULT] = - g_signal_new (REGISTRATION_RESULT, + g_signal_new (NM_SECRET_AGENT_REGISTRATION_RESULT, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, From 519b1ea61d279db09dd914962dafbce5931ca6ed Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 13:22:00 -0600 Subject: [PATCH 160/264] keyfile: namespace commonly-named functions (bgo #639537) Now that keyfile is built in, we may have symbol naming conflicts with the other plugins where code was copied & pasted around. Fix that by namespacing common function names in the keyfile plugin. Thanks to Giovanni Campagna for pinpointing the issue. --- .../plugins/keyfile/nm-keyfile-connection.c | 2 +- system-settings/plugins/keyfile/reader.c | 2 +- system-settings/plugins/keyfile/reader.h | 2 +- .../plugins/keyfile/tests/test-keyfile.c | 26 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index d19b709d9..5368464ef 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -56,7 +56,7 @@ nm_keyfile_connection_new (const char *full_path, if (source) tmp = g_object_ref (source); else { - tmp = connection_from_file (full_path, error); + tmp = nm_keyfile_plugin_connection_from_file (full_path, error); if (!tmp) return NULL; } diff --git a/system-settings/plugins/keyfile/reader.c b/system-settings/plugins/keyfile/reader.c index 841315d9c..9533e906a 100644 --- a/system-settings/plugins/keyfile/reader.c +++ b/system-settings/plugins/keyfile/reader.c @@ -1054,7 +1054,7 @@ read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn) } NMConnection * -connection_from_file (const char *filename, GError **error) +nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) { GKeyFile *key_file; struct stat statbuf; diff --git a/system-settings/plugins/keyfile/reader.h b/system-settings/plugins/keyfile/reader.h index 357271549..55819630e 100644 --- a/system-settings/plugins/keyfile/reader.h +++ b/system-settings/plugins/keyfile/reader.h @@ -25,6 +25,6 @@ #include #include -NMConnection *connection_from_file (const char *filename, GError **error); +NMConnection *nm_keyfile_plugin_connection_from_file (const char *filename, GError **error); #endif /* _KEYFILE_PLUGIN_READER_H */ diff --git a/system-settings/plugins/keyfile/tests/test-keyfile.c b/system-settings/plugins/keyfile/tests/test-keyfile.c index 05131c8fe..213d3e87f 100644 --- a/system-settings/plugins/keyfile/tests/test-keyfile.c +++ b/system-settings/plugins/keyfile/tests/test-keyfile.c @@ -83,7 +83,7 @@ test_read_valid_wired_connection (void) NMIP6Address *ip6_addr; NMIP6Route *ip6_route; - connection = connection_from_file (TEST_WIRED_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_WIRED_FILE); @@ -702,7 +702,7 @@ test_write_wired_connection (void) "connection-write", "didn't get keyfile name back after writing connection"); /* Read the connection back in and compare it to the one we just wrote out */ - reread = connection_from_file (testfile, NULL); + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, @@ -735,7 +735,7 @@ test_read_ip6_wired_connection (void) const char *expected6_gw1 = "abcd:1234:ffff::cdd1"; NMIP6Address *ip6_addr; - connection = connection_from_file (TEST_WIRED_IP6_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_IP6_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_WIRED_IP6_FILE); @@ -962,7 +962,7 @@ test_write_ip6_wired_connection (void) "connection-write", "didn't get keyfile name back after writing connection"); /* Read the connection back in and compare it to the one we just wrote out */ - reread = connection_from_file (testfile, NULL); + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, @@ -991,7 +991,7 @@ test_read_wired_mac_case (void) const char *expected_id = "Test Wired Connection MAC Case"; const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; - connection = connection_from_file (TEST_WIRED_MAC_CASE_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_MAC_CASE_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_WIRED_MAC_CASE_FILE); @@ -1077,7 +1077,7 @@ test_read_valid_wireless_connection (void) const guint64 expected_timestamp = 1226604314; guint64 timestamp; - connection = connection_from_file (TEST_WIRELESS_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_WIRELESS_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_WIRELESS_FILE); @@ -1280,7 +1280,7 @@ test_write_wireless_connection (void) "connection-write", "didn't get keyfile name back after writing connection"); /* Read the connection back in and compare it to the one we just wrote out */ - reread = connection_from_file (testfile, NULL); + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, @@ -1305,7 +1305,7 @@ test_read_string_ssid (void) const GByteArray *array; const char *expected_ssid = "blah blah ssid 1234"; - connection = connection_from_file (TEST_STRING_SSID_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_STRING_SSID_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_STRING_SSID_FILE); @@ -1423,7 +1423,7 @@ test_write_string_ssid (void) g_key_file_free (keyfile); /* Read the connection back in and compare it to the one we just wrote out */ - reread = connection_from_file (testfile, NULL); + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, @@ -1458,7 +1458,7 @@ test_read_bt_dun_connection (void) const char *expected_username = "ISP@CINGULARGPRS.COM"; const char *expected_password = "CINGULAR1"; - connection = connection_from_file (TEST_BT_DUN_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_BT_DUN_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_BT_DUN_FILE); @@ -1708,7 +1708,7 @@ test_write_bt_dun_connection (void) "connection-write", "didn't get keyfile name back after writing connection"); /* Read the connection back in and compare it to the one we just wrote out */ - reread = connection_from_file (testfile, NULL); + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, @@ -1742,7 +1742,7 @@ test_read_gsm_connection (void) const char *expected_network_id = "24005"; const char *expected_pin = "2345"; - connection = connection_from_file (TEST_GSM_FILE, NULL); + connection = nm_keyfile_plugin_connection_from_file (TEST_GSM_FILE, NULL); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_GSM_FILE); @@ -1970,7 +1970,7 @@ test_write_gsm_connection (void) "connection-write", "didn't get keyfile name back after writing connection"); /* Read the connection back in and compare it to the one we just wrote out */ - reread = connection_from_file (testfile, NULL); + reread = nm_keyfile_plugin_connection_from_file (testfile, NULL); ASSERT (reread != NULL, "connection-write", "failed to re-read test connection"); ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, From 9cf13cc3e11499c4b760a3ba1bfddabea62206dc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 14:17:18 -0600 Subject: [PATCH 161/264] agent: request_new -> flags Use some flags to modify GetSecrets behavior instead of just the request_new boolean. --- introspection/nm-secret-agent.xml | 30 +++++++++++++++++++++++++++++- libnm-glib/nm-secret-agent.c | 12 ++++++------ libnm-glib/nm-secret-agent.h | 9 +++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/introspection/nm-secret-agent.xml b/introspection/nm-secret-agent.xml index 9ac6950fa..655b2b72f 100644 --- a/introspection/nm-secret-agent.xml +++ b/introspection/nm-secret-agent.xml @@ -41,8 +41,9 @@ in this request. - + + Flags which modify the behavior of the secrets request. If true, new secrets are assumed to be invalid or incorrect, and the agent should ask the user for new secrets. If false, existing secrets should be retrieved from storage and @@ -59,6 +60,33 @@ + + + Flags modifying the behavior of GetSecrets request. + + + + No special behavior; by default no user interaction is allowed and + requests for secrets are fulfilled from persistent storage, or + if no secrets are available an error is returned. + + + + + Allows the request to interact with the user, possibly prompting + via UI for secrets if any are required, or if none are found in + persistent storage. + + + + + Explicitly prompt for new secrets from the user. This flag + signals that NetworkManager thinks any existing secrets are + invalid or wrong. This flag implies that interaction is allowed. + + + + Cancel a pending GetSecrets request for secrets of the given diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index c5b80dc72..cfe13dae8 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -15,7 +15,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2010 Red Hat, Inc. + * (C) Copyright 2010 - 2011 Red Hat, Inc. */ #include @@ -33,7 +33,7 @@ static void impl_secret_agent_get_secrets (NMSecretAgent *self, const char *connection_path, const char *setting_name, const char **hints, - gboolean request_new, + guint32 flags, DBusGMethodInvocation *context); static void impl_secret_agent_cancel_get_secrets (NMSecretAgent *self, @@ -295,7 +295,7 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, const char *connection_path, const char *setting_name, const char **hints, - gboolean request_new, + guint32 flags, DBusGMethodInvocation *context) { GError *error = NULL; @@ -313,7 +313,7 @@ impl_secret_agent_get_secrets (NMSecretAgent *self, connection_path, setting_name, hints, - request_new, + flags, get_secrets_cb, context); g_object_unref (connection); @@ -522,7 +522,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, NMConnection *connection, const char *setting_name, const char **hints, - gboolean request_new, + guint32 flags, NMSecretAgentGetSecretsFunc callback, gpointer callback_data) { @@ -540,7 +540,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, nm_connection_get_path (connection), setting_name, hints, - request_new, + flags, callback, callback_data); } diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index f62ebacd0..6fb470577 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -40,6 +40,11 @@ typedef enum { NM_SECRET_AGENT_ERROR_NO_SECRETS, } NMSecretAgentError; +enum { + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2 +}; #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) @@ -89,7 +94,7 @@ typedef struct { const char *connection_path, const char *setting_name, const char **hints, - gboolean request_new, + guint32 flags, NMSecretAgentGetSecretsFunc callback, gpointer callback_data); @@ -148,7 +153,7 @@ void nm_secret_agent_get_secrets (NMSecretAgent *self, NMConnection *connection, const char *setting_name, const char **hints, - gboolean request_new, + guint32 flags, NMSecretAgentGetSecretsFunc callback, gpointer callback_data); From 68ab26143bdf89f52332c268ef912aa7d9e269bb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 14:57:44 -0600 Subject: [PATCH 162/264] core: use GetSecrets flags everywhere --- src/modem-manager/nm-modem.c | 11 +++++++++-- src/nm-activation-request.c | 4 ++-- src/nm-activation-request.h | 2 +- src/nm-agent-manager.c | 16 ++++++++-------- src/nm-agent-manager.h | 4 ++-- src/nm-device-ethernet.c | 10 ++++++---- src/nm-device-wifi.c | 10 ++++++---- src/nm-secret-agent.c | 4 ++-- src/nm-secret-agent.h | 13 +++++++++++-- src/ppp-manager/nm-ppp-manager.c | 14 +++++++++----- src/vpn-manager/nm-vpn-connection.c | 2 +- 11 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 1e8d7941d..30817f932 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -516,13 +516,16 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); + if (request_new) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, NULL, setting_name, - request_new, + flags, hint, modem_secrets_cb, self); @@ -552,6 +555,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; + guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (priv->act_request) g_object_unref (priv->act_request); @@ -563,10 +567,13 @@ nm_modem_act_stage1_prepare (NMModem *self, &setting_name, reason); if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) { + if (priv->secrets_tries++) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + priv->secrets_id = nm_act_request_get_secrets (req, NULL, setting_name, - priv->secrets_tries++ ? TRUE : FALSE, + flags, hints ? g_ptr_array_index (hints, 0) : NULL, modem_secrets_cb, self); diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index dbc65b4d4..4192b9d8a 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -114,7 +114,7 @@ guint32 nm_act_request_get_secrets (NMActRequest *self, NMConnection *connection, const char *setting_name, - gboolean request_new, + guint32 flags, const char *hint, NMActRequestSecretsFunc callback, gpointer callback_data) @@ -137,7 +137,7 @@ nm_act_request_get_secrets (NMActRequest *self, call_id = nm_agent_manager_get_secrets (priv->agent_mgr, connection ? connection : priv->connection, setting_name, - request_new, + flags, hint, get_secrets_cb, self, diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index 172ebf39a..f7a3addd7 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -95,7 +95,7 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, guint32 nm_act_request_get_secrets (NMActRequest *req, NMConnection *connection, /* NULL == use activation request's connection */ const char *setting_name, - gboolean request_new, + guint32 flags, const char *hint, NMActRequestSecretsFunc callback, gpointer callback_data); diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index ddefc877b..7355a2ffc 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. */ #include @@ -331,7 +331,7 @@ struct _Request { NMConnection *connection; char *setting_name; - gboolean request_new; + guint32 flags; char *hint; /* Current agent being asked for secrets */ @@ -365,7 +365,7 @@ struct _Request { static Request * request_new (NMConnection *connection, const char *setting_name, - gboolean get_new, + guint32 flags, const char *hint, NMAgentSecretsResultFunc callback, gpointer callback_data, @@ -381,7 +381,7 @@ request_new (NMConnection *connection, req->reqid = next_id++; req->connection = g_object_ref (connection); req->setting_name = g_strdup (setting_name); - req->request_new = get_new; + req->flags = flags; req->hint = g_strdup (hint); req->callback = callback; req->callback_data = callback_data; @@ -547,7 +547,7 @@ request_next (Request *req) req->connection, req->setting_name, req->hint, - req->request_new, + req->flags, request_secrets_done_cb, req); if (req->current_call_id == NULL) { @@ -570,7 +570,7 @@ request_start_secrets (gpointer user_data) secrets = nm_sysconfig_connection_get_secrets (NM_SYSCONFIG_CONNECTION (req->connection), req->setting_name, req->hint, - req->request_new, + req->flags ? TRUE : FALSE, &error); if (secrets) setting_secrets = g_hash_table_lookup (secrets, req->setting_name); @@ -773,7 +773,7 @@ guint32 nm_agent_manager_get_secrets (NMAgentManager *self, NMConnection *connection, const char *setting_name, - gboolean get_new, + guint32 flags, const char *hint, NMAgentSecretsResultFunc callback, gpointer callback_data, @@ -797,7 +797,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, req = request_new (connection, setting_name, - get_new, + flags, hint, callback, callback_data, diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h index 4ddd6165d..0e22af3e5 100644 --- a/src/nm-agent-manager.h +++ b/src/nm-agent-manager.h @@ -27,7 +27,7 @@ #include #include "nm-dbus-manager.h" -#include "nm-session-monitor.h" +#include "nm-secret-agent.h" #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) #define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) @@ -59,7 +59,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, NMConnection *connection, const char *setting_name, - gboolean get_new, + guint32 flags, const char *hint, NMAgentSecretsResultFunc callback, gpointer callback_data, diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index c318f0869..159a66ad2 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1023,7 +1023,7 @@ link_timeout_cb (gpointer user_data) nm_act_request_get_secrets (req, NULL, setting_name, - TRUE, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wired_secrets_cb, self); @@ -1204,16 +1204,18 @@ handle_auth_or_fail (NMDeviceEthernet *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - gboolean get_new; + guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; /* If the caller doesn't necessarily want completely new secrets, * only ask for new secrets after the first failure. */ - get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); + if (new_secrets || tries) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + nm_act_request_get_secrets (req, NULL, setting_name, - get_new, + flags, NULL, wired_secrets_cb, self); diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index c19557b00..a07efc868 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2488,7 +2488,7 @@ link_timeout_cb (gpointer user_data) nm_act_request_get_secrets (req, NULL, setting_name, - TRUE, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wifi_secrets_cb, self); @@ -2726,16 +2726,18 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - gboolean get_new; + guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; /* If the caller doesn't necessarily want completely new secrets, * only ask for new secrets after the first failure. */ - get_new = new_secrets ? TRUE : (tries ? TRUE : FALSE); + if (new_secrets || tries) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + nm_act_request_get_secrets (req, NULL, setting_name, - get_new, + flags, NULL, wifi_secrets_cb, self); diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c index e1755d26a..d65f5f369 100644 --- a/src/nm-secret-agent.c +++ b/src/nm-secret-agent.c @@ -172,7 +172,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, NMConnection *connection, const char *setting_name, const char *hint, - gboolean get_new, + guint32 flags, NMSecretAgentCallback callback, gpointer callback_data) { @@ -200,7 +200,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), G_TYPE_STRING, setting_name, G_TYPE_STRV, hints, - G_TYPE_BOOLEAN, get_new, + G_TYPE_UINT, flags, G_TYPE_INVALID); g_hash_table_insert (priv->requests, r->call, r); diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h index 7241ecb92..bb86835e3 100644 --- a/src/nm-secret-agent.h +++ b/src/nm-secret-agent.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. */ #ifndef NM_SECRET_AGENT_H @@ -29,6 +29,15 @@ #include #include "nm-dbus-manager.h" +/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in + * the nm-secret-agent.xml introspection file. + */ +enum { + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, + NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2 +}; + #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) #define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) @@ -71,7 +80,7 @@ gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, NMConnection *connection, const char *setting_name, const char *hint, - gboolean request_new, + guint32 flags, NMSecretAgentCallback callback, gpointer callback_data); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 369466825..35db28e6e 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -442,6 +442,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, guint32 tries; GPtrArray *hints = NULL; GError *error = NULL; + guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; connection = nm_act_request_get_connection (priv->act_req); @@ -461,15 +462,18 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, return; } - tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); - /* Only ask for completely new secrets after retrying them once; some PPP - * servers (T-Mobile USA) appear to ask a few times when they actually don't - * even care what you pass back. + /* Only ask for completely new secrets after retrying them once; some devices + * appear to ask a few times when they actually don't even care what you + * pass back. */ + tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); + if (tries > 1) + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + priv->secrets_id = nm_act_request_get_secrets (priv->act_req, NULL, setting_name, - tries > 1 ? TRUE : FALSE, + flags, hints ? g_ptr_array_index (hints, 0) : NULL, ppp_secrets_cb, manager); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index e835aa692..bc1f3dbfe 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -839,7 +839,7 @@ connection_need_secrets_cb (DBusGProxy *proxy, priv->secrets_id = nm_act_request_get_secrets (priv->act_request, priv->connection, setting_name, - FALSE, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, NULL, vpn_secrets_cb, self); From 223c00fdee5c0b0d7df09fb25aae67141598b827 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 18 Jan 2011 20:40:58 -0600 Subject: [PATCH 163/264] core: don't require connection path for AddAndActivate There is no path yet since we haven't added the connection yet. --- src/nm-manager.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 1fbaa03f0..2247b3557 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -716,7 +716,6 @@ pending_activation_new (NMManager *manager, g_return_val_if_fail (authority != NULL, NULL); g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (device_path != NULL, NULL); - g_return_val_if_fail (connection_path != NULL, NULL); /* Create the partial connection from the given settings */ if (settings) { From 85409427beac38ac0c8586dc37d422c3b3a8d7b6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 19 Jan 2011 16:58:26 -0600 Subject: [PATCH 164/264] agent: add some debug logging --- src/nm-agent-manager.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 7355a2ffc..8d40044f8 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -567,6 +567,9 @@ request_start_secrets (gpointer user_data) req->idle_id = 0; + nm_log_dbg (LOGD_AGENTS, "(%p/%s) getting secrets from system settings", + req, req->setting_name); + secrets = nm_sysconfig_connection_get_secrets (NM_SYSCONFIG_CONNECTION (req->connection), req->setting_name, req->hint, @@ -593,9 +596,15 @@ request_start_secrets (gpointer user_data) /* Do we have everything we need? */ /* FIXME: handle second check for VPN connections */ if (nm_connection_need_secrets (tmp, NULL) == NULL) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets sufficient", + req, req->setting_name); + /* Got everything, we're done */ req->complete_callback (req, secrets, NULL, req->complete_callback_data); } else { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", + req, req->setting_name); + /* We don't, so ask some agents for additional secrets */ req->settings_secrets = g_hash_table_ref (secrets); request_next (req); @@ -603,6 +612,9 @@ request_start_secrets (gpointer user_data) } g_object_unref (tmp); } else if (error) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings returned error: (%d) %s", + req, req->setting_name, error->code, error->message); + /* Errors from the system settings are hard errors; we don't go on * to ask agents for secrets if the settings service failed. */ From 7ddf9c5e724527c49435f5242cb603301521b746 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 19 Jan 2011 16:59:01 -0600 Subject: [PATCH 165/264] libnm-glib: implement NMSecretAgent autoregistration Handles registering with NM and re-registering if NM restarts. --- libnm-glib/libnm-glib.ver | 1 - libnm-glib/nm-secret-agent.c | 86 ++++++++++++++++++++++++++++++++++-- libnm-glib/nm-secret-agent.h | 3 +- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index c31dc798d..e64569596 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -151,7 +151,6 @@ global: nm_secret_agent_error_quark; nm_secret_agent_get_secrets; nm_secret_agent_get_type; - nm_secret_agent_new; nm_secret_agent_register; nm_secret_agent_save_secrets; nm_secret_agent_unregister; diff --git a/libnm-glib/nm-secret-agent.c b/libnm-glib/nm-secret-agent.c index cfe13dae8..72431e2da 100644 --- a/libnm-glib/nm-secret-agent.c +++ b/libnm-glib/nm-secret-agent.c @@ -53,12 +53,14 @@ static void impl_secret_agent_delete_secrets (NMSecretAgent *self, #include "nm-secret-agent-glue.h" -G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) +G_DEFINE_ABSTRACT_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) #define NM_SECRET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_SECRET_AGENT, \ NMSecretAgentPrivate)) +static gboolean auto_register_cb (gpointer user_data); + typedef struct { gboolean registered; @@ -70,6 +72,9 @@ typedef struct { char *nm_owner; char *identifier; + gboolean auto_register; + gboolean suppress_auto; + gboolean auto_register_id; gboolean disposed; } NMSecretAgentPrivate; @@ -77,6 +82,7 @@ typedef struct { enum { PROP_0, PROP_IDENTIFIER, + PROP_AUTO_REGISTER, LAST_PROP }; @@ -155,6 +161,17 @@ get_nm_owner (NMSecretAgent *self) return priv->nm_owner; } +static void +_internal_unregister (NMSecretAgent *self) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + if (priv->registered) { + dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self)); + priv->registered = FALSE; + } +} + static void name_owner_changed (DBusGProxy *proxy, const char *name, @@ -164,10 +181,24 @@ name_owner_changed (DBusGProxy *proxy, { NMSecretAgent *self = NM_SECRET_AGENT (user_data); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + gboolean old_owner_good = (old_owner && strlen (old_owner)); + gboolean new_owner_good = (new_owner && strlen (new_owner)); if (strcmp (name, NM_DBUS_SERVICE) == 0) { g_free (priv->nm_owner); priv->nm_owner = g_strdup (new_owner); + + if (!old_owner_good && new_owner_good) { + /* NM appeared */ + auto_register_cb (self); + } else if (old_owner_good && !new_owner_good) { + /* NM disappeared */ + _internal_unregister (self); + } else if (old_owner_good && new_owner_good && strcmp (old_owner, new_owner)) { + /* Hmm, NM magically restarted */ + _internal_unregister (self); + auto_register_cb (self); + } } } @@ -430,7 +461,7 @@ reg_request_cb (DBusGProxy *proxy, priv->registered = TRUE; else { /* If registration failed we shouldn't expose ourselves on the bus */ - dbus_g_connection_unregister_g_object (priv->bus, G_OBJECT (self)); + _internal_unregister (self); } g_signal_emit (self, signals[REGISTRATION_RESULT], 0, error); @@ -472,6 +503,8 @@ nm_secret_agent_register (NMSecretAgent *self) g_return_val_if_fail (class->save_secrets != NULL, FALSE); g_return_val_if_fail (class->delete_secrets != NULL, FALSE); + priv->suppress_auto = FALSE; + /* Export our secret agent interface before registering with the manager */ dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SECRET_AGENT, @@ -482,7 +515,7 @@ nm_secret_agent_register (NMSecretAgent *self) reg_request_cb, self, NULL, - G_USEC_PER_SEC * 5, + 5000, G_TYPE_STRING, priv->identifier, G_TYPE_INVALID); @@ -514,9 +547,26 @@ nm_secret_agent_unregister (NMSecretAgent *self) dbus_g_proxy_call_no_reply (priv->manager_proxy, "Unregister", G_TYPE_INVALID); + _internal_unregister (self); + priv->suppress_auto = TRUE; + return TRUE; } +static gboolean +auto_register_cb (gpointer user_data) +{ + NMSecretAgent *self = NM_SECRET_AGENT (user_data); + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + priv->auto_register_id = 0; + if (priv->auto_register && !priv->suppress_auto && (priv->reg_call == NULL)) + nm_secret_agent_register (self); + return FALSE; +} + +/**************************************************************/ + void nm_secret_agent_get_secrets (NMSecretAgent *self, NMConnection *connection, @@ -653,6 +703,8 @@ nm_secret_agent_init (NMSecretAgent *self) g_warning ("Couldn't create NM agent manager proxy."); return; } + + priv->auto_register_id = g_idle_add (auto_register_cb, self); } static void @@ -667,6 +719,9 @@ get_property (GObject *object, case PROP_IDENTIFIER: g_value_set_string (value, priv->identifier); break; + case PROP_AUTO_REGISTER: + g_value_set_boolean (value, priv->auto_register); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -691,6 +746,9 @@ set_property (GObject *object, g_free (priv->identifier); priv->identifier = g_strdup (identifier); break; + case PROP_AUTO_REGISTER: + priv->auto_register = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -709,6 +767,9 @@ dispose (GObject *object) if (priv->registered) nm_secret_agent_unregister (self); + if (priv->auto_register_id) + g_source_remove (priv->auto_register_id); + g_free (priv->identifier); g_free (priv->nm_owner); @@ -756,6 +817,25 @@ nm_secret_agent_class_init (NMSecretAgentClass *class) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** + * NMSecretAgent:auto-register: + * + * If TRUE, the agent will attempt to automatically register itself after + * it is created (via an idle handler) and to re-register itself if + * NetworkManager restarts. If FALSE, the agent does not automatically + * register with NetworkManager, and nm_secret_agent_register() must be + * called. If 'auto-register' is TRUE, calling nm_secret_agent_unregister() + * will suppress auto-registration until nm_secret_agent_register() is + * called, which re-enables auto-registration. + **/ + g_object_class_install_property + (object_class, PROP_AUTO_REGISTER, + g_param_spec_boolean (NM_SECRET_AGENT_AUTO_REGISTER, + "Auto Register", + "Auto Register", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + /** * NMSecretAgent::registration-result: * @agent: the agent that received the signal diff --git a/libnm-glib/nm-secret-agent.h b/libnm-glib/nm-secret-agent.h index 6fb470577..60354d563 100644 --- a/libnm-glib/nm-secret-agent.h +++ b/libnm-glib/nm-secret-agent.h @@ -54,6 +54,7 @@ enum { #define NM_SECRET_AGENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) #define NM_SECRET_AGENT_IDENTIFIER "identifier" +#define NM_SECRET_AGENT_AUTO_REGISTER "auto-register" #define NM_SECRET_AGENT_REGISTRATION_RESULT "registration-result" @@ -143,8 +144,6 @@ typedef struct { GType nm_secret_agent_get_type (void); -NMSecretAgent *nm_secret_agent_new (const char *identifier); - gboolean nm_secret_agent_register (NMSecretAgent *self); gboolean nm_secret_agent_unregister (NMSecretAgent *self); From 8ff556be3cc3c4ff740efa1ec8c95e5d10c182c9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 19 Jan 2011 17:16:21 -0600 Subject: [PATCH 166/264] agent: fix current agent removal if agent goes away The current agent isn't in the 'pending' list, so don't check the list for the agent and bail if it's not found since that won't handle the current agent going away. --- src/nm-agent-manager.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 8d40044f8..2e88ee201 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -712,9 +712,6 @@ request_remove_agent (Request *req, NMSecretAgent *agent) g_return_if_fail (req != NULL); g_return_if_fail (agent != NULL); - if (!g_slist_find (req->pending, agent)) - return; - /* If this agent is being asked right now, cancel the request */ if (agent == req->current) { nm_secret_agent_cancel_secrets (req->current, req->current_call_id); From ec55e32ee6a92937d51d3de476b02f856bc7a27b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 19 Jan 2011 17:17:41 -0600 Subject: [PATCH 167/264] agent: pass the right call-id in the secrets callback --- src/nm-secret-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c index d65f5f369..f347ffeb5 100644 --- a/src/nm-secret-agent.c +++ b/src/nm-secret-agent.c @@ -160,7 +160,7 @@ secrets_callback (DBusGProxy *proxy, dbus_g_proxy_end_call (proxy, call, &error, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, G_TYPE_INVALID); - r->callback (r->agent, r, secrets, error, r->callback_data); + r->callback (r->agent, r->call, secrets, error, r->callback_data); if (secrets) g_hash_table_unref (secrets); g_clear_error (&error); From 5dd4f1ea018b64ba7a91ff2ec024ddc9f8f809fc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 19 Jan 2011 18:17:40 -0600 Subject: [PATCH 168/264] libnm-util: fix possible crash in nm_setting_update_secrets() If a pointer to a valid GError was not passed the function could crash. Make it simpler and fix the possible crash by just converting to hash table iters instead. --- libnm-util/nm-setting.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 190199c12..980a65b96 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -483,11 +483,6 @@ nm_setting_need_secrets (NMSetting *setting) return secrets; } -typedef struct { - NMSetting *setting; - GError **error; -} UpdateSecretsInfo; - static gboolean update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) { @@ -528,17 +523,6 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** return success; } -static void -update_one_cb (gpointer key, gpointer val, gpointer user_data) -{ - UpdateSecretsInfo *info = user_data; - const char *secret_key = (const char *) key; - GValue *secret_value = (GValue *) val; - - if (*(info->error) == NULL) - NM_SETTING_GET_CLASS (info->setting)->update_one_secret (info->setting, secret_key, secret_value, info->error); -} - /** * nm_setting_update_secrets: * @setting: the #NMSetting @@ -555,8 +539,9 @@ update_one_cb (gpointer key, gpointer val, gpointer user_data) gboolean nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error) { - UpdateSecretsInfo *info; - gboolean success; + GHashTableIter iter; + gpointer key, data; + GError *tmp_error = NULL; g_return_val_if_fail (setting != NULL, FALSE); g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); @@ -564,14 +549,16 @@ nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **err if (error) g_return_val_if_fail (*error == NULL, FALSE); - info = g_malloc0 (sizeof (UpdateSecretsInfo)); - info->setting = setting; - info->error = error; - g_hash_table_foreach (secrets, update_one_cb, info); - success = *(info->error) ? FALSE : TRUE; - g_free (info); + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, &key, &data) && !tmp_error) { + const char *secret_key = (const char *) key; + GValue *secret_value = (GValue *) data; - return success; + NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error); + } + g_propagate_error (error, tmp_error); + + return !!tmp_error; } /** From c6bfe8edb60cdc44375ab80fa4c3d309d71691cc Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 21 Jan 2011 14:15:38 -0600 Subject: [PATCH 169/264] libnm-glib: update symbol visibility list --- libnm-glib/libnm-glib.ver | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index e64569596..dc9d85479 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -141,13 +141,16 @@ global: nm_remote_connection_get_type; nm_remote_connection_new; nm_remote_settings_add_connection; + nm_remote_settings_error_get_type; + nm_remote_settings_error_quark; nm_remote_settings_get_connection_by_path; - nm_remote_settings_list_connections; nm_remote_settings_get_permissions; - nm_remote_settings_save_hostname; nm_remote_settings_get_type; + nm_remote_settings_list_connections; nm_remote_settings_new; + nm_remote_settings_save_hostname; nm_secret_agent_delete_secrets; + nm_secret_agent_error_get_type; nm_secret_agent_error_quark; nm_secret_agent_get_secrets; nm_secret_agent_get_type; @@ -157,10 +160,6 @@ global: nm_serial_device_get_bytes_received; nm_serial_device_get_bytes_sent; nm_serial_device_get_type; - nm_settings_error_quark; - nm_settings_get_type; - nm_settings_list_connections; - nm_settings_signal_new_connection; nm_ssid_get_type; nm_string_array_get_type; nm_uint_array_get_type; From 9067356856f56a949ef8af5838e3dc4acf506256 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 21 Jan 2011 14:20:38 -0600 Subject: [PATCH 170/264] core: fix policy handling of connections-loaded signal --- src/nm-policy.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 2961389b7..d31a2dd0b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1041,6 +1041,13 @@ connection_added (NMSettings *settings, schedule_activate_all ((NMPolicy *) user_data); } +static void +connections_loaded (NMSettings *settings, + gpointer user_data) +{ + schedule_activate_all ((NMPolicy *) user_data); +} + static void connection_updated (NMSettings *settings, NMConnection *connection, @@ -1162,12 +1169,14 @@ nm_policy_new (NMManager *manager, _connect_manager_signal (policy, "device-added", device_added); _connect_manager_signal (policy, "device-removed", device_removed); - _connect_settings_signal (policy, NM_SETTINGS_CONNECTIONS_LOADED, connection_added); + _connect_settings_signal (policy, NM_SETTINGS_CONNECTIONS_LOADED, connections_loaded); _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_ADDED, connection_added); _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_UPDATED, connection_updated); _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_REMOVED, connection_removed); _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, connection_visibility_changed); + + initialized = TRUE; return policy; } From 3ebecd2a295b40081321d1b3f26fb1204fe5d4c4 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Fri, 21 Jan 2011 14:46:09 -0600 Subject: [PATCH 171/264] introspection: add GObject introspection support (bgo #637032) Add the necessary annotations (the mininum required, that is those on return values. NULL parameters or container types may require more), and the Autotools stuff to get a NetworkManager GIR for libnm-util and a NMClient for libnm-glib. --- .gitignore | 2 + Makefile.am | 3 +- configure.ac | 2 + libnm-glib/Makefile.am | 58 ++++++++++++++---- libnm-glib/libnm-glib.pc.in | 2 +- libnm-glib/nm-active-connection.c | 4 +- libnm-glib/nm-client.c | 32 +++++----- libnm-glib/nm-device-wifi.c | 7 ++- libnm-glib/nm-device-wimax.c | 61 +++++++++---------- libnm-glib/nm-device.c | 10 ++-- libnm-glib/nm-dhcp4-config.c | 2 +- libnm-glib/nm-dhcp6-config.c | 2 +- libnm-glib/nm-ip4-config.c | 19 +++--- libnm-glib/nm-ip6-config.c | 23 ++++---- libnm-glib/nm-object.c | 2 +- libnm-glib/nm-remote-connection.c | 11 ++-- libnm-glib/nm-remote-settings.c | 14 +++-- libnm-glib/nm-remote-settings.h | 2 +- libnm-glib/nm-types.c | 14 ++--- libnm-util/Makefile.am | 47 ++++++++++++--- libnm-util/libnm-util.ver | 6 +- libnm-util/nm-connection.c | 26 +++++---- libnm-util/nm-setting-ip4-config.c | 2 + libnm-util/nm-setting-ip4-config.h | 4 ++ libnm-util/nm-setting-ip6-config.c | 2 + libnm-util/nm-setting-ip6-config.h | 4 ++ libnm-util/nm-setting-vpn.c | 20 ++++++- libnm-util/nm-setting-vpn.h | 8 ++- libnm-util/nm-setting.c | 8 +-- libnm-util/nm-utils.c | 28 ++++++--- m4/introspection.m4 | 94 ++++++++++++++++++++++++++++++ 31 files changed, 370 insertions(+), 149 deletions(-) create mode 100644 m4/introspection.m4 diff --git a/.gitignore b/.gitignore index b87df2330..cd8aa6a87 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ *.lo *.la *.bz2 +*.gir +*.typelib Makefile Makefile.in* configure diff --git a/Makefile.am b/Makefile.am index c3eb4e151..78924ab7d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,8 @@ DISTCHECK_CONFIGURE_FLAGS = \ --with-tests=yes \ --with-docs=yes \ --with-udev-dir=$$dc_install_base/lib/udev \ - --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) + --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) \ + --enable-wimax=no DISTCLEANFILES = intltool-extract intltool-merge intltool-update diff --git a/configure.ac b/configure.ac index a7b8b1a96..05fde82a4 100644 --- a/configure.ac +++ b/configure.ac @@ -241,6 +241,8 @@ PKG_CHECK_MODULES(GIO, gio-2.0) AC_SUBST(GIO_CFLAGS) AC_SUBST(GIO_LIBS) +GOBJECT_INTROSPECTION_CHECK([0.9.6]) + AC_ARG_WITH(udev-dir, AS_HELP_STRING([--with-udev-dir=DIR], [where the udev base directory is])) if test -n "$with_udev_dir" ; then UDEV_BASE_DIR="$with_udev_dir" diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index bedc9805b..40e43f89d 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -47,6 +47,9 @@ libdeprecated_nm_glib_la_LIBADD = \ $(DBUS_LIBS) \ $(GLIB_LIBS) +libdeprecateddir = $(includedir)/libnm-glib +libdeprecated_HEADERS = libnm_glib.h + ##################################################### # Real libnm-glib stuff ##################################################### @@ -59,9 +62,9 @@ libnm_glib_la_CFLAGS = \ $(GUDEV_CFLAGS) libnmincludedir = $(includedir)/libnm-glib +libnmvpndir = $(includedir)/libnm-glib libnminclude_HEADERS = \ - libnm_glib.h \ nm-object.h \ nm-client.h \ nm-device.h \ @@ -74,8 +77,6 @@ libnminclude_HEADERS = \ nm-cdma-device.h \ nm-serial-device.h \ nm-vpn-connection.h \ - nm-vpn-plugin.h \ - nm-vpn-plugin-ui-interface.h \ nm-types.h \ nm-active-connection.h \ nm-dhcp4-config.h \ @@ -87,14 +88,15 @@ libnminclude_HEADERS = \ nm-device-wimax.h \ nm-wimax-nsp.h -libnm_glib_la_SOURCES = \ +libnmvpn_HEADERS = \ + nm-vpn-plugin.h \ + nm-vpn-plugin-ui-interface.h + +libnm_glib_la_csources = \ nm-object.c \ - nm-object-private.h \ nm-client.c \ nm-dbus-utils.c \ - nm-dbus-utils.h \ nm-device.c \ - nm-device-private.h \ nm-device-ethernet.c \ nm-device-wifi.c \ nm-device-bt.c \ @@ -105,20 +107,29 @@ libnm_glib_la_SOURCES = \ nm-serial-device.c \ nm-vpn-connection.c \ nm-types.c \ - nm-types-private.h \ nm-object-cache.c \ - nm-object-cache.h \ nm-active-connection.c \ nm-dhcp4-config.c \ nm-ip6-config.c \ nm-dhcp6-config.c \ nm-remote-connection.c \ - nm-remote-connection-private.h \ nm-remote-settings.c \ nm-secret-agent.c \ nm-device-wimax.c \ nm-wimax-nsp.c +libnm_glib_la_private_headers = \ + nm-object-private.h \ + nm-dbus-utils.h \ + nm-device-private.h \ + nm-types-private.h \ + nm-object-cache.h \ + nm-remote-connection-private.h + +libnm_glib_la_SOURCES = \ + $(libnm_glib_la_csources) \ + $(libnm_glib_la_private_headers) + libnm_glib_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/marshallers/libmarshallers.la \ @@ -128,7 +139,7 @@ libnm_glib_la_LIBADD = \ $(GUDEV_LIBS) libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \ - -version-info "6:2:4" + -version-info "7:0:5" noinst_PROGRAMS = libnm-glib-test @@ -225,3 +236,28 @@ DISTCLEANFILES = libnm-glib.pc libnm-glib.pc EXTRA_DIST = libnm-glib.pc.in libnm-glib-vpn.pc.in libnm-glib.ver libnm-glib-vpn.ver CLEANFILES = $(BUILT_SOURCES) + +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = +INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/libnm-util + +if HAVE_INTROSPECTION +introspection_sources = $(libnminclude_HEADERS) $(libnm_glib_la_csources) + +NMClient-1.0.gir: libnm-glib.la +NMClient_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 +NMClient_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 gudev-1.0 +NMClient_1_0_gir_CFLAGS = $(INCLUDES) +NMClient_1_0_gir_LIBS = libnm-glib.la +NMClient_1_0_gir_FILES = $(introspection_sources) +NMClient_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm_ --include-uninstalled=$(top_builddir)/libnm-util/NetworkManager-1.0.gir +INTROSPECTION_GIRS += NMClient-1.0.gir + +girdir = $(datadir)/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += $(gir_DATA) $(typelib_DATA) +endif diff --git a/libnm-glib/libnm-glib.pc.in b/libnm-glib/libnm-glib.pc.in index 5c3471b16..a1010baab 100644 --- a/libnm-glib/libnm-glib.pc.in +++ b/libnm-glib/libnm-glib.pc.in @@ -6,7 +6,7 @@ includedir=@includedir@ Name: libnm-glib Description: Convenience library for clients of NetworkManager Version: @VERSION@ -Requires: NetworkManager >= 0.7.999 glib-2.0 dbus-glib-1 +Requires: NetworkManager >= 0.7.999 gobject-2.0 dbus-glib-1 Cflags: -I${includedir}/libnm-glib Libs: -L${libdir} -lnm-glib diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c index f9e8adbf1..46ca12f5c 100644 --- a/libnm-glib/nm-active-connection.c +++ b/libnm-glib/nm-active-connection.c @@ -149,7 +149,7 @@ nm_active_connection_get_specific_object (NMActiveConnection *connection) * * Gets the #NMDevices used for the active connections. * - * Returns: the #GPtrArray containing #NMDevices. + * Returns: (element-type NMClient.Device): the #GPtrArray containing #NMDevices. * This is the internal copy used by the connection, and must not be modified. **/ const GPtrArray * @@ -301,7 +301,7 @@ get_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - g_value_set_boxed (value, nm_active_connection_get_connection (self)); + g_value_set_string (value, nm_active_connection_get_connection (self)); break; case PROP_SPECIFIC_OBJECT: g_value_set_boxed (value, nm_active_connection_get_specific_object (self)); diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index ff8b999e6..cfb6a48b1 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -664,7 +664,7 @@ get_property (GObject *object, g_value_set_boolean (value, priv->manager_running); break; case PROP_NETWORKING_ENABLED: - g_value_set_boolean (value, priv->networking_enabled); + g_value_set_boolean (value, nm_client_networking_get_enabled (self)); break; case PROP_WIRELESS_ENABLED: g_value_set_boolean (value, priv->wireless_enabled); @@ -829,6 +829,7 @@ nm_client_class_init (NMClientClass *client_class) * NMClient::active-connections: * * The active connections. + * Type: GPtrArray **/ g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTIONS, @@ -843,7 +844,7 @@ nm_client_class_init (NMClientClass *client_class) /** * NMClient::device-added: * @client: the client that received the signal - * @device: the new device + * @device: (type NMClient.Device): the new device * * Notifies that a #NMDevice is added. **/ @@ -860,7 +861,7 @@ nm_client_class_init (NMClientClass *client_class) /** * NMClient::device-removed: * @widget: the client that received the signal - * @device: the removed device + * @device: (type NMClient.Device): the removed device * * Notifies that a #NMDevice is removed. **/ @@ -1012,7 +1013,7 @@ client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data) * * Gets all the detected devices. * - * Returns: a #GPtrArray containing all the #NMDevices. + * Returns: (transfer none) (element-type NMClient.Device): a #GPtrArray containing all the #NMDevices. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * @@ -1052,7 +1053,7 @@ nm_client_get_devices (NMClient *client) * * Gets a #NMDevice from a #NMClient. * - * Returns: the #NMDevice for the given @object_path or %NULL if none is found. + * Returns: (transfer none): the #NMDevice for the given @object_path or %NULL if none is found. **/ NMDevice * nm_client_get_device_by_path (NMClient *client, const char *object_path) @@ -1109,7 +1110,7 @@ activate_cb (DBusGProxy *proxy, * @device: the #NMDevice * @specific_object: the device specific object (currently used only for * activating wireless devices and should be the #NMAccessPoint's path. - * @callback: the function to call when the call is done + * @callback: (scope async): the function to call when the call is done * @user_data: user data to pass to the callback function * * Activates a connection with the given #NMDevice. @@ -1165,14 +1166,14 @@ add_activate_cb (DBusGProxy *proxy, * and will be completed by NetworkManager using the given @device and * @specific_object before being added * @device: the #NMDevice - * @specific_object: the object path of a connection-type-specific object this - * activation should use. This parameter is currently ignored for wired and - * mobile broadband connections, and the value of NULL should be used (ie, no - * specific object). For WiFi connections, pass the object path of a specific - * AP from the card's scan list, which will be used to complete the details of - * the newly added connection. - * @callback: the function to call when the call is done - * @user_data: user data to pass to the callback function + * @specific_object: (allow-none): the object path of a connection-type-specific + * object this activation should use. This parameter is currently ignored for + * wired and mobile broadband connections, and the value of NULL should be used + * (ie, no specific object). For WiFi connections, pass the object path of a + * specific AP from the card's scan list, which will be used to complete the + * details of the newly added connection. + * @callback: (scope async): the function to call when the call is done + * @user_data: (closure): user data to pass to the callback function * * Adds a new connection using the given details (if any) as a template * (automatically filling in missing settings with the capabilities of the @@ -1243,7 +1244,8 @@ nm_client_deactivate_connection (NMClient *client, NMActiveConnection *active) * * Gets the active connections. * - * Returns: a #GPtrArray containing all the active #NMActiveConnections. + * Returns: (transfer none) (element-type NMClient.ActiveConnection): a #GPtrArray +* containing all the active #NMActiveConnections. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * diff --git a/libnm-glib/nm-device-wifi.c b/libnm-glib/nm-device-wifi.c index 3d1702395..be5b98769 100644 --- a/libnm-glib/nm-device-wifi.c +++ b/libnm-glib/nm-device-wifi.c @@ -252,7 +252,7 @@ nm_device_wifi_get_capabilities (NMDeviceWifi *device) * * Gets the active #NMAccessPoint. * - * Returns: the access point or %NULL if none is active + * Returns: (transfer none): the access point or %NULL if none is active **/ NMAccessPoint * nm_device_wifi_get_active_access_point (NMDeviceWifi *device) @@ -302,7 +302,8 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device) * * Gets all the scanned access points of the #NMDeviceWifi. * - * Returns: a #GPtrArray containing all the scanned #NMAccessPoints. + * Returns: (element-type NMClient.AccessPoint): a #GPtrArray containing all the + * scanned #NMAccessPoints. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * @@ -342,7 +343,7 @@ nm_device_wifi_get_access_points (NMDeviceWifi *device) * * Gets a #NMAccessPoint by path. * - * Returns: the access point or %NULL if none is found. + * Returns: (transfer none): the access point or %NULL if none is found. **/ NMAccessPoint * nm_device_wifi_get_access_point_by_path (NMDeviceWifi *device, diff --git a/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c index bdab0eb74..4e7ebe8d8 100644 --- a/libnm-glib/nm-device-wimax.c +++ b/libnm-glib/nm-device-wimax.c @@ -108,12 +108,12 @@ nm_device_wimax_new (DBusGConnection *connection, const char *path) /** * nm_device_wimax_get_hw_address: - * @device: a #NMDeviceWimax + * @wimax: a #NMDeviceWimax * * Gets the hardware (MAC) address of the #NMDeviceWimax * * Returns: the hardware address. This is the internal string used by the - * device, and must not be modified. + * device, and must not be modified. **/ const char * nm_device_wimax_get_hw_address (NMDeviceWimax *wimax) @@ -138,7 +138,7 @@ nm_device_wimax_get_hw_address (NMDeviceWimax *wimax) * * Gets the active #NMWimaxNsp. * - * Returns: the access point or %NULL if none is active + * Returns: (transfer full): the access point or %NULL if none is active **/ NMWimaxNsp * nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) @@ -188,7 +188,8 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) * * Gets all the scanned NSPs of the #NMDeviceWimax. * - * Returns: a #GPtrArray containing all the scanned #NMWimaxNsps. + * Returns: (element-type NMClient.WimaxNsp): a #GPtrArray containing + * all the scanned #NMWimaxNsps. * The returned array is owned by the client and should not be modified. **/ const GPtrArray * @@ -228,7 +229,7 @@ nm_device_wimax_get_nsps (NMDeviceWimax *wimax) * * Gets a #NMWimaxNsp by path. * - * Returns: the access point or %NULL if none is found. + * Returns: (transfer none): the access point or %NULL if none is found. **/ NMWimaxNsp * nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, @@ -339,7 +340,7 @@ clean_up_nsps (NMDeviceWimax *self, gboolean notify) /** * nm_device_wimax_get_center_frequency: - * @device: a #NMDeviceWimax + * @self: a #NMDeviceWimax * * Gets the center frequency (in KHz) of the radio channel the device is using * to communicate with the network when connected. Has no meaning when the @@ -348,15 +349,15 @@ clean_up_nsps (NMDeviceWimax *self, gboolean notify) * Returns: the center frequency in KHz, or 0 **/ guint -nm_device_wimax_get_center_frequency (NMDeviceWimax *wimax) +nm_device_wimax_get_center_frequency (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); - priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); if (!priv->center_freq) { - priv->center_freq = _nm_object_get_uint_property (NM_OBJECT (wimax), + priv->center_freq = _nm_object_get_uint_property (NM_OBJECT (self), NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_CENTER_FREQUENCY); } @@ -365,7 +366,7 @@ nm_device_wimax_get_center_frequency (NMDeviceWimax *wimax) /** * nm_device_wimax_get_rssi: - * @device: a #NMDeviceWimax + * @self: a #NMDeviceWimax * * Gets the RSSI of the current radio link in dBm. This value indicates how * strong the raw received RF signal from the base station is, but does not @@ -375,15 +376,15 @@ nm_device_wimax_get_center_frequency (NMDeviceWimax *wimax) * Returns: the RSSI in dBm, or 0 **/ gint -nm_device_wimax_get_rssi (NMDeviceWimax *wimax) +nm_device_wimax_get_rssi (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); - priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); if (!priv->rssi) { - priv->rssi = _nm_object_get_int_property (NM_OBJECT (wimax), + priv->rssi = _nm_object_get_int_property (NM_OBJECT (self), NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_RSSI); } @@ -392,7 +393,7 @@ nm_device_wimax_get_rssi (NMDeviceWimax *wimax) /** * nm_device_wimax_get_cinr: - * @device: a #NMDeviceWimax + * @self: a #NMDeviceWimax * * Gets the CINR (Carrier to Interference + Noise Ratio) of the current radio * link in dB. CINR is a more accurate measure of radio link quality. Has no @@ -401,15 +402,15 @@ nm_device_wimax_get_rssi (NMDeviceWimax *wimax) * Returns: the CINR in dB, or 0 **/ gint -nm_device_wimax_get_cinr (NMDeviceWimax *wimax) +nm_device_wimax_get_cinr (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); - priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); if (!priv->cinr) { - priv->cinr = _nm_object_get_int_property (NM_OBJECT (wimax), + priv->cinr = _nm_object_get_int_property (NM_OBJECT (self), NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_CINR); } @@ -418,7 +419,7 @@ nm_device_wimax_get_cinr (NMDeviceWimax *wimax) /** * nm_device_wimax_get_tx_power: - * @device: a #NMDeviceWimax + * @self: a #NMDeviceWimax * * Average power of the last burst transmitted by the device, in units of * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of @@ -427,15 +428,15 @@ nm_device_wimax_get_cinr (NMDeviceWimax *wimax) * Returns: the TX power in dBm, or 0 **/ gint -nm_device_wimax_get_tx_power (NMDeviceWimax *wimax) +nm_device_wimax_get_tx_power (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); - priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); if (!priv->tx_power) { - priv->tx_power = _nm_object_get_int_property (NM_OBJECT (wimax), + priv->tx_power = _nm_object_get_int_property (NM_OBJECT (self), NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_TX_POWER); } @@ -444,22 +445,22 @@ nm_device_wimax_get_tx_power (NMDeviceWimax *wimax) /** * nm_device_wimax_get_bsid: - * @device: a #NMDeviceWimax + * @self: a #NMDeviceWimax * * Gets the ID of the serving Base Station when the device is connected. * * Returns: the ID of the serving Base Station, or NULL **/ const char * -nm_device_wimax_get_bsid (NMDeviceWimax *wimax) +nm_device_wimax_get_bsid (NMDeviceWimax *self) { NMDeviceWimaxPrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), NULL); - priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); if (!priv->bsid) { - priv->bsid = _nm_object_get_string_property (NM_OBJECT (wimax), + priv->bsid = _nm_object_get_string_property (NM_OBJECT (self), NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_BSID); } diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index b494749ad..6a39c77fd 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -934,7 +934,7 @@ nm_device_get_firmware_missing (NMDevice *device) * * Gets the current #NMIP4Config associated with the #NMDevice. * - * Returns: the #NMIP4Config or %NULL if the device is not activated. + * Returns: (transfer none): the #NMIP4Config or %NULL if the device is not activated. **/ NMIP4Config * nm_device_get_ip4_config (NMDevice *device) @@ -968,7 +968,7 @@ nm_device_get_ip4_config (NMDevice *device) * * Gets the current #NMDHCP4Config associated with the #NMDevice. * - * Returns: the #NMDHCPConfig or %NULL if the device is not activated or not + * Returns: (transfer none): the #NMDHCPConfig or %NULL if the device is not activated or not * using DHCP. **/ NMDHCP4Config * @@ -1003,7 +1003,7 @@ nm_device_get_dhcp4_config (NMDevice *device) * * Gets the current #NMIP6Config associated with the #NMDevice. * - * Returns: the #NMIP6Config or %NULL if the device is not activated. + * Returns: (transfer none): the #NMIP6Config or %NULL if the device is not activated. **/ NMIP6Config * nm_device_get_ip6_config (NMDevice *device) @@ -1037,7 +1037,7 @@ nm_device_get_ip6_config (NMDevice *device) * * Gets the current #NMDHCP6Config associated with the #NMDevice. * - * Returns: the #NMDHCPConfig or %NULL if the device is not activated or not + * Returns: (transfer none): the #NMDHCPConfig or %NULL if the device is not activated or not * using DHCP. **/ NMDHCP6Config * @@ -1317,7 +1317,7 @@ deactivate_cb (DBusGProxy *proxy, /** * nm_device_disconnect: * @device: a #NMDevice - * @callback: callback to be called when disconnect operation completes + * @callback: (scope async): callback to be called when disconnect operation completes * @user_data: caller-specific data passed to @callback * * Disconnects the device if currently connected, and prevents the device from diff --git a/libnm-glib/nm-dhcp4-config.c b/libnm-glib/nm-dhcp4-config.c index 442d19d19..45d48345c 100644 --- a/libnm-glib/nm-dhcp4-config.c +++ b/libnm-glib/nm-dhcp4-config.c @@ -203,7 +203,7 @@ nm_dhcp4_config_new (DBusGConnection *connection, const char *object_path) * * Gets all the options contained in the configuration. * - * Returns: the #GHashTable containing strings for keys and values. + * Returns: (transfer none) (element-type utf8 GObject.Value): the #GHashTable containing strings for keys and values. * This is the internal copy used by the configuration, and must not be modified. **/ GHashTable * diff --git a/libnm-glib/nm-dhcp6-config.c b/libnm-glib/nm-dhcp6-config.c index 379286720..dbcf4c682 100644 --- a/libnm-glib/nm-dhcp6-config.c +++ b/libnm-glib/nm-dhcp6-config.c @@ -203,7 +203,7 @@ nm_dhcp6_config_new (DBusGConnection *connection, const char *object_path) * * Gets all the options contained in the configuration. * - * Returns: the #GHashTable containing strings for keys and values. + * Returns: (transfer none) (element-type utf8 GObject.Value): the #GHashTable containing strings for keys and values. * This is the internal copy used by the configuration, and must not be modified. **/ GHashTable * diff --git a/libnm-glib/nm-ip4-config.c b/libnm-glib/nm-ip4-config.c index 4bedc7a1a..bc93a2c12 100644 --- a/libnm-glib/nm-ip4-config.c +++ b/libnm-glib/nm-ip4-config.c @@ -337,8 +337,8 @@ nm_ip4_config_new (DBusGConnection *connection, const char *object_path) * * Gets the IP4 addresses (containing the address, prefix, and gateway). * - * Returns: the #GSList containing #NMSettingIP4Addresses. This is the internal copy - * used by the configuration and must not be modified. + * Returns: (element-type NetworkManager.IP4Address): the #GSList containing #NMIP4Addresses. + * This is the internal copy used by the configuration and must not be modified. **/ const GSList * nm_ip4_config_get_addresses (NMIP4Config *config) @@ -366,7 +366,7 @@ nm_ip4_config_get_addresses (NMIP4Config *config) } /** - * nm_ip4_config_get_hostname: + * nm_ip4_config_get_hostname: (skip): * @config: a #NMIP4Config * * DEPRECATED. Don't use. @@ -385,7 +385,7 @@ nm_ip4_config_get_hostname (NMIP4Config *config) * * Gets the domain name servers (DNS). * - * Returns: the #GArray containing %guint32s. This is the internal copy used by the + * Returns: (element-type guint32): the #GArray containing %guint32s. This is the internal copy used by the * configuration and must not be modified. **/ const GArray * @@ -421,7 +421,7 @@ nm_ip4_config_get_nameservers (NMIP4Config *config) * * Gets the domain names. * - * Returns: the #GPtrArray containing domains as strings. This is the + * Returns: (element-type utf8): the #GPtrArray containing domains as strings. This is the * internal copy used by the configuration, and must not be modified. **/ const GPtrArray * @@ -460,8 +460,8 @@ nm_ip4_config_get_domains (NMIP4Config *config) * * Gets the Windows Internet Name Service servers (WINS). * - * Returns: the #GArray containing %guint32s. This is the internal copy used by the - * configuration and must not be modified. + * Returns: (element-type guint32): the #GArray containing %guint32s. + * This is the internal copy used by the configuration and must not be modified. **/ const GArray * nm_ip4_config_get_wins_servers (NMIP4Config *config) @@ -496,8 +496,9 @@ nm_ip4_config_get_wins_servers (NMIP4Config *config) * * Gets the routes. * - * Returns: the #GSList containing #NMSettingIP4Routes. This is the - * internal copy used by the configuration, and must not be modified. + * Returns: (element-type NetworkManager.IP4Route): the #GSList containing + * #NMIP4Routes. This is the internal copy used by the configuration, + * and must not be modified. **/ const GSList * nm_ip4_config_get_routes (NMIP4Config *config) diff --git a/libnm-glib/nm-ip6-config.c b/libnm-glib/nm-ip6-config.c index fe71c1b8d..fce6430e4 100644 --- a/libnm-glib/nm-ip6-config.c +++ b/libnm-glib/nm-ip6-config.c @@ -146,8 +146,9 @@ register_for_property_changed (NMIP6Config *config) * * Gets the IP6 addresses (containing the address, prefix, and gateway). * - * Returns: the #GSList containing #NMSettingIP6Addresses. This is the internal copy - * used by the configuration and must not be modified. + * Returns: (element-type NetworkManager.IP6Address): the #GSList containing + * #NMIP6Addresses. This is the internal copy used by the configuration + * and must not be modified. **/ const GSList * nm_ip6_config_get_addresses (NMIP6Config *config) @@ -174,15 +175,16 @@ nm_ip6_config_get_addresses (NMIP6Config *config) return priv->addresses; } +/* FIXME: like in libnm_util, in6_addr is not introspectable, so skipping here */ /** - * nm_ip6_config_get_nameservers: + * nm_ip6_config_get_nameservers: (skip) * @config: a #NMIP6Config * * Gets the domain name servers (DNS). * - * Returns: a #GSList containing elements of type 'struct in6_addr' which contain - * the addresses of nameservers of the configuration. This is the internal copy - * used by the configuration and must not be modified. + * Returns: (element-type Posix.in6_addr): a #GSList containing elements of type + * 'struct in6_addr' which contain the addresses of nameservers of the configuration. + * This is the internal copy used by the configuration and must not be modified. **/ const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config) @@ -217,8 +219,8 @@ nm_ip6_config_get_nameservers (NMIP6Config *config) * * Gets the domain names. * - * Returns: the #GPtrArray containing domains as strings. This is the - * internal copy used by the configuration, and must not be modified. + * Returns: (element-type utf8): the #GPtrArray containing domains as strings. + * This is the internal copy used by the configuration, and must not be modified. **/ const GPtrArray * nm_ip6_config_get_domains (NMIP6Config *config) @@ -251,8 +253,9 @@ nm_ip6_config_get_domains (NMIP6Config *config) * * Gets the routes. * - * Returns: the #GSList containing #NMSettingIP6Routes. This is the - * internal copy used by the configuration, and must not be modified. + * Returns: (element-type NetworkManager.IP6Route): the #GSList containing + * #NMIP6Routes. This is the internal copy used by the configuration, + * and must not be modified. **/ const GSList * nm_ip6_config_get_routes (NMIP6Config *config) diff --git a/libnm-glib/nm-object.c b/libnm-glib/nm-object.c index 85cb6b78a..78b46388a 100644 --- a/libnm-glib/nm-object.c +++ b/libnm-glib/nm-object.c @@ -223,7 +223,7 @@ nm_object_class_init (NMObjectClass *nm_object_class) * * Gets the #NMObject's DBusGConnection. * - * Returns: the connection + * Returns: (transfer none): the connection **/ DBusGConnection * nm_object_get_connection (NMObject *object) diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 0887b725f..f11d10021 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -101,7 +101,7 @@ update_cb (DBusGProxy *proxy, GError *error, gpointer user_data) /** * nm_remote_connection_commit_changes: * @connection: the #NMRemoteConnection - * @callback: a function to be called when the commit completes + * @callback: (scope async): a function to be called when the commit completes * @user_data: caller-specific data to be passed to @callback * * Save any local changes to the settings and properties of this connection and @@ -153,7 +153,7 @@ delete_cb (DBusGProxy *proxy, GError *error, gpointer user_data) /** * nm_remote_connection_delete: * @connection: the #NMRemoteConnection - * @callback: a function to be called when the delete completes + * @callback: (scope async): a function to be called when the delete completes * @user_data: caller-specific data to be passed to @callback * * Delete the connection. @@ -202,7 +202,7 @@ get_secrets_cb (DBusGProxy *proxy, GHashTable *secrets, GError *error, gpointer * @hints: #NMSetting key names to get secrets for (optional) * @request_new: hint that new secrets (instead of cached or stored secrets) * should be returned - * @callback: a function to be called when the update completes + * @callback: (scope async): a function to be called when the update completes * @user_data: caller-specific data to be passed to @callback * * Request the connection's secrets. @@ -483,8 +483,8 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMRemoteConnectionClass, updated), NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT); + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); signals[REMOVED] = g_signal_new (NM_REMOTE_CONNECTION_REMOVED, @@ -494,5 +494,4 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - } diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index e4b0bc55b..630e0cef1 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -168,7 +168,7 @@ add_connection_info_complete (NMRemoteSettings *self, * * Returns the %NMRemoteConnection representing the connection at @path. * - * Returns: the remote connection object on success, or NULL if the object was + * Returns: (transfer none): the remote connection object on success, or NULL if the object was * not known **/ NMRemoteConnection * @@ -366,7 +366,7 @@ fetch_connections (gpointer user_data) * nm_remote_settings_list_connections: * @settings: the %NMRemoteSettings * - * Returns: all connections in the remote settings service, represented as + * Returns: (transfer container) (element-type NMClient.RemoteConnection): all connections in the remote settings service, represented as * %NMRemoteConnection instances **/ GSList * @@ -407,12 +407,13 @@ add_connection_done (DBusGProxy *proxy, g_free (path); } + /** * nm_remote_settings_add_connection: * @settings: the %NMRemoteSettings * @connection: the connection to add. Note that this object's settings will be * added, not the object itself - * @callback: callback to be called when the add operation completes + * @callback: (scope async): callback to be called when the add operation completes * @user_data: caller-specific data passed to @callback * * Requests that the remote settings service add the given settings to a new @@ -513,7 +514,7 @@ save_hostname_cb (DBusGProxy *proxy, * @settings: the %NMRemoteSettings * @hostname: the new persistent hostname to set, or NULL to clear any existing * persistent hostname - * @callback: callback to be called when the hostname operation completes + * @callback: (scope async): callback to be called when the hostname operation completes * @user_data: caller-specific data passed to @callback * * Requests that the machine's persistent hostname be set to the specified value @@ -637,7 +638,7 @@ get_all_cb (DBusGProxy *proxy, /** * nm_remote_settings_new: - * @bus: a valid and connected D-Bus connection + * @bus: (allow-none): a valid and connected D-Bus connection * * Creates a new object representing the remote settings service. * @@ -646,7 +647,8 @@ get_all_cb (DBusGProxy *proxy, NMRemoteSettings * nm_remote_settings_new (DBusGConnection *bus) { - g_return_val_if_fail (bus != NULL, NULL); + if (bus == NULL) + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); return (NMRemoteSettings *) g_object_new (NM_TYPE_REMOTE_SETTINGS, NM_REMOTE_SETTINGS_BUS, bus, diff --git a/libnm-glib/nm-remote-settings.h b/libnm-glib/nm-remote-settings.h index b38266d9d..2bf748a6e 100644 --- a/libnm-glib/nm-remote-settings.h +++ b/libnm-glib/nm-remote-settings.h @@ -115,7 +115,7 @@ GSList * nm_remote_settings_list_connections (NMRemoteSettings *settings); NMRemoteConnection * nm_remote_settings_get_connection_by_path (NMRemoteSettings *settings, const char *path); -gboolean nm_remote_settings_add_connection (NMRemoteSettings *self, +gboolean nm_remote_settings_add_connection (NMRemoteSettings *settings, NMConnection *connection, NMRemoteSettingsAddConnectionFunc callback, gpointer user_data); diff --git a/libnm-glib/nm-types.c b/libnm-glib/nm-types.c index cf9e084c7..923c436b1 100644 --- a/libnm-glib/nm-types.c +++ b/libnm-glib/nm-types.c @@ -52,7 +52,7 @@ nm_ssid_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-ssid"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMSsid"), (GBoxedCopyFunc) nm_ssid_copy, (GBoxedFreeFunc) nm_ssid_free); return our_type; @@ -105,7 +105,7 @@ nm_uint_array_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-uint-array"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMUintArray"), (GBoxedCopyFunc) nm_uint_array_copy, (GBoxedFreeFunc) nm_uint_array_free); return our_type; @@ -163,7 +163,7 @@ nm_string_array_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-string-array"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMStringArray"), (GBoxedCopyFunc) nm_string_array_copy, (GBoxedFreeFunc) nm_string_array_free); return our_type; @@ -224,7 +224,7 @@ nm_object_array_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-object-array"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMObjectArray"), (GBoxedCopyFunc) nm_object_array_copy, (GBoxedFreeFunc) nm_object_array_free); return our_type; @@ -306,7 +306,7 @@ nm_ip6_address_object_array_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-ip6-address-object-array"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMIP6AddressObjectArray"), (GBoxedCopyFunc) nm_ip6_address_object_array_copy, (GBoxedFreeFunc) nm_ip6_address_object_array_free); return our_type; @@ -348,7 +348,7 @@ nm_ip6_address_array_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-ip6-address-array"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMIP6AddressArray"), (GBoxedCopyFunc) nm_ip6_address_array_copy, (GBoxedFreeFunc) nm_ip6_address_array_free); return our_type; @@ -415,7 +415,7 @@ nm_ip6_route_object_array_get_type (void) static GType our_type = 0; if (our_type == 0) - our_type = g_boxed_type_register_static (g_intern_static_string ("nm-ip6-route-object-array"), + our_type = g_boxed_type_register_static (g_intern_static_string ("NMIP6RouteObjectArray"), (GBoxedCopyFunc) nm_ip6_route_object_array_copy, (GBoxedFreeFunc) nm_ip6_route_object_array_free); return our_type; diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index fdadc7517..38109c0a5 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -31,12 +31,15 @@ libnm_util_include_HEADERS = \ nm-setting-vpn.h \ nm-utils.h -libnm_util_la_SOURCES= \ - crypto.c \ +libnm_util_la_private_headers = \ crypto.h \ + nm-param-spec-specialized.h \ + nm-utils-private.h + +libnm_util_la_csources = \ + crypto.c \ nm-connection.c \ nm-param-spec-specialized.c \ - nm-param-spec-specialized.h \ nm-setting.c \ nm-setting-8021x.c \ nm-setting-bluetooth.c \ @@ -54,14 +57,16 @@ libnm_util_la_SOURCES= \ nm-setting-wireless.c \ nm-setting-wireless-security.c \ nm-setting-vpn.c \ - nm-utils.c \ - nm-utils-private.h \ - $(libnm_util_include_HEADERS) + nm-utils.c + +libnm_util_la_SOURCES = \ + $(libnm_util_la_csources) \ + $(libnm_util_la_private_headers) libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \ - -version-info "7:0:6" + -version-info "8:0:7" if WITH_GNUTLS libnm_util_la_SOURCES += crypto_gnutls.c @@ -104,12 +109,36 @@ libtest_crypto_la_CPPFLAGS += $(NSS_CFLAGS) libtest_crypto_la_LIBADD += $(NSS_LIBS) endif - - pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnm-util.pc DISTCLEANFILES = libnm-util.pc +CLEANFILES = EXTRA_DIST = libnm-util.pc.in libnm-util.ver +-include $(INTROSPECTION_MAKEFILE) +INTROSPECTION_GIRS = +INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) +INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) + +if HAVE_INTROSPECTION +introspection_sources = $(libnm_util_include_HEADERS) $(libnm_util_la_csources) $(top_srcdir)/include/NetworkManager.h $(top_srcdir)/include/NetworkManagerVPN.h + +NetworkManager-1.0.gir: libnm-util.la +NetworkManager_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 +NetworkManager_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 +NetworkManager_1_0_gir_CFLAGS = $(INCLUDES) +NetworkManager_1_0_gir_LIBS = libnm-util.la +NetworkManager_1_0_gir_FILES = $(introspection_sources) +NetworkManager_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm_ +INTROSPECTION_GIRS += NetworkManager-1.0.gir + +girdir = $(datadir)/gir-1.0 +gir_DATA = $(INTROSPECTION_GIRS) + +typelibdir = $(libdir)/girepository-1.0 +typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) + +CLEANFILES += $(gir_DATA) $(typelib_DATA) +endif diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 2a8181bee..2c71f37de 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -170,6 +170,7 @@ global: nm_setting_ip4_config_get_dhcp_send_hostname; nm_setting_ip4_config_get_never_default; nm_setting_ip4_config_get_may_fail; + nm_ip6_address_get_type; nm_ip6_address_new; nm_ip6_address_dup; nm_ip6_address_ref; @@ -181,6 +182,7 @@ global: nm_ip6_address_set_gateway; nm_ip6_address_get_prefix; nm_ip6_address_set_prefix; + nm_ip6_route_get_type; nm_ip6_route_new; nm_ip6_route_dup; nm_ip6_route_ref; @@ -388,8 +390,9 @@ global: nm_ip4_address_compare; nm_ip4_address_dup; nm_ip4_address_get_address; - nm_ip4_address_get_prefix; nm_ip4_address_get_gateway; + nm_ip4_address_get_prefix; + nm_ip4_address_get_type; nm_ip4_address_new; nm_ip4_address_ref; nm_ip4_address_set_address; @@ -402,6 +405,7 @@ global: nm_ip4_route_get_prefix; nm_ip4_route_get_next_hop; nm_ip4_route_get_metric; + nm_ip4_route_get_type; nm_ip4_route_new; nm_ip4_route_ref; nm_ip4_route_unref; diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 3aa10c6a0..39766285a 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -350,7 +350,7 @@ nm_connection_lookup_setting_type_by_quark (GQuark error_quark) * * Create a new #NMSetting object of the desired type, given a setting name. * - * Returns: the new setting object, or NULL if the setting name was unknown + * Returns: (transfer full): the new setting object, or NULL if the setting name was unknown **/ NMSetting * nm_connection_create_setting (const char *name) @@ -384,7 +384,7 @@ parse_one_setting (gpointer key, gpointer value, gpointer user_data) /** * nm_connection_add_setting: * @connection: a #NMConnection - * @setting: the #NMSetting to add to the connection object + * @setting: (transfer full): the #NMSetting to add to the connection object * * Adds a #NMSetting to the connection, replacing any previous #NMSetting of the * same name which has previously been added to the #NMConnection. The @@ -426,7 +426,7 @@ nm_connection_remove_setting (NMConnection *connection, GType setting_type) * Gets the #NMSetting with the given #GType, if one has been previously added * to the #NMConnection. * - * Returns: the #NMSetting, or NULL if no setting of that type was previously + * Returns: (transfer none): the #NMSetting, or NULL if no setting of that type was previously * added to the #NMConnection **/ NMSetting * @@ -447,7 +447,7 @@ nm_connection_get_setting (NMConnection *connection, GType setting_type) * Gets the #NMSetting with the given name, if one has been previously added * the the #NMConnection. * - * Returns: the #NMSetting, or NULL if no setting with that name was previously + * Returns: (transfer none): the #NMSetting, or NULL if no setting with that name was previously * added to the #NMConnection **/ NMSetting * @@ -493,7 +493,7 @@ validate_permissions_type (GHashTable *hash, GError **error) /** * nm_connection_replace_settings: * @connection: a #NMConnection - * @new_settings: a #GHashTable of settings + * @new_settings: (element-type utf8 GLib.HashTable): a #GHashTable of settings * @error: location to store error, or %NULL * * Returns: %TRUE if the settings were valid and added to the connection, %FALSE @@ -651,7 +651,7 @@ nm_connection_verify (NMConnection *connection, GError **error) * nm_connection_update_secrets: * @connection: the #NMConnection * @setting_name: the setting object name to which the secrets apply - * @secrets: a #GHashTable mapping string:#GValue of setting property names and + * @secrets: (element-type utf8 GObject.Value): a #GHashTable mapping string:#GValue of setting property names and * secrets * @error: location to store error, or %NULL * @@ -826,9 +826,10 @@ add_one_setting_to_hash (gpointer key, gpointer data, gpointer user_data) * are #GHashTables mapping string:GValue, each of which represents the * properties of the #NMSetting object. * - * Returns: a new #GHashTable describing the connection, its settings, and - * each setting's properties. The caller owns the hash table and must unref - * the hash table with g_hash_table_unref() when it is no longer needed. + * Returns: (transfer full) (element-type utf8 GLib.HashTable): a new + * #GHashTable describing the connection, its settings, and each setting's + * properties. The caller owns the hash table and must unref the hash table + * with g_hash_table_unref() when it is no longer needed. **/ GHashTable * nm_connection_to_hash (NMConnection *connection) @@ -869,7 +870,7 @@ for_each_setting (gpointer key, gpointer value, gpointer user_data) /** * nm_connection_for_each_setting_value: * @connection: the #NMConnection - * @func: user-supplied function called for each setting's property + * @func: (scope call): user-supplied function called for each setting's property * @user_data: user data passed to @func at each invocation * * Iterates over the properties of each #NMSetting object in the #NMConnection, @@ -994,7 +995,8 @@ nm_connection_new (void) /** * nm_connection_new_from_hash: - * @hash: the #GHashTable describing the connection + * @hash: (element-type utf8 GLib.HashTable): the #GHashTable describing + * the connection * @error: on unsuccessful return, an error * * Creates a new #NMConnection from a hash table describing the connection. See @@ -1037,7 +1039,7 @@ duplicate_cb (gpointer key, gpointer value, gpointer user_data) * * Duplicates a #NMConnection. * - * Returns: a new #NMConnection containing the same settings and properties + * Returns: (transfer full): a new #NMConnection containing the same settings and properties * as the source #NMConnection **/ NMConnection * diff --git a/libnm-util/nm-setting-ip4-config.c b/libnm-util/nm-setting-ip4-config.c index 186e41e24..be124d926 100644 --- a/libnm-util/nm-setting-ip4-config.c +++ b/libnm-util/nm-setting-ip4-config.c @@ -66,6 +66,8 @@ nm_setting_ip4_config_error_get_type (void) return etype; } +G_DEFINE_BOXED_TYPE (NMIP4Address, nm_ip4_address, nm_ip4_address_dup, nm_ip4_address_unref) +G_DEFINE_BOXED_TYPE (NMIP4Route, nm_ip4_route, nm_ip4_route_dup, nm_ip4_route_unref) G_DEFINE_TYPE (NMSettingIP4Config, nm_setting_ip4_config, NM_TYPE_SETTING) diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h index 80ddd4758..91cf0ea6d 100644 --- a/libnm-util/nm-setting-ip4-config.h +++ b/libnm-util/nm-setting-ip4-config.h @@ -74,6 +74,8 @@ GQuark nm_setting_ip4_config_error_quark (void); typedef struct NMIP4Address NMIP4Address; +GType nm_ip4_address_get_type (void); + NMIP4Address * nm_ip4_address_new (void); NMIP4Address * nm_ip4_address_dup (NMIP4Address *source); void nm_ip4_address_ref (NMIP4Address *address); @@ -95,6 +97,8 @@ void nm_ip4_address_set_gateway (NMIP4Address *address, typedef struct NMIP4Route NMIP4Route; +GType nm_ip4_route_get_type (void); + NMIP4Route * nm_ip4_route_new (void); NMIP4Route * nm_ip4_route_dup (NMIP4Route *route); void nm_ip4_route_ref (NMIP4Route *route); diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c index e8af05804..10fe3ccd6 100644 --- a/libnm-util/nm-setting-ip6-config.c +++ b/libnm-util/nm-setting-ip6-config.c @@ -65,6 +65,8 @@ nm_setting_ip6_config_error_get_type (void) return etype; } +G_DEFINE_BOXED_TYPE (NMIP6Address, nm_ip6_address, nm_ip6_address_dup, nm_ip6_address_unref) +G_DEFINE_BOXED_TYPE (NMIP6Route, nm_ip6_route, nm_ip6_route_dup, nm_ip6_route_unref) G_DEFINE_TYPE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING) diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h index e3e286e68..b9733b4ac 100644 --- a/libnm-util/nm-setting-ip6-config.h +++ b/libnm-util/nm-setting-ip6-config.h @@ -74,6 +74,8 @@ GQuark nm_setting_ip6_config_error_quark (void); typedef struct NMIP6Address NMIP6Address; +GType nm_ip6_address_get_type (void); + NMIP6Address * nm_ip6_address_new (void); NMIP6Address * nm_ip6_address_dup (NMIP6Address *source); void nm_ip6_address_ref (NMIP6Address *address); @@ -95,6 +97,8 @@ void nm_ip6_address_set_gateway (NMIP6Address *address, typedef struct NMIP6Route NMIP6Route; +GType nm_ip6_route_get_type (void); + NMIP6Route * nm_ip6_route_new (void); NMIP6Route * nm_ip6_route_dup (NMIP6Route *route); void nm_ip6_route_ref (NMIP6Route *route); diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 53b609e2d..4b8a1dc9c 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -158,9 +158,17 @@ nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key) g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key); } +/** + * nm_setting_vpn_foreach_data_item: + * @setting: a #NMSettingVPN + * @func: (scope call): an user provided function + * @user_data: + * + * Iterates all data items stored in this setting + */ void nm_setting_vpn_foreach_data_item (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); @@ -200,9 +208,17 @@ nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key) g_hash_table_remove (NM_SETTING_VPN_GET_PRIVATE (setting)->secrets, key); } +/** + * nm_setting_vpn_foreach_secret: + * @setting: a #NMSettingVPN + * @func: (scope call): an user provided function + * @user_data: + * + * Iterates all secrets stored in this setting. + */ void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data) { g_return_if_fail (NM_IS_SETTING_VPN (setting)); diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h index 9c684bbf1..c848696a3 100644 --- a/libnm-util/nm-setting-vpn.h +++ b/libnm-util/nm-setting-vpn.h @@ -71,7 +71,9 @@ typedef struct { void (*_reserved4) (void); } NMSettingVPNClass; -typedef void (*VPNIterFunc) (const char *key, const char *value, gpointer user_data); +typedef void (*NMVPNIterFunc) (const char *key, const char *value, gpointer user_data); +/* For backward compatibility */ +typedef NMVPNIterFunc VPNIterFunc; GType nm_setting_vpn_get_type (void); @@ -87,7 +89,7 @@ const char * nm_setting_vpn_get_data_item (NMSettingVPN *setting, void nm_setting_vpn_remove_data_item (NMSettingVPN *setting, const char *key); void nm_setting_vpn_foreach_data_item (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data); void nm_setting_vpn_add_secret (NMSettingVPN *setting, @@ -98,7 +100,7 @@ const char * nm_setting_vpn_get_secret (NMSettingVPN *setting, void nm_setting_vpn_remove_secret (NMSettingVPN *setting, const char *key); void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, - VPNIterFunc func, + NMVPNIterFunc func, gpointer user_data); G_END_DECLS diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 980a65b96..f0ff42c88 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -112,7 +112,7 @@ destroy_gvalue (gpointer data) * name to a GValue describing that property, suitable for marshalling over * D-Bus or serializing. The mapping is string:GValue. * - * Returns: a new #GHashTable describing the setting's properties + * Returns: (transfer full) (element-type utf8 GObject.Value): a new #GHashTable describing the setting's properties **/ GHashTable * nm_setting_to_hash (NMSetting *setting) @@ -254,7 +254,7 @@ duplicate_setting (NMSetting *setting, * * Duplicates a #NMSetting. * - * Returns: a new #NMSetting containing the same properties and values as the + * Returns: (transfer full): a new #NMSetting containing the same properties and values as the * source #NMSetting **/ NMSetting * @@ -390,7 +390,7 @@ nm_setting_compare (NMSetting *a, /** * nm_setting_enumerate_values: * @setting: the #NMSetting - * @func: user-supplied function called for each property of the setting + * @func: (scope call): user-supplied function called for each property of the setting * @user_data: user data passed to @func at each invocation * * Iterates over each property of the #NMSetting object, calling the supplied @@ -465,7 +465,7 @@ nm_setting_clear_secrets (NMSetting *setting) * guide to what secrets may be required, because in some circumstances, there * is no way to conclusively determine exactly which secrets are needed. * - * Returns: a #GPtrArray containing the property names of secrets of the + * Returns: (transfer full) (element-type utf8): a #GPtrArray containing the property names of secrets of the * #NMSetting which may be required; the caller owns the array * and must free the each array element with g_free(), as well as the array * itself with g_ptr_array_free() diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 9c3662f47..87c5d5f6e 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -487,7 +487,7 @@ value_dup (gpointer key, gpointer val, gpointer user_data) * * Utility function to duplicate a hash table of GValues. * - * Returns: a newly allocated duplicated #GHashTable, caller must free the + * Returns: (transfer container) (element-type utf8 GObject.Value): a newly allocated duplicated #GHashTable, caller must free the * returned hash with g_hash_table_unref() or g_hash_table_destroy() **/ GHashTable * @@ -1359,7 +1359,7 @@ nm_utils_security_valid (NMUtilsSecurityType type, * this serialization is not guaranteed to be stable and the #GArray may be * extended in the future. * - * Returns: a newly allocated #GSList of #NMIP4Address objects + * Returns: (transfer full) (element-type NetworkManager.IP4Address): a newly allocated #GSList of #NMIP4Address objects **/ GSList * nm_utils_ip4_addresses_from_gvalue (const GValue *value) @@ -1441,7 +1441,7 @@ nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value) * format of this serialization is not guaranteed to be stable and may be * extended in the future. * - * Returns: a newly allocated #GSList of #NMIP4Route objects + * Returns: (transfer full) (element-type NetworkManager.IP4Route): a newly allocated #GSList of #NMIP4Route objects **/ GSList * nm_utils_ip4_routes_from_gvalue (const GValue *value) @@ -1604,7 +1604,7 @@ nm_utils_ip4_get_default_prefix (guint32 ip) * this serialization is not guaranteed to be stable and the #GValueArray may be * extended in the future. * - * Returns: a newly allocated #GSList of #NMIP6Address objects + * Returns: (transfer full) (element-type NetworkManager.IP6Address): a newly allocated #GSList of #NMIP6Address objects **/ GSList * nm_utils_ip6_addresses_from_gvalue (const GValue *value) @@ -1747,7 +1747,7 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) * into a GSList of #NMIP6Route objects. The specific format of this serialization * is not guaranteed to be stable and may be extended in the future. * - * Returns: a newly allocated #GSList of #NMIP6Route objects + * Returns: (transfer full) (element-type NetworkManager.IP6Route): a newly allocated #GSList of #NMIP6Route objects **/ GSList * nm_utils_ip6_routes_from_gvalue (const GValue *value) @@ -1863,6 +1863,18 @@ nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value) g_value_take_boxed (value, routes); } +/* FIXME: the Posix namespace does not exist, and thus neither does + the in6_addr struct. Marking (skip) for now */ +/** + * nm_utils_ip6_dns_from_gvalue: (skip): + * @value: a #GValue + * + * Converts a #GValue containing a #GPtrArray of IP6 DNS, represented as + * #GByteArrays into a #GSList of #in6_addrs. + * + * Returns: (transfer full) (element-type Posix.in6_addr): a #GSList of IP6 + * addresses. + */ GSList * nm_utils_ip6_dns_from_gvalue (const GValue *value) { @@ -2046,8 +2058,8 @@ utils_bin2hexstr (const char *bytes, int len, int final_len) /** * nm_utils_rsa_key_encrypt: * @data: RSA private key data to be encrypted - * @in_password: existing password to use, if any - * @out_password: if @in_password was NULL, a random password will be generated + * @in_password: (allow-none): existing password to use, if any + * @out_password: (out) (allow-none): if @in_password was NULL, a random password will be generated * and returned in this argument * @error: detailed error information on return, if an error occurred * @@ -2055,7 +2067,7 @@ utils_bin2hexstr (const char *bytes, int len, int final_len) * a password if no password was given) and converts the data to PEM format * suitable for writing to a file. * - * Returns: on success, PEM-formatted data suitable for writing to a PEM-formatted + * Returns: (transfer full): on success, PEM-formatted data suitable for writing to a PEM-formatted * certificate/private key file. **/ GByteArray * diff --git a/m4/introspection.m4 b/m4/introspection.m4 new file mode 100644 index 000000000..589721c5a --- /dev/null +++ b/m4/introspection.m4 @@ -0,0 +1,94 @@ +dnl -*- mode: autoconf -*- +dnl Copyright 2009 Johan Dahlin +dnl +dnl This file is free software; the author(s) gives unlimited +dnl permission to copy and/or distribute it, with or without +dnl modifications, as long as this notice is preserved. +dnl + +# serial 1 + +m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], +[ + AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([LT_INIT],[$0])dnl setup libtool first + + dnl enable/disable introspection + m4_if([$2], [require], + [dnl + enable_introspection=yes + ],[dnl + AC_ARG_ENABLE(introspection, + AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], + [Enable introspection for this build]),, + [enable_introspection=auto]) + ])dnl + + AC_MSG_CHECKING([for gobject-introspection]) + + dnl presence/version checking + AS_CASE([$enable_introspection], + [no], [dnl + found_introspection="no (disabled, use --enable-introspection to enable)" + ],dnl + [yes],[dnl + PKG_CHECK_EXISTS([gobject-introspection-1.0],, + AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) + PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], + found_introspection=yes, + AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) + ],dnl + [auto],[dnl + PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) + ],dnl + [dnl + AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) + ])dnl + + AC_MSG_RESULT([$found_introspection]) + + INTROSPECTION_SCANNER= + INTROSPECTION_COMPILER= + INTROSPECTION_GENERATE= + INTROSPECTION_GIRDIR= + INTROSPECTION_TYPELIBDIR= + if test "x$found_introspection" = "xyes"; then + INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` + INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` + INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` + INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` + INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" + INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` + INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` + INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection + fi + AC_SUBST(INTROSPECTION_SCANNER) + AC_SUBST(INTROSPECTION_COMPILER) + AC_SUBST(INTROSPECTION_GENERATE) + AC_SUBST(INTROSPECTION_GIRDIR) + AC_SUBST(INTROSPECTION_TYPELIBDIR) + AC_SUBST(INTROSPECTION_CFLAGS) + AC_SUBST(INTROSPECTION_LIBS) + AC_SUBST(INTROSPECTION_MAKEFILE) + + AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes") +]) + + +dnl Usage: +dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) + +AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], +[ + _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) +]) + +dnl Usage: +dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) + + +AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], +[ + _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) +]) From 9806a92eaa1754146cfdf1b57b95789ee405e089 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 25 Jan 2011 15:41:14 -0600 Subject: [PATCH 172/264] trivial: fix some possible uninitialized variable usage in error cases --- src/nm-session-monitor.c | 2 +- test/nm-tool.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index a70067a98..4877b7703 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -207,7 +207,7 @@ static gboolean reload_database (NMSessionMonitor *self, GError **error) { struct stat statbuf; - char **groups; + char **groups = NULL; gsize len = 0, i; Session *s; diff --git a/test/nm-tool.c b/test/nm-tool.c index 65546e48e..ea3ef13b6 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -724,7 +724,7 @@ get_all_connections (void) { GError *error = NULL; DBusGConnection *bus; - DBusGProxy *proxy; + DBusGProxy *proxy = NULL; GPtrArray *paths = NULL; int i; gboolean sucess = FALSE; From 4b6a86d74898beb8df29f2b0ba19d55a5cdc940d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 09:58:22 -0600 Subject: [PATCH 173/264] dbus: remove obsolete interfaces from permissions --- src/NetworkManager.conf | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/NetworkManager.conf b/src/NetworkManager.conf index c7ea5f735..b256a444e 100644 --- a/src/NetworkManager.conf +++ b/src/NetworkManager.conf @@ -83,12 +83,6 @@ - - - - @@ -107,10 +101,6 @@ - - 512 From d1979ba63e139004fc0e42e467aaff25d68ad5ad Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 10:17:07 -0600 Subject: [PATCH 174/264] secrets: simplify GetSecrets call flow The Settings.Connection interface is now only provided by NetworkManager itself since there is only one settings service. NM can validate requests for secrets internally and thus there's no need to lock down GetSecrets using a separate D-Bus interface, since PolicyKit provides that functionality on systems where this is desirable (ie multi-user). Single-user systems that do not have PolicyKit will inherently trust the user already, or if not D-Bus auth is flexible enough to lock down the GetSecrets method individually even if it's not on a separate D-Bus interface. Second, since only clients like connection editors or applets will be calling the GetSecrets method, there's no need for 'hints' or 'request_new' arguments here since this method should never trigger an interactive secrets request. Only NM should send those requests when it knows it needs to ask the user, either during connection or after validating the incoming GetSecrets request. A connection editor type application should never be able to trigger the normal "What's your passphrase" dialog thats provided by the secret agent for that user's session. --- introspection/nm-sysconfig-connection.xml | 77 +++++++++++------------ libnm-glib/nm-remote-connection.c | 30 ++------- libnm-glib/nm-remote-connection.h | 8 +-- src/nm-agent-manager.c | 3 +- src/settings/nm-sysconfig-connection.c | 46 +++++--------- src/settings/nm-sysconfig-connection.h | 4 +- 6 files changed, 63 insertions(+), 105 deletions(-) diff --git a/introspection/nm-sysconfig-connection.xml b/introspection/nm-sysconfig-connection.xml index da8c6a6b2..2d53d65ce 100644 --- a/introspection/nm-sysconfig-connection.xml +++ b/introspection/nm-sysconfig-connection.xml @@ -9,13 +9,16 @@ - Update the connection with new settings and properties, replacing all previous settings and properties. + Update the connection with new settings and properties, replacing + all previous settings and properties. Secrets may be part of the + update request, and will be either stored in persistent storage or + given to a Secret Agent for storage, depending on the request. - New connection properties. + New connection settings, properties, and (optionally) secrets. @@ -30,7 +33,10 @@ - Get the settings maps describing this object. + Get the settings maps describing this network configuration. + This will never include any secrets required for connection + to the network, as those are often protected. Secrets must + be requested separately using the GetSecrets() call. @@ -41,6 +47,29 @@ + + + Get the secrets belonging to this network configuration. Only + secrets from persistent storage or a Secret Agent running in + the requestor's session will be returned. The user will never + be prompted for secrets as a result of this request. + + + + + + Name of the setting to return secrets for. If empty, all + all secrets will be returned. + + + + + + Nested settings maps containing secrets. + + + + Emitted when any settings or permissions change. When handling @@ -52,47 +81,13 @@ - Emitted when this connection is no longer available. This happens when the connection is deleted or if it is no longer accessable by any of the system's logged in users. After receipt of this signal, the object no longer exists. + Emitted when this connection is no longer available. This + happens when the connection is deleted or if it is no longer + accessable by any of the system's logged-in users. After + receipt of this signal, the object no longer exists. - - - Secrets have a separate interface so that they can be locked down. - - - - - Get the secrets encapsulated in this object. - - - - - - Name of the setting to return. - - - - - Array of strings of key names in the Setting for which NM thinks - a secrets may be required. - - - - - Indicates whether new secrets should be requested or if the request can be fulfilled from storage. - - - - - - Nested settings maps containing secrets. Each setting MUST contain at least the 'name' field, containing the name of the setting, and one or more secrets. - - - - - - diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index f11d10021..8b7e57596 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #include @@ -54,7 +54,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { NMRemoteConnection *self; - DBusGProxy *proxy; DBusGProxyCall *call; GFunc callback; gpointer user_data; @@ -63,7 +62,6 @@ typedef struct { typedef struct { DBusGConnection *bus; DBusGProxy *proxy; - DBusGProxy *secrets_proxy; GSList *calls; NMRemoteConnectionInitResult init_result; @@ -126,7 +124,6 @@ nm_remote_connection_commit_changes (NMRemoteConnection *self, call->self = self; call->callback = (GFunc) callback; call->user_data = user_data; - call->proxy = priv->proxy; settings = nm_connection_to_hash (NM_CONNECTION (self)); @@ -176,7 +173,6 @@ nm_remote_connection_delete (NMRemoteConnection *self, call->self = self; call->callback = (GFunc) callback; call->user_data = user_data; - call->proxy = priv->proxy; call->call = org_freedesktop_NetworkManager_Settings_Connection_delete_async (priv->proxy, delete_cb, @@ -199,9 +195,6 @@ get_secrets_cb (DBusGProxy *proxy, GHashTable *secrets, GError *error, gpointer * nm_remote_connection_get_secrets: * @connection: the #NMRemoteConnection * @setting_name: the #NMSetting object name to get secrets for - * @hints: #NMSetting key names to get secrets for (optional) - * @request_new: hint that new secrets (instead of cached or stored secrets) - * should be returned * @callback: (scope async): a function to be called when the update completes * @user_data: caller-specific data to be passed to @callback * @@ -210,8 +203,6 @@ get_secrets_cb (DBusGProxy *proxy, GHashTable *secrets, GError *error, gpointer void nm_remote_connection_get_secrets (NMRemoteConnection *self, const char *setting_name, - const char **hints, - gboolean request_new, NMRemoteConnectionGetSecretsFunc callback, gpointer user_data) { @@ -228,14 +219,11 @@ nm_remote_connection_get_secrets (NMRemoteConnection *self, call->self = self; call->callback = (GFunc) callback; call->user_data = user_data; - call->proxy = priv->secrets_proxy; - call->call = org_freedesktop_NetworkManager_Settings_Connection_Secrets_get_secrets_async (priv->secrets_proxy, - setting_name, - hints, - request_new, - get_secrets_cb, - call); + call->call = org_freedesktop_NetworkManager_Settings_Connection_get_secrets_async (priv->proxy, + setting_name, + get_secrets_cb, + call); g_assert (call->call); priv->calls = g_slist_append (priv->calls, call); } @@ -366,13 +354,6 @@ constructor (GType type, g_assert (priv->proxy); dbus_g_proxy_set_default_timeout (priv->proxy, G_MAXINT); - priv->secrets_proxy = dbus_g_proxy_new_for_name (priv->bus, - NM_DBUS_SERVICE, - nm_connection_get_path (NM_CONNECTION (object)), - NM_DBUS_IFACE_SETTINGS_CONNECTION_SECRETS); - g_assert (priv->secrets_proxy); - dbus_g_proxy_set_default_timeout (priv->secrets_proxy, G_MAXINT); - dbus_g_proxy_add_signal (priv->proxy, "Updated", G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->proxy, "Updated", G_CALLBACK (updated_cb), object, NULL); @@ -437,7 +418,6 @@ dispose (GObject *object) remote_call_complete (self, priv->calls->data); g_object_unref (priv->proxy); - g_object_unref (priv->secrets_proxy); dbus_g_connection_unref (priv->bus); } diff --git a/libnm-glib/nm-remote-connection.h b/libnm-glib/nm-remote-connection.h index 0c627a604..809927ea4 100644 --- a/libnm-glib/nm-remote-connection.h +++ b/libnm-glib/nm-remote-connection.h @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2008 Novell, Inc. - * Copyright (C) 2007 - 2009 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #ifndef __NM_REMOTE_CONNECTION_H__ @@ -38,8 +38,8 @@ G_BEGIN_DECLS #define NM_IS_REMOTE_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_REMOTE_CONNECTION)) #define NM_REMOTE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_REMOTE_CONNECTION, NMRemoteConnectionClass)) -#define NM_REMOTE_CONNECTION_UPDATED "updated" -#define NM_REMOTE_CONNECTION_REMOVED "removed" +#define NM_REMOTE_CONNECTION_UPDATED "updated" +#define NM_REMOTE_CONNECTION_REMOVED "removed" typedef struct { NMConnection parent; @@ -91,8 +91,6 @@ void nm_remote_connection_delete (NMRemoteConnection *connection, void nm_remote_connection_get_secrets (NMRemoteConnection *connection, const char *setting_name, - const char **hints, - gboolean request_new, NMRemoteConnectionGetSecretsFunc callback, gpointer user_data); G_END_DECLS diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 2e88ee201..46c614439 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -570,10 +570,9 @@ request_start_secrets (gpointer user_data) nm_log_dbg (LOGD_AGENTS, "(%p/%s) getting secrets from system settings", req, req->setting_name); + /* Grab any secrets from persistent storage */ secrets = nm_sysconfig_connection_get_secrets (NM_SYSCONFIG_CONNECTION (req->connection), req->setting_name, - req->hint, - req->flags ? TRUE : FALSE, &error); if (secrets) setting_secrets = g_hash_table_lookup (secrets, req->setting_name); diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-sysconfig-connection.c index 3a280b943..40823562a 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-sysconfig-connection.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2010 Red Hat, Inc. + * (C) Copyright 2008 - 2011 Red Hat, Inc. */ #include @@ -47,8 +47,6 @@ static void impl_sysconfig_connection_delete (NMSysconfigConnection *connection, static void impl_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, const gchar *setting_name, - const gchar **hints, - gboolean request_new, DBusGMethodInvocation *context); #include "nm-sysconfig-connection-glue.h" @@ -410,11 +408,18 @@ destroy_gvalue (gpointer data) g_slice_free (GValue, value); } +/** + * nm_sysconfig_connection_get_secrets: + * @connection: the #NMSysconfigConnection + * @setting_name: the setting to return secrets for + * @error: an error on return, if an error occured + * + * Return secrets in persistent storage, if any. Does not query any Secret + * Agents for secrets. + **/ GHashTable * nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, const char *setting_name, - const char *hint, - gboolean request_new, GError **error) { NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); @@ -434,6 +439,8 @@ nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, return NULL; } + /* FIXME: if setting_name is empty, return all secrets */ + setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); if (!setting) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, @@ -739,19 +746,13 @@ impl_sysconfig_connection_delete (NMSysconfigConnection *self, auth_start (self, context, TRUE, delete_auth_cb, NULL); } -typedef struct { - char *setting_name; - char *hint; - gboolean request_new; -} GetSecretsInfo; - static void secrets_auth_cb (NMSysconfigConnection *self, DBusGMethodInvocation *context, GError *error, - gpointer data) + gpointer user_data) { - GetSecretsInfo *info = data; + char *setting_name = user_data; GHashTable *secrets; GError *local = NULL; @@ -760,11 +761,7 @@ secrets_auth_cb (NMSysconfigConnection *self, goto out; } - secrets = nm_sysconfig_connection_get_secrets (self, - info->setting_name, - info->hint, - info->request_new, - &error); + secrets = nm_sysconfig_connection_get_secrets (self, setting_name, &error); if (secrets) { dbus_g_method_return (context, secrets); g_hash_table_destroy (secrets); @@ -774,24 +771,15 @@ secrets_auth_cb (NMSysconfigConnection *self, } out: - g_free (info->setting_name); - g_free (info->hint); - g_slice_free (GetSecretsInfo, info); + g_free (setting_name); } static void impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, const gchar *setting_name, - const gchar **hints, - gboolean request_new, DBusGMethodInvocation *context) { - GetSecretsInfo *info = g_slice_new (GetSecretsInfo); - info->setting_name = g_strdup (setting_name); - info->hint = (hints && hints[0]) ? g_strdup (hints[0]) : NULL; - info->request_new = request_new; - - auth_start (self, context, TRUE, secrets_auth_cb, info); + auth_start (self, context, TRUE, secrets_auth_cb, g_strdup (setting_name)); } /**************************************************************/ diff --git a/src/settings/nm-sysconfig-connection.h b/src/settings/nm-sysconfig-connection.h index aaf926c1b..84196a366 100644 --- a/src/settings/nm-sysconfig-connection.h +++ b/src/settings/nm-sysconfig-connection.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2010 Red Hat, Inc. + * (C) Copyright 2008 - 2011 Red Hat, Inc. */ #ifndef NM_SYSCONFIG_CONNECTION_H @@ -90,8 +90,6 @@ void nm_sysconfig_connection_delete (NMSysconfigConnection *connection, GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, const char *setting_name, - const char *hint, - gboolean request_new, GError **error); gboolean nm_sysconfig_connection_is_visible (NMSysconfigConnection *self); From b92e3cca6e87583d0a6e896ed438cc06f9fc9ea8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 11:26:08 -0600 Subject: [PATCH 175/264] build: fix distcheck with gobject introspection enabled --- libnm-glib/Makefile.am | 2 +- libnm-util/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 40e43f89d..856dc89d9 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -247,7 +247,7 @@ introspection_sources = $(libnminclude_HEADERS) $(libnm_glib_la_csources) NMClient-1.0.gir: libnm-glib.la NMClient_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 NMClient_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 gudev-1.0 -NMClient_1_0_gir_CFLAGS = $(INCLUDES) +NMClient_1_0_gir_CFLAGS = $(INCLUDES) -I$(top_srcdir)/libnm-glib -I$(top_srcdir)/libnm-util NMClient_1_0_gir_LIBS = libnm-glib.la NMClient_1_0_gir_FILES = $(introspection_sources) NMClient_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm_ --include-uninstalled=$(top_builddir)/libnm-util/NetworkManager-1.0.gir diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 38109c0a5..15cf6126c 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -128,7 +128,7 @@ introspection_sources = $(libnm_util_include_HEADERS) $(libnm_util_la_csources) NetworkManager-1.0.gir: libnm-util.la NetworkManager_1_0_gir_INCLUDES = GObject-2.0 DBusGLib-1.0 NetworkManager_1_0_gir_PACKAGES = gobject-2.0 dbus-glib-1 -NetworkManager_1_0_gir_CFLAGS = $(INCLUDES) +NetworkManager_1_0_gir_CFLAGS = $(INCLUDES) -I$(top_srcdir)/libnm-util NetworkManager_1_0_gir_LIBS = libnm-util.la NetworkManager_1_0_gir_FILES = $(introspection_sources) NetworkManager_1_0_gir_SCANNERFLAGS = --warn-all --identifier-prefix=NM --symbol-prefix=nm_ From b3959aefa3025528359027c63bfe4c6671d4592e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 11:38:12 -0600 Subject: [PATCH 176/264] core: rename NMSysconfigConnection -> NMSettingsConnection --- docs/libnm-glib/Makefile.am | 2 +- introspection/Makefile.am | 2 +- introspection/all.xml | 2 +- ...nection.xml => nm-settings-connection.xml} | 8 +- libnm-glib/Makefile.am | 6 +- libnm-glib/nm-remote-connection.c | 2 +- src/nm-agent-manager.c | 10 +- src/nm-manager.c | 20 +- src/nm-policy.c | 16 +- src/settings/Makefile.am | 10 +- src/settings/nm-default-wired-connection.c | 24 +- src/settings/nm-default-wired-connection.h | 8 +- ...-connection.c => nm-settings-connection.c} | 277 +++++++++--------- src/settings/nm-settings-connection.h | 101 +++++++ src/settings/nm-settings.c | 84 +++--- src/settings/nm-settings.h | 22 +- src/settings/nm-sysconfig-connection.h | 101 ------- src/settings/nm-system-config-interface.c | 6 +- src/settings/nm-system-config-interface.h | 22 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.c | 22 +- .../plugins/ifcfg-rh/nm-ifcfg-connection.h | 8 +- system-settings/plugins/ifcfg-rh/plugin.c | 20 +- .../plugins/ifnet/nm-ifnet-connection.c | 24 +- .../plugins/ifnet/nm-ifnet-connection.h | 6 +- system-settings/plugins/ifnet/plugin.c | 18 +- .../plugins/ifupdown/nm-ifupdown-connection.c | 8 +- .../plugins/ifupdown/nm-ifupdown-connection.h | 6 +- system-settings/plugins/ifupdown/plugin.c | 16 +- .../plugins/keyfile/nm-keyfile-connection.c | 32 +- .../plugins/keyfile/nm-keyfile-connection.h | 8 +- system-settings/plugins/keyfile/plugin.c | 20 +- 31 files changed, 450 insertions(+), 461 deletions(-) rename introspection/{nm-sysconfig-connection.xml => nm-settings-connection.xml} (95%) rename src/settings/{nm-sysconfig-connection.c => nm-settings-connection.c} (70%) create mode 100644 src/settings/nm-settings-connection.h delete mode 100644 src/settings/nm-sysconfig-connection.h diff --git a/docs/libnm-glib/Makefile.am b/docs/libnm-glib/Makefile.am index cb077140d..66826cb8a 100644 --- a/docs/libnm-glib/Makefile.am +++ b/docs/libnm-glib/Makefile.am @@ -45,7 +45,7 @@ IGNORE_HFILES= \ nm-device-wifi-bindings.h \ nm-dhcp4-config-bindings.h \ nm-dhcp6-config-bindings.h \ - nm-sysconfig-connection-glue.h \ + nm-settings-connection-glue.h \ nm-ip4-config-bindings.h \ nm-ip6-config-bindings.h \ nm-settings-bindings.h \ diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 42640e302..8b4302b21 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -18,7 +18,7 @@ EXTRA_DIST = \ nm-manager.xml \ nm-manager-client.xml \ nm-settings.xml \ - nm-sysconfig-connection.xml \ + nm-settings-connection.xml \ nm-vpn-plugin.xml \ nm-vpn-connection.xml \ nm-ppp-manager.xml \ diff --git a/introspection/all.xml b/introspection/all.xml index fb2b749e8..edb22dc51 100644 --- a/introspection/all.xml +++ b/introspection/all.xml @@ -42,7 +42,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - + diff --git a/introspection/nm-sysconfig-connection.xml b/introspection/nm-settings-connection.xml similarity index 95% rename from introspection/nm-sysconfig-connection.xml rename to introspection/nm-settings-connection.xml index 2d53d65ce..82e53451c 100644 --- a/introspection/nm-sysconfig-connection.xml +++ b/introspection/nm-settings-connection.xml @@ -14,7 +14,7 @@ update request, and will be either stored in persistent storage or given to a Secret Agent for storage, depending on the request. - + @@ -27,7 +27,7 @@ Delete the connection. - + @@ -38,7 +38,7 @@ to the network, as those are often protected. Secrets must be requested separately using the GetSecrets() call. - + @@ -54,7 +54,7 @@ the requestor's session will be returned. The user will never be prompted for secrets as a result of this request. - + diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 856dc89d9..b6949781b 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -12,7 +12,7 @@ BUILT_SOURCES = \ nm-device-ethernet-bindings.h \ nm-device-wifi-bindings.h \ nm-device-bt-bindings.h \ - nm-sysconfig-connection-bindings.h \ + nm-settings-connection-bindings.h \ nm-device-wimax-bindings.h \ nm-settings-bindings.h \ nm-vpn-connection-bindings.h \ @@ -198,8 +198,8 @@ nm-access-point-bindings.h: $(top_srcdir)/introspection/nm-access-point.xml nm-settings-bindings.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-client --output=$@ $< -nm-sysconfig-connection-bindings.h: $(top_srcdir)/introspection/nm-sysconfig-connection.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_sysconfig_connection --mode=glib-client --output=$@ $< +nm-settings-connection-bindings.h: $(top_srcdir)/introspection/nm-settings-connection.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-client --output=$@ $< nm-vpn-connection-bindings.h: $(top_srcdir)/introspection/nm-vpn-connection.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-client --output=$@ $< diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 8b7e57596..b07c42945 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -29,7 +29,7 @@ #include "nm-remote-connection.h" #include "nm-remote-connection-private.h" #include "nm-dbus-glib-types.h" -#include "nm-sysconfig-connection-bindings.h" +#include "nm-settings-connection-bindings.h" #define NM_REMOTE_CONNECTION_BUS "bus" diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 46c614439..b4b776e32 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -31,7 +31,7 @@ #include "nm-agent-manager.h" #include "nm-secret-agent.h" #include "nm-manager-auth.h" -#include "nm-sysconfig-connection.h" +#include "nm-settings-connection.h" #include "nm-dbus-glib-types.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -571,9 +571,9 @@ request_start_secrets (gpointer user_data) req, req->setting_name); /* Grab any secrets from persistent storage */ - secrets = nm_sysconfig_connection_get_secrets (NM_SYSCONFIG_CONNECTION (req->connection), - req->setting_name, - &error); + secrets = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (req->connection), + req->setting_name, + &error); if (secrets) setting_secrets = g_hash_table_lookup (secrets, req->setting_name); @@ -795,7 +795,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, g_return_val_if_fail (self != NULL, 0); g_return_val_if_fail (connection != NULL, 0); - g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection), 0); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), 0); g_return_val_if_fail (callback != NULL, 0); nm_log_dbg (LOGD_SETTINGS, diff --git a/src/nm-manager.c b/src/nm-manager.c index 2247b3557..2f8cbdf4a 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -57,7 +57,7 @@ #include "nm-bluez-manager.h" #include "nm-bluez-common.h" #include "nm-settings.h" -#include "nm-sysconfig-connection.h" +#include "nm-settings-connection.h" #include "nm-manager-auth.h" #include "nm-agent-manager.h" #include "NetworkManagerUtils.h" @@ -480,7 +480,7 @@ nm_manager_update_state (NMManager *manager) } static void -ignore_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) +ignore_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { } @@ -509,7 +509,7 @@ update_active_connection_timestamp (NMManager *manager, NMDevice *device) if (nm_setting_connection_get_read_only (s_con)) return; - nm_sysconfig_connection_commit_changes (NM_SYSCONFIG_CONNECTION (connection), ignore_cb, NULL); + nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (connection), ignore_cb, NULL); } static void @@ -918,7 +918,7 @@ get_active_connections (NMManager *manager, NMConnection *filter) static void connections_changed (NMSettings *settings, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, NMManager *manager) { bluez_manager_resync_devices (manager); @@ -1995,7 +1995,7 @@ static void pending_activate (NMManager *self, PendingActivation *pending) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMSysconfigConnection *connection; + NMSettingsConnection *connection; const char *path = NULL; GError *error = NULL; @@ -2069,7 +2069,7 @@ impl_manager_activate_connection (NMManager *self, static void activation_add_done (NMSettings *self, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, GError *error, DBusGMethodInvocation *context, gpointer user_data) @@ -3097,13 +3097,13 @@ nm_manager_get (NMSettings *settings, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); - g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_ADDED, + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, G_CALLBACK (connections_changed), singleton); - g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_UPDATED, + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (connections_changed), singleton); - g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_REMOVED, + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK (connections_changed), singleton); - g_signal_connect (priv->settings, NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, G_CALLBACK (connections_changed), singleton); dbus_g_connection_register_g_object (bus, NM_DBUS_PATH, G_OBJECT (singleton)); diff --git a/src/nm-policy.c b/src/nm-policy.c index d31a2dd0b..23fc6ac73 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -741,7 +741,7 @@ auto_activate_device (gpointer user_data) /* Ignore connections that aren't visible to any logged-in users */ if (ignore == FALSE) { - if (!nm_sysconfig_connection_is_visible (NM_SYSCONFIG_CONNECTION (candidate))) + if (!nm_settings_connection_is_visible (NM_SETTINGS_CONNECTION (candidate))) ignore = TRUE; } @@ -1099,12 +1099,12 @@ connection_removed (NMSettings *settings, static void connection_visibility_changed (NMSettings *settings, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, gpointer user_data) { NMPolicy *policy = user_data; - if (nm_sysconfig_connection_is_visible (connection)) + if (nm_settings_connection_is_visible (connection)) schedule_activate_all (policy); else _deactivate_if_active (policy->manager, NM_CONNECTION (connection)); @@ -1169,11 +1169,11 @@ nm_policy_new (NMManager *manager, _connect_manager_signal (policy, "device-added", device_added); _connect_manager_signal (policy, "device-removed", device_removed); - _connect_settings_signal (policy, NM_SETTINGS_CONNECTIONS_LOADED, connections_loaded); - _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_ADDED, connection_added); - _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_UPDATED, connection_updated); - _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_REMOVED, connection_removed); - _connect_settings_signal (policy, NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, connections_loaded); + _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, connection_added); + _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, connection_updated); + _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, connection_removed); + _connect_settings_signal (policy, NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, connection_visibility_changed); initialized = TRUE; diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am index 927169cc2..ddb2e5a0a 100644 --- a/src/settings/Makefile.am +++ b/src/settings/Makefile.am @@ -9,7 +9,7 @@ noinst_LTLIBRARIES = libsettings.la BUILT_SOURCES = \ nm-settings-glue.h \ - nm-sysconfig-connection-glue.h + nm-settings-connection-glue.h libsettings_la_SOURCES = \ nm-settings.c \ @@ -21,8 +21,8 @@ libsettings_la_SOURCES = \ nm-settings-error.h \ nm-system-config-interface.c \ nm-system-config-interface.h \ - nm-sysconfig-connection.c \ - nm-sysconfig-connection.h \ + nm-settings-connection.c \ + nm-settings-connection.h \ nm-default-wired-connection.c \ nm-default-wired-connection.h @@ -56,8 +56,8 @@ libsettings_la_LDFLAGS = -rdynamic nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings --mode=glib-server --output=$@ $< -nm-sysconfig-connection-glue.h: $(top_srcdir)/introspection/nm-sysconfig-connection.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_sysconfig_connection --mode=glib-server --output=$@ $< +nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-server --output=$@ $< CLEANFILES = \ $(BUILT_SOURCES) diff --git a/src/settings/nm-default-wired-connection.c b/src/settings/nm-default-wired-connection.c index 63683480e..e8b9a1554 100644 --- a/src/settings/nm-default-wired-connection.c +++ b/src/settings/nm-default-wired-connection.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2009 Red Hat, Inc. + * (C) Copyright 2009 - 2011 Red Hat, Inc. */ #include @@ -32,7 +32,7 @@ #include "nm-marshal.h" #include "nm-default-wired-connection.h" -G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SYSCONFIG_CONNECTION) +G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SETTINGS_CONNECTION) #define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate)) @@ -85,8 +85,8 @@ nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired) } static void -commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, gpointer user_data) { NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection); @@ -101,17 +101,17 @@ commit_changes (NMSysconfigConnection *connection, } static void -do_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, gpointer user_data) { NMDefaultWiredConnection *self = NM_DEFAULT_WIRED_CONNECTION (connection); NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (connection); g_signal_emit (self, signals[DELETED], 0, priv->mac); - NM_SYSCONFIG_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->delete (connection, - callback, - user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_default_wired_connection_parent_class)->delete (connection, + callback, + user_data); } /****************************************************************/ @@ -237,7 +237,7 @@ static void nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (klass); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (klass); g_type_class_add_private (klass, sizeof (NMDefaultWiredConnectionPrivate)); @@ -246,8 +246,8 @@ nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - sysconfig_class->commit_changes = commit_changes; - sysconfig_class->delete = do_delete; + settings_class->commit_changes = commit_changes; + settings_class->delete = do_delete; /* Properties */ g_object_class_install_property diff --git a/src/settings/nm-default-wired-connection.h b/src/settings/nm-default-wired-connection.h index de89b6756..9a3bafd02 100644 --- a/src/settings/nm-default-wired-connection.h +++ b/src/settings/nm-default-wired-connection.h @@ -16,13 +16,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2009 Red Hat, Inc. + * (C) Copyright 2009 - 2011 Red Hat, Inc. */ #ifndef NM_DEFAULT_WIRED_CONNECTION_H #define NM_DEFAULT_WIRED_CONNECTION_H -#include "nm-sysconfig-connection.h" +#include "nm-settings-connection.h" #include "nm-device.h" G_BEGIN_DECLS @@ -39,11 +39,11 @@ G_BEGIN_DECLS #define NM_DEFAULT_WIRED_CONNECTION_READ_ONLY "read-only" typedef struct { - NMSysconfigConnection parent; + NMSettingsConnection parent; } NMDefaultWiredConnection; typedef struct { - NMSysconfigConnectionClass parent; + NMSettingsConnectionClass parent; } NMDefaultWiredConnectionClass; GType nm_default_wired_connection_get_type (void); diff --git a/src/settings/nm-sysconfig-connection.c b/src/settings/nm-settings-connection.c similarity index 70% rename from src/settings/nm-sysconfig-connection.c rename to src/settings/nm-settings-connection.c index 40823562a..5977ebad6 100644 --- a/src/settings/nm-sysconfig-connection.c +++ b/src/settings/nm-settings-connection.c @@ -26,7 +26,7 @@ #include #include -#include "nm-sysconfig-connection.h" +#include "nm-settings-connection.h" #include "nm-session-monitor.h" #include "nm-dbus-manager.h" #include "nm-settings-error.h" @@ -35,27 +35,27 @@ #include "nm-logging.h" #include "nm-manager-auth.h" -static void impl_sysconfig_connection_get_settings (NMSysconfigConnection *connection, - DBusGMethodInvocation *context); - -static void impl_sysconfig_connection_update (NMSysconfigConnection *connection, - GHashTable *new_settings, - DBusGMethodInvocation *context); - -static void impl_sysconfig_connection_delete (NMSysconfigConnection *connection, - DBusGMethodInvocation *context); - -static void impl_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, - const gchar *setting_name, +static void impl_settings_connection_get_settings (NMSettingsConnection *connection, DBusGMethodInvocation *context); -#include "nm-sysconfig-connection-glue.h" +static void impl_settings_connection_update (NMSettingsConnection *connection, + GHashTable *new_settings, + DBusGMethodInvocation *context); -G_DEFINE_TYPE (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_CONNECTION) +static void impl_settings_connection_delete (NMSettingsConnection *connection, + DBusGMethodInvocation *context); -#define NM_SYSCONFIG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_SYSCONFIG_CONNECTION, \ - NMSysconfigConnectionPrivate)) +static void impl_settings_connection_get_secrets (NMSettingsConnection *connection, + const gchar *setting_name, + DBusGMethodInvocation *context); + +#include "nm-settings-connection-glue.h" + +G_DEFINE_TYPE (NMSettingsConnection, nm_settings_connection, NM_TYPE_CONNECTION) + +#define NM_SETTINGS_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_SETTINGS_CONNECTION, \ + NMSettingsConnectionPrivate)) enum { PROP_0 = 0, @@ -77,7 +77,7 @@ typedef struct { NMSessionMonitor *session_monitor; guint session_changed_id; -} NMSysconfigConnectionPrivate; +} NMSettingsConnectionPrivate; /**************************************************************/ @@ -113,37 +113,36 @@ perm_to_user (const char *perm, char *out_user, gsize out_user_size) /**************************************************************/ static void -set_visible (NMSysconfigConnection *self, gboolean new_visible) +set_visible (NMSettingsConnection *self, gboolean new_visible) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); if (new_visible == priv->visible) return; priv->visible = new_visible; - g_object_notify (G_OBJECT (self), NM_SYSCONFIG_CONNECTION_VISIBLE); + g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_VISIBLE); } gboolean -nm_sysconfig_connection_is_visible (NMSysconfigConnection *self) +nm_settings_connection_is_visible (NMSettingsConnection *self) { - g_return_val_if_fail (NM_SYSCONFIG_CONNECTION (self), FALSE); + g_return_val_if_fail (NM_SETTINGS_CONNECTION (self), FALSE); - return NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self)->visible; + return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->visible; } void -nm_sysconfig_connection_recheck_visibility (NMSysconfigConnection *self) +nm_settings_connection_recheck_visibility (NMSettingsConnection *self) { - NMSysconfigConnectionPrivate *priv; + NMSettingsConnectionPrivate *priv; NMSettingConnection *s_con; guint32 num, i; - g_return_if_fail (NM_SYSCONFIG_CONNECTION (self)); + g_return_if_fail (NM_SETTINGS_CONNECTION (self)); - priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (self), - NM_TYPE_SETTING_CONNECTION)); + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); g_assert (s_con); /* Check every user in the ACL for a session */ @@ -174,7 +173,7 @@ nm_sysconfig_connection_recheck_visibility (NMSysconfigConnection *self) static void session_changed_cb (NMSessionMonitor *self, gpointer user_data) { - nm_sysconfig_connection_recheck_visibility (NM_SYSCONFIG_CONNECTION (user_data)); + nm_settings_connection_recheck_visibility (NM_SETTINGS_CONNECTION (user_data)); } /**************************************************************/ @@ -182,20 +181,20 @@ session_changed_cb (NMSessionMonitor *self, gpointer user_data) /* Update the settings of this connection to match that of 'new', taking care to * make a private copy of secrets. */ gboolean -nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, - NMConnection *new, - GError **error) +nm_settings_connection_replace_settings (NMSettingsConnection *self, + NMConnection *new, + GError **error) { - NMSysconfigConnectionPrivate *priv; + NMSettingsConnectionPrivate *priv; GHashTable *new_settings; gboolean success = FALSE; g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (self), FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), FALSE); g_return_val_if_fail (new != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (new), FALSE); - priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); new_settings = nm_connection_to_hash (new); g_assert (new_settings); @@ -207,7 +206,7 @@ nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, g_object_unref (priv->secrets); priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); - nm_sysconfig_connection_recheck_visibility (self); + nm_settings_connection_recheck_visibility (self); success = TRUE; } g_hash_table_destroy (new_settings); @@ -215,7 +214,7 @@ nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, } static void -ignore_cb (NMSysconfigConnection *connection, +ignore_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -227,15 +226,15 @@ ignore_cb (NMSysconfigConnection *connection, * 'user_data' along with any errors encountered. */ void -nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, - NMConnection *new, - NMSysconfigConnectionCommitFunc callback, - gpointer user_data) +nm_settings_connection_replace_and_commit (NMSettingsConnection *self, + NMConnection *new, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) { GError *error = NULL; g_return_if_fail (self != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (self)); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (self)); g_return_if_fail (new != NULL); g_return_if_fail (NM_IS_CONNECTION (new)); @@ -246,12 +245,12 @@ nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, if (nm_connection_compare (NM_CONNECTION (self), NM_CONNECTION (new), NM_SETTING_COMPARE_FLAG_EXACT)) { - callback (self, NULL, user_data); - return; + callback (self, NULL, user_data); + return; } - if (nm_sysconfig_connection_replace_settings (self, new, &error)) { - nm_sysconfig_connection_commit_changes (self, callback, user_data); + if (nm_settings_connection_replace_settings (self, new, &error)) { + nm_settings_connection_commit_changes (self, callback, user_data); } else { callback (self, error, user_data); g_clear_error (&error); @@ -259,18 +258,18 @@ nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, } void -nm_sysconfig_connection_commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, - gpointer user_data) +nm_settings_connection_commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data) { g_return_if_fail (connection != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); g_return_if_fail (callback != NULL); - if (NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->commit_changes) { - NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->commit_changes (connection, - callback, - user_data); + if (NM_SETTINGS_CONNECTION_GET_CLASS (connection)->commit_changes) { + NM_SETTINGS_CONNECTION_GET_CLASS (connection)->commit_changes (connection, + callback, + user_data); } else { GError *error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR, @@ -281,18 +280,18 @@ nm_sysconfig_connection_commit_changes (NMSysconfigConnection *connection, } void -nm_sysconfig_connection_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, - gpointer user_data) +nm_settings_connection_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) { g_return_if_fail (connection != NULL); - g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); g_return_if_fail (callback != NULL); - if (NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->delete) { - NM_SYSCONFIG_CONNECTION_GET_CLASS (connection)->delete (connection, - callback, - user_data); + if (NM_SETTINGS_CONNECTION_GET_CLASS (connection)->delete) { + NM_SETTINGS_CONNECTION_GET_CLASS (connection)->delete (connection, + callback, + user_data); } else { GError *error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INTERNAL_ERROR, @@ -303,8 +302,8 @@ nm_sysconfig_connection_delete (NMSysconfigConnection *connection, } static void -commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, gpointer user_data) { g_object_ref (connection); @@ -314,9 +313,9 @@ commit_changes (NMSysconfigConnection *connection, } static void -do_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, - gpointer user_data) +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data) { g_object_ref (connection); set_visible (connection, FALSE); @@ -328,7 +327,7 @@ do_delete (NMSysconfigConnection *connection, /**************************************************************/ static gboolean -supports_secrets (NMSysconfigConnection *connection, const char *setting_name) +supports_secrets (NMSettingsConnection *connection, const char *setting_name) { /* All secrets supported */ return TRUE; @@ -409,8 +408,8 @@ destroy_gvalue (gpointer data) } /** - * nm_sysconfig_connection_get_secrets: - * @connection: the #NMSysconfigConnection + * nm_settings_connection_get_secrets: + * @connection: the #NMSettingsConnection * @setting_name: the setting to return secrets for * @error: an error on return, if an error occured * @@ -418,11 +417,11 @@ destroy_gvalue (gpointer data) * Agents for secrets. **/ GHashTable * -nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, - const char *setting_name, - GError **error) +nm_settings_connection_get_secrets (NMSettingsConnection *connection, + const char *setting_name, + GError **error) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (connection); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); GHashTable *settings = NULL; GHashTable *secrets = NULL; NMSetting *setting; @@ -430,7 +429,7 @@ nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() * will clear secrets on this object's settings. priv->secrets should be * a complete copy of this object and kept in sync by - * nm_sysconfig_connection_replace_settings(). + * nm_settings_connection_replace_settings(). */ if (!priv->secrets) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -466,10 +465,10 @@ nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, /**** User authorization **************************************/ -typedef void (*AuthCallback) (NMSysconfigConnection *connection, - DBusGMethodInvocation *context, - GError *error, - gpointer data); +typedef void (*AuthCallback) (NMSettingsConnection *connection, + DBusGMethodInvocation *context, + GError *error, + gpointer data); static void pk_auth_cb (NMAuthChain *chain, @@ -477,8 +476,8 @@ pk_auth_cb (NMAuthChain *chain, DBusGMethodInvocation *context, gpointer user_data) { - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (user_data); - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GError *error = NULL; NMAuthCallResult result; AuthCallback callback; @@ -486,7 +485,7 @@ pk_auth_cb (NMAuthChain *chain, priv->pending_auths = g_slist_remove (priv->pending_auths, chain); - /* If our NMSysconfigConnection is already gone, do nothing */ + /* If our NMSettingsConnection is already gone, do nothing */ if (chain_error) { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_GENERAL, @@ -498,8 +497,8 @@ pk_auth_cb (NMAuthChain *chain, /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - "Insufficient privileges."); + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Insufficient privileges."); } } @@ -512,13 +511,13 @@ pk_auth_cb (NMAuthChain *chain, } static void -auth_start (NMSysconfigConnection *self, +auth_start (NMSettingsConnection *self, DBusGMethodInvocation *context, gboolean check_modify, AuthCallback callback, gpointer callback_data) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMAuthChain *chain; gulong sender_uid = G_MAXULONG; GError *error = NULL; @@ -540,8 +539,8 @@ auth_start (NMSysconfigConnection *self, sender_uid, &error_desc)) { error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); g_free (error_desc); goto error; } @@ -576,8 +575,7 @@ check_writable (NMConnection *connection, GError **error) g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_CONNECTION); + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); if (!s_con) { g_set_error_literal (error, NM_SETTINGS_ERROR, @@ -602,7 +600,7 @@ check_writable (NMConnection *connection, GError **error) } static void -get_settings_auth_cb (NMSysconfigConnection *self, +get_settings_auth_cb (NMSettingsConnection *self, DBusGMethodInvocation *context, GError *error, gpointer data) @@ -632,14 +630,14 @@ get_settings_auth_cb (NMSysconfigConnection *self, } static void -impl_sysconfig_connection_get_settings (NMSysconfigConnection *self, - DBusGMethodInvocation *context) +impl_settings_connection_get_settings (NMSettingsConnection *self, + DBusGMethodInvocation *context) { auth_start (self, context, FALSE, get_settings_auth_cb, NULL); } static void -con_update_cb (NMSysconfigConnection *connection, +con_update_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -652,10 +650,10 @@ con_update_cb (NMSysconfigConnection *connection, } static void -update_auth_cb (NMSysconfigConnection *self, - DBusGMethodInvocation *context, - GError *error, - gpointer data) +update_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer data) { NMConnection *new_settings = data; @@ -665,19 +663,19 @@ update_auth_cb (NMSysconfigConnection *self, } /* Update and commit our settings. */ - nm_sysconfig_connection_replace_and_commit (self, - new_settings, - con_update_cb, - context); + nm_settings_connection_replace_and_commit (self, + new_settings, + con_update_cb, + context); out: g_object_unref (new_settings); } static void -impl_sysconfig_connection_update (NMSysconfigConnection *self, - GHashTable *new_settings, - DBusGMethodInvocation *context) +impl_settings_connection_update (NMSettingsConnection *self, + GHashTable *new_settings, + DBusGMethodInvocation *context) { NMConnection *tmp; GError *error = NULL; @@ -705,7 +703,7 @@ impl_sysconfig_connection_update (NMSysconfigConnection *self, } static void -con_delete_cb (NMSysconfigConnection *connection, +con_delete_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -718,22 +716,22 @@ con_delete_cb (NMSysconfigConnection *connection, } static void -delete_auth_cb (NMSysconfigConnection *self, - DBusGMethodInvocation *context, - GError *error, - gpointer data) +delete_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer data) { if (error) { dbus_g_method_return_error (context, error); return; } - nm_sysconfig_connection_delete (self, con_delete_cb, context); + nm_settings_connection_delete (self, con_delete_cb, context); } static void -impl_sysconfig_connection_delete (NMSysconfigConnection *self, - DBusGMethodInvocation *context) +impl_settings_connection_delete (NMSettingsConnection *self, + DBusGMethodInvocation *context) { GError *error = NULL; @@ -747,10 +745,10 @@ impl_sysconfig_connection_delete (NMSysconfigConnection *self, } static void -secrets_auth_cb (NMSysconfigConnection *self, - DBusGMethodInvocation *context, - GError *error, - gpointer user_data) +secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer user_data) { char *setting_name = user_data; GHashTable *secrets; @@ -761,7 +759,7 @@ secrets_auth_cb (NMSysconfigConnection *self, goto out; } - secrets = nm_sysconfig_connection_get_secrets (self, setting_name, &error); + secrets = nm_settings_connection_get_secrets (self, setting_name, &error); if (secrets) { dbus_g_method_return (context, secrets); g_hash_table_destroy (secrets); @@ -775,9 +773,9 @@ out: } static void -impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, - const gchar *setting_name, - DBusGMethodInvocation *context) +impl_settings_connection_get_secrets (NMSettingsConnection *self, + const gchar *setting_name, + DBusGMethodInvocation *context) { auth_start (self, context, TRUE, secrets_auth_cb, g_strdup (setting_name)); } @@ -785,9 +783,9 @@ impl_sysconfig_connection_get_secrets (NMSysconfigConnection *self, /**************************************************************/ static void -nm_sysconfig_connection_init (NMSysconfigConnection *self) +nm_settings_connection_init (NMSettingsConnection *self) { - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); static guint32 dbus_counter = 0; char *dbus_path; GError *error = NULL; @@ -801,7 +799,7 @@ nm_sysconfig_connection_init (NMSysconfigConnection *self) } dbus_path = g_strdup_printf ("%s/%u", NM_DBUS_PATH_SETTINGS, dbus_counter++); - nm_connection_set_path (NM_CONNECTION (self), dbus_path); + nm_connection_set_path (NM_CONNECTION (self), dbus_path); g_free (dbus_path); priv->visible = FALSE; @@ -815,8 +813,8 @@ nm_sysconfig_connection_init (NMSysconfigConnection *self) static void dispose (GObject *object) { - NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (object); - NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GSList *iter; if (priv->secrets) @@ -832,16 +830,16 @@ dispose (GObject *object) g_object_unref (priv->session_monitor); - G_OBJECT_CLASS (nm_sysconfig_connection_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); } static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { switch (prop_id) { case PROP_VISIBLE: - g_value_set_boolean (value, NM_SYSCONFIG_CONNECTION_GET_PRIVATE (object)->visible); + g_value_set_boolean (value, NM_SETTINGS_CONNECTION_GET_PRIVATE (object)->visible); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -851,17 +849,17 @@ get_property (GObject *object, guint prop_id, static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } static void -nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) +nm_settings_connection_class_init (NMSettingsConnectionClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - g_type_class_add_private (class, sizeof (NMSysconfigConnectionPrivate)); + g_type_class_add_private (class, sizeof (NMSettingsConnectionPrivate)); /* Virtual methods */ object_class->dispose = dispose; @@ -875,7 +873,7 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) /* Properties */ g_object_class_install_property (object_class, PROP_VISIBLE, - g_param_spec_boolean (NM_SYSCONFIG_CONNECTION_VISIBLE, + g_param_spec_boolean (NM_SETTINGS_CONNECTION_VISIBLE, "Visible", "Visible", FALSE, @@ -883,7 +881,7 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) /* Signals */ signals[UPDATED] = - g_signal_new (NM_SYSCONFIG_CONNECTION_UPDATED, + g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_FIRST, 0, @@ -892,7 +890,7 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) G_TYPE_NONE, 0); signals[REMOVED] = - g_signal_new (NM_SYSCONFIG_CONNECTION_REMOVED, + g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_FIRST, 0, @@ -901,6 +899,5 @@ nm_sysconfig_connection_class_init (NMSysconfigConnectionClass *class) G_TYPE_NONE, 0); dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), - &dbus_glib_nm_sysconfig_connection_object_info); - + &dbus_glib_nm_settings_connection_object_info); } diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h new file mode 100644 index 000000000..e62aa4b97 --- /dev/null +++ b/src/settings/nm-settings-connection.h @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager system settings service + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * (C) Copyright 2008 Novell, Inc. + * (C) Copyright 2008 - 2011 Red Hat, Inc. + */ + +#ifndef NM_SETTINGS_CONNECTION_H +#define NM_SETTINGS_CONNECTION_H + +#include +#include + +G_BEGIN_DECLS + +#define NM_TYPE_SETTINGS_CONNECTION (nm_settings_connection_get_type ()) +#define NM_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnection)) +#define NM_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) +#define NM_IS_SETTINGS_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION)) +#define NM_IS_SETTINGS_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTINGS_CONNECTION)) +#define NM_SETTINGS_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_CONNECTION, NMSettingsConnectionClass)) + +#define NM_SETTINGS_CONNECTION_UPDATED "updated" +#define NM_SETTINGS_CONNECTION_REMOVED "removed" +#define NM_SETTINGS_CONNECTION_VISIBLE "visible" + +typedef struct _NMSettingsConnection NMSettingsConnection; + +typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; + +typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *connection, + GError *error, + gpointer user_data); + +typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection, + GError *error, + gpointer user_data); + +struct _NMSettingsConnection { + NMConnection parent; +}; + +struct _NMSettingsConnectionClass { + NMConnectionClass parent; + + void (*commit_changes) (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + + void (*delete) (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data); + + gboolean (*supports_secrets) (NMSettingsConnection *connection, + const char *setting_name); +}; + +GType nm_settings_connection_get_type (void); + +void nm_settings_connection_commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + +gboolean nm_settings_connection_replace_settings (NMSettingsConnection *self, + NMConnection *new_settings, + GError **error); + +void nm_settings_connection_replace_and_commit (NMSettingsConnection *self, + NMConnection *new_settings, + NMSettingsConnectionCommitFunc callback, + gpointer user_data); + +void nm_settings_connection_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, + gpointer user_data); + +GHashTable *nm_settings_connection_get_secrets (NMSettingsConnection *connection, + const char *setting_name, + GError **error); + +gboolean nm_settings_connection_is_visible (NMSettingsConnection *self); + +void nm_settings_connection_recheck_visibility (NMSettingsConnection *self); + +G_END_DECLS + +#endif /* NM_SETTINGS_CONNECTION_H */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 2f299c8d6..542c398a6 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -54,7 +54,7 @@ #include "../nm-device-ethernet.h" #include "nm-dbus-glib-types.h" #include "nm-settings.h" -#include "nm-sysconfig-connection.h" +#include "nm-settings-connection.h" #include "nm-polkit-helpers.h" #include "nm-settings-error.h" #include "nm-default-wired-connection.h" @@ -75,13 +75,13 @@ EXPORT(nm_inotify_helper_get) EXPORT(nm_inotify_helper_add_watch) EXPORT(nm_inotify_helper_remove_watch) -EXPORT(nm_sysconfig_connection_get_type) -EXPORT(nm_sysconfig_connection_replace_settings) -EXPORT(nm_sysconfig_connection_replace_and_commit) +EXPORT(nm_settings_connection_get_type) +EXPORT(nm_settings_connection_replace_settings) +EXPORT(nm_settings_connection_replace_and_commit) /* END LINKER CRACKROCK */ static void claim_connection (NMSettings *self, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, gboolean do_export); static gboolean impl_settings_list_connections (NMSettings *self, @@ -164,7 +164,7 @@ load_connections (NMSettings *self) // priority plugin. for (elt = plugin_connections; elt; elt = g_slist_next (elt)) - claim_connection (self, NM_SYSCONFIG_CONNECTION (elt->data), TRUE); + claim_connection (self, NM_SETTINGS_CONNECTION (elt->data), TRUE); g_slist_free (plugin_connections); } @@ -196,7 +196,7 @@ nm_settings_for_each_connection (NMSettings *self, g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) - for_each_func (self, NM_SYSCONFIG_CONNECTION (data), user_data); + for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data); } static gboolean @@ -243,7 +243,7 @@ connection_sort (gconstpointer pa, gconstpointer pb) return 1; } -/* Returns a list of NMSysconfigConnections. Caller must free the list with +/* Returns a list of NMSettingsConnections. Caller must free the list with * g_slist_free(). */ GSList * @@ -261,7 +261,7 @@ nm_settings_get_connections (NMSettings *self) return list; } -NMSysconfigConnection * +NMSettingsConnection * nm_settings_get_connection_by_path (NMSettings *self, const char *path) { NMSettingsPrivate *priv; @@ -274,7 +274,7 @@ nm_settings_get_connection_by_path (NMSettings *self, const char *path) load_connections (self); - return (NMSysconfigConnection *) g_hash_table_lookup (priv->connections, path); + return (NMSettingsConnection *) g_hash_table_lookup (priv->connections, path); } static void @@ -389,7 +389,7 @@ nm_settings_get_hostname (NMSettings *self) static void plugin_connection_added (NMSystemConfigInterface *config, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, gpointer user_data) { claim_connection (NM_SETTINGS (user_data), connection, TRUE); @@ -586,7 +586,7 @@ load_plugins (NMSettings *self, const char *plugins, GError **error) #define VISIBLE_ID_TAG "visible-id-tag" static void -connection_removed (NMSysconfigConnection *obj, gpointer user_data) +connection_removed (NMSettingsConnection *obj, gpointer user_data) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data); GObject *connection = G_OBJECT (obj); @@ -626,7 +626,7 @@ connection_removed (NMSysconfigConnection *obj, gpointer user_data) } static void -connection_updated (NMSysconfigConnection *connection, gpointer user_data) +connection_updated (NMSettingsConnection *connection, gpointer user_data) { /* Re-emit for listeners like NMPolicy */ g_signal_emit (NM_SETTINGS (user_data), @@ -636,7 +636,7 @@ connection_updated (NMSysconfigConnection *connection, gpointer user_data) } static void -connection_visibility_changed (NMSysconfigConnection *connection, +connection_visibility_changed (NMSettingsConnection *connection, GParamSpec *pspec, gpointer user_data) { @@ -649,7 +649,7 @@ connection_visibility_changed (NMSysconfigConnection *connection, static void claim_connection (NMSettings *self, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, gboolean do_export) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); @@ -660,7 +660,7 @@ claim_connection (NMSettings *self, char *path; guint id; - g_return_if_fail (NM_IS_SYSCONFIG_CONNECTION (connection)); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); g_return_if_fail (nm_connection_get_path (NM_CONNECTION (connection)) == NULL); g_hash_table_iter_init (&iter, priv->connections); @@ -679,19 +679,19 @@ claim_connection (NMSettings *self, } /* Ensure it's initial visibility is up-to-date */ - nm_sysconfig_connection_recheck_visibility (connection); + nm_settings_connection_recheck_visibility (connection); - id = g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_REMOVED, + id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id)); - id = g_signal_connect (connection, NM_SYSCONFIG_CONNECTION_UPDATED, + id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED, G_CALLBACK (connection_updated), self); g_object_set_data (G_OBJECT (connection), UPDATED_ID_TAG, GUINT_TO_POINTER (id)); - id = g_signal_connect (connection, "notify::" NM_SYSCONFIG_CONNECTION_VISIBLE, + id = g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_VISIBLE, G_CALLBACK (connection_visibility_changed), self); g_object_set_data (G_OBJECT (connection), VISIBLE_ID_TAG, GUINT_TO_POINTER (id)); @@ -726,31 +726,31 @@ claim_connection (NMSettings *self, // *needs* a better name! static void remove_default_wired_connection (NMSettings *self, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, gboolean do_signal) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); const char *path = nm_connection_get_path (NM_CONNECTION (connection)); if (g_hash_table_lookup (priv->connections, path)) { - g_signal_emit_by_name (G_OBJECT (connection), NM_SYSCONFIG_CONNECTION_REMOVED); + g_signal_emit_by_name (G_OBJECT (connection), NM_SETTINGS_SIGNAL_CONNECTION_REMOVED); g_hash_table_remove (priv->connections, path); } } -static NMSysconfigConnection * +static NMSettingsConnection * add_new_connection (NMSettings *self, NMConnection *connection, GError **error) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; - NMSysconfigConnection *added = NULL; + NMSettingsConnection *added = NULL; /* 1) plugin writes the NMConnection to disk - * 2) plugin creates a new NMSysconfigConnection subclass with the settings + * 2) plugin creates a new NMSettingsConnection subclass with the settings * from the NMConnection and returns it to the settings service - * 3) settings service exports the new NMSysconfigConnection subclass + * 3) settings service exports the new NMSettingsConnection subclass * 4) plugin notices that something on the filesystem has changed * 5) plugin reads the changes and ignores them because they will * contain the same data as the connection it already knows about @@ -781,7 +781,7 @@ pk_add_cb (NMAuthChain *chain, NMAuthCallResult result; GError *error = NULL, *add_error = NULL; NMConnection *connection; - NMSysconfigConnection *added = NULL; + NMSettingsConnection *added = NULL; gulong caller_uid = G_MAXULONG; char *error_desc = NULL; NMSettingsAddCallback callback; @@ -858,7 +858,7 @@ done: static void add_cb (NMSettings *self, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, GError *error, DBusGMethodInvocation *context, gpointer user_data) @@ -935,7 +935,7 @@ pk_hostname_cb (NMAuthChain *chain, priv->auths = g_slist_remove (priv->auths, chain); - /* If our NMSysconfigConnection is already gone, do nothing */ + /* If our NMSettingsConnection is already gone, do nothing */ if (chain_error) { error = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_GENERAL, @@ -1209,7 +1209,7 @@ cleanup: } static void -delete_cb (NMSysconfigConnection *connection, GError *error, gpointer user_data) +delete_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { } @@ -1220,7 +1220,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, GError *error = NULL; NMSettingConnection *s_con; const char *id; - NMSysconfigConnection *added; + NMSettingsConnection *added; /* Try to move this default wired conneciton to a plugin so that it has * persistent storage. @@ -1232,12 +1232,10 @@ default_wired_try_update (NMDefaultWiredConnection *wired, id = nm_setting_connection_get_id (s_con); g_assert (id); - remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); + remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE); added = add_new_connection (self, NM_CONNECTION (wired), &error); if (added) { - nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (wired), - delete_cb, - NULL); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (wired), delete_cb, NULL); g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), DEFAULT_WIRED_TAG, @@ -1256,7 +1254,7 @@ default_wired_try_update (NMDefaultWiredConnection *wired, * but add it back to the system settings service. Connection is already * exported on the bus, don't export it again, thus do_export == FALSE. */ - claim_connection (self, NM_SYSCONFIG_CONNECTION (wired), FALSE); + claim_connection (self, NM_SETTINGS_CONNECTION (wired), FALSE); return TRUE; } @@ -1307,7 +1305,7 @@ nm_settings_device_added (NMSettings *self, NMDevice *device) g_signal_connect (wired, "try-update", (GCallback) default_wired_try_update, self); g_signal_connect (wired, "deleted", (GCallback) default_wired_deleted, self); - claim_connection (self, NM_SYSCONFIG_CONNECTION (wired), TRUE); + claim_connection (self, NM_SETTINGS_CONNECTION (wired), TRUE); g_object_unref (wired); g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, wired); @@ -1326,7 +1324,7 @@ nm_settings_device_removed (NMSettings *self, NMDevice *device) connection = (NMDefaultWiredConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG); if (connection) - remove_default_wired_connection (self, NM_SYSCONFIG_CONNECTION (connection), TRUE); + remove_default_wired_connection (self, NM_SETTINGS_CONNECTION (connection), TRUE); } /***************************************************************/ @@ -1508,7 +1506,7 @@ nm_settings_class_init (NMSettingsClass *class) g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT); signals[CONNECTION_ADDED] = - g_signal_new (NM_SETTINGS_CONNECTION_ADDED, + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_ADDED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMSettingsClass, connection_added), @@ -1517,7 +1515,7 @@ nm_settings_class_init (NMSettingsClass *class) G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_UPDATED] = - g_signal_new (NM_SETTINGS_CONNECTION_UPDATED, + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMSettingsClass, connection_updated), @@ -1526,7 +1524,7 @@ nm_settings_class_init (NMSettingsClass *class) G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_REMOVED] = - g_signal_new (NM_SETTINGS_CONNECTION_REMOVED, + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMSettingsClass, connection_removed), @@ -1535,7 +1533,7 @@ nm_settings_class_init (NMSettingsClass *class) G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTION_VISIBILITY_CHANGED] = - g_signal_new (NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED, + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed), @@ -1544,7 +1542,7 @@ nm_settings_class_init (NMSettingsClass *class) G_TYPE_NONE, 1, G_TYPE_OBJECT); signals[CONNECTIONS_LOADED] = - g_signal_new (NM_SETTINGS_CONNECTIONS_LOADED, + g_signal_new (NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMSettingsClass, connections_loaded), diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 0ba3170d1..9b478ca92 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -28,7 +28,7 @@ #include -#include "nm-sysconfig-connection.h" +#include "nm-settings-connection.h" #include "nm-system-config-interface.h" #include "nm-device.h" @@ -43,11 +43,11 @@ #define NM_SETTINGS_HOSTNAME "hostname" #define NM_SETTINGS_CAN_MODIFY "can-modify" -#define NM_SETTINGS_CONNECTION_ADDED "connection-added" -#define NM_SETTINGS_CONNECTION_UPDATED "connection-updated" -#define NM_SETTINGS_CONNECTION_REMOVED "connection-removed" -#define NM_SETTINGS_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" -#define NM_SETTINGS_CONNECTIONS_LOADED "connections-loaded" +#define NM_SETTINGS_SIGNAL_CONNECTION_ADDED "connection-added" +#define NM_SETTINGS_SIGNAL_CONNECTION_UPDATED "connection-updated" +#define NM_SETTINGS_SIGNAL_CONNECTION_REMOVED "connection-removed" +#define NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED "connection-visibility-changed" +#define NM_SETTINGS_SIGNAL_CONNECTIONS_LOADED "connections-loaded" typedef struct { GObject parent_instance; @@ -77,7 +77,7 @@ NMSettings *nm_settings_new (const char *config_file, GError **error); typedef void (*NMSettingsForEachFunc) (NMSettings *settings, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, gpointer user_data); void nm_settings_for_each_connection (NMSettings *settings, @@ -85,7 +85,7 @@ void nm_settings_for_each_connection (NMSettings *settings, gpointer user_data); typedef void (*NMSettingsAddCallback) (NMSettings *settings, - NMSysconfigConnection *connection, + NMSettingsConnection *connection, GError *error, DBusGMethodInvocation *context, gpointer user_data); @@ -96,13 +96,13 @@ void nm_settings_add_connection (NMSettings *self, NMSettingsAddCallback callback, gpointer user_data); -/* Returns a list of NMSysconfigConnections. Caller must free the list with +/* Returns a list of NMSettingsConnections. Caller must free the list with * g_slist_free(). */ GSList *nm_settings_get_connections (NMSettings *settings); -NMSysconfigConnection *nm_settings_get_connection_by_path (NMSettings *settings, - const char *path); +NMSettingsConnection *nm_settings_get_connection_by_path (NMSettings *settings, + const char *path); const GSList *nm_settings_get_unmanaged_specs (NMSettings *self); diff --git a/src/settings/nm-sysconfig-connection.h b/src/settings/nm-sysconfig-connection.h deleted file mode 100644 index 84196a366..000000000 --- a/src/settings/nm-sysconfig-connection.h +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager system settings service - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * (C) Copyright 2008 Novell, Inc. - * (C) Copyright 2008 - 2011 Red Hat, Inc. - */ - -#ifndef NM_SYSCONFIG_CONNECTION_H -#define NM_SYSCONFIG_CONNECTION_H - -#include -#include - -G_BEGIN_DECLS - -#define NM_TYPE_SYSCONFIG_CONNECTION (nm_sysconfig_connection_get_type ()) -#define NM_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnection)) -#define NM_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) -#define NM_IS_SYSCONFIG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) -#define NM_IS_SYSCONFIG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSCONFIG_CONNECTION)) -#define NM_SYSCONFIG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_CONNECTION, NMSysconfigConnectionClass)) - -#define NM_SYSCONFIG_CONNECTION_UPDATED "updated" -#define NM_SYSCONFIG_CONNECTION_REMOVED "removed" -#define NM_SYSCONFIG_CONNECTION_VISIBLE "visible" - -typedef struct _NMSysconfigConnection NMSysconfigConnection; - -typedef struct _NMSysconfigConnectionClass NMSysconfigConnectionClass; - -typedef void (*NMSysconfigConnectionCommitFunc) (NMSysconfigConnection *connection, - GError *error, - gpointer user_data); - -typedef void (*NMSysconfigConnectionDeleteFunc) (NMSysconfigConnection *connection, - GError *error, - gpointer user_data); - -struct _NMSysconfigConnection { - NMConnection parent; -}; - -struct _NMSysconfigConnectionClass { - NMConnectionClass parent; - - void (*commit_changes) (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, - gpointer user_data); - - void (*delete) (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, - gpointer user_data); - - gboolean (*supports_secrets) (NMSysconfigConnection *connection, - const char *setting_name); -}; - -GType nm_sysconfig_connection_get_type (void); - -void nm_sysconfig_connection_commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, - gpointer user_data); - -gboolean nm_sysconfig_connection_replace_settings (NMSysconfigConnection *self, - NMConnection *new_settings, - GError **error); - -void nm_sysconfig_connection_replace_and_commit (NMSysconfigConnection *self, - NMConnection *new_settings, - NMSysconfigConnectionCommitFunc callback, - gpointer user_data); - -void nm_sysconfig_connection_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, - gpointer user_data); - -GHashTable *nm_sysconfig_connection_get_secrets (NMSysconfigConnection *connection, - const char *setting_name, - GError **error); - -gboolean nm_sysconfig_connection_is_visible (NMSysconfigConnection *self); - -void nm_sysconfig_connection_recheck_visibility (NMSysconfigConnection *self); - -G_END_DECLS - -#endif /* NM_SYSCONFIG_CONNECTION_H */ diff --git a/src/settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c index b5f9d7207..b7fcfd607 100644 --- a/src/settings/nm-system-config-interface.c +++ b/src/settings/nm-system-config-interface.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ @@ -73,7 +73,7 @@ interface_init (gpointer g_iface) NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, - NM_TYPE_SYSCONFIG_CONNECTION); + NM_TYPE_SETTINGS_CONNECTION); g_signal_new (NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED, iface_type, @@ -146,7 +146,7 @@ nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config) return NULL; } -NMSysconfigConnection * +NMSettingsConnection * nm_system_config_interface_add_connection (NMSystemConfigInterface *config, NMConnection *connection, GError **error) diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h index f31beabc3..fb394785d 100644 --- a/src/settings/nm-system-config-interface.h +++ b/src/settings/nm-system-config-interface.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ @@ -25,7 +25,7 @@ #include #include #include -#include +#include G_BEGIN_DECLS @@ -90,7 +90,7 @@ struct _NMSystemConfigInterface { /* Called when the plugin is loaded to initialize it */ void (*init) (NMSystemConfigInterface *config); - /* Returns a GSList of NMSysconfigConnection objects that represent + /* Returns a GSList of NMSettingsConnection objects that represent * connections the plugin knows about. The returned list is freed by the * system settings service. */ @@ -118,18 +118,18 @@ struct _NMSystemConfigInterface { /* * Save the given connection to backing storage, and return a new - * NMSysconfigConnection subclass that contains the same settings as the + * NMSettingsConnection subclass that contains the same settings as the * original connection. */ - NMSysconfigConnection * (*add_connection) (NMSystemConfigInterface *config, - NMConnection *connection, - GError **error); + NMSettingsConnection * (*add_connection) (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); /* Signals */ /* Emitted when a new connection has been found by the plugin */ void (*connection_added) (NMSystemConfigInterface *config, - NMSysconfigConnection *connection); + NMSettingsConnection *connection); /* Emitted when the list of unmanaged device specifications changes */ void (*unmanaged_specs_changed) (NMSystemConfigInterface *config); @@ -144,9 +144,9 @@ GSList *nm_system_config_interface_get_connections (NMSystemConfigInterface *con GSList *nm_system_config_interface_get_unmanaged_specs (NMSystemConfigInterface *config); -NMSysconfigConnection *nm_system_config_interface_add_connection (NMSystemConfigInterface *config, - NMConnection *connection, - GError **error); +NMSettingsConnection *nm_system_config_interface_add_connection (NMSystemConfigInterface *config, + NMConnection *connection, + GError **error); G_END_DECLS diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 218054c1c..52c172dae 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -40,7 +40,7 @@ #include "writer.h" #include "nm-inotify-helper.h" -G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SYSCONFIG_CONNECTION) +G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_SETTINGS_CONNECTION) #define NM_IFCFG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionPrivate)) @@ -134,7 +134,7 @@ nm_ifcfg_connection_new (const char *full_path, goto out; /* Update our settings with what was read from the file */ - if (!nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, error)) { + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) { g_object_unref (object); object = NULL; goto out; @@ -179,8 +179,8 @@ nm_ifcfg_connection_get_unmanaged_spec (NMIfcfgConnection *self) } static void -commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, gpointer user_data) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); @@ -218,12 +218,12 @@ commit_changes (NMSysconfigConnection *connection, out: if (reread) g_object_unref (reread); - NM_SYSCONFIG_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->commit_changes (connection, callback, user_data); } static void -do_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, gpointer user_data) { NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection); @@ -237,7 +237,7 @@ do_delete (NMSysconfigConnection *connection, if (priv->route6file) g_unlink (priv->route6file); - NM_SYSCONFIG_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_ifcfg_connection_parent_class)->delete (connection, callback, user_data); } /* GObject */ @@ -315,7 +315,7 @@ static void nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class); - NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (ifcfg_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifcfg_connection_class); g_type_class_add_private (ifcfg_connection_class, sizeof (NMIfcfgConnectionPrivate)); @@ -323,8 +323,8 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - sysconfig_class->delete = do_delete; - sysconfig_class->commit_changes = commit_changes; + settings_class->delete = do_delete; + settings_class->commit_changes = commit_changes; /* Properties */ g_object_class_install_property diff --git a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h index 4d9d699bc..731aa598c 100644 --- a/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h +++ b/system-settings/plugins/ifcfg-rh/nm-ifcfg-connection.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #ifndef NM_IFCFG_CONNECTION_H @@ -24,7 +24,7 @@ G_BEGIN_DECLS #include -#include +#include #define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ()) #define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection)) @@ -36,11 +36,11 @@ G_BEGIN_DECLS #define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged" typedef struct { - NMSysconfigConnection parent; + NMSettingsConnection parent; } NMIfcfgConnection; typedef struct { - NMSysconfigConnectionClass parent; + NMSettingsConnectionClass parent; } NMIfcfgConnectionClass; GType nm_ifcfg_connection_get_type (void); diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index b718574a1..24e271df3 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -18,7 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #include @@ -195,10 +195,10 @@ read_connections (SCPluginIfcfg *plugin) /* Monitoring */ -/* Callback for nm_sysconfig_connection_replace_and_commit. Report any errors +/* Callback for nm_settings_connection_replace_and_commit. Report any errors * encountered when commiting connection settings updates. */ static void -commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused) +commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) { if (error) { PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error updating: %s", @@ -221,7 +221,7 @@ remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) g_object_ref (connection); g_hash_table_remove (priv->connections, path); - g_signal_emit_by_name (connection, NM_SYSCONFIG_CONNECTION_REMOVED); + g_signal_emit_by_name (connection, NM_SETTINGS_CONNECTION_REMOVED); g_object_unref (connection); /* Emit unmanaged changes _after_ removing the connection */ @@ -294,7 +294,7 @@ connection_new_or_changed (SCPluginIfcfg *self, * been removed, and notify the settings service by signalling that * unmanaged specs have changed. */ - g_signal_emit_by_name (existing, NM_SYSCONFIG_CONNECTION_REMOVED); + g_signal_emit_by_name (existing, NM_SETTINGS_CONNECTION_REMOVED); g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } } else { @@ -312,9 +312,9 @@ connection_new_or_changed (SCPluginIfcfg *self, g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, existing); } - nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (existing), - NM_CONNECTION (new), - commit_cb, NULL); + nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (existing), + NM_CONNECTION (new), + commit_cb, NULL); /* Update unmanaged status */ g_object_set (existing, NM_IFCFG_CONNECTION_UNMANAGED, new_unmanaged, NULL); @@ -445,7 +445,7 @@ get_unmanaged_specs (NMSystemConfigInterface *config) return list; } -static NMSysconfigConnection * +static NMSettingsConnection * add_connection (NMSystemConfigInterface *config, NMConnection *connection, GError **error) @@ -459,7 +459,7 @@ add_connection (NMSystemConfigInterface *config, added = _internal_new_connection (self, path, connection, error); g_free (path); } - return (NMSysconfigConnection *) added; + return (NMSettingsConnection *) added; } #define SC_NETWORK_FILE SYSCONFDIR"/sysconfig/network" diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.c b/system-settings/plugins/ifnet/nm-ifnet-connection.c index 8e774de8f..16a21bafa 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.c +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include "nm-ifnet-connection.h" @@ -34,7 +34,7 @@ #include "wpa_parser.h" #include "plugin.h" -G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SYSCONFIG_CONNECTION) +G_DEFINE_TYPE (NMIfnetConnection, nm_ifnet_connection, NM_TYPE_SETTINGS_CONNECTION) #define NM_IFNET_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionPrivate)) enum { @@ -80,7 +80,7 @@ nm_ifnet_connection_new (const char *conn_name, NMConnection *source) } NM_IFNET_CONNECTION_GET_PRIVATE (object)->conn_name = g_strdup (conn_name); - nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, NULL); + nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, NULL); g_object_unref (tmp); return NM_IFNET_CONNECTION (object); @@ -92,8 +92,8 @@ nm_ifnet_connection_init (NMIfnetConnection * connection) } static void -commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, gpointer user_data) { GError *error = NULL; @@ -118,15 +118,15 @@ commit_changes (NMSysconfigConnection *connection, g_free (priv->conn_name); priv->conn_name = g_strdup (new_name); - NM_SYSCONFIG_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, callback, user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->commit_changes (connection, callback, user_data); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully updated %s", priv->conn_name); g_signal_emit (connection, signals[IFNET_SETUP_MONITORS], 0); } static void -do_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, gpointer user_data) { GError *error = NULL; @@ -144,7 +144,7 @@ do_delete (NMSysconfigConnection *connection, return; } - NM_SYSCONFIG_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_ifnet_connection_parent_class)->delete (connection, callback, user_data); PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Successfully deleted %s", priv->conn_name); @@ -167,14 +167,14 @@ static void nm_ifnet_connection_class_init (NMIfnetConnectionClass * ifnet_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifnet_connection_class); - NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (ifnet_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (ifnet_connection_class); g_type_class_add_private (ifnet_connection_class, sizeof (NMIfnetConnectionPrivate)); object_class->finalize = finalize; - sysconfig_class->delete = do_delete; - sysconfig_class->commit_changes = commit_changes; + settings_class->delete = do_delete; + settings_class->commit_changes = commit_changes; signals[IFNET_SETUP_MONITORS] = g_signal_new ("ifnet_setup_monitors", diff --git a/system-settings/plugins/ifnet/nm-ifnet-connection.h b/system-settings/plugins/ifnet/nm-ifnet-connection.h index cde260a45..9423f20d7 100644 --- a/system-settings/plugins/ifnet/nm-ifnet-connection.h +++ b/system-settings/plugins/ifnet/nm-ifnet-connection.h @@ -22,7 +22,7 @@ #ifndef NM_IFNET_CONNECTION_H #define NM_IFNET_CONNECTION_H -#include +#include #include "net_parser.h" G_BEGIN_DECLS @@ -35,11 +35,11 @@ G_BEGIN_DECLS #define NM_IFNET_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFNET_CONNECTION, NMIfnetConnectionClass)) typedef struct { - NMSysconfigConnection parent; + NMSettingsConnection parent; } NMIfnetConnection; typedef struct { - NMSysconfigConnectionClass parent; + NMSettingsConnectionClass parent; } NMIfnetConnectionClass; GType nm_ifnet_connection_get_type (void); diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index 710b9b5b5..f7cc6b394 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -182,10 +182,10 @@ monitor_file_changes (const char *filename, return monitor; } -/* Callback for nm_sysconfig_connection_replace_and_commit. Report any errors +/* Callback for nm_settings_connection_replace_and_commit. Report any errors * encountered when commiting connection settings updates. */ static void -commit_cb (NMSysconfigConnection *connection, GError *error, gpointer unused) +commit_cb (NMSettingsConnection *connection, GError *error, gpointer unused) { if (error) { PLUGIN_WARN (IFNET_PLUGIN_NAME, " error updating: %s", @@ -287,7 +287,7 @@ reload_connections (gpointer config) PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name); /* Remove and re-add to disconnect and reconnect with new settings */ - g_signal_emit_by_name (old, NM_SYSCONFIG_CONNECTION_REMOVED); + g_signal_emit_by_name (old, NM_SETTINGS_CONNECTION_REMOVED); g_hash_table_remove (priv->config_connections, conn_name); g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); if (is_managed (conn_name)) @@ -295,9 +295,9 @@ reload_connections (gpointer config) } } else { /* Update existing connection with new settings */ - nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (old), - NM_CONNECTION (new), - commit_cb, NULL); + nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (old), + NM_CONNECTION (new), + commit_cb, NULL); g_object_unref (new); } g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); @@ -313,7 +313,7 @@ reload_connections (gpointer config) g_hash_table_iter_init (&iter, priv->config_connections); while (g_hash_table_iter_next (&iter, &key, &value)) { if (!g_hash_table_lookup (new_conn_names, key)) { - g_signal_emit_by_name (value, NM_SYSCONFIG_CONNECTION_REMOVED); + g_signal_emit_by_name (value, NM_SETTINGS_CONNECTION_REMOVED); g_hash_table_remove (priv->config_connections, key); } } @@ -321,7 +321,7 @@ reload_connections (gpointer config) g_list_free (conn_names); } -static NMSysconfigConnection * +static NMSettingsConnection * add_connection (NMSystemConfigInterface *config, NMConnection *source, GError **error) @@ -333,7 +333,7 @@ add_connection (NMSystemConfigInterface *config, if (conn_name) connection = nm_ifnet_connection_new (conn_name, source); reload_connections (config); - return connection ? NM_SYSCONFIG_CONNECTION (connection) : NULL; + return connection ? NM_SETTINGS_CONNECTION (connection) : NULL; } static void diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c index 17d250c28..0cc73b34f 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.c +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.c @@ -26,13 +26,13 @@ #include #include #include -#include +#include #include #include #include "nm-ifupdown-connection.h" #include "parser.h" -G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SYSCONFIG_CONNECTION) +G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SETTINGS_CONNECTION) #define NM_IFUPDOWN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFUPDOWN_CONNECTION, NMIfupdownConnectionPrivate)) @@ -58,7 +58,7 @@ nm_ifupdown_connection_new (if_block *block) } static gboolean -supports_secrets (NMSysconfigConnection *connection, const char *setting_name) +supports_secrets (NMSettingsConnection *connection, const char *setting_name) { PLUGIN_PRINT ("SCPlugin-Ifupdown", "supports_secrets() for setting_name: '%s'", setting_name); @@ -146,7 +146,7 @@ static void nm_ifupdown_connection_class_init (NMIfupdownConnectionClass *ifupdown_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (ifupdown_connection_class); - NMSysconfigConnectionClass *connection_class = NM_SYSCONFIG_CONNECTION_CLASS (ifupdown_connection_class); + NMSettingsConnectionClass *connection_class = NM_SETTINGS_CONNECTION_CLASS (ifupdown_connection_class); g_type_class_add_private (ifupdown_connection_class, sizeof (NMIfupdownConnectionPrivate)); diff --git a/system-settings/plugins/ifupdown/nm-ifupdown-connection.h b/system-settings/plugins/ifupdown/nm-ifupdown-connection.h index 2aa74df6b..510a4d56a 100644 --- a/system-settings/plugins/ifupdown/nm-ifupdown-connection.h +++ b/system-settings/plugins/ifupdown/nm-ifupdown-connection.h @@ -24,7 +24,7 @@ #ifndef NM_IFUPDOWN_CONNECTION_H #define NM_IFUPDOWN_CONNECTION_H -#include +#include #include "interface_parser.h" G_BEGIN_DECLS @@ -39,11 +39,11 @@ G_BEGIN_DECLS #define NM_IFUPDOWN_CONNECTION_IFBLOCK "ifblock" typedef struct { - NMSysconfigConnection parent; + NMSettingsConnection parent; } NMIfupdownConnection; typedef struct { - NMSysconfigConnectionClass parent; + NMSettingsConnectionClass parent; } NMIfupdownConnectionClass; GType nm_ifupdown_connection_get_type (void); diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c index 389d6d973..9944546cb 100644 --- a/system-settings/plugins/ifupdown/plugin.c +++ b/system-settings/plugins/ifupdown/plugin.c @@ -179,7 +179,7 @@ sc_plugin_ifupdown_class_init (SCPluginIfupdownClass *req_class) } static void -ignore_cb (NMSysconfigConnection *connection, +ignore_cb (NMSettingsConnection *connection, GError *error, gpointer user_data) { @@ -229,9 +229,7 @@ bind_device_to_connection (SCPluginIfupdown *self, } g_byte_array_free (mac_address, TRUE); - nm_sysconfig_connection_commit_changes (NM_SYSCONFIG_CONNECTION (exported), - ignore_cb, - NULL); + nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); } static void @@ -411,9 +409,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) exported = g_hash_table_lookup (priv->iface_connections, block->name); if (exported) { PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name); - nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (exported), - ignore_cb, - NULL); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); g_hash_table_remove (priv->iface_connections, block->name); } @@ -446,9 +442,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); - nm_sysconfig_connection_commit_changes (NM_SYSCONFIG_CONNECTION (exported), - ignore_cb, - NULL); + nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); } @@ -507,7 +501,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, - NM_SYSCONFIG_CONNECTION (cl_iter->data)); + NM_SETTINGS_CONNECTION (cl_iter->data)); } g_list_free (con_list); } diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 5368464ef..2e9aa0fb5 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #include @@ -32,7 +32,7 @@ #include "writer.h" #include "common.h" -G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SYSCONFIG_CONNECTION) +G_DEFINE_TYPE (NMKeyfileConnection, nm_keyfile_connection, NM_TYPE_SETTINGS_CONNECTION) #define NM_KEYFILE_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionPrivate)) @@ -69,7 +69,7 @@ nm_keyfile_connection_new (const char *full_path, priv->path = g_strdup (full_path); /* Update our settings with what was read from the file */ - if (!nm_sysconfig_connection_replace_settings (NM_SYSCONFIG_CONNECTION (object), tmp, error)) { + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) { g_object_unref (object); object = NULL; goto out; @@ -109,8 +109,8 @@ nm_keyfile_connection_get_path (NMKeyfileConnection *self) } static void -commit_changes (NMSysconfigConnection *connection, - NMSysconfigConnectionCommitFunc callback, +commit_changes (NMSettingsConnection *connection, + NMSettingsConnectionCommitFunc callback, gpointer user_data) { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); @@ -130,23 +130,23 @@ commit_changes (NMSysconfigConnection *connection, } else g_free (path); - NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, - callback, - user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, + callback, + user_data); } static void -do_delete (NMSysconfigConnection *connection, - NMSysconfigConnectionDeleteFunc callback, +do_delete (NMSettingsConnection *connection, + NMSettingsConnectionDeleteFunc callback, gpointer user_data) { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); g_unlink (priv->path); - NM_SYSCONFIG_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, - callback, - user_data); + NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, + callback, + user_data); } /* GObject */ @@ -172,12 +172,12 @@ static void nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_class) { GObjectClass *object_class = G_OBJECT_CLASS (keyfile_connection_class); - NMSysconfigConnectionClass *sysconfig_class = NM_SYSCONFIG_CONNECTION_CLASS (keyfile_connection_class); + NMSettingsConnectionClass *settings_class = NM_SETTINGS_CONNECTION_CLASS (keyfile_connection_class); g_type_class_add_private (keyfile_connection_class, sizeof (NMKeyfileConnectionPrivate)); /* Virtual methods */ object_class->finalize = finalize; - sysconfig_class->commit_changes = commit_changes; - sysconfig_class->delete = do_delete; + settings_class->commit_changes = commit_changes; + settings_class->delete = do_delete; } diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.h b/system-settings/plugins/keyfile/nm-keyfile-connection.h index ab7b42eaa..bf64e69a3 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.h +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.h @@ -16,13 +16,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #ifndef NM_KEYFILE_CONNECTION_H #define NM_KEYFILE_CONNECTION_H -#include +#include G_BEGIN_DECLS @@ -34,11 +34,11 @@ G_BEGIN_DECLS #define NM_KEYFILE_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_KEYFILE_CONNECTION, NMKeyfileConnectionClass)) typedef struct { - NMSysconfigConnection parent; + NMSettingsConnection parent; } NMKeyfileConnection; typedef struct { - NMSysconfigConnectionClass parent; + NMSettingsConnectionClass parent; } NMKeyfileConnectionClass; GType nm_keyfile_connection_get_type (void); diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 27ddb299f..819b80971 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #include @@ -69,7 +69,7 @@ typedef struct { gboolean disposed; } SCPluginKeyfilePrivate; -static NMSysconfigConnection * +static NMSettingsConnection * _internal_new_connection (SCPluginKeyfile *self, const char *full_path, NMConnection *source, @@ -102,7 +102,7 @@ _internal_new_connection (SCPluginKeyfile *self, if (out_cid) *out_cid = cid; - return NM_SYSCONFIG_CONNECTION (connection); + return NM_SETTINGS_CONNECTION (connection); } static void @@ -124,7 +124,7 @@ read_connections (NMSystemConfigInterface *config) } while ((item = g_dir_read_name (dir))) { - NMSysconfigConnection *connection; + NMSettingsConnection *connection; char *full_path; if (utils_should_ignore_file (item)) @@ -147,7 +147,7 @@ read_connections (NMSystemConfigInterface *config) } static void -update_connection_settings_commit_cb (NMSysconfigConnection *orig, GError *error, gpointer user_data) +update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, gpointer user_data) { if (error) { g_warning ("%s: '%s' / '%s' invalid: %d", @@ -165,9 +165,9 @@ static void update_connection_settings (NMKeyfileConnection *orig, NMKeyfileConnection *new) { - nm_sysconfig_connection_replace_and_commit (NM_SYSCONFIG_CONNECTION (orig), - NM_CONNECTION (new), - update_connection_settings_commit_cb, NULL); + nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (orig), + NM_CONNECTION (new), + update_connection_settings_commit_cb, NULL); } /* Monitoring */ @@ -406,13 +406,13 @@ get_connections (NMSystemConfigInterface *config) return list; } -static NMSysconfigConnection * +static NMSettingsConnection * add_connection (NMSystemConfigInterface *config, NMConnection *connection, GError **error) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); - NMSysconfigConnection *added = NULL; + NMSettingsConnection *added = NULL; char *path = NULL; /* Write it out first, then add the connection to our internal list */ From 6fc469d74a5f9153934a2989bea72cbf2e5e4991 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 13:32:25 -0600 Subject: [PATCH 177/264] agent: pass setting name back in secrets callback --- src/nm-activation-request.c | 1 + src/nm-agent-manager.c | 1 + src/nm-agent-manager.h | 1 + 3 files changed, 3 insertions(+) diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 5bb1ad7d3..1ecdbf598 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -97,6 +97,7 @@ static void get_secrets_cb (NMAgentManager *manager, guint32 call_id, NMConnection *connection, + const char *setting_name, GError *error, gpointer user_data, gpointer user_data2, diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index b4b776e32..8a3400256 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -768,6 +768,7 @@ mgr_req_complete_cb (Request *req, req->callback (self, req->reqid, req->connection, + req->setting_name, local, req->callback_data, req->other_data2, diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h index 0e22af3e5..e9caa10bd 100644 --- a/src/nm-agent-manager.h +++ b/src/nm-agent-manager.h @@ -51,6 +51,7 @@ NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr); typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 call_id, NMConnection *connection, + const char *setting_name, GError *error, gpointer user_data, gpointer user_data2, From e68e27aa75b65a71145472f5bc3b843cc0a9d857 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 14:14:37 -0600 Subject: [PATCH 178/264] libnm-util: add 'flags' argument to nm_connection_to_hash() and nm_setting_to_hash() Simplifies code internally, and makes it easier for clients as well in some cases where they want to control what ends up in the resulting hash and what does not. --- examples/C/add-connection-glib.c | 2 +- libnm-glib/nm-client.c | 2 +- libnm-glib/nm-remote-connection.c | 2 +- libnm-glib/nm-remote-settings.c | 2 +- libnm-util/nm-connection.c | 51 +++++++------- libnm-util/nm-connection.h | 4 +- libnm-util/nm-setting.c | 38 +++++++---- libnm-util/nm-setting.h | 20 +++++- libnm-util/tests/test-general.c | 98 +++++++++++++++++++++++++++ src/NetworkManagerUtils.c | 2 +- src/nm-secret-agent.c | 3 +- src/settings/nm-settings-connection.c | 34 ++++------ src/vpn-manager/nm-vpn-connection.c | 11 +-- 13 files changed, 194 insertions(+), 75 deletions(-) diff --git a/examples/C/add-connection-glib.c b/examples/C/add-connection-glib.c index d650dc2f4..433c7124a 100644 --- a/examples/C/add-connection-glib.c +++ b/examples/C/add-connection-glib.c @@ -74,7 +74,7 @@ add_connection (DBusGProxy *proxy, const char *con_name) NULL); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - hash = nm_connection_to_hash (connection); + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); /* Call AddConnection with the hash as argument */ dbus_g_proxy_call (proxy, "AddConnection", &error, diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index cfb6a48b1..bbc0c91f6 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -1200,7 +1200,7 @@ nm_client_add_and_activate_connection (NMClient *client, info->client = client; if (partial) - hash = nm_connection_to_hash (partial); + hash = nm_connection_to_hash (partial, NM_SETTING_HASH_FLAG_ALL); else hash = g_hash_table_new (g_str_hash, g_str_equal); org_freedesktop_NetworkManager_add_and_activate_connection_async (NM_CLIENT_GET_PRIVATE (client)->client_proxy, diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index b07c42945..64f032577 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -125,7 +125,7 @@ nm_remote_connection_commit_changes (NMRemoteConnection *self, call->callback = (GFunc) callback; call->user_data = user_data; - settings = nm_connection_to_hash (NM_CONNECTION (self)); + settings = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ALL); call->call = org_freedesktop_NetworkManager_Settings_Connection_update_async (priv->proxy, settings, diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 630e0cef1..8e5ffb118 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -444,7 +444,7 @@ nm_remote_settings_add_connection (NMRemoteSettings *settings, info->callback = callback; info->callback_data = user_data; - new_settings = nm_connection_to_hash (connection); + new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); org_freedesktop_NetworkManager_Settings_add_connection_async (priv->proxy, new_settings, add_connection_done, diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 39766285a..fef255ddf 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -798,26 +798,10 @@ nm_connection_clear_secrets (NMConnection *connection) g_hash_table_foreach (priv->settings, clear_setting_secrets, NULL); } -static void -add_one_setting_to_hash (gpointer key, gpointer data, gpointer user_data) -{ - NMSetting *setting = (NMSetting *) data; - GHashTable *connection_hash = (GHashTable *) user_data; - GHashTable *setting_hash; - - g_return_if_fail (setting != NULL); - g_return_if_fail (connection_hash != NULL); - - setting_hash = nm_setting_to_hash (setting); - if (setting_hash) - g_hash_table_insert (connection_hash, - g_strdup (nm_setting_get_name (setting)), - setting_hash); -} - /** * nm_connection_to_hash: * @connection: the #NMConnection + * @flags: hash flags, e.g. %NM_SETTING_HASH_FLAG_ALL * * Converts the #NMConnection into a #GHashTable describing the connection, * suitable for marshalling over D-Bus or serializing. The hash table mapping @@ -832,26 +816,39 @@ add_one_setting_to_hash (gpointer key, gpointer data, gpointer user_data) * with g_hash_table_unref() when it is no longer needed. **/ GHashTable * -nm_connection_to_hash (NMConnection *connection) +nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags) { NMConnectionPrivate *priv; - GHashTable *connection_hash; + GHashTableIter iter; + gpointer key, data; + GHashTable *ret, *setting_hash; + g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - connection_hash = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_hash_table_destroy); + ret = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_hash_table_destroy); priv = NM_CONNECTION_GET_PRIVATE (connection); - g_hash_table_foreach (priv->settings, add_one_setting_to_hash, connection_hash); - /* Don't send empty hashes */ - if (g_hash_table_size (connection_hash) < 1) { - g_hash_table_destroy (connection_hash); - connection_hash = NULL; + /* Add each setting's hash to the main hash */ + g_hash_table_iter_init (&iter, priv->settings); + while (g_hash_table_iter_next (&iter, &key, &data)) { + const char *setting_name = key; + NMSetting *setting = NM_SETTING (data); + + setting_hash = nm_setting_to_hash (setting, flags); + if (setting_hash) + g_hash_table_insert (ret, g_strdup (setting_name), setting_hash); } - return connection_hash; + /* Don't send empty hashes */ + if (g_hash_table_size (ret) < 1) { + g_hash_table_destroy (ret); + ret = NULL; + } + + return ret; } typedef struct ForEachValueInfo { diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 453f9eff0..371d55906 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -130,7 +130,9 @@ void nm_connection_for_each_setting_value (NMConnection *connection, NMSettingValueIterFn func, gpointer user_data); -GHashTable *nm_connection_to_hash (NMConnection *connection); +GHashTable *nm_connection_to_hash (NMConnection *connection, + NMSettingHashFlags flags); + void nm_connection_dump (NMConnection *connection); NMSetting *nm_connection_create_setting (const char *name); diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index f0ff42c88..e27450482 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -107,6 +107,7 @@ destroy_gvalue (gpointer data) /** * nm_setting_to_hash: * @setting: the #NMSetting + * @flags: hash flags, e.g. %NM_SETTING_HASH_FLAG_ALL * * Converts the #NMSetting into a #GHashTable mapping each setting property * name to a GValue describing that property, suitable for marshalling over @@ -115,13 +116,14 @@ destroy_gvalue (gpointer data) * Returns: (transfer full) (element-type utf8 GObject.Value): a new #GHashTable describing the setting's properties **/ GHashTable * -nm_setting_to_hash (NMSetting *setting) +nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags) { GHashTable *hash; GParamSpec **property_specs; guint n_property_specs; guint i; + g_return_val_if_fail (setting != NULL, NULL); g_return_val_if_fail (NM_IS_SETTING (setting), NULL); property_specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (setting), &n_property_specs); @@ -132,29 +134,35 @@ nm_setting_to_hash (NMSetting *setting) } hash = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - destroy_gvalue); + (GDestroyNotify) g_free, destroy_gvalue); for (i = 0; i < n_property_specs; i++) { GParamSpec *prop_spec = property_specs[i]; + GValue *value; - if (prop_spec->flags & NM_SETTING_PARAM_SERIALIZE) { - GValue *value; + if (!(prop_spec->flags & NM_SETTING_PARAM_SERIALIZE)) + continue; - value = g_slice_new0 (GValue); - g_value_init (value, prop_spec->value_type); - g_object_get_property (G_OBJECT (setting), prop_spec->name, value); + if ( (flags & NM_SETTING_HASH_FLAG_NO_SECRETS) + && (prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; - /* Don't serialize values with default values */ - if (!g_param_value_defaults (prop_spec, value)) - g_hash_table_insert (hash, g_strdup (prop_spec->name), value); - else - destroy_gvalue (value); - } + if ( (flags & NM_SETTING_HASH_FLAG_ONLY_SECRETS) + && !(prop_spec->flags & NM_SETTING_PARAM_SECRET)) + continue; + + value = g_slice_new0 (GValue); + g_value_init (value, prop_spec->value_type); + g_object_get_property (G_OBJECT (setting), prop_spec->name, value); + + /* Don't serialize values with default values */ + if (!g_param_value_defaults (prop_spec, value)) + g_hash_table_insert (hash, g_strdup (prop_spec->name), value); + else + destroy_gvalue (value); } g_free (property_specs); - return hash; } diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index de5657eea..07a38daad 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -124,7 +124,25 @@ typedef void (*NMSettingValueIterFn) (NMSetting *setting, GType nm_setting_get_type (void); -GHashTable *nm_setting_to_hash (NMSetting *setting); +/** + * NMSettingHashFlags: + * @NM_SETTING_HASH_FLAG_ALL: hash all properties (including secrets) + * @NM_SETTING_HASH_FLAG_NO_SECRETS: do not include secrets + * @NM_SETTING_HASH_FLAG_ONLY_SECRETS: only hash secrets + * + * These flags determine which properties are added to the resulting hash + * when calling nm_setting_to_hash(). + * + **/ +typedef enum { + NM_SETTING_HASH_FLAG_ALL = 0x00000000, + NM_SETTING_HASH_FLAG_NO_SECRETS = 0x00000001, + NM_SETTING_HASH_FLAG_ONLY_SECRETS = 0x00000002, +} NMSettingHashFlags; + +GHashTable *nm_setting_to_hash (NMSetting *setting, + NMSettingHashFlags flags); + NMSetting *nm_setting_new_from_hash (GType setting_type, GHashTable *hash); diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index e91e2b5ce..43f32620b 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -29,6 +29,7 @@ #include "nm-setting-connection.h" #include "nm-setting-vpn.h" #include "nm-setting-gsm.h" +#include "nm-setting-wireless-security.h" #include "nm-setting-ip6-config.h" #include "nm-dbus-glib-types.h" @@ -289,6 +290,100 @@ test_setting_gsm_apn_bad_chars (void) "gsm-apn-bad-chars", "unexpectedly valid GSM setting"); } +static NMSettingWirelessSecurity * +make_test_wsec_setting (const char *detail) +{ + NMSettingWirelessSecurity *s_wsec; + + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + ASSERT (s_wsec != NULL, detail, "error creating setting"); + + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME, "foobarbaz", + NM_SETTING_WIRELESS_SECURITY_PSK, "random psk", + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, "aaaaaaaaaa", + NULL); + + return s_wsec; +} + +static void +test_setting_to_hash_all (void) +{ + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + s_wsec = make_test_wsec_setting ("setting-to-hash-all"); + + hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ALL); + + /* Make sure all keys are there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0), + "setting-to-hash-all", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_hash_table_destroy (hash); + g_object_unref (s_wsec); +} + +static void +test_setting_to_hash_no_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + s_wsec = make_test_wsec_setting ("setting-to-hash-no-secrets"); + + hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_NO_SECRETS); + + /* Make sure non-secret keys are there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT), + "setting-to-hash-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME), + "setting-to-hash-no-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are not there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK) == NULL, + "setting-to-hash-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) == NULL, + "setting-to-hash-no-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_hash_table_destroy (hash); + g_object_unref (s_wsec); +} + +static void +test_setting_to_hash_only_secrets (void) +{ + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + s_wsec = make_test_wsec_setting ("setting-to-hash-only-secrets"); + + hash = nm_setting_to_hash (NM_SETTING (s_wsec), NM_SETTING_HASH_FLAG_ONLY_SECRETS); + + /* Make sure non-secret keys are there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT) == NULL, + "setting-to-hash-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME) == NULL, + "setting-to-hash-only-secrets", "unexpectedly present " NM_SETTING_WIRELESS_SECURITY_LEAP_USERNAME); + + /* Make sure secrets are not there */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_PSK), + "setting-to-hash-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_PSK); + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0), + "setting-to-hash-only-secrets", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_hash_table_destroy (hash); + g_object_unref (s_wsec); +} + int main (int argc, char **argv) { GError *error = NULL; @@ -306,6 +401,9 @@ int main (int argc, char **argv) test_setting_ip6_config_old_address_array (); test_setting_gsm_apn_spaces (); test_setting_gsm_apn_bad_chars (); + test_setting_to_hash_all (); + test_setting_to_hash_no_secrets (); + test_setting_to_hash_only_secrets (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index ee8c61f37..38176b3de 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -405,7 +405,7 @@ nm_utils_call_dispatcher (const char *action, } if (connection) { - connection_hash = nm_connection_to_hash (connection); + connection_hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_NO_SECRETS); connection_props = value_hash_create (); diff --git a/src/nm-secret-agent.c b/src/nm-secret-agent.c index f347ffeb5..13a7592a4 100644 --- a/src/nm-secret-agent.c +++ b/src/nm-secret-agent.c @@ -187,7 +187,8 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, priv = NM_SECRET_AGENT_GET_PRIVATE (self); - hash = nm_connection_to_hash (connection); + /* FIXME: allow system secrets to be sent to the agent? */ + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 5977ebad6..2743f841e 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -196,7 +196,7 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - new_settings = nm_connection_to_hash (new); + new_settings = nm_connection_to_hash (new, NM_SETTING_HASH_FLAG_ALL); g_assert (new_settings); if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) { /* Copy the connection to keep its secrets around even if NM @@ -605,28 +605,20 @@ get_settings_auth_cb (NMSettingsConnection *self, GError *error, gpointer data) { - NMConnection *no_secrets; - GHashTable *settings; - - if (error) { + if (error) dbus_g_method_return_error (context, error); - return; + else { + GHashTable *settings; + + /* Secrets should *never* be returned by the GetSettings method, they + * get returned by the GetSecrets method which can be better + * protected against leakage of secrets to unprivileged callers. + */ + settings = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_NO_SECRETS); + g_assert (settings); + dbus_g_method_return (context, settings); + g_hash_table_destroy (settings); } - - /* Secrets should *never* be returned by the GetSettings method, they - * get returned by the GetSecrets method which can be better - * protected against leakage of secrets to unprivileged callers. - */ - no_secrets = nm_connection_duplicate (NM_CONNECTION (self)); - g_assert (no_secrets); - nm_connection_clear_secrets (no_secrets); - settings = nm_connection_to_hash (no_secrets); - g_assert (settings); - - dbus_g_method_return (context, settings); - - g_object_unref (no_secrets); - g_hash_table_destroy (settings); } static void diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 15025c6e9..6f160dfa1 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -591,6 +591,7 @@ static void really_activate (NMVPNConnection *connection) { NMVPNConnectionPrivate *priv; + GHashTable *hash; g_return_if_fail (NM_IS_VPN_CONNECTION (connection)); g_return_if_fail (nm_vpn_connection_get_vpn_state (connection) == NM_VPN_CONNECTION_STATE_NEED_AUTH); @@ -607,10 +608,12 @@ really_activate (NMVPNConnection *connection) G_CALLBACK (nm_vpn_connection_ip4_config_get), connection, NULL); + hash = nm_connection_to_hash (priv->connection, NM_SETTING_HASH_FLAG_ALL); org_freedesktop_NetworkManager_VPN_Plugin_connect_async (priv->proxy, - nm_connection_to_hash (priv->connection), - nm_vpn_connection_connect_cb, - connection); + hash, + nm_vpn_connection_connect_cb, + connection); + g_hash_table_destroy (hash); nm_vpn_connection_set_vpn_state (connection, NM_VPN_CONNECTION_STATE_CONNECT, @@ -826,7 +829,7 @@ call_need_secrets (NMVPNConnection *vpn_connection) GHashTable *settings; priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); - settings = nm_connection_to_hash (priv->connection); + settings = nm_connection_to_hash (priv->connection, NM_SETTING_HASH_FLAG_ALL); org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy, settings, connection_need_secrets_cb, From 75af6105b71ef2a44d178799f5c443f5a44b347c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 15:24:41 -0600 Subject: [PATCH 179/264] settings: update signal prototypes No functional change, but makes the internal API clearer. --- src/settings/nm-settings.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 9b478ca92..a5cb4d7c8 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -59,13 +59,13 @@ typedef struct { /* Signals */ void (*properties_changed) (NMSettings *self, GHashTable *properties); - void (*connection_added) (NMSettings *self, NMConnection *connection); + void (*connection_added) (NMSettings *self, NMSettingsConnection *connection); - void (*connection_updated) (NMSettings *self, NMConnection *connection); + void (*connection_updated) (NMSettings *self, NMSettingsConnection *connection); - void (*connection_removed) (NMSettings *self, NMConnection *connection); + void (*connection_removed) (NMSettings *self, NMSettingsConnection *connection); - void (*connection_visibility_changed) (NMSettings *self, NMConnection *connection); + void (*connection_visibility_changed) (NMSettings *self, NMSettingsConnection *connection); void (*connections_loaded) (NMSettings *self); } NMSettingsClass; From 68812f61d9e7a6b62ff1d61534cc3bdfbaa9a710 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 17:13:15 -0600 Subject: [PATCH 180/264] settings: request secrets from agents when clients call GetSecrets A client calling GetSecrets on the connection should also request secrets from agents in that client's session. ie, a connection editor should be able to call GetSecrets, and get the secrets stored by the agent in that session (the applet). --- marshallers/nm-marshal.list | 1 + src/nm-manager.c | 67 +++++++- src/settings/nm-settings-connection.c | 214 +++++++++++++------------- src/settings/nm-settings-connection.h | 18 +++ 4 files changed, 191 insertions(+), 109 deletions(-) diff --git a/marshallers/nm-marshal.list b/marshallers/nm-marshal.list index 359fbed2d..3aefac93b 100644 --- a/marshallers/nm-marshal.list +++ b/marshallers/nm-marshal.list @@ -26,4 +26,5 @@ BOOLEAN:VOID VOID:STRING,BOOLEAN VOID:STRING,OBJECT,POINTER VOID:BOOLEAN,UINT +UINT:STRING,POINTER,POINTER diff --git a/src/nm-manager.c b/src/nm-manager.c index 2f8cbdf4a..f28a405ee 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -924,6 +924,71 @@ connections_changed (NMSettings *settings, bluez_manager_resync_devices (manager); } +static void +secrets_result_cb (NMAgentManager *manager, + guint32 call_id, + NMConnection *connection, + const char *setting_name, + GError *error, + gpointer user_data, + gpointer user_data2, + gpointer user_data3) +{ + NMSettingsConnectionSecretsUpdatedFunc callback = user_data2; + gpointer callback_data = user_data3; + + callback (NM_SETTINGS_CONNECTION (connection), setting_name, call_id, error, callback_data); +} + +static guint32 +system_connection_get_secrets_cb (NMSettingsConnection *connection, + const char *setting_name, + NMSettingsConnectionSecretsUpdatedFunc callback, + gpointer callback_data, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + gboolean call_id; + + call_id = nm_agent_manager_get_secrets (priv->agent_mgr, + NM_CONNECTION (connection), + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, + NULL, + secrets_result_cb, + self, + callback, + callback_data); + return call_id; +} + +static void +system_connection_cancel_secrets_cb (NMSettingsConnection *connection, + guint32 call_id, + gpointer user_data) +{ + NMManager *self = NM_MANAGER (user_data); + + nm_agent_manager_cancel_secrets (NM_MANAGER_GET_PRIVATE (self)->agent_mgr, call_id); +} + +static void +connection_added (NMSettings *settings, + NMSettingsConnection *connection, + NMManager *manager) +{ + /* Hook up secrets request listeners */ + g_signal_connect (connection, NM_SETTINGS_CONNECTION_GET_SECRETS, + G_CALLBACK (system_connection_get_secrets_cb), + manager); + g_signal_connect (connection, NM_SETTINGS_CONNECTION_CANCEL_SECRETS, + G_CALLBACK (system_connection_cancel_secrets_cb), + manager); + + connections_changed (settings, connection, manager); +} + static void system_unmanaged_devices_changed_cb (NMSettings *settings, GParamSpec *pspec, @@ -3098,7 +3163,7 @@ nm_manager_get (NMSettings *settings, g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (connections_changed), singleton); + G_CALLBACK (connection_added), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (connections_changed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 2743f841e..7bf4b7daf 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -34,6 +34,7 @@ #include "nm-polkit-helpers.h" #include "nm-logging.h" #include "nm-manager-auth.h" +#include "nm-marshal.h" static void impl_settings_connection_get_settings (NMSettingsConnection *connection, DBusGMethodInvocation *context); @@ -65,16 +66,22 @@ enum { enum { UPDATED, REMOVED, + GET_SECRETS, + CANCEL_SECRETS, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { + gboolean disposed; + PolkitAuthority *authority; GSList *pending_auths; /* List of pending authentication requests */ NMConnection *secrets; gboolean visible; /* Is this connection is visible by some session? */ + GSList *reqs; /* in-progress secrets requests */ + NMSessionMonitor *session_monitor; guint session_changed_id; } NMSettingsConnectionPrivate; @@ -333,80 +340,6 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name) return TRUE; } -static GValue * -string_to_gvalue (const char *str) -{ - GValue *val = g_slice_new0 (GValue); - - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - return val; -} - -static GValue * -byte_array_to_gvalue (const GByteArray *array) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_set_boxed (val, array); - - return val; -} - -static void -copy_one_secret (gpointer key, gpointer value, gpointer user_data) -{ - const char *value_str = (const char *) value; - - if (value_str) { - g_hash_table_insert ((GHashTable *) user_data, - g_strdup ((char *) key), - string_to_gvalue (value_str)); - } -} - -static void -add_secrets (NMSetting *setting, - const char *key, - const GValue *value, - GParamFlags flags, - gpointer user_data) -{ - GHashTable *secrets = user_data; - - if (!(flags & NM_SETTING_PARAM_SECRET)) - return; - - /* Copy secrets into the returned hash table */ - if (G_VALUE_HOLDS_STRING (value)) { - const char *tmp; - - tmp = g_value_get_string (value); - if (tmp) - g_hash_table_insert (secrets, g_strdup (key), string_to_gvalue (tmp)); - } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { - /* Flatten the string hash by pulling its keys/values out; for VPN secrets */ - g_hash_table_foreach (g_value_get_boxed (value), copy_one_secret, secrets); - } else if (G_VALUE_TYPE (value) == DBUS_TYPE_G_UCHAR_ARRAY) { - GByteArray *array; - - array = g_value_get_boxed (value); - if (array) - g_hash_table_insert (secrets, g_strdup (key), byte_array_to_gvalue (array)); - } -} - -static void -destroy_gvalue (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - /** * nm_settings_connection_get_secrets: * @connection: the #NMSettingsConnection @@ -415,6 +348,9 @@ destroy_gvalue (gpointer data) * * Return secrets in persistent storage, if any. Does not query any Secret * Agents for secrets. + * + * Returns: a hash mapping setting names to hash tables, each inner hash + * containing string:value mappings of secrets **/ GHashTable * nm_settings_connection_get_secrets (NMSettingsConnection *connection, @@ -422,8 +358,6 @@ nm_settings_connection_get_secrets (NMSettingsConnection *connection, GError **error) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); - GHashTable *settings = NULL; - GHashTable *secrets = NULL; NMSetting *setting; /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() @@ -448,19 +382,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *connection, return NULL; } - /* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that - * will contain all the individual settings hashes. - */ - settings = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, (GDestroyNotify) g_hash_table_destroy); - - /* Add the secrets from this setting to the inner secrets hash for this setting */ - secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_gvalue); - nm_setting_enumerate_values (setting, add_secrets, secrets); - - g_hash_table_insert (settings, g_strdup (setting_name), secrets); - - return secrets; + return nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); } /**** User authorization **************************************/ @@ -736,31 +658,79 @@ impl_settings_connection_delete (NMSettingsConnection *self, auth_start (self, context, TRUE, delete_auth_cb, NULL); } -static void -secrets_auth_cb (NMSettingsConnection *self, - DBusGMethodInvocation *context, - GError *error, - gpointer user_data) +/**************************************************************/ + +static gboolean +get_secrets_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) { + guint handler_call_id = g_value_get_uint (handler_return); + + if (handler_call_id > 0) + g_value_set_uint (return_accu, handler_call_id); + + /* Abort signal emission if a valid call ID got returned */ + return handler_call_id ? FALSE : TRUE; +} + +static void +dbus_get_agent_secrets_cb (NMSettingsConnection *self, + const char *setting_name, + guint32 call_id, + GError *error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + DBusGMethodInvocation *context = user_data; + GHashTable *hash; + + priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); + + /* The connection's secrets will have been updated by the agent manager, + * so we want to refresh the secrets cache. + */ + if (priv->secrets) + g_object_unref (priv->secrets); + priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + + if (error) + dbus_g_method_return_error (context, error); + else { + hash = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS); + dbus_g_method_return (context, hash); + g_hash_table_destroy (hash); + } +} + +static void +dbus_secrets_auth_cb (NMSettingsConnection *self, + DBusGMethodInvocation *context, + GError *error, + gpointer user_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); char *setting_name = user_data; - GHashTable *secrets; + guint32 call_id = 0; GError *local = NULL; - if (error) { + if (error) dbus_g_method_return_error (context, error); - goto out; + else { + g_signal_emit (self, signals[GET_SECRETS], 0, setting_name, dbus_get_agent_secrets_cb, context, &call_id); + if (call_id > 0) { + /* track the request and wait for the callback */ + priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); + } else { + local = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, + "No secrets were available"); + dbus_g_method_return_error (context, local); + g_error_free (local); + } } - secrets = nm_settings_connection_get_secrets (self, setting_name, &error); - if (secrets) { - dbus_g_method_return (context, secrets); - g_hash_table_destroy (secrets); - } else { - dbus_g_method_return_error (context, local); - g_clear_error (&local); - } - -out: g_free (setting_name); } @@ -769,7 +739,7 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, const gchar *setting_name, DBusGMethodInvocation *context) { - auth_start (self, context, TRUE, secrets_auth_cb, g_strdup (setting_name)); + auth_start (self, context, TRUE, dbus_secrets_auth_cb, g_strdup (setting_name)); } /**************************************************************/ @@ -809,6 +779,10 @@ dispose (GObject *object) NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GSList *iter; + if (priv->disposed) + goto out; + priv->disposed = TRUE; + if (priv->secrets) g_object_unref (priv->secrets); @@ -818,10 +792,16 @@ dispose (GObject *object) g_slist_free (priv->pending_auths); priv->pending_auths = NULL; + /* Cancel in-progress secrets requests */ + for (iter = priv->reqs; iter; iter = g_slist_next (iter)) + g_signal_emit (self, signals[CANCEL_SECRETS], 0, GPOINTER_TO_UINT (iter->data)); + g_slist_free (priv->reqs); + set_visible (self, FALSE); g_object_unref (priv->session_monitor); +out: G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); } @@ -890,6 +870,24 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /* not exported over D-Bus */ + signals[GET_SECRETS] = + g_signal_new (NM_SETTINGS_CONNECTION_GET_SECRETS, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsConnectionClass, get_secrets), + get_secrets_accumulator, NULL, + _nm_marshal_UINT__STRING_POINTER_POINTER, + G_TYPE_UINT, 3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); + + signals[CANCEL_SECRETS] = + g_signal_new (NM_SETTINGS_CONNECTION_CANCEL_SECRETS, + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 0); + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_settings_connection_object_info); } diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index e62aa4b97..6f7a2ed92 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -36,6 +36,9 @@ G_BEGIN_DECLS #define NM_SETTINGS_CONNECTION_UPDATED "updated" #define NM_SETTINGS_CONNECTION_REMOVED "removed" +#define NM_SETTINGS_CONNECTION_GET_SECRETS "get-secrets" +#define NM_SETTINGS_CONNECTION_CANCEL_SECRETS "cancel-secrets" + #define NM_SETTINGS_CONNECTION_VISIBLE "visible" typedef struct _NMSettingsConnection NMSettingsConnection; @@ -50,6 +53,12 @@ typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection GError *error, gpointer user_data); +typedef void (*NMSettingsConnectionSecretsUpdatedFunc) (NMSettingsConnection *connection, + const char *setting_name, + guint32 call_id, + GError *error, + gpointer user_data); + struct _NMSettingsConnection { NMConnection parent; }; @@ -57,6 +66,7 @@ struct _NMSettingsConnection { struct _NMSettingsConnectionClass { NMConnectionClass parent; + /* virtual methods */ void (*commit_changes) (NMSettingsConnection *connection, NMSettingsConnectionCommitFunc callback, gpointer user_data); @@ -67,6 +77,14 @@ struct _NMSettingsConnectionClass { gboolean (*supports_secrets) (NMSettingsConnection *connection, const char *setting_name); + + /* signals */ + guint32 (*get_secrets) (NMSettingsConnection *connection, + const char *setting_name, + NMSettingsConnectionSecretsUpdatedFunc callback, + gpointer callback_data); + + void (*cancel_secrets) (NMSettingsConnection *connection, guint32 call_id); }; GType nm_settings_connection_get_type (void); From 4427774d576c90d9e1c6e2daa5dc6f9ca3776125 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Jan 2011 18:36:08 -0600 Subject: [PATCH 181/264] agents: filter agents by UID for user-requested connections When a user makes an explicit request for secrets via GetSecrets or activates a device, don't ask other users' agents for secrets. Restrict secrets request to agents owned by the user that made the initial activate or GetSecrets request. Automatic activations still request secrets from any available agent. --- marshallers/nm-marshal.list | 2 +- src/modem-manager/nm-modem.c | 2 - src/nm-activation-request.c | 66 +++++++++++++++++++++---- src/nm-activation-request.h | 24 ++++++--- src/nm-agent-manager.c | 21 +++++++- src/nm-agent-manager.h | 4 +- src/nm-device-ethernet.c | 10 +--- src/nm-device-wifi.c | 10 +--- src/nm-manager.c | 71 +++++++++++++++++++++------ src/nm-manager.h | 2 +- src/nm-policy.c | 2 +- src/ppp-manager/nm-ppp-manager.c | 1 - src/settings/nm-settings-connection.c | 29 +++++++---- src/settings/nm-settings-connection.h | 1 + src/vpn-manager/nm-vpn-connection.c | 24 ++++++--- src/vpn-manager/nm-vpn-connection.h | 6 ++- src/vpn-manager/nm-vpn-manager.c | 4 +- src/vpn-manager/nm-vpn-manager.h | 2 + src/vpn-manager/nm-vpn-service.c | 4 +- src/vpn-manager/nm-vpn-service.h | 2 + 20 files changed, 209 insertions(+), 78 deletions(-) diff --git a/marshallers/nm-marshal.list b/marshallers/nm-marshal.list index 3aefac93b..b152d9c1f 100644 --- a/marshallers/nm-marshal.list +++ b/marshallers/nm-marshal.list @@ -26,5 +26,5 @@ BOOLEAN:VOID VOID:STRING,BOOLEAN VOID:STRING,OBJECT,POINTER VOID:BOOLEAN,UINT -UINT:STRING,POINTER,POINTER +UINT:STRING,STRING,POINTER,POINTER diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 30817f932..2131d90ca 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -523,7 +523,6 @@ nm_modem_get_secrets (NMModem *self, if (request_new) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, - NULL, setting_name, flags, hint, @@ -571,7 +570,6 @@ nm_modem_act_stage1_prepare (NMModem *self, flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, - NULL, setting_name, flags, hints ? g_ptr_array_index (hints, 0) : NULL, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 1ecdbf598..a25e46e2e 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2007 - 2008 Novell, Inc. */ @@ -66,6 +66,7 @@ typedef struct { char *specific_object; NMDevice *device; gboolean user_requested; + gulong user_uid; NMActiveConnectionState state; gboolean is_default; @@ -112,14 +113,16 @@ get_secrets_cb (NMAgentManager *manager, callback (self, call_id, connection, error, user_data3); } -guint32 -nm_act_request_get_secrets (NMActRequest *self, - NMConnection *connection, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data) +static guint32 +_internal_get_secrets (NMActRequest *self, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data) { NMActRequestPrivate *priv; guint32 call_id; @@ -137,7 +140,9 @@ nm_act_request_get_secrets (NMActRequest *self, * itself. */ call_id = nm_agent_manager_get_secrets (priv->agent_mgr, - connection ? connection : priv->connection, + connection, + filter_by_uid, + uid, setting_name, flags, hint, @@ -151,6 +156,45 @@ nm_act_request_get_secrets (NMActRequest *self, return call_id; } +guint32 +nm_act_request_get_secrets (NMActRequest *self, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data) +{ + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + + /* non-VPN requests use the activation request's internal connection, and + * also the user-requested status and user_uid if the activation was + * requested by a user. + */ + return _internal_get_secrets (self, priv->connection, priv->user_requested, + priv->user_uid, setting_name, flags, hint, + callback, callback_data); +} + +guint32 +nm_act_request_get_secrets_vpn (NMActRequest *self, + NMConnection *connection, + gboolean user_requested, + gulong user_uid, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data) +{ + g_return_val_if_fail (connection != NULL, 0); + + /* VPN requests use the VPN's connection, and also the VPN's user-requested + * status and user_uid if the activation was requested by a user. + */ + return _internal_get_secrets (self, connection, user_requested, user_uid, + setting_name, flags, hint, callback, callback_data); +} + void nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) { @@ -448,6 +492,7 @@ nm_act_request_new (NMConnection *connection, const char *specific_object, NMAgentManager *agent_mgr, gboolean user_requested, + gulong user_uid, gboolean assumed, gpointer *device) { @@ -475,6 +520,7 @@ nm_act_request_new (NMConnection *connection, G_CALLBACK (device_state_changed), NM_ACT_REQUEST (object)); + priv->user_uid = user_uid; priv->user_requested = user_requested; priv->assumed = assumed; diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index f7a3addd7..f91eb1c72 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -51,6 +51,7 @@ NMActRequest *nm_act_request_new (NMConnection *connection, const char *specific_object, NMAgentManager *agent_mgr, gboolean user_requested, + gulong user_uid, gboolean assumed, gpointer *device); /* An NMDevice */ @@ -92,13 +93,22 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, GError *error, gpointer user_data); -guint32 nm_act_request_get_secrets (NMActRequest *req, - NMConnection *connection, /* NULL == use activation request's connection */ - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data); +guint32 nm_act_request_get_secrets (NMActRequest *req, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data); + +guint32 nm_act_request_get_secrets_vpn (NMActRequest *req, + NMConnection *connection, + gboolean user_requested, + gulong user_uid, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data); void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id); diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index 8a3400256..d5f8ef472 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -330,6 +330,8 @@ struct _Request { guint32 reqid; NMConnection *connection; + gboolean filter_by_uid; + gulong uid_filter; char *setting_name; guint32 flags; char *hint; @@ -364,6 +366,8 @@ struct _Request { static Request * request_new (NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, const char *setting_name, guint32 flags, const char *hint, @@ -380,6 +384,8 @@ request_new (NMConnection *connection, req = g_malloc0 (sizeof (Request)); req->reqid = next_id++; req->connection = g_object_ref (connection); + req->filter_by_uid = filter_by_uid; + req->uid_filter = uid_filter; req->setting_name = g_strdup (setting_name); req->flags = flags; req->hint = g_strdup (hint); @@ -682,7 +688,7 @@ request_add_agent (Request *req, agent_uid = nm_secret_agent_get_owner_uid (agent); if (0 != agent_uid) { if (!nm_auth_uid_in_acl (req->connection, session_monitor, agent_uid, NULL)) { - nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s", + nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s (not in ACL)", nm_secret_agent_get_description (agent), req, req->setting_name); /* Connection not visible to this agent's user */ @@ -691,6 +697,15 @@ request_add_agent (Request *req, /* Caller is allowed to add this connection */ } + /* If the request should filter agents by UID, do that now */ + if (req->filter_by_uid && (agent_uid != req->uid_filter)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent ignored for secrets request %p/%s " + "(uid %ld not required %ld)", + nm_secret_agent_get_description (agent), + req, req->setting_name, agent_uid, req->uid_filter); + return; + } + nm_log_dbg (LOGD_AGENTS, "(%s) agent allowed for secrets request %p/%s", nm_secret_agent_get_description (agent), req, req->setting_name); @@ -781,6 +796,8 @@ mgr_req_complete_cb (Request *req, guint32 nm_agent_manager_get_secrets (NMAgentManager *self, NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, const char *setting_name, guint32 flags, const char *hint, @@ -805,6 +822,8 @@ nm_agent_manager_get_secrets (NMAgentManager *self, setting_name); req = request_new (connection, + filter_by_uid, + uid_filter, setting_name, flags, hint, diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h index e9caa10bd..17d918d5d 100644 --- a/src/nm-agent-manager.h +++ b/src/nm-agent-manager.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. */ #ifndef NM_AGENT_MANAGER_H @@ -59,6 +59,8 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, NMConnection *connection, + gboolean filter_by_uid, + gulong uid, const char *setting_name, guint32 flags, const char *hint, diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 0250490a5..f18d5b9a9 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1055,7 +1055,6 @@ link_timeout_cb (gpointer user_data) nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, - NULL, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, @@ -1245,14 +1244,7 @@ handle_auth_or_fail (NMDeviceEthernet *self, */ if (new_secrets || tries) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - - nm_act_request_get_secrets (req, - NULL, - setting_name, - flags, - NULL, - wired_secrets_cb, - self); + nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else { diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 1068b0e1b..8dfc81b9e 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2495,7 +2495,6 @@ link_timeout_cb (gpointer user_data) cleanup_association_attempt (self, TRUE); nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, - NULL, setting_name, NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, NULL, @@ -2742,14 +2741,7 @@ handle_auth_or_fail (NMDeviceWifi *self, */ if (new_secrets || tries) flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - - nm_act_request_get_secrets (req, - NULL, - setting_name, - flags, - NULL, - wifi_secrets_cb, - self); + nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); } else { diff --git a/src/nm-manager.c b/src/nm-manager.c index f28a405ee..3bd1482e5 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -140,6 +140,7 @@ static const char *internal_activate_device (NMManager *manager, NMConnection *connection, const char *specific_object, gboolean user_requested, + gulong sender_uid, gboolean assumed, GError **error); @@ -942,6 +943,7 @@ secrets_result_cb (NMAgentManager *manager, static guint32 system_connection_get_secrets_cb (NMSettingsConnection *connection, + const char *sender, const char *setting_name, NMSettingsConnectionSecretsUpdatedFunc callback, gpointer callback_data, @@ -949,17 +951,31 @@ system_connection_get_secrets_cb (NMSettingsConnection *connection, { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gboolean call_id; + gboolean call_id = 0; + DBusError error; + gulong sender_uid; + + /* Get the unix user of the requestor */ + dbus_error_init (&error); + sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), + sender, + &error); + if (dbus_error_is_set (&error)) + dbus_error_free (&error); + else { + call_id = nm_agent_manager_get_secrets (priv->agent_mgr, + NM_CONNECTION (connection), + TRUE, + sender_uid, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, + NULL, + secrets_result_cb, + self, + callback, + callback_data); + } - call_id = nm_agent_manager_get_secrets (priv->agent_mgr, - NM_CONNECTION (connection), - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, - NULL, - secrets_result_cb, - self, - callback, - callback_data); return call_id; } @@ -1576,7 +1592,7 @@ add_device (NMManager *self, NMDevice *device) nm_log_dbg (LOGD_DEVICE, "(%s): will attempt to assume existing connection", nm_device_get_iface (device)); - ac_path = internal_activate_device (self, device, existing, NULL, FALSE, TRUE, &error); + ac_path = internal_activate_device (self, device, existing, NULL, FALSE, 0, TRUE, &error); if (ac_path) g_object_notify (G_OBJECT (self), NM_MANAGER_ACTIVE_CONNECTIONS); else { @@ -1910,6 +1926,7 @@ internal_activate_device (NMManager *manager, NMConnection *connection, const char *specific_object, gboolean user_requested, + gulong sender_uid, gboolean assumed, GError **error) { @@ -1938,6 +1955,7 @@ internal_activate_device (NMManager *manager, specific_object, NM_MANAGER_GET_PRIVATE (manager)->agent_mgr, user_requested, + sender_uid, assumed, (gpointer) device); success = nm_device_interface_activate (dev_iface, req, error); @@ -1951,7 +1969,7 @@ nm_manager_activate_connection (NMManager *manager, NMConnection *connection, const char *specific_object, const char *device_path, - gboolean user_requested, + const char *dbus_sender, GError **error) { NMManagerPrivate *priv; @@ -1959,6 +1977,8 @@ nm_manager_activate_connection (NMManager *manager, NMSettingConnection *s_con; NMVPNConnection *vpn_connection; const char *path = NULL; + gulong sender_uid = 0; + DBusError dbus_error; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); @@ -1967,6 +1987,21 @@ nm_manager_activate_connection (NMManager *manager, priv = NM_MANAGER_GET_PRIVATE (manager); + /* Get the UID of the user that originated the request, if any */ + if (dbus_sender) { + dbus_error_init (&dbus_error); + sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), + dbus_sender, + &dbus_error); + if (dbus_error_is_set (&dbus_error)) { + g_set_error_literal (error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, + "Failed to get unix user for dbus sender"); + dbus_error_free (&dbus_error); + return NULL; + } + } + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); @@ -2014,6 +2049,8 @@ nm_manager_activate_connection (NMManager *manager, connection, parent_req, device, + TRUE, + sender_uid, error); if (vpn_connection) path = nm_vpn_connection_get_active_connection_path (vpn_connection); @@ -2042,7 +2079,8 @@ nm_manager_activate_connection (NMManager *manager, device, connection, specific_object, - user_requested, + dbus_sender ? TRUE : FALSE, + dbus_sender ? sender_uid : 0, FALSE, error); } @@ -2063,6 +2101,7 @@ pending_activate (NMManager *self, PendingActivation *pending) NMSettingsConnection *connection; const char *path = NULL; GError *error = NULL; + char *sender; /* Ok, we're authorized */ @@ -2074,12 +2113,16 @@ pending_activate (NMManager *self, PendingActivation *pending) goto out; } + sender = dbus_g_method_get_sender (pending->context); + g_assert (sender); path = nm_manager_activate_connection (self, NM_CONNECTION (connection), pending->specific_object_path, pending->device_path, - TRUE, + sender, &error); + g_free (sender); + if (!path) { nm_log_warn (LOGD_CORE, "connection %s failed to activate: (%d) %s", pending->connection_path, error->code, error->message); diff --git a/src/nm-manager.h b/src/nm-manager.h index ba9375488..22bfca9e8 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -87,7 +87,7 @@ const char * nm_manager_activate_connection (NMManager *manager, NMConnection *connection, const char *specific_object, const char *device_path, - gboolean user_requested, + const char *dbus_sender, /* NULL if automatic */ GError **error); gboolean nm_manager_deactivate_connection (NMManager *manager, diff --git a/src/nm-policy.c b/src/nm-policy.c index 23fc6ac73..06cdb24bb 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -758,7 +758,7 @@ auto_activate_device (gpointer user_data) best_connection, specific_object, nm_device_get_path (data->device), - FALSE, + NULL, &error)) { NMSettingConnection *s_con; diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index 35db28e6e..bf0f020d5 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -471,7 +471,6 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_req, - NULL, setting_name, flags, hints ? g_ptr_array_index (hints, 0) : NULL, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 7bf4b7daf..01be34601 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -711,14 +711,22 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, gpointer user_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - char *setting_name = user_data; + char *sender, *setting_name = user_data; guint32 call_id = 0; GError *local = NULL; - if (error) - dbus_g_method_return_error (context, error); - else { - g_signal_emit (self, signals[GET_SECRETS], 0, setting_name, dbus_get_agent_secrets_cb, context, &call_id); + sender = dbus_g_method_get_sender (context); + if (!sender) { + local = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to get request D-Bus sender"); + } else if (!error) { + g_signal_emit (self, signals[GET_SECRETS], 0, + sender, + setting_name, + dbus_get_agent_secrets_cb, + context, + &call_id); if (call_id > 0) { /* track the request and wait for the callback */ priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); @@ -726,12 +734,15 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, local = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, "No secrets were available"); - dbus_g_method_return_error (context, local); - g_error_free (local); } } + if (error || local) + dbus_g_method_return_error (context, error ? error : local); + g_free (setting_name); + g_free (sender); + g_clear_error (&local); } static void @@ -877,8 +888,8 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (NMSettingsConnectionClass, get_secrets), get_secrets_accumulator, NULL, - _nm_marshal_UINT__STRING_POINTER_POINTER, - G_TYPE_UINT, 3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); + _nm_marshal_UINT__STRING_STRING_POINTER_POINTER, + G_TYPE_UINT, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); signals[CANCEL_SECRETS] = g_signal_new (NM_SETTINGS_CONNECTION_CANCEL_SECRETS, diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 6f7a2ed92..b192346fc 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -80,6 +80,7 @@ struct _NMSettingsConnectionClass { /* signals */ guint32 (*get_secrets) (NMSettingsConnection *connection, + const char *sender, /* dbus bus name of requestor */ const char *setting_name, NMSettingsConnectionSecretsUpdatedFunc callback, gpointer callback_data); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 6f160dfa1..30790f03f 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -57,6 +57,8 @@ typedef struct { NMConnection *connection; + gboolean user_requested; + gulong user_uid; NMActRequest *act_request; guint32 secrets_id; @@ -198,7 +200,9 @@ device_ip4_config_changed (NMDevice *device, NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, NMActRequest *act_request, - NMDevice *parent_device) + NMDevice *parent_device, + gboolean user_requested, + gulong user_uid) { NMVPNConnection *self; NMVPNConnectionPrivate *priv; @@ -213,6 +217,8 @@ nm_vpn_connection_new (NMConnection *connection, priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + priv->user_requested = user_requested; + priv->user_uid = user_uid; priv->connection = g_object_ref (connection); priv->parent_dev = g_object_ref (parent_device); priv->act_request = g_object_ref (act_request); @@ -811,13 +817,15 @@ connection_need_secrets_cb (DBusGProxy *proxy, return; } - priv->secrets_id = nm_act_request_get_secrets (priv->act_request, - priv->connection, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, - NULL, - vpn_secrets_cb, - self); + priv->secrets_id = nm_act_request_get_secrets_vpn (priv->act_request, + priv->connection, + priv->user_requested, + priv->user_uid, + setting_name, + NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, + NULL, + vpn_secrets_cb, + self); if (!priv->secrets_id) nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); } diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index ecd0a89aa..fd5ee24e1 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2010 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -58,7 +58,9 @@ GType nm_vpn_connection_get_type (void); NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, NMActRequest *act_request, - NMDevice *parent_device); + NMDevice *parent_device, + gboolean user_requested, + gulong user_uid); void nm_vpn_connection_activate (NMVPNConnection *connection); NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection); diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 4b58be0d4..aec6f9121 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -159,6 +159,8 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, NMConnection *connection, NMActRequest *act_request, NMDevice *device, + gboolean user_requested, + gulong user_uid, GError **error) { NMSettingVPN *vpn_setting; @@ -205,7 +207,7 @@ nm_vpn_manager_activate_connection (NMVPNManager *manager, return NULL; } - vpn = nm_vpn_service_activate (service, connection, act_request, device, error); + vpn = nm_vpn_service_activate (service, connection, act_request, device, user_requested, user_uid, error); if (vpn) { g_signal_connect (vpn, "vpn-state-changed", G_CALLBACK (connection_vpn_state_changed), diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index f14844a9d..6159bb86f 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -71,6 +71,8 @@ NMVPNConnection *nm_vpn_manager_activate_connection (NMVPNManager *manager, NMConnection *connection, NMActRequest *act_request, NMDevice *device, + gboolean user_requested, + gulong user_uid, GError **error); gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager, diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c index 3377cd9ad..3b4e2b481 100644 --- a/src/vpn-manager/nm-vpn-service.c +++ b/src/vpn-manager/nm-vpn-service.c @@ -325,6 +325,8 @@ nm_vpn_service_activate (NMVPNService *service, NMConnection *connection, NMActRequest *act_request, NMDevice *device, + gboolean user_requested, + gulong user_uid, GError **error) { NMVPNConnection *vpn; @@ -341,7 +343,7 @@ nm_vpn_service_activate (NMVPNService *service, clear_quit_timeout (service); - vpn = nm_vpn_connection_new (connection, act_request, device); + vpn = nm_vpn_connection_new (connection, act_request, device, user_requested, user_uid); g_signal_connect (vpn, "vpn-state-changed", G_CALLBACK (connection_vpn_state_changed), service); diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h index c7c1b0366..0c2445e26 100644 --- a/src/vpn-manager/nm-vpn-service.h +++ b/src/vpn-manager/nm-vpn-service.h @@ -59,6 +59,8 @@ NMVPNConnection * nm_vpn_service_activate (NMVPNService *service, NMConnection *connection, NMActRequest *act_request, NMDevice *device, + gboolean user_requested, + gulong user_uid, GError **error); GSList * nm_vpn_service_get_active_connections (NMVPNService *service); From 37a9303c2ea6dfbc7a6c801b29389c322b9b2c51 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 27 Jan 2011 10:37:01 -0600 Subject: [PATCH 182/264] libnm-util: fix hashing connections and settings The first-level hash table key should be the setting name itself, not the GType name of the setting's GObject. There's probably a better way to do this to reduce that confusion. --- libnm-util/nm-connection.c | 3 +-- libnm-util/tests/test-general.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index fef255ddf..cb677e566 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -834,12 +834,11 @@ nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags) /* Add each setting's hash to the main hash */ g_hash_table_iter_init (&iter, priv->settings); while (g_hash_table_iter_next (&iter, &key, &data)) { - const char *setting_name = key; NMSetting *setting = NM_SETTING (data); setting_hash = nm_setting_to_hash (setting, flags); if (setting_hash) - g_hash_table_insert (ret, g_strdup (setting_name), setting_hash); + g_hash_table_insert (ret, g_strdup (nm_setting_get_name (setting)), setting_hash); } /* Don't send empty hashes */ diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 43f32620b..1d23d99b9 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -384,6 +384,29 @@ test_setting_to_hash_only_secrets (void) g_object_unref (s_wsec); } +static void +test_connection_to_hash_setting_name (void) +{ + NMConnection *connection; + NMSettingWirelessSecurity *s_wsec; + GHashTable *hash; + + connection = nm_connection_new (); + s_wsec = make_test_wsec_setting ("connection-to-hash-setting-name"); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + + /* Make sure the keys of the first level hash are setting names, not + * the GType name of the setting objects. + */ + ASSERT (g_hash_table_lookup (hash, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) != NULL, + "connection-to-hash-setting-name", "unexpectedly missing " NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + g_hash_table_destroy (hash); + g_object_unref (connection); +} + int main (int argc, char **argv) { GError *error = NULL; @@ -404,6 +427,7 @@ int main (int argc, char **argv) test_setting_to_hash_all (); test_setting_to_hash_no_secrets (); test_setting_to_hash_only_secrets (); + test_connection_to_hash_setting_name (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); From 0e6a5365d4f3991f6b10b5db1fb211d2d0696f2c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 27 Jan 2011 10:41:02 -0600 Subject: [PATCH 183/264] core: move secrets handling to NMSettingsConnection It's the thing that owns the secrets anyway, and it simplifies things to have the secrets handling there instead of half in NMActRequest and half in NMManager. It also means we can get rid of the ugly signals that NMSettingsConnection had to emit to get agent's secrets, and we can consolidate the requests for the persistent secrets that the NMSettingsConnection owned into NMSettingsConnection itself instead of also in NMAgentManager. Since the NMActRequest and the NMVPNConnection classes already tracked the underlying NMSettingsConnection representing the activation, its trivial to just have them ask the NMSettingsConnection for secrets instead of talking to the NMAgentManager. Thus, only the NMSettingsConnection now has to know about the agent manager, and it presents a cleaner interface to other objects further up the chain, instead of having bits of the secrets request splattered around the activation request, the VPN connection, the NMManager, etc. --- src/modem-manager/nm-modem.c | 8 +- src/nm-activation-request.c | 158 ++++++++----------- src/nm-activation-request.h | 31 ++-- src/nm-agent-manager.c | 170 +++++---------------- src/nm-agent-manager.h | 13 +- src/nm-device-ethernet.c | 6 +- src/nm-device-wifi.c | 6 +- src/nm-manager.c | 89 +---------- src/nm-secret-agent.h | 9 -- src/ppp-manager/nm-ppp-manager.c | 4 +- src/settings/nm-settings-connection.c | 210 +++++++++++++++++--------- src/settings/nm-settings-connection.h | 37 +++-- src/settings/nm-settings.c | 11 ++ src/vpn-manager/nm-vpn-connection.c | 34 +++-- 14 files changed, 326 insertions(+), 460 deletions(-) diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 2131d90ca..44937eedc 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -516,12 +516,12 @@ nm_modem_get_secrets (NMModem *self, const char *hint) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; cancel_get_secrets (self); if (request_new) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_request, setting_name, flags, @@ -554,7 +554,7 @@ nm_modem_act_stage1_prepare (NMModem *self, NMActStageReturn ret; GPtrArray *hints = NULL; const char *setting_name = NULL; - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; if (priv->act_request) g_object_unref (priv->act_request); @@ -567,7 +567,7 @@ nm_modem_act_stage1_prepare (NMModem *self, reason); if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) { if (priv->secrets_tries++) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (req, setting_name, diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index a25e46e2e..6a36975a8 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -36,6 +36,7 @@ #include "nm-active-connection.h" #include "nm-dbus-glib-types.h" #include "nm-active-connection-glue.h" +#include "nm-settings-connection.h" G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT) @@ -60,7 +61,6 @@ typedef struct { NMConnection *connection; - NMAgentManager *agent_mgr; GSList *secrets_calls; char *specific_object; @@ -94,66 +94,28 @@ enum { /*******************************************************************/ +typedef struct { + NMActRequest *self; + guint32 call_id; + NMActRequestSecretsFunc callback; + gpointer callback_data; +} GetSecretsInfo; + static void -get_secrets_cb (NMAgentManager *manager, +get_secrets_cb (NMSettingsConnection *connection, guint32 call_id, - NMConnection *connection, const char *setting_name, GError *error, - gpointer user_data, - gpointer user_data2, - gpointer user_data3) + gpointer user_data) { - NMActRequest *self = NM_ACT_REQUEST (user_data); - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); - NMActRequestSecretsFunc callback = user_data2; + GetSecretsInfo *info = user_data; + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self); - priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id)); + g_return_if_fail (info->call_id == call_id); + priv->secrets_calls = g_slist_remove (priv->secrets_calls, info); - callback (self, call_id, connection, error, user_data3); -} - -static guint32 -_internal_get_secrets (NMActRequest *self, - NMConnection *connection, - gboolean filter_by_uid, - gulong uid, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data) -{ - NMActRequestPrivate *priv; - guint32 call_id; - - g_return_val_if_fail (self, 0); - g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); - - priv = NM_ACT_REQUEST_GET_PRIVATE (self); - - /* If given a connection (ie, called from an NMVpnConnection) then - * use that, otherwise use the private connection. - * - * FIXME: this is icky, and should go away when NMVPNConnection finally - * uses NMActRequest for activation tracking instead of impersonating one - * itself. - */ - call_id = nm_agent_manager_get_secrets (priv->agent_mgr, - connection, - filter_by_uid, - uid, - setting_name, - flags, - hint, - get_secrets_cb, - self, - callback, - callback_data); - if (call_id > 0) - priv->secrets_calls = g_slist_append (priv->secrets_calls, GUINT_TO_POINTER (call_id)); - - return call_id; + info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data); + g_free (info); } guint32 @@ -164,41 +126,43 @@ nm_act_request_get_secrets (NMActRequest *self, NMActRequestSecretsFunc callback, gpointer callback_data) { - NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self); + NMActRequestPrivate *priv; + GetSecretsInfo *info; + guint32 call_id; - /* non-VPN requests use the activation request's internal connection, and - * also the user-requested status and user_uid if the activation was - * requested by a user. - */ - return _internal_get_secrets (self, priv->connection, priv->user_requested, - priv->user_uid, setting_name, flags, hint, - callback, callback_data); -} + g_return_val_if_fail (self, 0); + g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0); -guint32 -nm_act_request_get_secrets_vpn (NMActRequest *self, - NMConnection *connection, - gboolean user_requested, - gulong user_uid, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data) -{ - g_return_val_if_fail (connection != NULL, 0); + priv = NM_ACT_REQUEST_GET_PRIVATE (self); - /* VPN requests use the VPN's connection, and also the VPN's user-requested - * status and user_uid if the activation was requested by a user. - */ - return _internal_get_secrets (self, connection, user_requested, user_uid, - setting_name, flags, hint, callback, callback_data); + info = g_malloc0 (sizeof (GetSecretsInfo)); + info->self = self; + info->callback = callback; + info->callback_data = callback_data; + + call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), + priv->user_requested, + priv->user_uid, + setting_name, + flags, + hint, + get_secrets_cb, + info, + NULL); + if (call_id > 0) { + info->call_id = call_id; + priv->secrets_calls = g_slist_append (priv->secrets_calls, info); + } else + g_free (info); + + return call_id; } void nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) { NMActRequestPrivate *priv; + GSList *iter; g_return_if_fail (self); g_return_if_fail (NM_IS_ACT_REQUEST (self)); @@ -206,9 +170,18 @@ nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id) priv = NM_ACT_REQUEST_GET_PRIVATE (self); - if (g_slist_find (priv->secrets_calls, GUINT_TO_POINTER (call_id))) { - priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id)); - nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); + for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { + GetSecretsInfo *info = iter->data; + + /* Remove the matching info */ + if (info->call_id == call_id) { + priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter); + g_slist_free (iter); + + nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), call_id); + g_free (info); + break; + } } } @@ -490,7 +463,6 @@ device_state_changed (NMDevice *device, NMActRequest * nm_act_request_new (NMConnection *connection, const char *specific_object, - NMAgentManager *agent_mgr, gboolean user_requested, gulong user_uid, gboolean assumed, @@ -500,7 +472,6 @@ nm_act_request_new (NMConnection *connection, NMActRequestPrivate *priv; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (NM_IS_AGENT_MANAGER (agent_mgr), NULL); g_return_val_if_fail (NM_DEVICE (device), NULL); object = g_object_new (NM_TYPE_ACT_REQUEST, NULL); @@ -513,8 +484,6 @@ nm_act_request_new (NMConnection *connection, if (specific_object) priv->specific_object = g_strdup (specific_object); - priv->agent_mgr = g_object_ref (agent_mgr); - priv->device = NM_DEVICE (device); g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), @@ -595,8 +564,6 @@ dispose (GObject *object) } priv->disposed = TRUE; - g_assert (priv->connection); - g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device), G_CALLBACK (device_state_changed), NM_ACT_REQUEST (object)); @@ -604,14 +571,17 @@ dispose (GObject *object) /* Clear any share rules */ nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE); - g_object_unref (priv->connection); - + /* Kill any in-progress secrets requests */ + g_assert (priv->connection); for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) { - nm_agent_manager_cancel_secrets (priv->agent_mgr, - GPOINTER_TO_UINT (iter->data)); + GetSecretsInfo *info = iter->data; + + nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), info->call_id); + g_free (info); } g_slist_free (priv->secrets_calls); - g_object_unref (priv->agent_mgr); + + g_object_unref (priv->connection); G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object); } diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index f91eb1c72..61456cc65 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -25,7 +25,6 @@ #include #include "nm-connection.h" #include "nm-active-connection.h" -#include "nm-agent-manager.h" #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) @@ -49,7 +48,6 @@ GType nm_act_request_get_type (void); NMActRequest *nm_act_request_new (NMConnection *connection, const char *specific_object, - NMAgentManager *agent_mgr, gboolean user_requested, gulong user_uid, gboolean assumed, @@ -93,22 +91,21 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req, GError *error, gpointer user_data); -guint32 nm_act_request_get_secrets (NMActRequest *req, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data); +/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in + * the nm-secret-agent.xml introspection file. + */ +enum { + NM_ACT_REQUEST_GET_SECRETS_FLAG_NONE = 0x0, + NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, + NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW = 0x2 +}; -guint32 nm_act_request_get_secrets_vpn (NMActRequest *req, - NMConnection *connection, - gboolean user_requested, - gulong user_uid, - const char *setting_name, - guint32 flags, - const char *hint, - NMActRequestSecretsFunc callback, - gpointer callback_data); +guint32 nm_act_request_get_secrets (NMActRequest *req, + const char *setting_name, + guint32 flags, + const char *hint, + NMActRequestSecretsFunc callback, + gpointer callback_data); void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id); diff --git a/src/nm-agent-manager.c b/src/nm-agent-manager.c index d5f8ef472..11f824408 100644 --- a/src/nm-agent-manager.c +++ b/src/nm-agent-manager.c @@ -31,7 +31,6 @@ #include "nm-agent-manager.h" #include "nm-secret-agent.h" #include "nm-manager-auth.h" -#include "nm-settings-connection.h" #include "nm-dbus-glib-types.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -353,7 +352,7 @@ struct _Request { guint32 idle_id; - GHashTable *settings_secrets; + GHashTable *existing_secrets; NMAgentSecretsResultFunc callback; gpointer callback_data; @@ -368,6 +367,7 @@ static Request * request_new (NMConnection *connection, gboolean filter_by_uid, gulong uid_filter, + GHashTable *existing_secrets, const char *setting_name, guint32 flags, const char *hint, @@ -386,6 +386,7 @@ request_new (NMConnection *connection, req->connection = g_object_ref (connection); req->filter_by_uid = filter_by_uid; req->uid_filter = uid_filter; + req->existing_secrets = g_hash_table_ref (existing_secrets); req->setting_name = g_strdup (setting_name); req->flags = flags; req->hint = g_strdup (hint); @@ -413,60 +414,14 @@ request_free (Request *req) g_object_unref (req->connection); g_free (req->setting_name); g_free (req->hint); - if (req->settings_secrets) - g_hash_table_unref (req->settings_secrets); + if (req->existing_secrets) + g_hash_table_unref (req->existing_secrets); memset (req, 0, sizeof (Request)); g_free (req); } static void request_next (Request *req); -static void -destroy_gvalue (gpointer data) -{ - GValue *value = (GValue *) data; - - g_value_unset (value); - g_slice_free (GValue, value); -} - -static void -merge_secrets (GHashTable *src, GHashTable *dest) -{ - GHashTableIter iter; - gpointer key, data; - - g_hash_table_iter_init (&iter, src); - while (g_hash_table_iter_next (&iter, &key, &data)) { - const char *setting_name = key; - GHashTable *dstsetting; - GHashTableIter subiter; - gpointer subkey, subval; - - /* Find the corresponding setting in the merged secrets hash, or create - * it if it doesn't exist. - */ - dstsetting = g_hash_table_lookup (dest, setting_name); - if (!dstsetting) { - dstsetting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) destroy_gvalue); - g_hash_table_insert (dest, (gpointer) setting_name, dstsetting); - } - - /* And copy in each secret from src */ - g_hash_table_iter_init (&subiter, (GHashTable *) data); - while (g_hash_table_iter_next (&subiter, &subkey, &subval)) { - const char *keyname = subkey; - GValue *srcval = subval, *dstval; - - dstval = g_slice_new0 (GValue); - g_value_init (dstval, G_VALUE_TYPE (srcval)); - g_value_copy (srcval, dstval); - - g_hash_table_insert (dstsetting, (gpointer) keyname, dstval); - } - } -} - static void request_secrets_done_cb (NMSecretAgent *agent, gconstpointer call_id, @@ -475,7 +430,7 @@ request_secrets_done_cb (NMSecretAgent *agent, gpointer user_data) { Request *req = user_data; - GHashTable *setting_secrets, *merged; + GHashTable *setting_secrets; g_return_if_fail (call_id == req->current_call_id); @@ -510,20 +465,7 @@ request_secrets_done_cb (NMSecretAgent *agent, nm_secret_agent_get_description (agent), req, req->setting_name); - /* Success! If we got some secrets from the settings service, merge those - * with the ones from the secret agent. - */ - if (req->settings_secrets) { - merged = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_unref); - - /* Copy agent secrets first, then overwrite with settings secrets */ - merge_secrets (secrets, merged); - merge_secrets (req->settings_secrets, merged); - - req->complete_callback (req, merged, NULL, req->complete_callback_data); - g_hash_table_destroy (merged); - } else - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + req->complete_callback (req, secrets, NULL, req->complete_callback_data); } static void @@ -568,23 +510,17 @@ static gboolean request_start_secrets (gpointer user_data) { Request *req = user_data; - GHashTable *secrets, *setting_secrets = NULL; - GError *error = NULL; + GHashTable *setting_secrets = NULL; req->idle_id = 0; - nm_log_dbg (LOGD_AGENTS, "(%p/%s) getting secrets from system settings", - req, req->setting_name); - - /* Grab any secrets from persistent storage */ - secrets = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (req->connection), - req->setting_name, - &error); - if (secrets) - setting_secrets = g_hash_table_lookup (secrets, req->setting_name); + /* Check if there are any existing secrets */ + if (req->existing_secrets) + setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name); if (setting_secrets && g_hash_table_size (setting_secrets)) { NMConnection *tmp; + GError *error = NULL; /* The connection already had secrets; check if any more are required. * If no more are required, we're done. If secrets are still needed, @@ -594,7 +530,7 @@ request_start_secrets (gpointer user_data) tmp = nm_connection_duplicate (req->connection); g_assert (tmp); - if (!nm_connection_update_secrets (tmp, req->setting_name, secrets, &error)) { + if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { req->complete_callback (req, NULL, error, req->complete_callback_data); g_clear_error (&error); } else { @@ -605,26 +541,16 @@ request_start_secrets (gpointer user_data) req, req->setting_name); /* Got everything, we're done */ - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + req->complete_callback (req, req->existing_secrets, NULL, req->complete_callback_data); } else { nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", req, req->setting_name); /* We don't, so ask some agents for additional secrets */ - req->settings_secrets = g_hash_table_ref (secrets); request_next (req); } } g_object_unref (tmp); - } else if (error) { - nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings returned error: (%d) %s", - req, req->setting_name, error->code, error->message); - - /* Errors from the system settings are hard errors; we don't go on - * to ask agents for secrets if the settings service failed. - */ - req->complete_callback (req, NULL, error, req->complete_callback_data); - g_error_free (error); } else { /* Couldn't get secrets from system settings, so now we ask the * agents for secrets. Let the Agent Manager handle which agents @@ -633,9 +559,6 @@ request_start_secrets (gpointer user_data) request_next (req); } - if (secrets) - g_hash_table_unref (secrets); - return FALSE; } @@ -759,38 +682,18 @@ mgr_req_complete_cb (Request *req, { NMAgentManager *self = NM_AGENT_MANAGER (user_data); NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); - GError *local = NULL; - if (error) - local = g_error_copy (error); - else { - /* Save the secrets into the connection */ - nm_connection_update_secrets (req->connection, - req->setting_name, - secrets, - &local); - } - - if (local) { - nm_log_warn (LOGD_SETTINGS, - "Failed to %s connection secrets: (%d) %s", - error ? "get" : "update", - local->code, - local->message ? local->message : "(none)"); - } - - /* Call the activation requests' secrets callback */ + /* Send secrets back to the requesting object */ req->callback (self, req->reqid, - req->connection, req->setting_name, - local, + error ? NULL : secrets, + error, req->callback_data, req->other_data2, req->other_data3); g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); - g_clear_error (&local); } guint32 @@ -798,6 +701,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, NMConnection *connection, gboolean filter_by_uid, gulong uid_filter, + GHashTable *existing_secrets, const char *setting_name, guint32 flags, const char *hint, @@ -813,7 +717,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, g_return_val_if_fail (self != NULL, 0); g_return_val_if_fail (connection != NULL, 0); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); g_return_val_if_fail (callback != NULL, 0); nm_log_dbg (LOGD_SETTINGS, @@ -824,6 +728,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, req = request_new (connection, filter_by_uid, uid_filter, + existing_secrets, setting_name, flags, hint, @@ -875,30 +780,33 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr, /*************************************************************/ NMAgentManager * -nm_agent_manager_new (NMDBusManager *dbus_mgr) +nm_agent_manager_get (void) { - NMAgentManager *self; + static NMAgentManager *singleton = NULL; NMAgentManagerPrivate *priv; DBusGConnection *connection; - g_return_val_if_fail (dbus_mgr != NULL, NULL); + if (singleton) + return g_object_ref (singleton); - self = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); - if (self) { - priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + singleton = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL); + g_assert (singleton); - priv->session_monitor = nm_session_monitor_get (); - priv->dbus_mgr = g_object_ref (dbus_mgr); - connection = nm_dbus_manager_get_connection (dbus_mgr); - dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_AGENT_MANAGER, G_OBJECT (self)); + priv = NM_AGENT_MANAGER_GET_PRIVATE (singleton); + priv->session_monitor = nm_session_monitor_get (); + priv->dbus_mgr = nm_dbus_manager_get (); - g_signal_connect (priv->dbus_mgr, - NM_DBUS_MANAGER_NAME_OWNER_CHANGED, - G_CALLBACK (name_owner_changed_cb), - self); - } + connection = nm_dbus_manager_get_connection (priv->dbus_mgr); + dbus_g_connection_register_g_object (connection, + NM_DBUS_PATH_AGENT_MANAGER, + G_OBJECT (singleton)); - return self; + g_signal_connect (priv->dbus_mgr, + NM_DBUS_MANAGER_NAME_OWNER_CHANGED, + G_CALLBACK (name_owner_changed_cb), + singleton); + + return singleton; } static void diff --git a/src/nm-agent-manager.h b/src/nm-agent-manager.h index 17d918d5d..582680741 100644 --- a/src/nm-agent-manager.h +++ b/src/nm-agent-manager.h @@ -23,12 +23,8 @@ #include #include - #include -#include "nm-dbus-manager.h" -#include "nm-secret-agent.h" - #define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ()) #define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager)) #define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass)) @@ -46,21 +42,22 @@ typedef struct { GType nm_agent_manager_get_type (void); -NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr); +NMAgentManager *nm_agent_manager_get (void); typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 call_id, - NMConnection *connection, const char *setting_name, + GHashTable *secrets, GError *error, gpointer user_data, - gpointer user_data2, - gpointer user_data3); + gpointer other_data2, + gpointer other_data3); guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, NMConnection *connection, gboolean filter_by_uid, gulong uid, + GHashTable *existing_secrets, const char *setting_name, guint32 flags, const char *hint, diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index f18d5b9a9..079d9cf1f 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -1056,7 +1056,7 @@ link_timeout_cb (gpointer user_data) nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, + NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wired_secrets_cb, self); @@ -1237,13 +1237,13 @@ handle_auth_or_fail (NMDeviceEthernet *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; /* If the caller doesn't necessarily want completely new secrets, * only ask for new secrets after the first failure. */ if (new_secrets || tries) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 8dfc81b9e..da1068e8d 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2496,7 +2496,7 @@ link_timeout_cb (gpointer user_data) nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); nm_act_request_get_secrets (req, setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW, + NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW, NULL, wifi_secrets_cb, self); @@ -2734,13 +2734,13 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_connection_clear_secrets (connection); setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; /* If the caller doesn't necessarily want completely new secrets, * only ask for new secrets after the first failure. */ if (new_secrets || tries) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); diff --git a/src/nm-manager.c b/src/nm-manager.c index 3bd1482e5..a7adb13ad 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -59,7 +59,6 @@ #include "nm-settings.h" #include "nm-settings-connection.h" #include "nm-manager-auth.h" -#include "nm-agent-manager.h" #include "NetworkManagerUtils.h" #define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd" @@ -213,7 +212,6 @@ typedef struct { NMSettings *settings; char *hostname; - NMAgentManager *agent_mgr; RadioState radio_states[RFKILL_TYPE_MAX]; gboolean sleeping; @@ -925,86 +923,6 @@ connections_changed (NMSettings *settings, bluez_manager_resync_devices (manager); } -static void -secrets_result_cb (NMAgentManager *manager, - guint32 call_id, - NMConnection *connection, - const char *setting_name, - GError *error, - gpointer user_data, - gpointer user_data2, - gpointer user_data3) -{ - NMSettingsConnectionSecretsUpdatedFunc callback = user_data2; - gpointer callback_data = user_data3; - - callback (NM_SETTINGS_CONNECTION (connection), setting_name, call_id, error, callback_data); -} - -static guint32 -system_connection_get_secrets_cb (NMSettingsConnection *connection, - const char *sender, - const char *setting_name, - NMSettingsConnectionSecretsUpdatedFunc callback, - gpointer callback_data, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gboolean call_id = 0; - DBusError error; - gulong sender_uid; - - /* Get the unix user of the requestor */ - dbus_error_init (&error); - sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), - sender, - &error); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - else { - call_id = nm_agent_manager_get_secrets (priv->agent_mgr, - NM_CONNECTION (connection), - TRUE, - sender_uid, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE, - NULL, - secrets_result_cb, - self, - callback, - callback_data); - } - - return call_id; -} - -static void -system_connection_cancel_secrets_cb (NMSettingsConnection *connection, - guint32 call_id, - gpointer user_data) -{ - NMManager *self = NM_MANAGER (user_data); - - nm_agent_manager_cancel_secrets (NM_MANAGER_GET_PRIVATE (self)->agent_mgr, call_id); -} - -static void -connection_added (NMSettings *settings, - NMSettingsConnection *connection, - NMManager *manager) -{ - /* Hook up secrets request listeners */ - g_signal_connect (connection, NM_SETTINGS_CONNECTION_GET_SECRETS, - G_CALLBACK (system_connection_get_secrets_cb), - manager); - g_signal_connect (connection, NM_SETTINGS_CONNECTION_CANCEL_SECRETS, - G_CALLBACK (system_connection_cancel_secrets_cb), - manager); - - connections_changed (settings, connection, manager); -} - static void system_unmanaged_devices_changed_cb (NMSettings *settings, GParamSpec *pspec, @@ -1953,7 +1871,6 @@ internal_activate_device (NMManager *manager, req = nm_act_request_new (connection, specific_object, - NM_MANAGER_GET_PRIVATE (manager)->agent_mgr, user_requested, sender_uid, assumed, @@ -3190,8 +3107,6 @@ nm_manager_get (NMSettings *settings, priv->settings = g_object_ref (settings); - priv->agent_mgr = nm_agent_manager_new (priv->dbus_mgr); - priv->config_file = g_strdup (config_file); priv->state_file = g_strdup (state_file); @@ -3206,7 +3121,7 @@ nm_manager_get (NMSettings *settings, g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME, G_CALLBACK (system_hostname_changed_cb), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED, - G_CALLBACK (connection_added), singleton); + G_CALLBACK (connections_changed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, G_CALLBACK (connections_changed), singleton); g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, @@ -3275,8 +3190,6 @@ dispose (GObject *object) g_object_unref (priv->settings); - g_object_unref (priv->agent_mgr); - if (priv->vpn_manager_id) { g_source_remove (priv->vpn_manager_id); priv->vpn_manager_id = 0; diff --git a/src/nm-secret-agent.h b/src/nm-secret-agent.h index bb86835e3..f1e8bb322 100644 --- a/src/nm-secret-agent.h +++ b/src/nm-secret-agent.h @@ -29,15 +29,6 @@ #include #include "nm-dbus-manager.h" -/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in - * the nm-secret-agent.xml introspection file. - */ -enum { - NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1, - NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2 -}; - #define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ()) #define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent)) #define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass)) diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index bf0f020d5..62faaad72 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -442,7 +442,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, guint32 tries; GPtrArray *hints = NULL; GError *error = NULL; - guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION; connection = nm_act_request_get_connection (priv->act_req); @@ -468,7 +468,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, */ tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); if (tries > 1) - flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_req, setting_name, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 01be34601..f532442c2 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -35,6 +35,7 @@ #include "nm-logging.h" #include "nm-manager-auth.h" #include "nm-marshal.h" +#include "nm-agent-manager.h" static void impl_settings_connection_get_settings (NMSettingsConnection *connection, DBusGMethodInvocation *context); @@ -66,8 +67,6 @@ enum { enum { UPDATED, REMOVED, - GET_SECRETS, - CANCEL_SECRETS, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -75,6 +74,9 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { gboolean disposed; + NMDBusManager *dbus_mgr; + NMAgentManager *agent_mgr; + PolkitAuthority *authority; GSList *pending_auths; /* List of pending authentication requests */ NMConnection *secrets; @@ -340,25 +342,77 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name) return TRUE; } +static void +agent_secrets_done_cb (NMAgentManager *manager, + guint32 call_id, + const char *setting_name, + GHashTable *secrets, + GError *error, + gpointer user_data, + gpointer other_data2, + gpointer other_data3) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingsConnectionSecretsFunc callback = other_data2; + gpointer callback_data = other_data3; + GError *local = NULL; + GHashTable *hash; + + if (error) { + callback (self, call_id, setting_name, error, callback_data); + return; + } + + /* Update the connection with the agent's secrets */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + /* FIXME: if the agent's owner has "modify" permission, then agent + * supplied secrets should overwrite existing secrets, and those agent + * supplied secrets should get written back out to persistent storage. + */ + + hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local); + g_hash_table_destroy (hash); + } + + callback (self, call_id, setting_name, local, callback_data); + g_clear_error (&local); +} + /** * nm_settings_connection_get_secrets: * @connection: the #NMSettingsConnection + * @filter_by_uid: if TRUE, only request secrets from agents registered by the + * same UID as @uid. + * @uid: when @filter_by_uid is TRUE, only request secrets from agents belonging + * to this UID * @setting_name: the setting to return secrets for - * @error: an error on return, if an error occured + * @flags: flags to modify the secrets request + * @hint: the name of a key in @setting_name for which a secret may be required + * @callback: the function to call with returned secrets + * @callback_data: user data to pass to @callback * - * Return secrets in persistent storage, if any. Does not query any Secret - * Agents for secrets. + * Retrieves secrets from persistent storage and queries any secret agents for + * additional secrets. * - * Returns: a hash mapping setting names to hash tables, each inner hash - * containing string:value mappings of secrets + * Returns: a call ID which may be used to cancel the ongoing secrets request **/ -GHashTable * -nm_settings_connection_get_secrets (NMSettingsConnection *connection, +guint32 +nm_settings_connection_get_secrets (NMSettingsConnection *self, + gboolean filter_by_uid, + gulong uid, const char *setting_name, + guint32 flags, + const char *hint, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data, GError **error) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); - NMSetting *setting; + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + GHashTable *existing_secrets; + guint32 call_id = 0; /* Use priv->secrets to work around the fact that nm_connection_clear_secrets() * will clear secrets on this object's settings. priv->secrets should be @@ -369,20 +423,44 @@ nm_settings_connection_get_secrets (NMSettingsConnection *connection, g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "%s.%d - Internal error; secrets cache invalid.", __FILE__, __LINE__); - return NULL; + return 0; } /* FIXME: if setting_name is empty, return all secrets */ - setting = nm_connection_get_setting_by_name (priv->secrets, setting_name); - if (!setting) { + if (!nm_connection_get_setting_by_name (priv->secrets, setting_name)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); - return NULL; + return 0; } - return nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + existing_secrets = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + call_id = nm_agent_manager_get_secrets (priv->agent_mgr, + NM_CONNECTION (self), + filter_by_uid, + uid, + existing_secrets, + setting_name, + flags, + hint, + agent_secrets_done_cb, + self, + callback, + callback_data); + g_hash_table_unref (existing_secrets); + + return call_id; +} + +void +nm_settings_connection_cancel_secrets (NMSettingsConnection *self, + guint32 call_id) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); + nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); } /**** User authorization **************************************/ @@ -660,25 +738,10 @@ impl_settings_connection_delete (NMSettingsConnection *self, /**************************************************************/ -static gboolean -get_secrets_accumulator (GSignalInvocationHint *ihint, - GValue *return_accu, - const GValue *handler_return, - gpointer data) -{ - guint handler_call_id = g_value_get_uint (handler_return); - - if (handler_call_id > 0) - g_value_set_uint (return_accu, handler_call_id); - - /* Abort signal emission if a valid call ID got returned */ - return handler_call_id ? FALSE : TRUE; -} - static void dbus_get_agent_secrets_cb (NMSettingsConnection *self, - const char *setting_name, guint32 call_id, + const char *setting_name, GError *error, gpointer user_data) { @@ -712,36 +775,59 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); char *sender, *setting_name = user_data; + DBusError dbus_error; + gulong sender_uid; guint32 call_id = 0; GError *local = NULL; + if (error) { + local = g_error_copy (error); + goto done; + } + sender = dbus_g_method_get_sender (context); if (!sender) { local = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, "Unable to get request D-Bus sender"); - } else if (!error) { - g_signal_emit (self, signals[GET_SECRETS], 0, - sender, - setting_name, - dbus_get_agent_secrets_cb, - context, - &call_id); - if (call_id > 0) { - /* track the request and wait for the callback */ - priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); - } else { - local = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE, - "No secrets were available"); - } + goto done; } - if (error || local) + /* Get the unix user of the requestor */ + dbus_error_init (&dbus_error); + sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), + sender, + &dbus_error); + g_free (sender); + + if (dbus_error_is_set (&dbus_error)) { + local = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + "Unable to get sender UID: %s", + dbus_error.message); + dbus_error_free (&dbus_error); + goto done; + } + + call_id = nm_settings_connection_get_secrets (self, + TRUE, + sender_uid, + setting_name, + 0, /* GET_SECRETS_FLAG_NONE */ + NULL, + dbus_get_agent_secrets_cb, + context, + &local); + if (call_id > 0) { + /* track the request and wait for the callback */ + priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); + } + +done: + if (local) dbus_g_method_return_error (context, error ? error : local); g_free (setting_name); - g_free (sender); g_clear_error (&local); } @@ -763,6 +849,8 @@ nm_settings_connection_init (NMSettingsConnection *self) char *dbus_path; GError *error = NULL; + priv->dbus_mgr = nm_dbus_manager_get (); + priv->authority = polkit_authority_get_sync (NULL, NULL); if (!priv->authority) { nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", @@ -781,6 +869,8 @@ nm_settings_connection_init (NMSettingsConnection *self) NM_SESSION_MONITOR_CHANGED, G_CALLBACK (session_changed_cb), self); + + priv->agent_mgr = nm_agent_manager_get (); } static void @@ -805,12 +895,14 @@ dispose (GObject *object) /* Cancel in-progress secrets requests */ for (iter = priv->reqs; iter; iter = g_slist_next (iter)) - g_signal_emit (self, signals[CANCEL_SECRETS], 0, GPOINTER_TO_UINT (iter->data)); + nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data)); g_slist_free (priv->reqs); set_visible (self, FALSE); g_object_unref (priv->session_monitor); + g_object_unref (priv->agent_mgr); + g_object_unref (priv->dbus_mgr); out: G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); @@ -881,24 +973,6 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - /* not exported over D-Bus */ - signals[GET_SECRETS] = - g_signal_new (NM_SETTINGS_CONNECTION_GET_SECRETS, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMSettingsConnectionClass, get_secrets), - get_secrets_accumulator, NULL, - _nm_marshal_UINT__STRING_STRING_POINTER_POINTER, - G_TYPE_UINT, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); - - signals[CANCEL_SECRETS] = - g_signal_new (NM_SETTINGS_CONNECTION_CANCEL_SECRETS, - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 0); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_settings_connection_object_info); } diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index b192346fc..643b1756e 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -23,7 +23,6 @@ #define NM_SETTINGS_CONNECTION_H #include -#include G_BEGIN_DECLS @@ -53,12 +52,6 @@ typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection GError *error, gpointer user_data); -typedef void (*NMSettingsConnectionSecretsUpdatedFunc) (NMSettingsConnection *connection, - const char *setting_name, - guint32 call_id, - GError *error, - gpointer user_data); - struct _NMSettingsConnection { NMConnection parent; }; @@ -77,15 +70,6 @@ struct _NMSettingsConnectionClass { gboolean (*supports_secrets) (NMSettingsConnection *connection, const char *setting_name); - - /* signals */ - guint32 (*get_secrets) (NMSettingsConnection *connection, - const char *sender, /* dbus bus name of requestor */ - const char *setting_name, - NMSettingsConnectionSecretsUpdatedFunc callback, - gpointer callback_data); - - void (*cancel_secrets) (NMSettingsConnection *connection, guint32 call_id); }; GType nm_settings_connection_get_type (void); @@ -107,9 +91,24 @@ void nm_settings_connection_delete (NMSettingsConnection *connection, NMSettingsConnectionDeleteFunc callback, gpointer user_data); -GHashTable *nm_settings_connection_get_secrets (NMSettingsConnection *connection, - const char *setting_name, - GError **error); +typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *connection, + guint32 call_id, + const char *setting_name, + GError *error, + gpointer user_data); + +guint32 nm_settings_connection_get_secrets (NMSettingsConnection *connection, + gboolean filter_by_uid, + gulong uid, + const char *setting_name, + guint32 flags, + const char *hint, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data, + GError **error); + +void nm_settings_connection_cancel_secrets (NMSettingsConnection *connection, + guint32 call_id); gboolean nm_settings_connection_is_visible (NMSettingsConnection *self); diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 542c398a6..e47b89fb4 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -63,6 +63,7 @@ #include "nm-manager-auth.h" #include "nm-session-monitor.h" #include "system-settings/plugins/keyfile/plugin.h" +#include "nm-agent-manager.h" #define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" @@ -104,6 +105,8 @@ typedef struct { NMDBusManager *dbus_mgr; DBusGConnection *bus; + NMAgentManager *agent_mgr; + PolkitAuthority *authority; guint auth_changed_id; char *config_file; @@ -1383,6 +1386,13 @@ nm_settings_init (NMSettings *self) } priv->session_monitor = nm_session_monitor_get (); + + /* Hold a reference to the agent manager so it stays alive; the only + * other holders are NMSettingsConnection objects which are often + * transient, and we don't want the agent manager to get destroyed and + * recreated often. + */ + priv->agent_mgr = nm_agent_manager_get (); } static void @@ -1404,6 +1414,7 @@ dispose (GObject *object) g_object_unref (priv->dbus_mgr); g_object_unref (priv->session_monitor); + g_object_unref (priv->agent_mgr); G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object); } diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 30790f03f..7081f227a 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -47,6 +47,7 @@ #include "nm-dns-manager.h" #include "nm-netlink-monitor.h" #include "nm-glib-compat.h" +#include "settings/nm-settings-connection.h" #include "nm-vpn-connection-glue.h" @@ -768,22 +769,22 @@ cancel_get_secrets (NMVPNConnection *self) NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); if (priv->secrets_id) { - nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id); + nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->secrets_id); priv->secrets_id = 0; } } static void -vpn_secrets_cb (NMActRequest *req, +vpn_secrets_cb (NMSettingsConnection *connection, guint32 call_id, - NMConnection *connection, + const char *setting_name, GError *error, gpointer user_data) { NMVPNConnection *self = NM_VPN_CONNECTION (user_data); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - g_return_if_fail (req == priv->act_request); + g_return_if_fail (NM_CONNECTION (connection) == priv->connection); g_return_if_fail (call_id == priv->secrets_id); priv->secrets_id = 0; @@ -802,6 +803,7 @@ connection_need_secrets_cb (DBusGProxy *proxy, { NMVPNConnection *self = NM_VPN_CONNECTION (user_data); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + GError *local = NULL; if (error) { nm_log_err (LOGD_VPN, "NeedSecrets failed: %s %s", @@ -817,17 +819,21 @@ connection_need_secrets_cb (DBusGProxy *proxy, return; } - priv->secrets_id = nm_act_request_get_secrets_vpn (priv->act_request, - priv->connection, - priv->user_requested, - priv->user_uid, - setting_name, - NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION, - NULL, - vpn_secrets_cb, - self); - if (!priv->secrets_id) + priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), + priv->user_requested, + priv->user_uid, + setting_name, + NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION, + NULL, + vpn_secrets_cb, + self, + &local); + if (!priv->secrets_id) { + if (local) + nm_log_err (LOGD_VPN, "failed to get secrets: (%d) %s", local->code, local->message); nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + g_clear_error (&local); + } } static void From 89fcc757a4650d688ca7fcf1fa86854f6065a241 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 27 Jan 2011 18:38:45 -0600 Subject: [PATCH 184/264] libnm-util: remove deprecated GSM bits --- libnm-util/nm-setting-gsm.c | 61 ------------------------------------- libnm-util/nm-setting-gsm.h | 15 --------- 2 files changed, 76 deletions(-) diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index 9f24265d8..4af7c5ac1 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -92,9 +92,7 @@ enum { PROP_APN, PROP_NETWORK_ID, PROP_NETWORK_TYPE, - PROP_BAND, PROP_PIN, - PROP_PUK, PROP_ALLOWED_BANDS, PROP_HOME_ONLY, @@ -164,13 +162,6 @@ nm_setting_gsm_get_network_type (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->network_type; } -int -nm_setting_gsm_get_band (NMSettingGsm *setting) -{ - g_warning ("Tried to get deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_BAND); - return -1; -} - guint32 nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting) { @@ -187,13 +178,6 @@ nm_setting_gsm_get_pin (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->pin; } -const char * -nm_setting_gsm_get_puk (NMSettingGsm *setting) -{ - g_warning ("Tried to get deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_PUK); - return NULL; -} - gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting) { @@ -343,7 +327,6 @@ set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (object); - const char *str; char *tmp; switch (prop_id) { @@ -376,10 +359,6 @@ set_property (GObject *object, guint prop_id, case PROP_NETWORK_TYPE: priv->network_type = g_value_get_int (value); break; - case PROP_BAND: - if (g_value_get_int (value) != -1) - g_warning ("Tried to set deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_BAND); - break; case PROP_ALLOWED_BANDS: priv->allowed_bands = g_value_get_uint (value); break; @@ -387,11 +366,6 @@ set_property (GObject *object, guint prop_id, g_free (priv->pin); priv->pin = g_value_dup_string (value); break; - case PROP_PUK: - str = g_value_get_string (value); - if (str && strlen (str)) - g_warning ("Tried to set deprecated property " NM_SETTING_GSM_SETTING_NAME "/" NM_SETTING_GSM_PUK); - break; case PROP_HOME_ONLY: priv->home_only = g_value_get_boolean (value); break; @@ -432,14 +406,6 @@ get_property (GObject *object, guint prop_id, case PROP_PIN: g_value_set_string (value, nm_setting_gsm_get_pin (setting)); break; - case PROP_PUK: - /* deprecated */ - g_value_set_string (value, NULL); - break; - case PROP_BAND: - /* deprecated */ - g_value_set_int (value, -1); - break; case PROP_HOME_ONLY: g_value_set_boolean (value, nm_setting_gsm_get_home_only (setting)); break; @@ -654,31 +620,4 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) "not be made.", FALSE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); - - /* Deprecated properties */ - /** - * NMSettingGsm:puk: - * - * DEPRECATED - **/ - g_object_class_install_property - (object_class, PROP_PUK, - g_param_spec_string (NM_SETTING_GSM_PUK, - "PUK (DEPRECATED and UNUSED)", - "PUK (DEPRECATED and UNUSED)", - NULL, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); - - /** - * NMSettingGsm:band: - * - * DEPRECATED - **/ - g_object_class_install_property - (object_class, PROP_BAND, - g_param_spec_int (NM_SETTING_GSM_BAND, - "Band (DEPRECATED and UNUSED)", - "Band (DEPRECATED and UNUSED)", - -1, 5, -1, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-gsm.h b/libnm-util/nm-setting-gsm.h index 0ac712246..12406dbff 100644 --- a/libnm-util/nm-setting-gsm.h +++ b/libnm-util/nm-setting-gsm.h @@ -63,17 +63,6 @@ GQuark nm_setting_gsm_error_quark (void); #define NM_SETTING_GSM_PIN "pin" #define NM_SETTING_GSM_HOME_ONLY "home-only" -/* DEPRECATED & UNUSED */ -#define NM_SETTING_GSM_PUK "puk" -#define NM_SETTING_GSM_BAND "band" - -/* DEPRECATED, use NM_SETTING_NETWORK_TYPE_* instead */ -#define NM_GSM_NETWORK_ANY NM_SETTING_GSM_NETWORK_TYPE_ANY -#define NM_GSM_NETWORK_UMTS_HSPA NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA -#define NM_GSM_NETWORK_GPRS_EDGE NM_SETTING_GSM_NETWORK_TYPE_GPRS_EDGE -#define NM_GSM_NETWORK_PREFER_UMTS_HSPA NM_SETTING_GSM_NETWORK_TYPE_PREFER_UMTS_HSPA -#define NM_GSM_NETWORK_PREFER_GPRS_EDGE NM_SETTING_GSM_NETWORK_TYPE_PREFER_GPRS_EDGE - typedef enum { NM_SETTING_GSM_NETWORK_TYPE_ANY = -1, NM_SETTING_GSM_NETWORK_TYPE_UMTS_HSPA = 0, @@ -126,10 +115,6 @@ guint32 nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting); const char *nm_setting_gsm_get_pin (NMSettingGsm *setting); gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting); -/* DEPRECATED & UNUSED */ -const char *nm_setting_gsm_get_puk (NMSettingGsm *setting); -int nm_setting_gsm_get_band (NMSettingGsm *setting); - G_END_DECLS #endif /* NM_SETTING_GSM_H */ From d2329ef5f7214c332435b2ffd31e0d37e8290387 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 27 Jan 2011 18:45:21 -0600 Subject: [PATCH 185/264] libnm-util: remove deprecated 802.1x cert blob functions --- libnm-util/nm-setting-8021x.c | 426 ---------------------------------- libnm-util/nm-setting-8021x.h | 51 ---- 2 files changed, 477 deletions(-) diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index eea6ba5e7..d84318d21 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -423,29 +423,6 @@ nm_setting_802_1x_get_ca_cert_blob (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->ca_cert; } -/** - * nm_setting_802_1x_get_ca_cert: - * @setting: the #NMSetting8021x - * - * Returns the CA certificate blob if the CA certificate is stored using the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. Not all EAP methods use a - * CA certificate (LEAP for example), and those that can take advantage of the - * CA certificate allow it to be unset. Note that lack of a CA certificate - * reduces security by allowing man-in-the-middle attacks, because the identity - * of the network cannot be confirmed by the client. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_ca_cert_blob(). - * - * Returns: the CA certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_ca_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_ca_cert_blob (setting); -} - /** * nm_setting_802_1x_get_ca_cert_path: * @setting: the #NMSetting8021x @@ -560,61 +537,6 @@ nm_setting_802_1x_set_ca_cert (NMSetting8021x *self, return priv->ca_cert != NULL; } -static NMSetting8021xCKType -ck_format_to_type (NMSetting8021xCKFormat format) -{ - switch (format) { - case NM_SETTING_802_1X_CK_FORMAT_X509: - return NM_SETTING_802_1X_CK_TYPE_X509; - case NM_SETTING_802_1X_CK_FORMAT_RAW_KEY: - return NM_SETTING_802_1X_CK_TYPE_RAW_KEY; - case NM_SETTING_802_1X_CK_FORMAT_PKCS12: - return NM_SETTING_802_1X_CK_TYPE_PKCS12; - default: - break; - } - return NM_SETTING_802_1X_CK_TYPE_UNKNOWN; -} - -/** - * nm_setting_802_1x_set_ca_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the CA certificate file (PEM or DER format). Passing - * NULL clears the CA certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:ca-cert property - * with the raw certificate data using the %NM_SETTING_802_1X_CK_SCHEME_BLOB - * scheme. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_ca_cert() with the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_ca_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_client_cert_scheme: * @setting: the #NMSetting8021x @@ -656,26 +578,6 @@ nm_setting_802_1x_get_client_cert_blob (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->client_cert; } -/** - * nm_setting_802_1x_get_client_cert: - * @setting: the #NMSetting8021x - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_client_cert_blob(). - * - * Returns: the client certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_client_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_client_cert_blob (setting); -} - /** * nm_setting_802_1x_get_client_cert_path: * @setting: the #NMSetting8021x @@ -795,48 +697,6 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *self, return priv->client_cert != NULL; } -/** - * nm_setting_802_1x_set_client_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the client certificate file (PEM, DER, or - * PKCS#12 format). Passing NULL clears the client certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:client-cert - * property with the raw certificate data. - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_client_cert() with the - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_client_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_phase1_peapver: * @setting: the #NMSetting8021x @@ -982,28 +842,6 @@ nm_setting_802_1x_get_phase2_ca_cert_blob (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_ca_cert; } -/** - * nm_setting_802_1x_get_phase2_ca_cert: - * @setting: the #NMSetting8021x - * - * Returns the "phase 2" CA certificate blob. Not all EAP methods use - * a CA certificate (LEAP for example), and those that can take advantage of the - * CA certificate allow it to be unset. Note that lack of a CA certificate - * reduces security by allowing man-in-the-middle attacks, because the identity - * of the network cannot be confirmed by the client. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_phase2_ca_cert_blob(). - * - * Returns: the "phase 2" CA certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_phase2_ca_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_phase2_ca_cert_blob (setting); -} - /** * nm_setting_802_1x_get_phase2_ca_cert_path: * @setting: the #NMSetting8021x @@ -1118,44 +956,6 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *self, return priv->phase2_ca_cert != NULL; } -/** - * nm_setting_802_1x_set_phase2_ca_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the "phase2" CA certificate file (PEM or DER format). - * Passing NULL with any @scheme clears the "phase2" CA certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:phase2-ca-cert - * property with the raw certificate data. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_phase2_ca_cert(). - * with the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_phase2_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_phase2_ca_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_phase2_client_cert_scheme: * @setting: the #NMSetting8021x @@ -1199,26 +999,6 @@ nm_setting_802_1x_get_phase2_client_cert_blob (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert; } -/** - * nm_setting_802_1x_get_phase2_client_cert: - * @setting: the #NMSetting8021x - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_phase2_client_cert_blob(). - * - * Returns: the "phase 2" client certificate data - **/ -const GByteArray * -nm_setting_802_1x_get_phase2_client_cert (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_phase2_client_cert_blob (setting); -} - /** * nm_setting_802_1x_get_phase2_client_cert_path: * @setting: the #NMSetting8021x @@ -1338,48 +1118,6 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *self, return priv->phase2_client_cert != NULL; } -/** - * nm_setting_802_1x_set_phase2_client_cert_from_file: - * @setting: the #NMSetting8021x - * @filename: pass the path of the "phase2" client certificate file (PEM, DER, - * or PKCS#12 format). Passing NULL clears the "phase2" client certificate. - * @out_ck_type: on successful return, the type of the certificate added - * @error: on unsuccessful return, an error - * - * Reads a certificate from disk and sets the #NMSetting8021x:phase2-client-cert - * property with the raw certificate data. - * - * Client certificates are used to identify the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_phase2_client_cert() with the. - * %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_phase2_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_phase2_client_cert (setting, - filename, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_password: * @setting: the #NMSetting8021x @@ -1468,26 +1206,6 @@ nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key; } -/** - * nm_setting_802_1x_get_private_key: - * @setting: the #NMSetting8021x - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_private_key_blob(). - * - * Returns: the private key data - **/ -const GByteArray * -nm_setting_802_1x_get_private_key (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_private_key_blob (setting); -} - /** * nm_setting_802_1x_get_private_key_path: * @setting: the #NMSetting8021x @@ -1659,51 +1377,6 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *self, return priv->private_key != NULL; } -/** - * nm_setting_802_1x_set_private_key_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the private key file (PEM, DER, or PKCS#12 format). - * Passing NULL clears the private key. - * @password: password used to decrypt the private key - * @out_ck_type: on successful return, the type of the private key added - * @error: on unsuccessful return, an error - * - * Reads a private key from disk and sets the #NMSetting8021x:private-key - * property with the raw private key data. - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_private_key() with. - * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_private_key (setting, - filename, - password, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_private_key_password: * @setting: the #NMSetting8021x @@ -1763,23 +1436,6 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting) return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; } -/** - * nm_setting_802_1x_get_private_key_type: - * @setting: the #NMSetting8021x - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_private_key_format(). - * - * Returns: the data format of the private key data stored in the - * #NMSetting8021x:private-key property - **/ -NMSetting8021xCKType -nm_setting_802_1x_get_private_key_type (NMSetting8021x *setting) -{ - return ck_format_to_type (nm_setting_802_1x_get_private_key_format (setting)); -} - /** * nm_setting_802_1x_get_phase2_private_key_password: * @setting: the #NMSetting8021x @@ -1840,26 +1496,6 @@ nm_setting_802_1x_get_phase2_private_key_blob (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key; } -/** - * nm_setting_802_1x_get_phase2_private_key: - * @setting: the #NMSetting8021x - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_private_key_blob(). - * - * Returns: the "phase 2" private key data - **/ -const GByteArray * -nm_setting_802_1x_get_phase2_private_key (NMSetting8021x *setting) -{ - return nm_setting_802_1x_get_phase2_private_key_blob (setting); -} - /** * nm_setting_802_1x_get_phase2_private_key_path: * @setting: the #NMSetting8021x @@ -2031,51 +1667,6 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *self, return priv->phase2_private_key != NULL; } -/** - * nm_setting_802_1x_set_phase2_private_key_from_file: - * @setting: the #NMSetting8021x - * @filename: the path of the "phase2" private key file (PEM, DER, or PKCS#12 - * format). Passing NULL clears the "phase2" private key. - * @password: password used to decrypt the private key - * @out_ck_type: on successful return, the type of the private key added - * @error: on unsuccessful return, an error - * - * Reads a "phase 2" private key from disk and sets the - * #NMSetting8021x:phase2-private-key property with the raw private key data. - * - * Private keys are used to authenticate the connecting client to the network - * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x - * authentication method. - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_set_phase2_private_key() with - * the %NM_SETTING_802_1X_CK_SCHEME_BLOB scheme. - * - * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful - **/ -gboolean -nm_setting_802_1x_set_phase2_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error) -{ - gboolean success; - NMSetting8021xCKFormat format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; - - success = nm_setting_802_1x_set_phase2_private_key (setting, - filename, - password, - NM_SETTING_802_1X_CK_SCHEME_BLOB, - &format, - error); - if (success && out_ck_type) - *out_ck_type = ck_format_to_type (format); - - return success; -} - /** * nm_setting_802_1x_get_phase2_private_key_format: * @setting: the #NMSetting8021x @@ -2118,23 +1709,6 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting) return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; } -/** - * nm_setting_802_1x_get_phase2_private_key_type: - * @setting: the #NMSetting8021x - * - * Deprecated: 0.8: This function has been deprecated and should - * not be used in newly written code. Calling this function is - * equivalent to calling nm_setting_802_1x_get_phase2_private_key_format(). - * - * Returns: the data format of the private key data stored in the - * #NMSetting8021x:phase2-private-key property - **/ -NMSetting8021xCKType -nm_setting_802_1x_get_phase2_private_key_type (NMSetting8021x *setting) -{ - return ck_format_to_type (nm_setting_802_1x_get_phase2_private_key_format (setting)); -} - static void need_secrets_password (NMSetting8021x *self, GPtrArray *secrets, diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index 7ee868a01..4b31fbf6c 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -224,57 +224,6 @@ const char * nm_setting_802_1x_get_phase2_private_key_password (NMSett NMSetting8021xCKFormat nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting); -/***** DEPRECATED; anything below will be removed in version 0.9 *****/ - -typedef enum { - NM_SETTING_802_1X_CK_TYPE_UNKNOWN = 0, - NM_SETTING_802_1X_CK_TYPE_X509, - NM_SETTING_802_1X_CK_TYPE_RAW_KEY, - NM_SETTING_802_1X_CK_TYPE_PKCS12 -} NMSetting8021xCKType; - -const GByteArray *nm_setting_802_1x_get_ca_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_client_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_phase2_ca_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_phase2_ca_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_phase2_client_cert (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_phase2_client_cert_from_file (NMSetting8021x *setting, - const char *filename, - NMSetting8021xCKType *out_ck_type, - GError **error); - -const GByteArray *nm_setting_802_1x_get_private_key (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error); - -NMSetting8021xCKType nm_setting_802_1x_get_private_key_type (NMSetting8021x *setting); - -const GByteArray *nm_setting_802_1x_get_phase2_private_key (NMSetting8021x *setting); -gboolean nm_setting_802_1x_set_phase2_private_key_from_file (NMSetting8021x *setting, - const char *filename, - const char *password, - NMSetting8021xCKType *out_ck_type, - GError **error); - -NMSetting8021xCKType nm_setting_802_1x_get_phase2_private_key_type (NMSetting8021x *setting); - G_END_DECLS #endif /* NM_SETTING_8021X_H */ From 5a14d17792be5d8a2cf179613b5f022cfbbf1c7b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 28 Jan 2011 13:48:54 -0600 Subject: [PATCH 186/264] libnm-util: remove 802.1x PSK functions and defines There was never a property for it anyway, so it never got serialized across D-Bus, because it was folded into the "password" property in wpa_supplicant between 0.5 and 0.6. --- cli/src/settings.c | 7 ++----- libnm-util/nm-setting-8021x.c | 19 +------------------ libnm-util/nm-setting-8021x.h | 5 +---- 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/cli/src/settings.c b/cli/src/settings.c index 35711d923..fbec9ab34 100644 --- a/cli/src/settings.c +++ b/cli/src/settings.c @@ -93,8 +93,7 @@ static NmcOutputField nmc_fields_setting_8021X[] = { SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY, 20), /* 18 */ SETTING_FIELD (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, 20), /* 19 */ SETTING_FIELD (NM_SETTING_802_1X_PIN, 8), /* 20 */ - SETTING_FIELD (NM_SETTING_802_1X_PSK, 8), /* 21 */ - SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17), /* 22 */ + SETTING_FIELD (NM_SETTING_802_1X_SYSTEM_CA_CERTS, 17), /* 21 */ {NULL, NULL, 0, NULL, 0} }; #define NMC_FIELDS_SETTING_802_1X_ALL "name"","\ @@ -118,7 +117,6 @@ static NmcOutputField nmc_fields_setting_8021X[] = { NM_SETTING_802_1X_PHASE2_PRIVATE_KEY","\ NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD","\ NM_SETTING_802_1X_PIN","\ - NM_SETTING_802_1X_PSK","\ NM_SETTING_802_1X_SYSTEM_CA_CERTS #define NMC_FIELDS_SETTING_802_1X_COMMON NMC_FIELDS_SETTING_802_1X_ALL @@ -660,8 +658,7 @@ setting_802_1X_details (NMSetting *setting, NmCli *nmc) nmc->allowed_fields[18].value = phase2_private_key_str; nmc->allowed_fields[19].value = nm_setting_802_1x_get_phase2_private_key_password (s_8021X); nmc->allowed_fields[20].value = nm_setting_802_1x_get_pin (s_8021X); - nmc->allowed_fields[21].value = nm_setting_802_1x_get_psk (s_8021X); - nmc->allowed_fields[22].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no"); + nmc->allowed_fields[21].value = nm_setting_802_1x_get_system_ca_certs (s_8021X) ? _("yes") : _("no"); nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index d84318d21..a1096e402 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -126,7 +126,6 @@ typedef struct { GByteArray *phase2_client_cert; char *password; char *pin; - char *psk; GByteArray *private_key; char *private_key_password; GByteArray *phase2_private_key; @@ -156,7 +155,6 @@ enum { PROP_PHASE2_PRIVATE_KEY, PROP_PHASE2_PRIVATE_KEY_PASSWORD, PROP_PIN, - PROP_PSK, PROP_SYSTEM_CA_CERTS, LAST_PROP @@ -1148,21 +1146,6 @@ nm_setting_802_1x_get_pin (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin; } -/** - * nm_setting_802_1x_get_psk: - * @setting: the #NMSetting8021x - * - * Returns: the Pre-Shared-Key used by the authentication method, if any, as - * specified by the #NMSetting8021x:psk property - **/ -const char * -nm_setting_802_1x_get_psk (NMSetting8021x *setting) -{ - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); - - return NM_SETTING_802_1X_GET_PRIVATE (setting)->psk; -} - /** * nm_setting_802_1x_get_private_key_scheme: * @setting: the #NMSetting8021x diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index 4b31fbf6c..53dbdd421 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2009 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -86,7 +86,6 @@ GQuark nm_setting_802_1x_error_quark (void); #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key" #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD "phase2-private-key-password" #define NM_SETTING_802_1X_PIN "pin" -#define NM_SETTING_802_1X_PSK "psk" #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" /* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties @@ -195,8 +194,6 @@ const char * nm_setting_802_1x_get_password (NMSetting8 const char * nm_setting_802_1x_get_pin (NMSetting8021x *setting); -const char * nm_setting_802_1x_get_psk (NMSetting8021x *setting); - NMSetting8021xCKScheme nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting); const GByteArray * nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting); const char * nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting); From 12908c8a1a71b0fde1bd8aed160244c01b979865 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 28 Jan 2011 17:41:59 -0600 Subject: [PATCH 187/264] docs: update libnm-glib docs for WiMAX --- docs/libnm-glib/libnm-glib-docs.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/libnm-glib/libnm-glib-docs.sgml b/docs/libnm-glib/libnm-glib-docs.sgml index efe379744..85e626e28 100644 --- a/docs/libnm-glib/libnm-glib-docs.sgml +++ b/docs/libnm-glib/libnm-glib-docs.sgml @@ -22,12 +22,12 @@ + - From 5a7cf39a62442df3747dda304fb41df3b9587837 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 29 Jan 2011 13:34:24 -0600 Subject: [PATCH 188/264] libnm-util: add secret flags for each secret describing how the secret is stored This allows the necessary flexibility when handling secrets; otherwise it wouldn't be known when NM should save secrets returned from agents to backing storage, or when the agents should store the secrets. We can't simply use lack of a secret in persistent storage as the indicator of this, as (for example) when creating a new connection without secrets the storage method would be abmiguous. At the same time, fold in "always ask" functionality for OTP tokens so user agents don't have to store that attribute themselves out-of-band. --- libnm-util/libnm-util.ver | 31 ++-- libnm-util/nm-setting-8021x.c | 191 ++++++++++++++++++++-- libnm-util/nm-setting-8021x.h | 28 +++- libnm-util/nm-setting-cdma.c | 38 ++++- libnm-util/nm-setting-cdma.h | 10 +- libnm-util/nm-setting-gsm.c | 74 ++++++++- libnm-util/nm-setting-gsm.h | 25 +-- libnm-util/nm-setting-pppoe.c | 38 ++++- libnm-util/nm-setting-pppoe.h | 10 +- libnm-util/nm-setting-vpn.c | 71 ++++++++ libnm-util/nm-setting-vpn.h | 8 + libnm-util/nm-setting-wireless-security.c | 128 ++++++++++++++- libnm-util/nm-setting-wireless-security.h | 13 +- libnm-util/nm-setting.h | 27 ++- 14 files changed, 627 insertions(+), 65 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 2c71f37de..b7b94f81e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -46,6 +46,7 @@ global: nm_setting_802_1x_get_identity; nm_setting_802_1x_get_num_eap_methods; nm_setting_802_1x_get_password; + nm_setting_802_1x_get_password_flags; nm_setting_802_1x_get_phase1_fast_provisioning; nm_setting_802_1x_get_phase1_peaplabel; nm_setting_802_1x_get_phase1_peapver; @@ -69,6 +70,7 @@ global: nm_setting_802_1x_get_phase2_private_key_format; nm_setting_802_1x_set_phase2_private_key_from_file; nm_setting_802_1x_get_phase2_private_key_password; + nm_setting_802_1x_get_phase2_private_key_password_flags; nm_setting_802_1x_get_phase2_private_key_path; nm_setting_802_1x_get_phase2_private_key_scheme; nm_setting_802_1x_get_phase2_private_key_type; @@ -79,11 +81,11 @@ global: nm_setting_802_1x_get_private_key_format; nm_setting_802_1x_set_private_key_from_file; nm_setting_802_1x_get_private_key_password; + nm_setting_802_1x_get_private_key_password_flags; nm_setting_802_1x_get_private_key_path; nm_setting_802_1x_get_private_key_scheme; nm_setting_802_1x_get_private_key_type; nm_setting_802_1x_set_private_key; - nm_setting_802_1x_get_psk; nm_setting_802_1x_get_system_ca_certs; nm_setting_802_1x_get_type; nm_setting_802_1x_new; @@ -101,6 +103,7 @@ global: nm_setting_cdma_get_number; nm_setting_cdma_get_username; nm_setting_cdma_get_password; + nm_setting_cdma_get_password_flags; nm_setting_clear_secrets; nm_setting_compare; nm_setting_connection_error_get_type; @@ -130,13 +133,13 @@ global: nm_setting_gsm_get_number; nm_setting_gsm_get_username; nm_setting_gsm_get_password; + nm_setting_gsm_get_password_flags; nm_setting_gsm_get_apn; nm_setting_gsm_get_network_id; nm_setting_gsm_get_network_type; nm_setting_gsm_get_allowed_bands; - nm_setting_gsm_get_band; nm_setting_gsm_get_pin; - nm_setting_gsm_get_puk; + nm_setting_gsm_get_pin_flags; nm_setting_gsm_get_home_only; nm_setting_ip4_config_error_get_type; nm_setting_ip4_config_error_quark; @@ -255,6 +258,7 @@ global: nm_setting_pppoe_get_service; nm_setting_pppoe_get_username; nm_setting_pppoe_get_password; + nm_setting_pppoe_get_password_flags; nm_setting_serial_error_get_type; nm_setting_serial_error_quark; nm_setting_serial_get_type; @@ -268,20 +272,22 @@ global: nm_setting_to_string; nm_setting_update_secrets; nm_setting_verify; + nm_setting_vpn_add_data_item; + nm_setting_vpn_add_secret; nm_setting_vpn_error_get_type; nm_setting_vpn_error_quark; - nm_setting_vpn_get_type; - nm_setting_vpn_new; - nm_setting_vpn_get_service_type; - nm_setting_vpn_get_user_name; - nm_setting_vpn_add_data_item; nm_setting_vpn_foreach_data_item; - nm_setting_vpn_get_data_item; - nm_setting_vpn_remove_data_item; - nm_setting_vpn_add_secret; nm_setting_vpn_foreach_secret; + nm_setting_vpn_get_data_item; nm_setting_vpn_get_secret; + nm_setting_vpn_get_secret_flags; + nm_setting_vpn_get_service_type; + nm_setting_vpn_get_type; + nm_setting_vpn_get_user_name; + nm_setting_vpn_new; + nm_setting_vpn_remove_data_item; nm_setting_vpn_remove_secret; + nm_setting_vpn_set_secret_flags; nm_setting_wimax_error_get_type; nm_setting_wimax_error_quark; nm_setting_wimax_get_type; @@ -338,14 +344,17 @@ global: nm_setting_wireless_security_get_key_mgmt; nm_setting_wireless_security_get_leap_username; nm_setting_wireless_security_get_leap_password; + nm_setting_wireless_security_get_leap_password_flags; nm_setting_wireless_security_get_num_groups; nm_setting_wireless_security_get_num_pairwise; nm_setting_wireless_security_get_num_protos; nm_setting_wireless_security_get_pairwise; nm_setting_wireless_security_get_proto; nm_setting_wireless_security_get_psk; + nm_setting_wireless_security_get_psk_flags; nm_setting_wireless_security_get_type; nm_setting_wireless_security_get_wep_key; + nm_setting_wireless_security_get_wep_key_flags; nm_setting_wireless_security_get_wep_key_type; nm_setting_wireless_security_get_wep_tx_keyidx; nm_setting_wireless_security_new; diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index a1096e402..f29010494 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -125,11 +125,15 @@ typedef struct { char *phase2_ca_path; GByteArray *phase2_client_cert; char *password; + NMSettingSecretFlags password_flags; char *pin; + NMSettingSecretFlags pin_flags; GByteArray *private_key; char *private_key_password; + NMSettingSecretFlags private_key_password_flags; GByteArray *phase2_private_key; char *phase2_private_key_password; + NMSettingSecretFlags phase2_private_key_password_flags; gboolean system_ca_certs; } NMSetting8021xPrivate; @@ -150,11 +154,15 @@ enum { PROP_PHASE2_CA_PATH, PROP_PHASE2_CLIENT_CERT, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, PROP_PRIVATE_KEY, PROP_PRIVATE_KEY_PASSWORD, + PROP_PRIVATE_KEY_PASSWORD_FLAGS, PROP_PHASE2_PRIVATE_KEY, PROP_PHASE2_PRIVATE_KEY_PASSWORD, + PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, PROP_PIN, + PROP_PIN_FLAGS, PROP_SYSTEM_CA_CERTS, LAST_PROP @@ -1131,6 +1139,20 @@ nm_setting_802_1x_get_password (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->password; } +/** + * nm_setting_802_1x_get_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSetting8021x:password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_flags; +} + /** * nm_setting_802_1x_get_pin: * @setting: the #NMSetting8021x @@ -1146,6 +1168,21 @@ nm_setting_802_1x_get_pin (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin; } +/** + * nm_setting_802_1x_get_pin_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:pin + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin_flags; +} + /** * nm_setting_802_1x_get_private_key_scheme: * @setting: the #NMSetting8021x @@ -1174,6 +1211,10 @@ nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting) * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * * Returns: the private key data **/ const GByteArray * @@ -1234,6 +1275,11 @@ nm_setting_802_1x_get_private_key_path (NMSetting8021x *setting) * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * WARNING: the private key property is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful **/ gboolean @@ -1377,6 +1423,21 @@ nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password; } +/** + * nm_setting_802_1x_get_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password_flags; +} + /** * nm_setting_802_1x_get_private_key_format: * @setting: the #NMSetting8021x @@ -1436,6 +1497,21 @@ nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting) return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password; } +/** + * nm_setting_802_1x_get_phase2_private_key_password_flags: + * @setting: the #NMSetting8021x + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSetting8021x:phase2-private-key-password + **/ +NMSettingSecretFlags +nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password_flags; +} + /** * nm_setting_802_1x_get_phase2_private_key_scheme: * @setting: the #NMSetting8021x @@ -1464,6 +1540,10 @@ nm_setting_802_1x_get_phase2_private_key_scheme (NMSetting8021x *setting) * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * WARNING: the phase2 private key property is not a "secret" property, and thus + * unencrypted private key data may be readable by unprivileged users. Private + * keys should always be encrypted with a private key password. + * * Returns: the "phase 2" private key data **/ const GByteArray * @@ -1524,6 +1604,11 @@ nm_setting_802_1x_get_phase2_private_key_path (NMSetting8021x *setting) * when EAP-TLS is used as either the "phase 1" or "phase 2" 802.1x * authentication method. * + * WARNING: the phase2 private key property is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a private + * key password to prevent unauthorized access to unencrypted private key data. + * * Returns: TRUE if the operation succeeded, FALSE if it was unsuccessful **/ gboolean @@ -2374,6 +2459,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; case PROP_PRIVATE_KEY: if (priv->private_key) { g_byte_array_free (priv->private_key, TRUE); @@ -2390,6 +2478,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->private_key_password); priv->private_key_password = g_value_dup_string (value); break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + priv->private_key_password_flags = g_value_get_uint (value); + break; case PROP_PHASE2_PRIVATE_KEY: if (priv->phase2_private_key) { g_byte_array_free (priv->phase2_private_key, TRUE); @@ -2406,6 +2497,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->phase2_private_key_password); priv->phase2_private_key_password = g_value_dup_string (value); break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + priv->phase2_private_key_password_flags = g_value_get_uint (value); + break; case PROP_SYSTEM_CA_CERTS: priv->system_ca_certs = g_value_get_boolean (value); break; @@ -2468,18 +2562,27 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, priv->password); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, priv->password_flags); + break; case PROP_PRIVATE_KEY: g_value_set_boxed (value, priv->private_key); break; case PROP_PRIVATE_KEY_PASSWORD: g_value_set_string (value, priv->private_key_password); break; + case PROP_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_uint (value, priv->private_key_password_flags); + break; case PROP_PHASE2_PRIVATE_KEY: g_value_set_boxed (value, priv->phase2_private_key); break; case PROP_PHASE2_PRIVATE_KEY_PASSWORD: g_value_set_string (value, priv->phase2_private_key_password); break; + case PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS: + g_value_set_uint (value, priv->phase2_private_key_password_flags); + break; case PROP_SYSTEM_CA_CERTS: g_value_set_boolean (value, priv->system_ca_certs); break; @@ -2842,12 +2945,32 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSetting8021x:password-flags: + * + * Flags indicating how to handle #NMSetting8021x:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the 802.1x password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSetting8021x:private-key: * * Contains the private key if the #NMSetting8021x:eap property is set to * 'tls'. Setting this property directly is discouraged; use the * nm_setting_802_1x_set_private_key() function instead. + * + * WARNING: #NMSetting8021x:private-key is not a "secret" property, and thus + * unencrypted private key data using the BLOB scheme may be readable by + * unprivileged users. Private keys should always be encrypted with a + * private key password to prevent unauthorized access to unencrypted + * private key data. **/ g_object_class_install_property (object_class, PROP_PRIVATE_KEY, @@ -2858,12 +2981,17 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "'scheme'; two are currently supported: blob and " "path. When using the blob scheme and X.509 private " "keys, this property should be set to the keys's " - "decrypted DER encoded data. When using X.509 " - "private keys with the path scheme, this property " - "should be set to the full UTF-8 encoded path of " - "the key, prefixed with the string 'file://' and " - "and ending with a terminating NULL byte. When " - "using PKCS#12 format private keys and the blob " + "PEM or DER encoded data; if using DER-encoded " + "data the private key must be decrypted as the " + "DER format is incomplete. Use of decrypted " + "DER-format private keys is not recommended as it " + "may allow unprivileged users access to the " + "decrypted data. When using X.509 private keys " + "with the path scheme, this property should be " + "set to the full UTF-8 encoded path of the key, " + "prefixed with the string 'file://' and ending " + "with a terminating NULL byte. When using " + "PKCS#12 format private keys and the blob " "scheme, this property should be set to the " "PKCS#12 data (which is encrypted) and the " "'private-key-password' property must be set to " @@ -2877,7 +3005,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "be set to the password used to decode the PKCS#12 " "private key and certificate.", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** * NMSetting8021x:private-key-password: @@ -2900,6 +3028,21 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSetting8021x:private-key-password-flags: + * + * Flags indicating how to handle #NMSetting8021x:private-key-password:. + **/ + g_object_class_install_property (object_class, PROP_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS, + "Private Key Password Flags", + "Flags indicating how to handle the 802.1x private " + "key password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSetting8021x:phase2-private-key: * @@ -2920,12 +3063,17 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "'scheme'; two are currently supported: blob and " "path. When using the blob scheme and X.509 private " "keys, this property should be set to the keys's " - "decrypted DER encoded data. When using X.509 " - "private keys with the path scheme, this property " - "should be set to the full UTF-8 encoded path of " - "the key, prefixed with the string 'file://' and " - "and ending with a terminating NULL byte. When " - "using PKCS#12 format private keys and the blob " + "PEM or DER encoded data; if using DER-encoded " + "data the private key must be decrypted as the " + "DER format is incomplete. Use of decrypted " + "DER-format private keys is not recommended as it " + "may allow unprivileged users access to the " + "decrypted data. When using X.509 private keys " + "with the path scheme, this property should be " + "set to the full UTF-8 encoded path of the key, " + "prefixed with the string 'file://' and ending " + "with a terminating NULL byte. When using " + "PKCS#12 format private keys and the blob " "scheme, this property should be set to the " "PKCS#12 data (which is encrypted) and the " "'private-key-password' property must be set to " @@ -2939,7 +3087,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "be set to the password used to decode the PKCS#12 " "private key and certificate.", DBUS_TYPE_G_UCHAR_ARRAY, - G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** * NMSetting8021x:phase2-private-key-password: @@ -2962,6 +3110,21 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSetting8021x:phase2-private-key-password-flags: + * + * Flags indicating how to handle #NMSetting8021x:phase2-private-key-password:. + **/ + g_object_class_install_property (object_class, PROP_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS, + "Phase2 Private Key Password Flags", + "Flags indicating how to handle the 802.1x phase2 " + "private key password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSetting8021x:system-ca-certs: * diff --git a/libnm-util/nm-setting-8021x.h b/libnm-util/nm-setting-8021x.h index 53dbdd421..00cfedd04 100644 --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -81,11 +81,15 @@ GQuark nm_setting_802_1x_error_quark (void); #define NM_SETTING_802_1X_PHASE2_CA_PATH "phase2-ca-path" #define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert" #define NM_SETTING_802_1X_PASSWORD "password" +#define NM_SETTING_802_1X_PASSWORD_FLAGS "password-flags" #define NM_SETTING_802_1X_PRIVATE_KEY "private-key" #define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD "private-key-password" +#define NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS "private-key-password-flags" #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY "phase2-private-key" #define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD "phase2-private-key-password" +#define NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS "phase2-private-key-password-flags" #define NM_SETTING_802_1X_PIN "pin" +#define NM_SETTING_802_1X_PIN_FLAGS "pin-flags" #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" /* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties @@ -101,15 +105,17 @@ GQuark nm_setting_802_1x_error_quark (void); * * When setting OpenSSL-derived "traditional" format (ie S/MIME style, not * PKCS#8) RSA and DSA keys directly via properties with the "blob" scheme, they - * must passed to NetworkManager completely decrypted because the OpenSSL - * "traditional" format is non-standard and is not complete enough for all - * crypto libraries to use. Thus, for OpenSSL "traditional" format keys, the - * private key password is not passed to NetworkManager (because the data is - * already decrypted by the client), and the appropriate "client-cert" (or - * "phase2-client-cert") property of the NMSetting8021x object must be a valid - * client certificate. When using the "path" scheme, just set the private-key - * and client-cert properties to the paths to their respective objects, and - * set the private-key password correctly. + * should be passed to NetworkManager in PEM format with the "DEK-Info" and + * "Proc-Type" tags intact, or in decrypted binary DER format (not recommended, + * as this may allow unprivileged users to read the decrypted private key). + * When decryped keys are used (again, not recommended) the private key password + * should not be set. The recommended method for passing private keys to + * NetworkManager is via the "path" scheme with encrypted private keys, and a + * private key password. + * + * When using the "path" scheme, just set the private-key and client-cert + * properties to the paths to their respective objects, and set the private-key + * password correctly. */ typedef struct { @@ -191,8 +197,10 @@ gboolean nm_setting_802_1x_set_phase2_client_cert (NMSett GError **error); const char * nm_setting_802_1x_get_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_password_flags (NMSetting8021x *setting); const char * nm_setting_802_1x_get_pin (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting); NMSetting8021xCKScheme nm_setting_802_1x_get_private_key_scheme (NMSetting8021x *setting); const GByteArray * nm_setting_802_1x_get_private_key_blob (NMSetting8021x *setting); @@ -204,6 +212,7 @@ gboolean nm_setting_802_1x_set_private_key (NMSett NMSetting8021xCKFormat *out_format, GError **error); const char * nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting); NMSetting8021xCKFormat nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting); @@ -217,6 +226,7 @@ gboolean nm_setting_802_1x_set_phase2_private_key (NMSett NMSetting8021xCKFormat *out_format, GError **error); const char * nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting); +NMSettingSecretFlags nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting); NMSetting8021xCKFormat nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting); diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index 7255eb915..bcd78ec2f 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. */ #include @@ -87,6 +87,7 @@ typedef struct { char *number; /* For dialing, duh */ char *username; char *password; + NMSettingSecretFlags password_flags; } NMSettingCdmaPrivate; enum { @@ -94,6 +95,7 @@ enum { PROP_NUMBER, PROP_USERNAME, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, LAST_PROP }; @@ -153,6 +155,20 @@ nm_setting_cdma_get_password (NMSettingCdma *setting) return NM_SETTING_CDMA_GET_PRIVATE (setting)->password; } +/** + * nm_setting_cdma_get_password_flags: + * @setting: the #NMSettingCdma + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingCdma:password + **/ +NMSettingSecretFlags +nm_setting_cdma_get_password_flags (NMSettingCdma *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_CDMA_GET_PRIVATE (setting)->password_flags; +} + static gint find_setting_by_name (gconstpointer a, gconstpointer b) { @@ -264,6 +280,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -286,6 +305,9 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, nm_setting_cdma_get_password (setting)); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, nm_setting_cdma_get_password_flags (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -360,4 +382,18 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) "a password or accept any password.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + /** + * NMSettingCdma:password-flags: + * + * Flags indicating how to handle #NMSettingCdma:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_CDMA_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the CDMA password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-cdma.h b/libnm-util/nm-setting-cdma.h index 8a6c4505b..8abfce4ab 100644 --- a/libnm-util/nm-setting-cdma.h +++ b/libnm-util/nm-setting-cdma.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -53,9 +53,10 @@ GType nm_setting_cdma_error_get_type (void); #define NM_SETTING_CDMA_ERROR nm_setting_cdma_error_quark () GQuark nm_setting_cdma_error_quark (void); -#define NM_SETTING_CDMA_NUMBER "number" -#define NM_SETTING_CDMA_USERNAME "username" -#define NM_SETTING_CDMA_PASSWORD "password" +#define NM_SETTING_CDMA_NUMBER "number" +#define NM_SETTING_CDMA_USERNAME "username" +#define NM_SETTING_CDMA_PASSWORD "password" +#define NM_SETTING_CDMA_PASSWORD_FLAGS "password-flags" typedef struct { NMSetting parent; @@ -77,6 +78,7 @@ NMSetting *nm_setting_cdma_new (void); const char *nm_setting_cdma_get_number (NMSettingCdma *setting); const char *nm_setting_cdma_get_username (NMSettingCdma *setting); const char *nm_setting_cdma_get_password (NMSettingCdma *setting); +NMSettingSecretFlags nm_setting_cdma_get_password_flags (NMSettingCdma *setting); G_END_DECLS diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index 4af7c5ac1..7cb3c790a 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -73,6 +73,7 @@ typedef struct { char *number; /* For dialing, duh */ char *username; char *password; + NMSettingSecretFlags password_flags; char *apn; /* NULL for dynamic */ char *network_id; /* for manual registration or NULL for automatic */ @@ -80,6 +81,7 @@ typedef struct { guint32 allowed_bands; /* A bitfield of NM_SETTING_GSM_BAND_* */ char *pin; + NMSettingSecretFlags pin_flags; gboolean home_only; } NMSettingGsmPrivate; @@ -89,10 +91,12 @@ enum { PROP_NUMBER, PROP_USERNAME, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, PROP_APN, PROP_NETWORK_ID, PROP_NETWORK_TYPE, PROP_PIN, + PROP_PIN_FLAGS, PROP_ALLOWED_BANDS, PROP_HOME_ONLY, @@ -138,6 +142,20 @@ nm_setting_gsm_get_password (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->password; } +/** + * nm_setting_gsm_get_password_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:password + **/ +NMSettingSecretFlags +nm_setting_gsm_get_password_flags (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->password_flags; +} + const char * nm_setting_gsm_get_apn (NMSettingGsm *setting) { @@ -178,6 +196,20 @@ nm_setting_gsm_get_pin (NMSettingGsm *setting) return NM_SETTING_GSM_GET_PRIVATE (setting)->pin; } +/** + * nm_setting_gsm_get_pin_flags: + * @setting: the #NMSettingGsm + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingGsm:pin + **/ +NMSettingSecretFlags +nm_setting_gsm_get_pin_flags (NMSettingGsm *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_GSM_GET_PRIVATE (setting)->pin_flags; +} + gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting) { @@ -342,6 +374,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; case PROP_APN: g_free (priv->apn); priv->apn = NULL; @@ -366,6 +401,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->pin); priv->pin = g_value_dup_string (value); break; + case PROP_PIN_FLAGS: + priv->pin_flags = g_value_get_uint (value); + break; case PROP_HOME_ONLY: priv->home_only = g_value_get_boolean (value); break; @@ -391,6 +429,9 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, nm_setting_gsm_get_password (setting)); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, nm_setting_gsm_get_password_flags (setting)); + break; case PROP_APN: g_value_set_string (value, nm_setting_gsm_get_apn (setting)); break; @@ -406,6 +447,9 @@ get_property (GObject *object, guint prop_id, case PROP_PIN: g_value_set_string (value, nm_setting_gsm_get_pin (setting)); break; + case PROP_PIN_FLAGS: + g_value_set_uint (value, nm_setting_gsm_get_pin_flags (setting)); + break; case PROP_HOME_ONLY: g_value_set_boolean (value, nm_setting_gsm_get_home_only (setting)); break; @@ -486,6 +530,20 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSettingGsm:password-flags: + * + * Flags indicating how to handle #NMSettingGsm:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_GSM_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the GSM password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingGsm:apn: * @@ -605,6 +663,20 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSettingGsm:pin-flags: + * + * Flags indicating how to handle #NMSettingGsm:pin:. + **/ + g_object_class_install_property (object_class, PROP_PIN_FLAGS, + g_param_spec_uint (NM_SETTING_GSM_PIN_FLAGS, + "PIN Flags", + "Flags indicating how to handle the GSM SIM PIN.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingGsm:home-only: * diff --git a/libnm-util/nm-setting-gsm.h b/libnm-util/nm-setting-gsm.h index 12406dbff..855787c2d 100644 --- a/libnm-util/nm-setting-gsm.h +++ b/libnm-util/nm-setting-gsm.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -53,15 +53,17 @@ GType nm_setting_gsm_error_get_type (void); #define NM_SETTING_GSM_ERROR nm_setting_gsm_error_quark () GQuark nm_setting_gsm_error_quark (void); -#define NM_SETTING_GSM_NUMBER "number" -#define NM_SETTING_GSM_USERNAME "username" -#define NM_SETTING_GSM_PASSWORD "password" -#define NM_SETTING_GSM_APN "apn" -#define NM_SETTING_GSM_NETWORK_ID "network-id" -#define NM_SETTING_GSM_NETWORK_TYPE "network-type" -#define NM_SETTING_GSM_ALLOWED_BANDS "allowed-bands" -#define NM_SETTING_GSM_PIN "pin" -#define NM_SETTING_GSM_HOME_ONLY "home-only" +#define NM_SETTING_GSM_NUMBER "number" +#define NM_SETTING_GSM_USERNAME "username" +#define NM_SETTING_GSM_PASSWORD "password" +#define NM_SETTING_GSM_PASSWORD_FLAGS "password-flags" +#define NM_SETTING_GSM_APN "apn" +#define NM_SETTING_GSM_NETWORK_ID "network-id" +#define NM_SETTING_GSM_NETWORK_TYPE "network-type" +#define NM_SETTING_GSM_ALLOWED_BANDS "allowed-bands" +#define NM_SETTING_GSM_PIN "pin" +#define NM_SETTING_GSM_PIN_FLAGS "pin-flags" +#define NM_SETTING_GSM_HOME_ONLY "home-only" typedef enum { NM_SETTING_GSM_NETWORK_TYPE_ANY = -1, @@ -115,6 +117,9 @@ guint32 nm_setting_gsm_get_allowed_bands (NMSettingGsm *setting); const char *nm_setting_gsm_get_pin (NMSettingGsm *setting); gboolean nm_setting_gsm_get_home_only (NMSettingGsm *setting); +NMSettingSecretFlags nm_setting_gsm_get_pin_flags (NMSettingGsm *setting); +NMSettingSecretFlags nm_setting_gsm_get_password_flags (NMSettingGsm *setting); + G_END_DECLS #endif /* NM_SETTING_GSM_H */ diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index d1aba43d3..e03f00c04 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -71,6 +71,7 @@ typedef struct { char *service; char *username; char *password; + NMSettingSecretFlags password_flags; } NMSettingPPPOEPrivate; enum { @@ -78,6 +79,7 @@ enum { PROP_SERVICE, PROP_USERNAME, PROP_PASSWORD, + PROP_PASSWORD_FLAGS, LAST_PROP }; @@ -112,6 +114,20 @@ nm_setting_pppoe_get_password (NMSettingPPPOE *setting) return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password; } +/** + * nm_setting_pppoe_get_password_flags: + * @setting: the #NMSettingPPPOE + * + * Returns: the #NMSettingSecretFlags pertaining to the #NMSettingPPPOE:password + **/ +NMSettingSecretFlags +nm_setting_pppoe_get_password_flags (NMSettingPPPOE *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password_flags; +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -182,6 +198,9 @@ set_property (GObject *object, guint prop_id, g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PASSWORD_FLAGS: + priv->password_flags = g_value_get_uint (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -204,6 +223,9 @@ get_property (GObject *object, guint prop_id, case PROP_PASSWORD: g_value_set_string (value, nm_setting_pppoe_get_password (setting)); break; + case PROP_PASSWORD_FLAGS: + g_value_set_uint (value, nm_setting_pppoe_get_password_flags (setting)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -271,4 +293,18 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) "Password used to authenticate with the PPPoE service.", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + /** + * NMSettingPPPOE:password-flags: + * + * Flags indicating how to handle #NMSettingPPPOE:password:. + **/ + g_object_class_install_property (object_class, PROP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_PPPOE_PASSWORD_FLAGS, + "Password Flags", + "Flags indicating how to handle the PPPoE password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-pppoe.h b/libnm-util/nm-setting-pppoe.h index 83e95d4ee..d163decb4 100644 --- a/libnm-util/nm-setting-pppoe.h +++ b/libnm-util/nm-setting-pppoe.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -53,9 +53,10 @@ GType nm_setting_pppoe_error_get_type (void); #define NM_SETTING_PPPOE_ERROR nm_setting_pppoe_error_quark () GQuark nm_setting_pppoe_error_quark (void); -#define NM_SETTING_PPPOE_SERVICE "service" -#define NM_SETTING_PPPOE_USERNAME "username" -#define NM_SETTING_PPPOE_PASSWORD "password" +#define NM_SETTING_PPPOE_SERVICE "service" +#define NM_SETTING_PPPOE_USERNAME "username" +#define NM_SETTING_PPPOE_PASSWORD "password" +#define NM_SETTING_PPPOE_PASSWORD_FLAGS "password-flags" typedef struct { NMSetting parent; @@ -77,6 +78,7 @@ NMSetting *nm_setting_pppoe_new (void); const char *nm_setting_pppoe_get_service (NMSettingPPPOE *setting); const char *nm_setting_pppoe_get_username (NMSettingPPPOE *setting); const char *nm_setting_pppoe_get_password (NMSettingPPPOE *setting); +NMSettingSecretFlags nm_setting_pppoe_get_password_flags (NMSettingPPPOE *setting); G_END_DECLS diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 4b8a1dc9c..fb3e58b44 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -23,6 +23,8 @@ */ #include +#include +#include #include #include "nm-setting-vpn.h" #include "nm-param-spec-specialized.h" @@ -227,6 +229,75 @@ nm_setting_vpn_foreach_secret (NMSettingVPN *setting, (GHFunc) func, user_data); } +/** + * nm_setting_vpn_get_secret_flags: + * @setting: a #NMSettingVPN + * @secret_name: the secret key name to get flags for + * @out_flags: on success, the flags for the secret @secret_name + * + * For a given VPN secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: TRUE on success (if the secret flags data item was found), FALSE if + * the secret flags data item was not found + */ +gboolean +nm_setting_vpn_get_secret_flags (NMSettingVPN *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags) +{ + char *flags_key; + unsigned long tmp; + gboolean success = FALSE; + gpointer val; + + g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (out_flags != NULL, FALSE); + + flags_key = g_strdup_printf ("%s-flags", secret_name); + g_assert (flags_key); + if (g_hash_table_lookup_extended (NM_SETTING_VPN_GET_PRIVATE (setting)->data, + flags_key, + NULL, + &val)) { + errno = 0; + tmp = strtoul ((const char *) val, NULL, 10); + if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAG_LAST)) { + success = TRUE; + *out_flags = (guint32) tmp; + } + } + g_free (flags_key); + return success; +} + +/** + * nm_setting_vpn_set_secret_flags: + * @setting: a #NMSettingVPN + * @secret_name: the secret key name to set flags for + * @flags: the flags for the secret + * + * For a given VPN secret, sets the #NMSettingSecretFlags describing how to + * handle that secret. + */ +void +nm_setting_vpn_set_secret_flags (NMSettingVPN *setting, + const char *secret_name, + NMSettingSecretFlags flags) +{ + char *key_name, *str_val; + + g_return_if_fail (NM_IS_SETTING_VPN (setting)); + g_return_if_fail (secret_name != NULL); + + key_name = g_strdup_printf ("%s-flags", secret_name); + g_assert (key_name); + str_val = g_strdup_printf ("%u", flags); + g_assert (str_val); + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key_name, str_val); +} + static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h index c848696a3..8dea7c744 100644 --- a/libnm-util/nm-setting-vpn.h +++ b/libnm-util/nm-setting-vpn.h @@ -103,6 +103,14 @@ void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, NMVPNIterFunc func, gpointer user_data); +gboolean nm_setting_vpn_get_secret_flags (NMSettingVPN *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags); + +void nm_setting_vpn_set_secret_flags (NMSettingVPN *setting, + const char *secret_name, + NMSettingSecretFlags flags); + G_END_DECLS #endif /* NM_SETTING_VPN_H */ diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index ca789b422..916522646 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -82,19 +82,28 @@ G_DEFINE_TYPE (NMSettingWirelessSecurity, nm_setting_wireless_security, NM_TYPE_ typedef struct { char *key_mgmt; - guint32 wep_tx_keyidx; char *auth_alg; GSList *proto; /* GSList of strings */ GSList *pairwise; /* GSList of strings */ GSList *group; /* GSList of strings */ + + /* LEAP */ char *leap_username; + char *leap_password; + NMSettingSecretFlags leap_password_flags; + + /* WEP */ char *wep_key0; char *wep_key1; char *wep_key2; char *wep_key3; - char *psk; - char *leap_password; + NMSettingSecretFlags wep_key_flags; NMWepKeyType wep_key_type; + guint32 wep_tx_keyidx; + + /* WPA-PSK */ + char *psk; + NMSettingSecretFlags psk_flags; } NMSettingWirelessSecurityPrivate; enum { @@ -110,9 +119,12 @@ enum { PROP_WEP_KEY1, PROP_WEP_KEY2, PROP_WEP_KEY3, - PROP_PSK, - PROP_LEAP_PASSWORD, + PROP_WEP_KEY_FLAGS, PROP_WEP_KEY_TYPE, + PROP_PSK, + PROP_PSK_FLAGS, + PROP_LEAP_PASSWORD, + PROP_LEAP_PASSWORD_FLAGS, LAST_PROP }; @@ -343,6 +355,21 @@ nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting) return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk; } +/** + * nm_setting_wireless_security_get_psk_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:psk + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk_flags; +} + const char * nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting) { @@ -359,6 +386,21 @@ nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setti return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password; } +/** + * nm_setting_wireless_security_get_leap_password_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the + * #NMSettingWirelessSecurity:leap-password + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password_flags; +} + const char * nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx) { @@ -428,6 +470,20 @@ nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting) return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->auth_alg; } +/** + * nm_setting_wireless_security_get_wep_key_flags: + * @setting: the #NMSettingWirelessSecurity + * + * Returns: the #NMSettingSecretFlags pertaining to the all WEP keys + **/ +NMSettingSecretFlags +nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + + return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_flags; +} + NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting) { @@ -852,14 +908,23 @@ set_property (GObject *object, guint prop_id, case PROP_WEP_KEY3: nm_setting_wireless_security_set_wep_key (setting, 3, g_value_get_string (value)); break; + case PROP_WEP_KEY_FLAGS: + priv->wep_key_flags = g_value_get_uint (value); + break; case PROP_PSK: g_free (priv->psk); priv->psk = g_value_dup_string (value); break; + case PROP_PSK_FLAGS: + priv->psk_flags = g_value_get_uint (value); + break; case PROP_LEAP_PASSWORD: g_free (priv->leap_password); priv->leap_password = g_value_dup_string (value); break; + case PROP_LEAP_PASSWORD_FLAGS: + priv->leap_password_flags = g_value_get_uint (value); + break; case PROP_WEP_KEY_TYPE: priv->wep_key_type = g_value_get_uint (value); break; @@ -910,12 +975,21 @@ get_property (GObject *object, guint prop_id, case PROP_WEP_KEY3: g_value_set_string (value, priv->wep_key3); break; + case PROP_WEP_KEY_FLAGS: + g_value_set_uint (value, priv->wep_key_flags); + break; case PROP_PSK: g_value_set_string (value, priv->psk); break; + case PROP_PSK_FLAGS: + g_value_set_uint (value, priv->psk_flags); + break; case PROP_LEAP_PASSWORD: g_value_set_string (value, priv->leap_password); break; + case PROP_LEAP_PASSWORD_FLAGS: + g_value_set_uint (value, priv->leap_password_flags); + break; case PROP_WEP_KEY_TYPE: g_value_set_uint (value, priv->wep_key_type); break; @@ -1139,6 +1213,20 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSettingWirelessSecurity:wep-key-flags: + * + * Flags indicating how to handle #NMSettingWirelessSecurity WEP keys. + **/ + g_object_class_install_property (object_class, PROP_WEP_KEY_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, + "WEP Key Flags", + "Flags indicating how to handle the WEP keys.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingWirelessSecurity:psk: * @@ -1164,6 +1252,20 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSettingWirelessSecurity:psk-flags: + * + * Flags indicating how to handle #NMSettingWirelessSecurity:psk + **/ + g_object_class_install_property (object_class, PROP_PSK_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, + "PSK Flags", + "Flags indicating how to handle the WPA PSK key.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingWirelessSecurity:leap-password: * @@ -1179,6 +1281,20 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + /** + * NMSettingWirelessSecurity:leap-password-flags: + * + * Flags indicating how to handle #NMSettingWirelessSecurity:leap-password. + **/ + g_object_class_install_property (object_class, PROP_LEAP_PASSWORD_FLAGS, + g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, + "LEAP Password Flags", + "Flags indicating how to handle the LEAP password.", + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + /** * NMSettingWirelessSecurity:wep-key-type: * diff --git a/libnm-util/nm-setting-wireless-security.h b/libnm-util/nm-setting-wireless-security.h index 90d971b23..743e161f0 100644 --- a/libnm-util/nm-setting-wireless-security.h +++ b/libnm-util/nm-setting-wireless-security.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -75,9 +75,12 @@ typedef enum { #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY1 "wep-key1" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY2 "wep-key2" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY3 "wep-key3" -#define NM_SETTING_WIRELESS_SECURITY_PSK "psk" -#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password" +#define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS "wep-key-flags" #define NM_SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE "wep-key-type" +#define NM_SETTING_WIRELESS_SECURITY_PSK "psk" +#define NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS "psk-flags" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD "leap-password" +#define NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS "leap-password-flags" typedef struct { NMSetting parent; @@ -118,14 +121,18 @@ void nm_setting_wireless_security_remove_group (NMSettingWirelessSec void nm_setting_wireless_security_clear_groups (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_leap_username (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setting); +NMSettingSecretFlags nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_wep_key (NMSettingWirelessSecurity *setting, guint32 idx); void nm_setting_wireless_security_set_wep_key (NMSettingWirelessSecurity *setting, guint32 idx, const char *key); guint32 nm_setting_wireless_security_get_wep_tx_keyidx (NMSettingWirelessSecurity *setting); const char *nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting); + +NMSettingSecretFlags nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting); NMWepKeyType nm_setting_wireless_security_get_wep_key_type (NMSettingWirelessSecurity *setting); G_END_DECLS diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index 07a38daad..907921358 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -185,6 +185,31 @@ void nm_setting_enumerate_values (NMSetting *setting, char *nm_setting_to_string (NMSetting *setting); /* Secrets */ + +/** + * NMSettingSecretFlags: + * @NM_SETTING_SECRET_FLAG_SYTSEM_OWNED: the system is responsible for providing + * and storing this secret (default) + * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible + * for providing and storing this secret; when it is required agents will be + * asked to retrieve it + * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but + * should be requested from the user each time it is needed + * + * These flags indicate specific behavior related to handling of a secret. Each + * secret has a corresponding set of these flags which indicate how the secret + * is to be stored and/or requested when it is needed. + * + **/ +typedef enum { + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED = 0x00000000, + NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002, + + /* Placeholder for bounds checking */ + NM_SETTING_SECRET_FLAG_LAST = NM_SETTING_SECRET_FLAG_NOT_SAVED, +} NMSettingSecretFlags; + void nm_setting_clear_secrets (NMSetting *setting); GPtrArray *nm_setting_need_secrets (NMSetting *setting); gboolean nm_setting_update_secrets (NMSetting *setting, From 3a97939525a5fdb34ca1b37d97c545cf9b66aabb Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 30 Jan 2011 11:00:33 -0600 Subject: [PATCH 189/264] settings: move agent code into settings directory Since that's where it's used, and it doesn't need to be exposed to any other code. --- src/Makefile.am | 12 ++---------- src/settings/Makefile.am | 12 ++++++++++-- src/{ => settings}/nm-agent-manager.c | 0 src/{ => settings}/nm-agent-manager.h | 0 src/{ => settings}/nm-secret-agent.c | 0 src/{ => settings}/nm-secret-agent.h | 0 6 files changed, 12 insertions(+), 12 deletions(-) rename src/{ => settings}/nm-agent-manager.c (100%) rename src/{ => settings}/nm-agent-manager.h (100%) rename src/{ => settings}/nm-secret-agent.c (100%) rename src/{ => settings}/nm-secret-agent.h (100%) diff --git a/src/Makefile.am b/src/Makefile.am index ce3c222c8..8a04d8115 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -175,11 +175,7 @@ NetworkManager_SOURCES = \ nm-dhcp6-config.h \ nm-rfkill.h \ nm-session-monitor.c \ - nm-session-monitor.h \ - nm-agent-manager.c \ - nm-agent-manager.h \ - nm-secret-agent.c \ - nm-secret-agent.h + nm-session-monitor.h nm-access-point-glue.h: $(top_srcdir)/introspection/nm-access-point.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_access_point --mode=glib-server --output=$@ $< @@ -223,9 +219,6 @@ nm-device-cdma-glue.h: $(top_srcdir)/introspection/nm-device-cdma.xml nm-device-gsm-glue.h: $(top_srcdir)/introspection/nm-device-gsm.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_device_gsm --mode=glib-server --output=$@ $< -nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml - $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $< - BUILT_SOURCES = \ nm-access-point-glue.h \ nm-manager-glue.h \ @@ -240,8 +233,7 @@ BUILT_SOURCES = \ nm-ip6-config-glue.h \ nm-active-connection-glue.h \ nm-dhcp4-config-glue.h \ - nm-dhcp6-config-glue.h \ - nm-agent-manager-glue.h + nm-dhcp6-config-glue.h NetworkManager_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/settings/Makefile.am b/src/settings/Makefile.am index ddb2e5a0a..b6a241310 100644 --- a/src/settings/Makefile.am +++ b/src/settings/Makefile.am @@ -9,7 +9,8 @@ noinst_LTLIBRARIES = libsettings.la BUILT_SOURCES = \ nm-settings-glue.h \ - nm-settings-connection-glue.h + nm-settings-connection-glue.h \ + nm-agent-manager-glue.h libsettings_la_SOURCES = \ nm-settings.c \ @@ -24,7 +25,11 @@ libsettings_la_SOURCES = \ nm-settings-connection.c \ nm-settings-connection.h \ nm-default-wired-connection.c \ - nm-default-wired-connection.h + nm-default-wired-connection.h \ + nm-agent-manager.c \ + nm-agent-manager.h \ + nm-secret-agent.c \ + nm-secret-agent.h libsettings_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ @@ -59,6 +64,9 @@ nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_settings_connection --mode=glib-server --output=$@ $< +nm-agent-manager-glue.h: $(top_srcdir)/introspection/nm-agent-manager.xml + $(AM_V_GEN) dbus-binding-tool --prefix=nm_agent_manager --mode=glib-server --output=$@ $< + CLEANFILES = \ $(BUILT_SOURCES) diff --git a/src/nm-agent-manager.c b/src/settings/nm-agent-manager.c similarity index 100% rename from src/nm-agent-manager.c rename to src/settings/nm-agent-manager.c diff --git a/src/nm-agent-manager.h b/src/settings/nm-agent-manager.h similarity index 100% rename from src/nm-agent-manager.h rename to src/settings/nm-agent-manager.h diff --git a/src/nm-secret-agent.c b/src/settings/nm-secret-agent.c similarity index 100% rename from src/nm-secret-agent.c rename to src/settings/nm-secret-agent.c diff --git a/src/nm-secret-agent.h b/src/settings/nm-secret-agent.h similarity index 100% rename from src/nm-secret-agent.h rename to src/settings/nm-secret-agent.h From b285c6467a4890d2f029c0436ee0bff8b3b7e297 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 30 Jan 2011 13:49:56 -0600 Subject: [PATCH 190/264] settings: simplify GetSecrets handling of sender UID We've already gotten the UI when doing the PK auth checks, so it's pointless to get it again. Just pass the known UID through. --- src/settings/nm-settings-connection.c | 104 ++++++++++++-------------- 1 file changed, 46 insertions(+), 58 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index f532442c2..60a6deff7 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -467,9 +467,16 @@ nm_settings_connection_cancel_secrets (NMSettingsConnection *self, typedef void (*AuthCallback) (NMSettingsConnection *connection, DBusGMethodInvocation *context, + gulong sender_uid, GError *error, gpointer data); +typedef struct { + AuthCallback callback; + gpointer callback_data; + gulong sender_uid; +} PkAuthInfo; + static void pk_auth_cb (NMAuthChain *chain, GError *chain_error, @@ -480,8 +487,7 @@ pk_auth_cb (NMAuthChain *chain, NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GError *error = NULL; NMAuthCallResult result; - AuthCallback callback; - gpointer callback_data; + PkAuthInfo *info; priv->pending_auths = g_slist_remove (priv->pending_auths, chain); @@ -502,9 +508,8 @@ pk_auth_cb (NMAuthChain *chain, } } - callback = nm_auth_chain_get_data (chain, "callback"); - callback_data = nm_auth_chain_get_data (chain, "callback-data"); - callback (self, context, error, callback_data); + info = nm_auth_chain_get_data (chain, "pk-auth-info"); + info->callback (self, context, info->sender_uid, error, info->callback_data); g_clear_error (&error); nm_auth_chain_unref (chain); @@ -520,6 +525,7 @@ auth_start (NMSettingsConnection *self, NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMAuthChain *chain; gulong sender_uid = G_MAXULONG; + PkAuthInfo *info; GError *error = NULL; char *error_desc = NULL; @@ -528,7 +534,7 @@ auth_start (NMSettingsConnection *self, error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, error_desc); - g_free (error); + g_free (error_desc); goto error; } @@ -549,19 +555,24 @@ auth_start (NMSettingsConnection *self, if (check_modify) { chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self); g_assert (chain); - priv->pending_auths = g_slist_append (priv->pending_auths, chain); + + info = g_malloc0 (sizeof (*info)); + info->callback = callback; + info->callback_data = callback_data; + info->sender_uid = sender_uid; + nm_auth_chain_set_data (chain, "pk-auth-info", info, g_free); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); - nm_auth_chain_set_data (chain, "callback", callback, NULL); - nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); + priv->pending_auths = g_slist_append (priv->pending_auths, chain); } else { /* Don't need polkit auth, automatic success */ - callback (self, context, NULL, callback_data); + callback (self, context, sender_uid, NULL, callback_data); } return; error: - callback (self, context, error, callback_data); + callback (self, context, G_MAXULONG, error, callback_data); g_error_free (error); } @@ -602,6 +613,7 @@ check_writable (NMConnection *connection, GError **error) static void get_settings_auth_cb (NMSettingsConnection *self, DBusGMethodInvocation *context, + gulong sender_uid, GError *error, gpointer data) { @@ -642,8 +654,9 @@ con_update_cb (NMSettingsConnection *connection, } static void -update_auth_cb (NMSettingsConnection *self, +update_auth_cb (NMSettingsConnection *self, DBusGMethodInvocation *context, + gulong sender_uid, GError *error, gpointer data) { @@ -710,6 +723,7 @@ con_delete_cb (NMSettingsConnection *connection, static void delete_auth_cb (NMSettingsConnection *self, DBusGMethodInvocation *context, + gulong sender_uid, GError *error, gpointer data) { @@ -770,65 +784,39 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, static void dbus_secrets_auth_cb (NMSettingsConnection *self, DBusGMethodInvocation *context, + gulong sender_uid, GError *error, gpointer user_data) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - char *sender, *setting_name = user_data; - DBusError dbus_error; - gulong sender_uid; + char *setting_name = user_data; guint32 call_id = 0; GError *local = NULL; - if (error) { + if (error) local = g_error_copy (error); - goto done; + else { + call_id = nm_settings_connection_get_secrets (self, + TRUE, + sender_uid, + setting_name, + 0, /* GET_SECRETS_FLAG_NONE */ + NULL, + dbus_get_agent_secrets_cb, + context, + &local); + if (call_id > 0) { + /* track the request and wait for the callback */ + priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); + } } - sender = dbus_g_method_get_sender (context); - if (!sender) { - local = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to get request D-Bus sender"); - goto done; - } - - /* Get the unix user of the requestor */ - dbus_error_init (&dbus_error); - sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr), - sender, - &dbus_error); - g_free (sender); - - if (dbus_error_is_set (&dbus_error)) { - local = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - "Unable to get sender UID: %s", - dbus_error.message); - dbus_error_free (&dbus_error); - goto done; - } - - call_id = nm_settings_connection_get_secrets (self, - TRUE, - sender_uid, - setting_name, - 0, /* GET_SECRETS_FLAG_NONE */ - NULL, - dbus_get_agent_secrets_cb, - context, - &local); - if (call_id > 0) { - /* track the request and wait for the callback */ - priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id)); - } - -done: - if (local) + if (local) { dbus_g_method_return_error (context, error ? error : local); + g_clear_error (&local); + } g_free (setting_name); - g_clear_error (&local); } static void From f1300897350034f4f3baf8d73568e9f4aea7ec71 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 30 Jan 2011 13:53:37 -0600 Subject: [PATCH 191/264] settings: use less memory in error handling of GetSecrets --- src/settings/nm-settings-connection.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 60a6deff7..e0b079d39 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -793,9 +793,7 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, guint32 call_id = 0; GError *local = NULL; - if (error) - local = g_error_copy (error); - else { + if (!error) { call_id = nm_settings_connection_get_secrets (self, TRUE, sender_uid, @@ -811,7 +809,7 @@ dbus_secrets_auth_cb (NMSettingsConnection *self, } } - if (local) { + if (error || local) { dbus_g_method_return_error (context, error ? error : local); g_clear_error (&local); } From 562246cb8033fb912fb8a6cdea5c2829c4cedf8a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 12:36:53 -0600 Subject: [PATCH 192/264] libnm-util: fix handling of secrets flags It's a bitfield, not a single value. Update GObject property max accordingly. --- libnm-util/Makefile.am | 3 ++- libnm-util/nm-setting-8021x.c | 7 +++--- libnm-util/nm-setting-cdma.c | 3 ++- libnm-util/nm-setting-gsm.c | 5 ++-- libnm-util/nm-setting-pppoe.c | 3 ++- libnm-util/nm-setting-private.h | 30 +++++++++++++++++++++++ libnm-util/nm-setting-vpn.c | 5 ++-- libnm-util/nm-setting-wireless-security.c | 7 +++--- libnm-util/nm-setting.c | 3 ++- libnm-util/nm-setting.h | 5 ++-- 10 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 libnm-util/nm-setting-private.h diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 15cf6126c..395775213 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -34,7 +34,8 @@ libnm_util_include_HEADERS = \ libnm_util_la_private_headers = \ crypto.h \ nm-param-spec-specialized.h \ - nm-utils-private.h + nm-utils-private.h \ + nm-setting-private.h libnm_util_la_csources = \ crypto.c \ diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index f29010494..341b60a53 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -32,6 +32,7 @@ #include "nm-dbus-glib-types.h" #include "crypto.h" #include "nm-utils-private.h" +#include "nm-setting-private.h" /** * SECTION:nm-setting-8021x @@ -2955,7 +2956,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Password Flags", "Flags indicating how to handle the 802.1x password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); @@ -3039,7 +3040,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Flags indicating how to handle the 802.1x private " "key password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); @@ -3121,7 +3122,7 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Flags indicating how to handle the 802.1x phase2 " "private key password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index bcd78ec2f..1fd800d8b 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -25,6 +25,7 @@ #include "nm-setting-cdma.h" #include "nm-setting-serial.h" #include "nm-utils.h" +#include "nm-setting-private.h" /** * SECTION:nm-setting-cdma @@ -393,7 +394,7 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) "Password Flags", "Flags indicating how to handle the CDMA password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index 7cb3c790a..f0bdfee83 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -28,6 +28,7 @@ #include "nm-setting-gsm.h" #include "nm-setting-serial.h" #include "nm-utils.h" +#include "nm-setting-private.h" GQuark nm_setting_gsm_error_quark (void) @@ -540,7 +541,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) "Password Flags", "Flags indicating how to handle the GSM password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); @@ -673,7 +674,7 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) "PIN Flags", "Flags indicating how to handle the GSM SIM PIN.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index e03f00c04..ee82d8e50 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -26,6 +26,7 @@ #include #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" +#include "nm-setting-private.h" GQuark nm_setting_pppoe_error_quark (void) @@ -304,7 +305,7 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) "Password Flags", "Flags indicating how to handle the PPPoE password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h new file mode 100644 index 000000000..0c1b0e7a0 --- /dev/null +++ b/libnm-util/nm-setting-private.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2011 Red Hat, Inc. + */ + +#ifndef NM_SETTING_PRIVATE_H +#define NM_SETTING_PRIVATE_H + +#define NM_SETTING_SECRET_FLAGS_ALL \ + (NM_SETTING_SECRET_FLAG_SYSTEM_OWNED | \ + NM_SETTING_SECRET_FLAG_AGENT_OWNED | \ + NM_SETTING_SECRET_FLAG_NOT_SAVED) + +#endif /* NM_SETTING_PRIVATE_H */ + diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index fb3e58b44..87e58182f 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -30,6 +30,7 @@ #include "nm-param-spec-specialized.h" #include "nm-utils.h" #include "nm-dbus-glib-types.h" +#include "nm-setting-private.h" GQuark nm_setting_vpn_error_quark (void) @@ -263,7 +264,7 @@ nm_setting_vpn_get_secret_flags (NMSettingVPN *setting, &val)) { errno = 0; tmp = strtoul ((const char *) val, NULL, 10); - if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAG_LAST)) { + if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { success = TRUE; *out_flags = (guint32) tmp; } @@ -482,7 +483,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) * * D-Bus service name of the VPN plugin that this setting uses to connect * to its network. i.e. org.freedesktop.NetworkManager.vpnc for the vpnc - * plugin. + * plugin. **/ g_object_class_install_property (object_class, PROP_SERVICE_TYPE, diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index 916522646..b31f85ad5 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -33,6 +33,7 @@ #include "nm-utils.h" #include "nm-dbus-glib-types.h" #include "nm-utils-private.h" +#include "nm-setting-private.h" GQuark nm_setting_wireless_security_error_quark (void) @@ -1223,7 +1224,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting "WEP Key Flags", "Flags indicating how to handle the WEP keys.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); @@ -1262,7 +1263,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting "PSK Flags", "Flags indicating how to handle the WPA PSK key.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); @@ -1291,7 +1292,7 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting "LEAP Password Flags", "Flags indicating how to handle the LEAP password.", NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, - NM_SETTING_SECRET_FLAG_LAST, + NM_SETTING_SECRET_FLAGS_ALL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index e27450482..8d4b295fa 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -19,13 +19,14 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ #include #include "nm-setting.h" +#include "nm-setting-private.h" #include "nm-setting-connection.h" #include "nm-utils.h" diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index 907921358..2790d8b5a 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -204,10 +204,9 @@ char *nm_setting_to_string (NMSetting *setting); typedef enum { NM_SETTING_SECRET_FLAG_SYSTEM_OWNED = 0x00000000, NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, - NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002, + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002 - /* Placeholder for bounds checking */ - NM_SETTING_SECRET_FLAG_LAST = NM_SETTING_SECRET_FLAG_NOT_SAVED, + /* NOTE: if adding flags, update nm-setting-private.h as well */ } NMSettingSecretFlags; void nm_setting_clear_secrets (NMSetting *setting); From 092a6535e03d68803b585f7dcfb99dd9e2e2c8e4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 12:41:54 -0600 Subject: [PATCH 193/264] libnm-util: add generic functions for getting/setting secret flags And remove the VPN-specific ones. It's useful to have this stuff be generic and the functionality wasn't really VPN-specific anyway. --- libnm-util/libnm-util.ver | 4 +- libnm-util/nm-setting-vpn.c | 122 +++++++++++++++--------------------- libnm-util/nm-setting-vpn.h | 10 +-- libnm-util/nm-setting.c | 116 ++++++++++++++++++++++++++++++++++ libnm-util/nm-setting.h | 67 +++++++++++++------- 5 files changed, 214 insertions(+), 105 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index b7b94f81e..1f98a083d 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -268,6 +268,8 @@ global: nm_setting_serial_get_parity; nm_setting_serial_get_stopbits; nm_setting_serial_get_send_delay; + nm_setting_get_secret_flags; + nm_setting_set_secret_flags; nm_setting_to_hash; nm_setting_to_string; nm_setting_update_secrets; @@ -280,14 +282,12 @@ global: nm_setting_vpn_foreach_secret; nm_setting_vpn_get_data_item; nm_setting_vpn_get_secret; - nm_setting_vpn_get_secret_flags; nm_setting_vpn_get_service_type; nm_setting_vpn_get_type; nm_setting_vpn_get_user_name; nm_setting_vpn_new; nm_setting_vpn_remove_data_item; nm_setting_vpn_remove_secret; - nm_setting_vpn_set_secret_flags; nm_setting_wimax_error_get_type; nm_setting_wimax_error_quark; nm_setting_wimax_get_type; diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 87e58182f..aa064f315 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -230,75 +230,6 @@ nm_setting_vpn_foreach_secret (NMSettingVPN *setting, (GHFunc) func, user_data); } -/** - * nm_setting_vpn_get_secret_flags: - * @setting: a #NMSettingVPN - * @secret_name: the secret key name to get flags for - * @out_flags: on success, the flags for the secret @secret_name - * - * For a given VPN secret, retrieves the #NMSettingSecretFlags describing how to - * handle that secret. - * - * Returns: TRUE on success (if the secret flags data item was found), FALSE if - * the secret flags data item was not found - */ -gboolean -nm_setting_vpn_get_secret_flags (NMSettingVPN *setting, - const char *secret_name, - NMSettingSecretFlags *out_flags) -{ - char *flags_key; - unsigned long tmp; - gboolean success = FALSE; - gpointer val; - - g_return_val_if_fail (NM_IS_SETTING_VPN (setting), FALSE); - g_return_val_if_fail (secret_name != NULL, FALSE); - g_return_val_if_fail (out_flags != NULL, FALSE); - - flags_key = g_strdup_printf ("%s-flags", secret_name); - g_assert (flags_key); - if (g_hash_table_lookup_extended (NM_SETTING_VPN_GET_PRIVATE (setting)->data, - flags_key, - NULL, - &val)) { - errno = 0; - tmp = strtoul ((const char *) val, NULL, 10); - if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { - success = TRUE; - *out_flags = (guint32) tmp; - } - } - g_free (flags_key); - return success; -} - -/** - * nm_setting_vpn_set_secret_flags: - * @setting: a #NMSettingVPN - * @secret_name: the secret key name to set flags for - * @flags: the flags for the secret - * - * For a given VPN secret, sets the #NMSettingSecretFlags describing how to - * handle that secret. - */ -void -nm_setting_vpn_set_secret_flags (NMSettingVPN *setting, - const char *secret_name, - NMSettingSecretFlags flags) -{ - char *key_name, *str_val; - - g_return_if_fail (NM_IS_SETTING_VPN (setting)); - g_return_if_fail (secret_name != NULL); - - key_name = g_strdup_printf ("%s-flags", secret_name); - g_assert (key_name); - str_val = g_strdup_printf ("%u", flags); - g_assert (str_val); - g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, key_name, str_val); -} - static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -361,6 +292,54 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** return TRUE; } +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + gboolean success = FALSE; + char *flags_key; + gpointer val; + unsigned long tmp; + + flags_key = g_strdup_printf ("%s-flags", secret_name); + if (g_hash_table_lookup_extended (priv->data, flags_key, NULL, &val)) { + errno = 0; + tmp = strtoul ((const char *) val, NULL, 10); + if ((errno == 0) && (tmp <= NM_SETTING_SECRET_FLAGS_ALL)) { + *out_flags = (guint32) tmp; + success = TRUE; + } else { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Failed to convert '%s' value '%s' to uint", + flags_key, (const char *) val); + } + } else { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_FOUND, + "Secret flags property '%s' not found", flags_key); + } + g_free (flags_key); + return success; +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error) +{ + g_hash_table_insert (NM_SETTING_VPN_GET_PRIVATE (setting)->data, + g_strdup_printf ("%s-flags", secret_name), + g_strdup_printf ("%u", flags)); + return TRUE; +} + static void destroy_one_secret (gpointer data) { @@ -474,8 +453,11 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; + + parent_class->verify = verify; parent_class->update_one_secret = update_one_secret; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; /* Properties */ /** diff --git a/libnm-util/nm-setting-vpn.h b/libnm-util/nm-setting-vpn.h index 8dea7c744..bb203560f 100644 --- a/libnm-util/nm-setting-vpn.h +++ b/libnm-util/nm-setting-vpn.h @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -103,14 +103,6 @@ void nm_setting_vpn_foreach_secret (NMSettingVPN *setting, NMVPNIterFunc func, gpointer user_data); -gboolean nm_setting_vpn_get_secret_flags (NMSettingVPN *setting, - const char *secret_name, - NMSettingSecretFlags *out_flags); - -void nm_setting_vpn_set_secret_flags (NMSettingVPN *setting, - const char *secret_name, - NMSettingSecretFlags flags); - G_END_DECLS #endif /* NM_SETTING_VPN_H */ diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 8d4b295fa..31d9c9d18 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -570,6 +570,120 @@ nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **err return !!tmp_error; } +static gboolean +is_secret_prop (NMSetting *setting, const char *secret_name, GError **error) +{ + GParamSpec *pspec; + + pspec = g_object_class_find_property (G_OBJECT_CLASS (setting), secret_name); + if (!pspec) { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_FOUND, + "Secret %s not provided by this setting", secret_name); + return FALSE; + } + + if (!(pspec->flags & NM_SETTING_PARAM_SECRET)) { + g_set_error (error, + NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_NOT_SECRET, + "Property %s is not a secret", secret_name); + return FALSE; + } + + return TRUE; +} + +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error) +{ + char *flags_prop; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + + flags_prop = g_strdup_printf ("%s-flags", secret_name); + g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL); + g_free (flags_prop); + + if (out_flags) + *out_flags = flags; + return TRUE; +} + +/** + * nm_setting_get_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to get flags for + * @out_flags: on success, the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), FALSE if not + **/ +gboolean +nm_setting_get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error) +{ + g_return_val_if_fail (setting != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + + return NM_SETTING_GET_CLASS (setting)->get_secret_flags (setting, secret_name, out_flags, error); +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error) +{ + char *flags_prop; + + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + + flags_prop = g_strdup_printf ("%s-flags", secret_name); + g_object_set (G_OBJECT (setting), flags_prop, flags, NULL); + g_free (flags_prop); + return TRUE; +} + +/** + * nm_setting_set_secret_flags: + * @setting: the #NMSetting + * @secret_name: the secret key name to set flags for + * @flags: the #NMSettingSecretFlags for the secret + * @error: location to store error, or %NULL + * + * For a given secret, retrieves the #NMSettingSecretFlags describing how to + * handle that secret. + * + * Returns: TRUE on success (if the given secret name was a valid property of + * this setting, and if that property is secret), FALSE if not + **/ +gboolean +nm_setting_set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error) +{ + g_return_val_if_fail (setting != NULL, FALSE); + g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (flags & NM_SETTING_SECRET_FLAGS_ALL, FALSE); + + return NM_SETTING_GET_CLASS (setting)->set_secret_flags (setting, secret_name, flags, error); +} + /** * nm_setting_to_string: * @setting: the #NMSetting @@ -726,6 +840,8 @@ nm_setting_class_init (NMSettingClass *setting_class) object_class->finalize = finalize; setting_class->update_one_secret = update_one_secret; + setting_class->get_secret_flags = get_secret_flags; + setting_class->set_secret_flags = set_secret_flags; /* Properties */ diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index 2790d8b5a..bf2c63f00 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -83,6 +83,29 @@ GQuark nm_setting_error_quark (void); #define NM_SETTING_NAME "name" +/** + * NMSettingSecretFlags: + * @NM_SETTING_SECRET_FLAG_SYTSEM_OWNED: the system is responsible for providing + * and storing this secret (default) + * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible + * for providing and storing this secret; when it is required agents will be + * asked to retrieve it + * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but + * should be requested from the user each time it is needed + * + * These flags indicate specific behavior related to handling of a secret. Each + * secret has a corresponding set of these flags which indicate how the secret + * is to be stored and/or requested when it is needed. + * + **/ +typedef enum { + NM_SETTING_SECRET_FLAG_SYSTEM_OWNED = 0x00000000, + NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002 + + /* NOTE: if adding flags, update nm-setting-private.h as well */ +} NMSettingSecretFlags; + /** * NMSetting: * @@ -108,6 +131,16 @@ typedef struct { GValue *value, GError **error); + gboolean (*get_secret_flags) (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error); + + gboolean (*set_secret_flags) (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error); + /* Padding for future expansion */ void (*_reserved1) (void); void (*_reserved2) (void); @@ -185,36 +218,22 @@ void nm_setting_enumerate_values (NMSetting *setting, char *nm_setting_to_string (NMSetting *setting); /* Secrets */ - -/** - * NMSettingSecretFlags: - * @NM_SETTING_SECRET_FLAG_SYTSEM_OWNED: the system is responsible for providing - * and storing this secret (default) - * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible - * for providing and storing this secret; when it is required agents will be - * asked to retrieve it - * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but - * should be requested from the user each time it is needed - * - * These flags indicate specific behavior related to handling of a secret. Each - * secret has a corresponding set of these flags which indicate how the secret - * is to be stored and/or requested when it is needed. - * - **/ -typedef enum { - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED = 0x00000000, - NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, - NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002 - - /* NOTE: if adding flags, update nm-setting-private.h as well */ -} NMSettingSecretFlags; - void nm_setting_clear_secrets (NMSetting *setting); GPtrArray *nm_setting_need_secrets (NMSetting *setting); gboolean nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **error); +gboolean nm_setting_get_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags *out_flags, + GError **error); + +gboolean nm_setting_set_secret_flags (NMSetting *setting, + const char *secret_name, + NMSettingSecretFlags flags, + GError **error); + G_END_DECLS #endif /* NM_SETTING_H */ From d391e1fac3351c9c0994e1f28d350b9d79b41b89 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 14:06:18 -0600 Subject: [PATCH 194/264] keyfile: don't save agent-owned or always-ask secrets --- system-settings/plugins/keyfile/writer.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index ffac35cff..165c9b660 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -564,6 +564,7 @@ write_setting_value (NMSetting *setting, GType type = G_VALUE_TYPE (value); KeyWriter *writer = &key_writers[0]; GParamSpec *pspec; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; /* Setting name gets picked up from the keyfile's section name instead */ if (!strcmp (key, NM_SETTING_NAME)) @@ -585,6 +586,14 @@ write_setting_value (NMSetting *setting, } } + /* Don't write secrets that are owned by user secret agents or aren't + * supposed to be saved. + */ + if ( (pspec->flags & NM_SETTING_PARAM_SECRET) + && nm_setting_get_secret_flags (setting, key, &flags, NULL) + && !(flags & NM_SETTING_SECRET_FLAG_SYSTEM_OWNED)) + return; + /* Look through the list of handlers for non-standard format key values */ while (writer->setting_name) { if (!strcmp (writer->setting_name, setting_name) && !strcmp (writer->key, key)) { From d95280756f9f4f1c91ad274820dd1b111e737a35 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 19:20:16 -0600 Subject: [PATCH 195/264] keyfile: fix flags check for writing secrets Duh, AND-ing flags with 0 (which is NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) is always going to be FALSE... NM_SETTING_SECRET_FLAG_SYSTEM_OWNED is special; because it's the default value if the key isn't present, and at this point it's exclusive of all other flags. So (at least for now) it's OK that it's 0 but we might want to change it later so that NM_SETTING_SECRET_FLAG_SYSTEM_OWNED can actually be used as a flag. --- system-settings/plugins/keyfile/writer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 165c9b660..550405f95 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -591,7 +591,7 @@ write_setting_value (NMSetting *setting, */ if ( (pspec->flags & NM_SETTING_PARAM_SECRET) && nm_setting_get_secret_flags (setting, key, &flags, NULL) - && !(flags & NM_SETTING_SECRET_FLAG_SYSTEM_OWNED)) + && (flags != NM_SETTING_SECRET_FLAG_SYSTEM_OWNED)) return; /* Look through the list of handlers for non-standard format key values */ From 93cbc77154c466778c3d64477766efd47969f66b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 19:57:48 -0600 Subject: [PATCH 196/264] libnm-util: handle get_secret_flags/set_secret_flags for WirelessSecurity setting Becuase there's only one 'flags' property for WEP keys (because it's pretty dumb to have different flags for all 4 WEP keys) we need to do some tap dancing with the secret name, so that requests for "wep-keyX" look up the "wep-key-flags" property. --- libnm-util/nm-setting-vpn.c | 2 + libnm-util/nm-setting-wireless-security.c | 58 ++++++++++++++++++++++- libnm-util/nm-setting.c | 12 +++-- libnm-util/nm-setting.h | 2 + 4 files changed, 68 insertions(+), 6 deletions(-) diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index aa064f315..3b33f3c8a 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -295,6 +295,7 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** static gboolean get_secret_flags (NMSetting *setting, const char *secret_name, + gboolean verify_secret, NMSettingSecretFlags *out_flags, GError **error) { @@ -331,6 +332,7 @@ get_secret_flags (NMSetting *setting, static gboolean set_secret_flags (NMSetting *setting, const char *secret_name, + gboolean verify_secret, NMSettingSecretFlags flags, GError **error) { diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index b31f85ad5..a0ffddddd 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -828,6 +828,58 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return TRUE; } +static gboolean +get_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags *out_flags, + GError **error) +{ + NMSettingClass *setting_class; + gboolean verify_override = verify_secret; + + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. + */ + if ( !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + secret_name = "wep-key"; + verify_override = FALSE; /* Already know it's a secret */ + } + + /* Chain up to superclass with modified key name */ + setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class); + return setting_class->get_secret_flags (setting, secret_name, verify_override, out_flags, error); +} + +static gboolean +set_secret_flags (NMSetting *setting, + const char *secret_name, + gboolean verify_secret, + NMSettingSecretFlags flags, + GError **error) +{ + NMSettingClass *setting_class; + gboolean verify_override = verify_secret; + + /* There's only one 'flags' property for WEP keys, so alias all the WEP key + * property names to that flags property. + */ + if ( !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2) + || !g_strcmp0 (secret_name, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) { + secret_name = "wep-key"; + verify_override = FALSE; /* Already know it's a secret */ + } + + /* Chain up to superclass with modified key name */ + setting_class = NM_SETTING_CLASS (nm_setting_wireless_security_parent_class); + return setting_class->set_secret_flags (setting, secret_name, verify_override, flags, error); +} + static void nm_setting_wireless_security_init (NMSettingWirelessSecurity *setting) { @@ -1013,8 +1065,10 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting object_class->get_property = get_property; object_class->finalize = finalize; - parent_class->verify = verify; - parent_class->need_secrets = need_secrets; + parent_class->verify = verify; + parent_class->need_secrets = need_secrets; + parent_class->get_secret_flags = get_secret_flags; + parent_class->set_secret_flags = set_secret_flags; /* Properties */ /** diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 31d9c9d18..5e1614c91 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -598,13 +598,15 @@ is_secret_prop (NMSetting *setting, const char *secret_name, GError **error) static gboolean get_secret_flags (NMSetting *setting, const char *secret_name, + gboolean verify_secret, NMSettingSecretFlags *out_flags, GError **error) { char *flags_prop; NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; - g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + if (verify_secret) + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); flags_prop = g_strdup_printf ("%s-flags", secret_name); g_object_get (G_OBJECT (setting), flags_prop, &flags, NULL); @@ -638,18 +640,20 @@ nm_setting_get_secret_flags (NMSetting *setting, g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); g_return_val_if_fail (secret_name != NULL, FALSE); - return NM_SETTING_GET_CLASS (setting)->get_secret_flags (setting, secret_name, out_flags, error); + return NM_SETTING_GET_CLASS (setting)->get_secret_flags (setting, secret_name, TRUE, out_flags, error); } static gboolean set_secret_flags (NMSetting *setting, const char *secret_name, + gboolean verify_secret, NMSettingSecretFlags flags, GError **error) { char *flags_prop; - g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); + if (verify_secret) + g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); flags_prop = g_strdup_printf ("%s-flags", secret_name); g_object_set (G_OBJECT (setting), flags_prop, flags, NULL); @@ -681,7 +685,7 @@ nm_setting_set_secret_flags (NMSetting *setting, g_return_val_if_fail (secret_name != NULL, FALSE); g_return_val_if_fail (flags & NM_SETTING_SECRET_FLAGS_ALL, FALSE); - return NM_SETTING_GET_CLASS (setting)->set_secret_flags (setting, secret_name, flags, error); + return NM_SETTING_GET_CLASS (setting)->set_secret_flags (setting, secret_name, TRUE, flags, error); } /** diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index bf2c63f00..bb5de530c 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -133,11 +133,13 @@ typedef struct { gboolean (*get_secret_flags) (NMSetting *setting, const char *secret_name, + gboolean verify_secret, NMSettingSecretFlags *out_flags, GError **error); gboolean (*set_secret_flags) (NMSetting *setting, const char *secret_name, + gboolean verify_secret, NMSettingSecretFlags flags, GError **error); From 5bc105e139c6592077bbbe5cd59a2c85a8a0c89f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 20:35:37 -0600 Subject: [PATCH 197/264] ifcfg-rh: don't save agent-owned or always-ask secrets --- system-settings/plugins/ifcfg-rh/writer.c | 50 +++++++++++++++++------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index e016d76f4..c8ef7e0ab 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -49,7 +49,11 @@ { g_warning (" " pname ": " fmt, ##args); } static void -set_secret (shvarFile *ifcfg, const char *key, const char *value, gboolean verbatim) +set_secret (shvarFile *ifcfg, + const char *key, + const char *value, + NMSettingSecretFlags flags, + gboolean verbatim) { shvarFile *keyfile; @@ -60,10 +64,14 @@ set_secret (shvarFile *ifcfg, const char *key, const char *value, gboolean verba goto error; } - /* Clear the secret from the actual ifcfg */ + /* Clear the secret from the ifcfg and the associated "keys" file */ svSetValue (ifcfg, key, NULL, FALSE); + svSetValue (keyfile, key, NULL, FALSE); + + /* Only write the secret if it's system owned */ + if (flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) + svSetValue (keyfile, key, value, verbatim); - svSetValue (keyfile, key, value, verbatim); if (svWriteFile (keyfile, 0600)) { PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: could not update key file '%s'", keyfile->fileName); @@ -341,6 +349,7 @@ write_8021x_certs (NMSetting8021x *s_8021x, gboolean success = FALSE, is_pkcs12 = FALSE; const ObjectType *otype = NULL; const GByteArray *blob = NULL; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; /* CA certificate */ if (phase2) @@ -358,12 +367,14 @@ write_8021x_certs (NMSetting8021x *s_8021x, is_pkcs12 = TRUE; } password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); + flags = nm_setting_802_1x_get_phase2_private_key_password_flags (s_8021x); } else { if (nm_setting_802_1x_get_private_key_scheme (s_8021x) != NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) is_pkcs12 = TRUE; } password = nm_setting_802_1x_get_private_key_password (s_8021x); + flags = nm_setting_802_1x_get_private_key_password_flags (s_8021x); } if (is_pkcs12) @@ -384,8 +395,10 @@ write_8021x_certs (NMSetting8021x *s_8021x, if (!enc_key) goto out; - if (generated_pw) + if (generated_pw) { password = generated_pw; + flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + } } /* Save the private key */ @@ -394,9 +407,9 @@ write_8021x_certs (NMSetting8021x *s_8021x, /* Private key password */ if (phase2) - set_secret (ifcfg, "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", password, FALSE); + set_secret (ifcfg, "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", password, flags, FALSE); else - set_secret (ifcfg, "IEEE_8021X_PRIVATE_KEY_PASSWORD", password, FALSE); + set_secret (ifcfg, "IEEE_8021X_PRIVATE_KEY_PASSWORD", password, flags, FALSE); /* Client certificate */ if (is_pkcs12) { @@ -469,7 +482,11 @@ write_8021x_setting (NMConnection *connection, nm_setting_802_1x_get_anonymous_identity (s_8021x), FALSE); - set_secret (ifcfg, "IEEE_8021X_PASSWORD", nm_setting_802_1x_get_password (s_8021x), FALSE); + set_secret (ifcfg, + "IEEE_8021X_PASSWORD", + nm_setting_802_1x_get_password (s_8021x), + nm_setting_802_1x_get_password_flags (s_8021x), + FALSE); /* PEAP version */ value = nm_setting_802_1x_get_phase1_peapver (s_8021x); @@ -574,6 +591,7 @@ write_wireless_security_setting (NMConnection *connection, FALSE); set_secret (ifcfg, "IEEE_8021X_PASSWORD", nm_setting_wireless_security_get_leap_password (s_wsec), + nm_setting_wireless_security_get_leap_password_flags (s_wsec), FALSE); *no_8021x = TRUE; } @@ -581,15 +599,17 @@ write_wireless_security_setting (NMConnection *connection, /* WEP keys */ + /* Clear any default key */ + set_secret (ifcfg, "KEY", NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); + /* Clear existing keys */ - set_secret (ifcfg, "KEY", NULL, FALSE); /* Clear any default key */ for (i = 0; i < 4; i++) { tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); - set_secret (ifcfg, tmp, NULL, FALSE); + set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); g_free (tmp); tmp = g_strdup_printf ("KEY%d", i + 1); - set_secret (ifcfg, tmp, NULL, FALSE); + set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); g_free (tmp); } @@ -624,7 +644,7 @@ write_wireless_security_setting (NMConnection *connection, } } - set_secret (ifcfg, tmp, key, FALSE); + set_secret (ifcfg, tmp, key, nm_setting_wireless_security_get_wep_key_flags (s_wsec), FALSE); g_free (tmp); g_free (ascii_key); } @@ -687,11 +707,15 @@ write_wireless_security_setting (NMConnection *connection, g_string_append (quoted, psk); g_string_append_c (quoted, '"'); } - set_secret (ifcfg, "WPA_PSK", quoted ? quoted->str : psk, TRUE); + set_secret (ifcfg, + "WPA_PSK", + quoted ? quoted->str : psk, + nm_setting_wireless_security_get_psk_flags (s_wsec), + TRUE); if (quoted) g_string_free (quoted, TRUE); } else - set_secret (ifcfg, "WPA_PSK", NULL, FALSE); + set_secret (ifcfg, "WPA_PSK", NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); return TRUE; } From 1f7143b5df810837ff8bc95fc3150fdcce1c1092 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 20:52:18 -0600 Subject: [PATCH 198/264] settings: remove obsolete comment --- src/settings/nm-system-config-interface.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h index fb394785d..33b67d587 100644 --- a/src/settings/nm-system-config-interface.h +++ b/src/settings/nm-system-config-interface.h @@ -41,15 +41,6 @@ G_BEGIN_DECLS */ GObject * nm_system_config_factory (void); -/* NOTE: - * When passing NMConnection objects to NetworkManager, any properties - * of that NMConnection's NMSetting objects that are secrets must be set as - * GObject data items on the NMSetting object, _not_ inside the NMSetting - * object itself. This is to ensure that the secrets are only given to - * NetworkManager itself and not exposed to clients like nm-applet that need - * connection details, but not secrets. - */ - #define NM_TYPE_SYSTEM_CONFIG_INTERFACE (nm_system_config_interface_get_type ()) #define NM_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE, NMSystemConfigInterface)) #define NM_IS_SYSTEM_CONFIG_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_INTERFACE)) From ac757766e6b69ba5efb2a3cfde76f07097686cc0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 21:11:18 -0600 Subject: [PATCH 199/264] settings: fix plugin capabilities max value It's a bitfield, not a single value. --- src/settings/nm-system-config-interface.c | 3 ++- src/settings/nm-system-config-interface.h | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/settings/nm-system-config-interface.c b/src/settings/nm-system-config-interface.c index b7fcfd607..0533ff33c 100644 --- a/src/settings/nm-system-config-interface.c +++ b/src/settings/nm-system-config-interface.c @@ -53,7 +53,8 @@ interface_init (gpointer g_iface) "Capabilities", "Plugin capabilties", NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, - NM_SYSTEM_CONFIG_INTERFACE_CAP_LAST - 1, + ( NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS + | NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME), NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE, G_PARAM_READABLE)); diff --git a/src/settings/nm-system-config-interface.h b/src/settings/nm-system-config-interface.h index 33b67d587..96a640619 100644 --- a/src/settings/nm-system-config-interface.h +++ b/src/settings/nm-system-config-interface.h @@ -58,9 +58,11 @@ GObject * nm_system_config_factory (void); typedef enum { NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE = 0x00000000, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS = 0x00000001, - NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME = 0x00000002, + NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME = 0x00000002 - NM_SYSTEM_CONFIG_INTERFACE_CAP_LAST = NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME + /* When adding more capabilities, be sure to update the "Capabilities" + * property max value in nm-system-config-interface.c. + */ } NMSystemConfigInterfaceCapabilities; typedef enum { From c4ada67108f30255acd9521fef811bd0955ee330 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 21:53:16 -0600 Subject: [PATCH 200/264] libnm-util: simplify nm_connection_for_each_setting_value() And use less memory as a bonus. --- libnm-util/nm-connection.c | 33 +++++---------------------------- libnm-util/nm-connection.h | 4 ++-- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index cb677e566..db4ebd783 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -850,19 +850,6 @@ nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags) return ret; } -typedef struct ForEachValueInfo { - NMSettingValueIterFn func; - gpointer user_data; -} ForEachValueInfo; - -static void -for_each_setting (gpointer key, gpointer value, gpointer user_data) -{ - ForEachValueInfo *info = (ForEachValueInfo *) user_data; - - nm_setting_enumerate_values (NM_SETTING (value), info->func, info->user_data); -} - /** * nm_connection_for_each_setting_value: * @connection: the #NMConnection @@ -877,25 +864,15 @@ nm_connection_for_each_setting_value (NMConnection *connection, NMSettingValueIterFn func, gpointer user_data) { - NMConnectionPrivate *priv; - ForEachValueInfo *info; + GHashTableIter iter; + gpointer value; g_return_if_fail (NM_IS_CONNECTION (connection)); g_return_if_fail (func != NULL); - priv = NM_CONNECTION_GET_PRIVATE (connection); - - info = g_slice_new0 (ForEachValueInfo); - if (!info) { - g_warning ("Not enough memory to enumerate values."); - return; - } - info->func = func; - info->user_data = user_data; - - g_hash_table_foreach (priv->settings, for_each_setting, info); - - g_slice_free (ForEachValueInfo, info); + g_hash_table_iter_init (&iter, NM_CONNECTION_GET_PRIVATE (connection)->settings); + while (g_hash_table_iter_next (&iter, NULL, &value)) + nm_setting_enumerate_values (NM_SETTING (value), func, user_data); } static void diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 371d55906..2a51428fc 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -127,8 +127,8 @@ void nm_connection_set_path (NMConnection *connection, const char * nm_connection_get_path (NMConnection *connection); void nm_connection_for_each_setting_value (NMConnection *connection, - NMSettingValueIterFn func, - gpointer user_data); + NMSettingValueIterFn func, + gpointer user_data); GHashTable *nm_connection_to_hash (NMConnection *connection, NMSettingHashFlags flags); From 393bcf8d12855059399b11da8a661f219cd4256b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 23:10:33 -0600 Subject: [PATCH 201/264] settings: implement saving secrets to agents on Update() --- src/settings/nm-agent-manager.c | 541 +++++++++++++++++--------- src/settings/nm-agent-manager.h | 5 + src/settings/nm-secret-agent.c | 63 ++- src/settings/nm-secret-agent.h | 7 +- src/settings/nm-settings-connection.c | 51 ++- 5 files changed, 461 insertions(+), 206 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 11f824408..c3a303bb4 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -324,6 +324,8 @@ typedef void (*RequestCompleteFunc) (Request *req, GHashTable *secrets, GError *error, gpointer user_data); +typedef void (*RequestNextFunc) (Request *req); +typedef void (*RequestCancelFunc) (Request *req); struct _Request { guint32 reqid; @@ -359,34 +361,40 @@ struct _Request { gpointer other_data2; gpointer other_data3; + RequestCancelFunc cancel_callback; + RequestNextFunc next_callback; RequestCompleteFunc complete_callback; gpointer complete_callback_data; }; +static guint32 next_req_id = 1; + static Request * -request_new (NMConnection *connection, - gboolean filter_by_uid, - gulong uid_filter, - GHashTable *existing_secrets, - const char *setting_name, - guint32 flags, - const char *hint, - NMAgentSecretsResultFunc callback, - gpointer callback_data, - gpointer other_data2, - gpointer other_data3, - RequestCompleteFunc complete_callback, - gpointer complete_callback_data) +request_new_get (NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, + GHashTable *existing_secrets, + const char *setting_name, + guint32 flags, + const char *hint, + NMAgentSecretsResultFunc callback, + gpointer callback_data, + gpointer other_data2, + gpointer other_data3, + RequestCompleteFunc complete_callback, + gpointer complete_callback_data, + RequestNextFunc next_callback, + RequestCancelFunc cancel_callback) { Request *req; - static guint32 next_id = 1; req = g_malloc0 (sizeof (Request)); - req->reqid = next_id++; + req->reqid = next_req_id++; req->connection = g_object_ref (connection); req->filter_by_uid = filter_by_uid; req->uid_filter = uid_filter; - req->existing_secrets = g_hash_table_ref (existing_secrets); + if (existing_secrets) + req->existing_secrets = g_hash_table_ref (existing_secrets); req->setting_name = g_strdup (setting_name); req->flags = flags; req->hint = g_strdup (hint); @@ -396,6 +404,30 @@ request_new (NMConnection *connection, req->other_data3 = other_data3; req->complete_callback = complete_callback; req->complete_callback_data = complete_callback_data; + req->next_callback = next_callback; + req->cancel_callback = cancel_callback; + + return req; +} + +static Request * +request_new_save (NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, + RequestCompleteFunc complete_callback, + gpointer complete_callback_data, + RequestNextFunc next_callback) +{ + Request *req; + + req = g_malloc0 (sizeof (Request)); + req->reqid = next_req_id++; + req->connection = g_object_ref (connection); + req->filter_by_uid = filter_by_uid; + req->uid_filter = uid_filter; + req->complete_callback = complete_callback; + req->complete_callback_data = complete_callback_data; + req->next_callback = next_callback; return req; } @@ -406,8 +438,7 @@ request_free (Request *req) if (req->idle_id) g_source_remove (req->idle_id); - if (req->current && req->current_call_id) - nm_secret_agent_cancel_secrets (req->current, req->current_call_id); + req->cancel_callback (req); g_slist_free (req->pending); g_slist_free (req->asked); @@ -420,148 +451,6 @@ request_free (Request *req) g_free (req); } -static void request_next (Request *req); - -static void -request_secrets_done_cb (NMSecretAgent *agent, - gconstpointer call_id, - GHashTable *secrets, - GError *error, - gpointer user_data) -{ - Request *req = user_data; - GHashTable *setting_secrets; - - g_return_if_fail (call_id == req->current_call_id); - - req->current = NULL; - req->current_call_id = NULL; - - if (error) { - nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s", - nm_secret_agent_get_description (agent), - req, req->setting_name, - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); - - /* Try the next agent */ - request_next (req); - return; - } - - /* Ensure the setting we wanted secrets for got returned and has something in it */ - setting_secrets = g_hash_table_lookup (secrets, req->setting_name); - if (!setting_secrets || !g_hash_table_size (setting_secrets)) { - nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s", - nm_secret_agent_get_description (agent), - req, req->setting_name); - - /* Try the next agent */ - request_next (req); - return; - } - - nm_log_dbg (LOGD_AGENTS, "(%s) agent returned secrets for request %p/%s", - nm_secret_agent_get_description (agent), - req, req->setting_name); - - req->complete_callback (req, secrets, NULL, req->complete_callback_data); -} - -static void -request_next (Request *req) -{ - GError *error = NULL; - - if (req->pending == NULL) { - /* No more secret agents are available to fulfill this secrets request */ - error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, - NM_AGENT_MANAGER_ERROR_NO_SECRETS, - "No secrets were available for this request."); - req->complete_callback (req, NULL, error, req->complete_callback_data); - g_error_free (error); - return; - } - - /* Send a secrets request to the next agent */ - req->current = req->pending->data; - req->pending = g_slist_remove (req->pending, req->current); - - nm_log_dbg (LOGD_AGENTS, "(%s) agent getting secrets for request %p/%s", - nm_secret_agent_get_description (req->current), - req, req->setting_name); - - req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), - req->connection, - req->setting_name, - req->hint, - req->flags, - request_secrets_done_cb, - req); - if (req->current_call_id == NULL) { - /* Shouldn't hit this, but handle it anyway */ - g_warn_if_fail (req->current_call_id != NULL); - req->current = NULL; - request_next (req); - } -} - -static gboolean -request_start_secrets (gpointer user_data) -{ - Request *req = user_data; - GHashTable *setting_secrets = NULL; - - req->idle_id = 0; - - /* Check if there are any existing secrets */ - if (req->existing_secrets) - setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name); - - if (setting_secrets && g_hash_table_size (setting_secrets)) { - NMConnection *tmp; - GError *error = NULL; - - /* The connection already had secrets; check if any more are required. - * If no more are required, we're done. If secrets are still needed, - * ask a secret agent for more. This allows admins to provide generic - * secrets but allow additional user-specific ones as well. - */ - tmp = nm_connection_duplicate (req->connection); - g_assert (tmp); - - if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { - req->complete_callback (req, NULL, error, req->complete_callback_data); - g_clear_error (&error); - } else { - /* Do we have everything we need? */ - /* FIXME: handle second check for VPN connections */ - if (nm_connection_need_secrets (tmp, NULL) == NULL) { - nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets sufficient", - req, req->setting_name); - - /* Got everything, we're done */ - req->complete_callback (req, req->existing_secrets, NULL, req->complete_callback_data); - } else { - nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", - req, req->setting_name); - - /* We don't, so ask some agents for additional secrets */ - request_next (req); - } - } - g_object_unref (tmp); - } else { - /* Couldn't get secrets from system settings, so now we ask the - * agents for secrets. Let the Agent Manager handle which agents - * we'll ask and in which order. - */ - request_next (req); - } - - return FALSE; -} - static gint agent_compare_func (NMSecretAgent *a, NMSecretAgent *b, gpointer user_data) { @@ -617,7 +506,7 @@ request_add_agent (Request *req, /* Connection not visible to this agent's user */ return; } - /* Caller is allowed to add this connection */ + /* Caller is allowed to manipulate this connection */ } /* If the request should filter agents by UID, do that now */ @@ -640,6 +529,18 @@ request_add_agent (Request *req, session_monitor); } +static void +request_add_agents (NMAgentManager *self, Request *req) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + GHashTableIter iter; + gpointer data; + + g_hash_table_iter_init (&iter, priv->agents); + while (g_hash_table_iter_next (&iter, NULL, &data)) + request_add_agent (req, NM_SECRET_AGENT (data), priv->session_monitor); +} + static void request_remove_agent (Request *req, NMSecretAgent *agent) { @@ -651,7 +552,7 @@ request_remove_agent (Request *req, NMSecretAgent *agent) /* If this agent is being asked right now, cancel the request */ if (agent == req->current) { - nm_secret_agent_cancel_secrets (req->current, req->current_call_id); + req->cancel_callback (req); req->current = NULL; req->current_call_id = NULL; try_next = TRUE; @@ -666,19 +567,169 @@ request_remove_agent (Request *req, NMSecretAgent *agent) if (try_next) { /* If the agent serving the in-progress secrets request went away then - * we need to ask the next agent for secrets. + * we need to send the request to the next agent. */ - request_next (req); + req->next_callback (req); } } +static gboolean +next_generic (Request *req, const char *detail) +{ + GError *error = NULL; + gboolean success = FALSE; + + if (req->pending == NULL) { + /* No more secret agents are available to fulfill this secrets request */ + error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, + NM_AGENT_MANAGER_ERROR_NO_SECRETS, + "No agents were available for this request."); + req->complete_callback (req, NULL, error, req->complete_callback_data); + g_error_free (error); + } else { + /* Send a secrets request to the next agent */ + req->current = req->pending->data; + req->pending = g_slist_remove (req->pending, req->current); + + nm_log_dbg (LOGD_AGENTS, "(%s) agent %s secrets for request %p/%s", + nm_secret_agent_get_description (req->current), + detail, req, req->setting_name); + success = TRUE; + } + + return success; +} + /*************************************************************/ static void -mgr_req_complete_cb (Request *req, - GHashTable *secrets, - GError *error, - gpointer user_data) +get_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + Request *req = user_data; + GHashTable *setting_secrets; + + g_return_if_fail (call_id == req->current_call_id); + + req->current = NULL; + req->current_call_id = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + + /* Try the next agent */ + req->next_callback (req); + return; + } + + /* Ensure the setting we wanted secrets for got returned and has something in it */ + setting_secrets = g_hash_table_lookup (secrets, req->setting_name); + if (!setting_secrets || !g_hash_table_size (setting_secrets)) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + /* Try the next agent */ + req->next_callback (req); + return; + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent returned secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + req->complete_callback (req, secrets, NULL, req->complete_callback_data); +} + +static void +get_next_cb (Request *req) +{ + if (!next_generic (req, "getting")) + return; + + req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), + req->connection, + req->setting_name, + req->hint, + req->flags, + get_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current = NULL; + req->next_callback (req); + } +} + +static gboolean +get_start (gpointer user_data) +{ + Request *req = user_data; + GHashTable *setting_secrets = NULL; + + req->idle_id = 0; + + /* Check if there are any existing secrets */ + if (req->existing_secrets) + setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name); + + if (setting_secrets && g_hash_table_size (setting_secrets)) { + NMConnection *tmp; + GError *error = NULL; + + /* The connection already had secrets; check if any more are required. + * If no more are required, we're done. If secrets are still needed, + * ask a secret agent for more. This allows admins to provide generic + * secrets but allow additional user-specific ones as well. + */ + tmp = nm_connection_duplicate (req->connection); + g_assert (tmp); + + if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { + req->complete_callback (req, NULL, error, req->complete_callback_data); + g_clear_error (&error); + } else { + /* Do we have everything we need? */ + /* FIXME: handle second check for VPN connections */ + if (nm_connection_need_secrets (tmp, NULL) == NULL) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets sufficient", + req, req->setting_name); + + /* Got everything, we're done */ + req->complete_callback (req, req->existing_secrets, NULL, req->complete_callback_data); + } else { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", + req, req->setting_name); + + /* We don't, so ask some agents for additional secrets */ + req->next_callback (req); + } + } + g_object_unref (tmp); + } else { + /* Couldn't get secrets from system settings, so now we ask the + * agents for secrets. Let the Agent Manager handle which agents + * we'll ask and in which order. + */ + req->next_callback (req); + } + + return FALSE; +} + +static void +get_complete_cb (Request *req, + GHashTable *secrets, + GError *error, + gpointer user_data) { NMAgentManager *self = NM_AGENT_MANAGER (user_data); NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); @@ -696,6 +747,13 @@ mgr_req_complete_cb (Request *req, g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); } +static void +get_cancel_cb (Request *req) +{ + if (req->current && req->current_call_id) + nm_secret_agent_cancel_secrets (req->current, req->current_call_id); +} + guint32 nm_agent_manager_get_secrets (NMAgentManager *self, NMConnection *connection, @@ -712,8 +770,6 @@ nm_agent_manager_get_secrets (NMAgentManager *self, { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); Request *req; - GHashTableIter iter; - gpointer data; g_return_val_if_fail (self != NULL, 0); g_return_val_if_fail (connection != NULL, 0); @@ -725,28 +781,26 @@ nm_agent_manager_get_secrets (NMAgentManager *self, nm_connection_get_path (connection), setting_name); - req = request_new (connection, - filter_by_uid, - uid_filter, - existing_secrets, - setting_name, - flags, - hint, - callback, - callback_data, - other_data2, - other_data3, - mgr_req_complete_cb, - self); - + req = request_new_get (connection, + filter_by_uid, + uid_filter, + existing_secrets, + setting_name, + flags, + hint, + callback, + callback_data, + other_data2, + other_data3, + get_complete_cb, + self, + get_next_cb, + get_cancel_cb); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); - /* Add agents to the request */ - g_hash_table_iter_init (&iter, priv->agents); - while (g_hash_table_iter_next (&iter, NULL, &data)) - request_add_agent (req, NM_SECRET_AGENT (data), priv->session_monitor); - - req->idle_id = g_idle_add (request_start_secrets, req); + /* Kick off the request */ + request_add_agents (self, req); + req->idle_id = g_idle_add (get_start, req); return req->reqid; } @@ -764,6 +818,113 @@ nm_agent_manager_cancel_secrets (NMAgentManager *self, /*************************************************************/ +static void +save_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + Request *req = user_data; + + g_return_if_fail (call_id == req->current_call_id); + + req->current = NULL; + req->current_call_id = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed save secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + + /* Try the next agent */ + req->next_callback (req); + return; + } + + nm_log_dbg (LOGD_AGENTS, "(%s) agent saved secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + + req->complete_callback (req, NULL, NULL, req->complete_callback_data); +} + +static void +save_next_cb (Request *req) +{ + if (!next_generic (req, "saving")) + return; + + req->current_call_id = nm_secret_agent_save_secrets (NM_SECRET_AGENT (req->current), + req->connection, + save_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current = NULL; + req->next_callback (req); + } +} + +static void +save_complete_cb (Request *req, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); +} + +static gboolean +save_start (gpointer user_data) +{ + Request *req = user_data; + + req->idle_id = 0; + req->next_callback (req); + return FALSE; +} + +guint32 +nm_agent_manager_save_secrets (NMAgentManager *self, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + Request *req; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); + + nm_log_dbg (LOGD_SETTINGS, + "Saving secrets for connection %s", + nm_connection_get_path (connection)); + + req = request_new_save (connection, + filter_by_uid, + uid_filter, + save_complete_cb, + self, + save_next_cb); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + + /* Kick off the request */ + request_add_agents (self, req); + req->idle_id = g_idle_add (save_start, req); + + return req->reqid; +} + +/*************************************************************/ + static void name_owner_changed_cb (NMDBusManager *dbus_mgr, const char *name, diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index 582680741..9b028aa95 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -69,4 +69,9 @@ guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, void nm_agent_manager_cancel_secrets (NMAgentManager *manager, guint32 request_id); +guint32 nm_agent_manager_save_secrets (NMAgentManager *manager, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter); + #endif /* NM_AGENT_MANAGER_H */ diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 13a7592a4..f63b63799 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. */ #include @@ -146,9 +146,9 @@ nm_secret_agent_get_hash (NMSecretAgent *agent) /*************************************************************/ static void -secrets_callback (DBusGProxy *proxy, - DBusGProxyCall *call, - void *user_data) +get_callback (DBusGProxy *proxy, + DBusGProxyCall *call, + void *user_data) { Request *r = user_data; NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); @@ -193,7 +193,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, "GetSecrets", - secrets_callback, + get_callback, r, NULL, 120000, /* 120 seconds */ @@ -233,6 +233,59 @@ nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call) /*************************************************************/ +static void +save_callback (DBusGProxy *proxy, + DBusGProxyCall *call, + void *user_data) +{ + Request *r = user_data; + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); + GError *error = NULL; + + g_return_if_fail (call == r->call); + + dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + r->callback (r->agent, r->call, NULL, error, r->callback_data); + g_clear_error (&error); + g_hash_table_remove (priv->requests, call); +} + +gconstpointer +nm_secret_agent_save_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + NMSecretAgentPrivate *priv; + Request *r; + GHashTable *hash; + + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); + + priv = NM_SECRET_AGENT_GET_PRIVATE (self); + + /* Caller should have ensured that only agent-owned secrets exist in 'connection' */ + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + + r = request_new (self, nm_connection_get_path (connection), NULL, callback, callback_data); + r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + "SaveSecrets", + save_callback, + r, + NULL, + 10000, /* 10 seconds */ + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), + G_TYPE_INVALID); + g_hash_table_insert (priv->requests, r->call, r); + + g_hash_table_destroy (hash); + return r->call; +} + +/*************************************************************/ + NMSecretAgent * nm_secret_agent_new (NMDBusManager *dbus_mgr, const char *owner, diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h index f1e8bb322..6387d1760 100644 --- a/src/settings/nm-secret-agent.h +++ b/src/settings/nm-secret-agent.h @@ -63,7 +63,7 @@ guint32 nm_secret_agent_get_hash (NMSecretAgent *agent); typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent, gconstpointer call, - GHashTable *secrets, + GHashTable *new_secrets, /* NULL for save & delete */ GError *error, gpointer user_data); @@ -78,4 +78,9 @@ gconstpointer nm_secret_agent_get_secrets (NMSecretAgent *agent, void nm_secret_agent_cancel_secrets (NMSecretAgent *agent, gconstpointer call_id); +gconstpointer nm_secret_agent_save_secrets (NMSecretAgent *agent, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data); + #endif /* NM_SECRET_AGENT_H */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index e0b079d39..a0cbbab21 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -653,6 +653,23 @@ con_update_cb (NMSettingsConnection *connection, dbus_g_method_return (context); } +static void +only_agent_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + if (flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + + /* Clear out system-owned or always-ask secrets */ + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_object_set (G_OBJECT (setting), key, NULL, NULL); + } +} + static void update_auth_cb (NMSettingsConnection *self, DBusGMethodInvocation *context, @@ -660,20 +677,29 @@ update_auth_cb (NMSettingsConnection *self, GError *error, gpointer data) { + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMConnection *new_settings = data; + NMConnection *for_agent; - if (error) { + if (error) dbus_g_method_return_error (context, error); - goto out; + else { + /* Update and commit our settings. */ + nm_settings_connection_replace_and_commit (self, + new_settings, + con_update_cb, + context); + + /* Dupe the connection and clear out non-agent-owned secrets so we can + * send the agent-owned ones to agents to be saved. Only send them to + * agents of the same UID as the Update() request sender. + */ + for_agent = nm_connection_duplicate (NM_CONNECTION (self)); + nm_connection_for_each_setting_value (for_agent, only_agent_secrets_cb, NULL); + nm_agent_manager_save_secrets (priv->agent_mgr, for_agent, TRUE, sender_uid); + g_object_unref (for_agent); } - /* Update and commit our settings. */ - nm_settings_connection_replace_and_commit (self, - new_settings, - con_update_cb, - context); - -out: g_object_unref (new_settings); } @@ -766,7 +792,12 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); /* The connection's secrets will have been updated by the agent manager, - * so we want to refresh the secrets cache. + * so we want to refresh the secrets cache. Note that we will never save + * new secrets to backing storage here because D-Bus initated requests will + * never ask for completely new secrets from agents. Thus system-owned + * secrets should not have changed from backing storage. We also don't + * send agent-owned back out to be saved since we assume the agent that + * provided the secrets saved them itself. */ if (priv->secrets) g_object_unref (priv->secrets); From 570c0eb2dff29ce3cb809e673b2f457430c4e5e4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 31 Jan 2011 23:33:46 -0600 Subject: [PATCH 202/264] settings: implement deleting secrets from agents when connection is deleted --- introspection/nm-secret-agent.xml | 4 +- src/settings/nm-agent-manager.c | 141 +++++++++++++++++++++----- src/settings/nm-agent-manager.h | 5 + src/settings/nm-secret-agent.c | 79 ++++++++++----- src/settings/nm-secret-agent.h | 5 + src/settings/nm-settings-connection.c | 10 ++ 6 files changed, 196 insertions(+), 48 deletions(-) diff --git a/introspection/nm-secret-agent.xml b/introspection/nm-secret-agent.xml index 655b2b72f..8a651dd66 100644 --- a/introspection/nm-secret-agent.xml +++ b/introspection/nm-secret-agent.xml @@ -137,8 +137,8 @@ - Nested settings maps containing the entire connection - (including secrets), for which the agent should delete the + Nested settings maps containing the connection properties + (sans secrets), for which the agent should delete the secrets from backing storage. diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index c3a303bb4..d8ac0493f 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -411,12 +411,12 @@ request_new_get (NMConnection *connection, } static Request * -request_new_save (NMConnection *connection, - gboolean filter_by_uid, - gulong uid_filter, - RequestCompleteFunc complete_callback, - gpointer complete_callback_data, - RequestNextFunc next_callback) +request_new_other (NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter, + RequestCompleteFunc complete_callback, + gpointer complete_callback_data, + RequestNextFunc next_callback) { Request *req; @@ -600,6 +600,17 @@ next_generic (Request *req, const char *detail) return success; } +static gboolean +start_generic (gpointer user_data) +{ + Request *req = user_data; + + req->idle_id = 0; + req->next_callback (req); + return FALSE; +} + + /*************************************************************/ static void @@ -881,16 +892,6 @@ save_complete_cb (Request *req, g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); } -static gboolean -save_start (gpointer user_data) -{ - Request *req = user_data; - - req->idle_id = 0; - req->next_callback (req); - return FALSE; -} - guint32 nm_agent_manager_save_secrets (NMAgentManager *self, NMConnection *connection, @@ -908,17 +909,111 @@ nm_agent_manager_save_secrets (NMAgentManager *self, "Saving secrets for connection %s", nm_connection_get_path (connection)); - req = request_new_save (connection, - filter_by_uid, - uid_filter, - save_complete_cb, - self, - save_next_cb); + req = request_new_other (connection, + filter_by_uid, + uid_filter, + save_complete_cb, + self, + save_next_cb); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); /* Kick off the request */ request_add_agents (self, req); - req->idle_id = g_idle_add (save_start, req); + req->idle_id = g_idle_add (start_generic, req); + + return req->reqid; +} + +/*************************************************************/ + +static void +delete_done_cb (NMSecretAgent *agent, + gconstpointer call_id, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + Request *req = user_data; + + g_return_if_fail (call_id == req->current_call_id); + + req->current = NULL; + req->current_call_id = NULL; + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%s) agent failed delete secrets request %p/%s: (%d) %s", + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + } else { + nm_log_dbg (LOGD_AGENTS, "(%s) agent deleted secrets for request %p/%s", + nm_secret_agent_get_description (agent), + req, req->setting_name); + } + + /* Tell the next agent to delete secrets */ + req->next_callback (req); +} + +static void +delete_next_cb (Request *req) +{ + if (!next_generic (req, "deleting")) + return; + + req->current_call_id = nm_secret_agent_delete_secrets (NM_SECRET_AGENT (req->current), + req->connection, + delete_done_cb, + req); + if (req->current_call_id == NULL) { + /* Shouldn't hit this, but handle it anyway */ + g_warn_if_fail (req->current_call_id != NULL); + req->current = NULL; + req->next_callback (req); + } +} + +static void +delete_complete_cb (Request *req, + GHashTable *secrets, + GError *error, + gpointer user_data) +{ + NMAgentManager *self = NM_AGENT_MANAGER (user_data); + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + + g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid)); +} + +guint32 +nm_agent_manager_delete_secrets (NMAgentManager *self, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter) +{ + NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + Request *req; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (connection != NULL, 0); + g_return_val_if_fail (NM_IS_CONNECTION (connection), 0); + + nm_log_dbg (LOGD_SETTINGS, + "Deleting secrets for connection %s", + nm_connection_get_path (connection)); + + req = request_new_other (connection, + filter_by_uid, + uid_filter, + delete_complete_cb, + self, + delete_next_cb); + g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req); + + /* Kick off the request */ + request_add_agents (self, req); + req->idle_id = g_idle_add (start_generic, req); return req->reqid; } diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index 9b028aa95..2c34b4f09 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -74,4 +74,9 @@ guint32 nm_agent_manager_save_secrets (NMAgentManager *manager, gboolean filter_by_uid, gulong uid_filter); +guint32 nm_agent_manager_delete_secrets (NMAgentManager *manager, + NMConnection *connection, + gboolean filter_by_uid, + gulong uid_filter); + #endif /* NM_AGENT_MANAGER_H */ diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index f63b63799..1a995f971 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -234,9 +234,9 @@ nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call) /*************************************************************/ static void -save_callback (DBusGProxy *proxy, - DBusGProxyCall *call, - void *user_data) +agent_save_delete_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + void *user_data) { Request *r = user_data; NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); @@ -250,38 +250,71 @@ save_callback (DBusGProxy *proxy, g_hash_table_remove (priv->requests, call); } +static gpointer +agent_new_save_delete (NMSecretAgent *self, + NMConnection *connection, + NMSettingHashFlags hash_flags, + const char *method, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); + GHashTable *hash; + Request *r; + const char *cpath = nm_connection_get_path (connection); + + hash = nm_connection_to_hash (connection, hash_flags); + + r = request_new (self, cpath, NULL, callback, callback_data); + r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, + method, + agent_save_delete_cb, + r, + NULL, + 10000, /* 10 seconds */ + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, + DBUS_TYPE_G_OBJECT_PATH, cpath, + G_TYPE_INVALID); + g_hash_table_insert (priv->requests, r->call, r); + + g_hash_table_destroy (hash); + return r->call; +} + gconstpointer nm_secret_agent_save_secrets (NMSecretAgent *self, NMConnection *connection, NMSecretAgentCallback callback, gpointer callback_data) { - NMSecretAgentPrivate *priv; - Request *r; - GHashTable *hash; - g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL); - priv = NM_SECRET_AGENT_GET_PRIVATE (self); - /* Caller should have ensured that only agent-owned secrets exist in 'connection' */ - hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + return agent_new_save_delete (self, + connection, + NM_SETTING_HASH_FLAG_ALL, + "SaveSecrets", + callback, + callback_data); +} - r = request_new (self, nm_connection_get_path (connection), NULL, callback, callback_data); - r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, - "SaveSecrets", - save_callback, - r, - NULL, - 10000, /* 10 seconds */ - DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, - DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), - G_TYPE_INVALID); - g_hash_table_insert (priv->requests, r->call, r); +gconstpointer +nm_secret_agent_delete_secrets (NMSecretAgent *self, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); - g_hash_table_destroy (hash); - return r->call; + /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ + return agent_new_save_delete (self, + connection, + NM_SETTING_HASH_FLAG_NO_SECRETS, + "DeleteSecrets", + callback, + callback_data); } /*************************************************************/ diff --git a/src/settings/nm-secret-agent.h b/src/settings/nm-secret-agent.h index 6387d1760..676a370b6 100644 --- a/src/settings/nm-secret-agent.h +++ b/src/settings/nm-secret-agent.h @@ -83,4 +83,9 @@ gconstpointer nm_secret_agent_save_secrets (NMSecretAgent *agent, NMSecretAgentCallback callback, gpointer callback_data); +gconstpointer nm_secret_agent_delete_secrets (NMSecretAgent *agent, + NMConnection *connection, + NMSecretAgentCallback callback, + gpointer callback_data); + #endif /* NM_SECRET_AGENT_H */ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index a0cbbab21..f7c9d6c0a 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -326,8 +326,18 @@ do_delete (NMSettingsConnection *connection, NMSettingsConnectionDeleteFunc callback, gpointer user_data) { + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); + NMConnection *for_agents; + g_object_ref (connection); set_visible (connection, FALSE); + + /* Tell agents to remove secrets for this connection */ + for_agents = nm_connection_duplicate (NM_CONNECTION (connection)); + nm_connection_clear_secrets (for_agents); + nm_agent_manager_delete_secrets (priv->agent_mgr, for_agents, FALSE, 0); + + /* Signal the connection is removed and deleted */ g_signal_emit (connection, signals[REMOVED], 0); callback (connection, NULL, user_data); g_object_unref (connection); From f9147ec369779049cee3aa3e140ab4a754618043 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 1 Feb 2011 12:19:58 -0600 Subject: [PATCH 203/264] settings: don't pass all secrets to agents when requesting secrets The agent can and will get the secrets it needs itself, since it's providing secrets anyway. --- src/settings/nm-secret-agent.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 1a995f971..03f9a2323 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -187,8 +187,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, priv = NM_SECRET_AGENT_GET_PRIVATE (self); - /* FIXME: allow system secrets to be sent to the agent? */ - hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_NO_SECRETS); r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, From fb033b0f05fb9df1a61b22a5a3a54235e8b62fac Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 11:58:19 -0600 Subject: [PATCH 204/264] libnm-util: fix setting property iteration when getting secret flags g_object_class_find_property() needs the object's class, not the object itself. --- libnm-util/nm-setting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 5e1614c91..ea02275f9 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -575,7 +575,7 @@ is_secret_prop (NMSetting *setting, const char *secret_name, GError **error) { GParamSpec *pspec; - pspec = g_object_class_find_property (G_OBJECT_CLASS (setting), secret_name); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (setting), secret_name); if (!pspec) { g_set_error (error, NM_SETTING_ERROR, From 4ff0b5f0b72371de8bf14bf8337e104c992cecf7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 12:17:26 -0600 Subject: [PATCH 205/264] core: add method to start authentication with a D-Bus sender --- src/nm-manager-auth.c | 18 +++++++++++++++--- src/nm-manager-auth.h | 5 +++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index da147fcc6..ea56f10f7 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -80,12 +80,13 @@ _auth_chain_new (PolkitAuthority *authority, DBusGMethodInvocation *context, DBusGProxy *proxy, DBusMessage *message, + const char *dbus_sender, NMAuthChainResultFunc done_func, gpointer user_data) { NMAuthChain *self; - g_return_val_if_fail (context || proxy || message, NULL); + g_return_val_if_fail (context || proxy || message || dbus_sender, NULL); self = g_malloc0 (sizeof (NMAuthChain)); self->refcount = 1; @@ -102,6 +103,8 @@ _auth_chain_new (PolkitAuthority *authority, self->owner = dbus_g_method_get_sender (context); else if (message) self->owner = g_strdup (dbus_message_get_sender (message)); + else if (dbus_sender) + self->owner = g_strdup (dbus_sender); if (!self->owner) { /* Need an owner */ @@ -120,7 +123,7 @@ nm_auth_chain_new (PolkitAuthority *authority, NMAuthChainResultFunc done_func, gpointer user_data) { - return _auth_chain_new (authority, context, proxy, NULL, done_func, user_data); + return _auth_chain_new (authority, context, proxy, NULL, NULL, done_func, user_data); } NMAuthChain * @@ -129,7 +132,16 @@ nm_auth_chain_new_raw_message (PolkitAuthority *authority, NMAuthChainResultFunc done_func, gpointer user_data) { - return _auth_chain_new (authority, NULL, NULL, message, done_func, user_data); + return _auth_chain_new (authority, NULL, NULL, message, NULL, done_func, user_data); +} + +NMAuthChain * +nm_auth_chain_new_dbus_sender (PolkitAuthority *authority, + const char *dbus_sender, + NMAuthChainResultFunc done_func, + gpointer user_data) +{ + return _auth_chain_new (authority, NULL, NULL, NULL, dbus_sender, done_func, user_data); } gpointer diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 26195bf06..15b8cde13 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -72,6 +72,11 @@ NMAuthChain *nm_auth_chain_new_raw_message (PolkitAuthority *authority, NMAuthChainResultFunc done_func, gpointer user_data); +NMAuthChain *nm_auth_chain_new_dbus_sender (PolkitAuthority *authority, + const char *dbus_sender, + NMAuthChainResultFunc done_func, + gpointer user_data); + gpointer nm_auth_chain_get_data (NMAuthChain *chain, const char *tag); void nm_auth_chain_set_data (NMAuthChain *chain, From 76aabe4b72c0b6089da0a999608ea3ad62b657e1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 12:17:58 -0600 Subject: [PATCH 206/264] settings: ensure an agent is authorized before overwriting system-owned secrets If the agent returns system-owned secrets, like when activating a new connection which was created with no secrets, make sure the agent is authorized to modify network settings before saving or using the new secrets. --- src/settings/nm-agent-manager.c | 24 +- src/settings/nm-agent-manager.h | 3 + src/settings/nm-settings-connection.c | 320 ++++++++++++++++++++++++-- 3 files changed, 325 insertions(+), 22 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index d8ac0493f..9979c4e88 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -322,6 +322,7 @@ done: typedef void (*RequestCompleteFunc) (Request *req, GHashTable *secrets, + const char *agent_dbus_owner, GError *error, gpointer user_data); typedef void (*RequestNextFunc) (Request *req); @@ -341,9 +342,7 @@ struct _Request { NMSecretAgent *current; gconstpointer current_call_id; - /* Stores the sorted list of NMSecretAgents which will be - * asked for secrets. - */ + /* Stores the sorted list of NMSecretAgents which will be asked for secrets */ GSList *pending; /* Stores the list of NMSecretAgent hashes that we've already @@ -584,7 +583,7 @@ next_generic (Request *req, const char *detail) error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS, "No agents were available for this request."); - req->complete_callback (req, NULL, error, req->complete_callback_data); + req->complete_callback (req, NULL, NULL, error, req->complete_callback_data); g_error_free (error); } else { /* Send a secrets request to the next agent */ @@ -622,6 +621,7 @@ get_done_cb (NMSecretAgent *agent, { Request *req = user_data; GHashTable *setting_secrets; + const char *agent_dbus_owner; g_return_if_fail (call_id == req->current_call_id); @@ -656,7 +656,8 @@ get_done_cb (NMSecretAgent *agent, nm_secret_agent_get_description (agent), req, req->setting_name); - req->complete_callback (req, secrets, NULL, req->complete_callback_data); + agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); + req->complete_callback (req, secrets, agent_dbus_owner, NULL, req->complete_callback_data); } static void @@ -705,7 +706,7 @@ get_start (gpointer user_data) g_assert (tmp); if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { - req->complete_callback (req, NULL, error, req->complete_callback_data); + req->complete_callback (req, NULL, NULL, error, req->complete_callback_data); g_clear_error (&error); } else { /* Do we have everything we need? */ @@ -715,7 +716,7 @@ get_start (gpointer user_data) req, req->setting_name); /* Got everything, we're done */ - req->complete_callback (req, req->existing_secrets, NULL, req->complete_callback_data); + req->complete_callback (req, req->existing_secrets, NULL, NULL, req->complete_callback_data); } else { nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", req, req->setting_name); @@ -739,6 +740,7 @@ get_start (gpointer user_data) static void get_complete_cb (Request *req, GHashTable *secrets, + const char *agent_dbus_owner, GError *error, gpointer user_data) { @@ -748,7 +750,9 @@ get_complete_cb (Request *req, /* Send secrets back to the requesting object */ req->callback (self, req->reqid, + agent_dbus_owner, req->setting_name, + req->flags, error ? NULL : secrets, error, req->callback_data, @@ -837,6 +841,7 @@ save_done_cb (NMSecretAgent *agent, gpointer user_data) { Request *req = user_data; + const char *agent_dbus_owner; g_return_if_fail (call_id == req->current_call_id); @@ -859,7 +864,8 @@ save_done_cb (NMSecretAgent *agent, nm_secret_agent_get_description (agent), req, req->setting_name); - req->complete_callback (req, NULL, NULL, req->complete_callback_data); + agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); + req->complete_callback (req, NULL, agent_dbus_owner, NULL, req->complete_callback_data); } static void @@ -883,6 +889,7 @@ save_next_cb (Request *req) static void save_complete_cb (Request *req, GHashTable *secrets, + const char *agent_dbus_owner, GError *error, gpointer user_data) { @@ -977,6 +984,7 @@ delete_next_cb (Request *req) static void delete_complete_cb (Request *req, GHashTable *secrets, + const char *agent_dbus_owner, GError *error, gpointer user_data) { diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index 2c34b4f09..6771f943a 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -44,9 +44,12 @@ GType nm_agent_manager_get_type (void); NMAgentManager *nm_agent_manager_get (void); +/* If no agent fulfilled the secrets request, agent_dbus_owner will be NULL */ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 call_id, + const char *agent_dbus_owner, const char *setting_name, + guint32 flags, GHashTable *secrets, GError *error, gpointer user_data, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index f7c9d6c0a..d82bb4414 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -352,10 +352,216 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name) return TRUE; } +/* Return TRUE to continue, FALSE to stop */ +typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data); + +static gboolean +clear_system_owned_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + if (flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) + g_hash_table_iter_remove (iter); + return TRUE; +} + +static gboolean +has_system_owned_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + gboolean *has_system_owned = user_data; + + if (flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) { + *has_system_owned = TRUE; + return FALSE; + } + return TRUE; +} + +static void +for_each_secret (NMConnection *connection, + GHashTable *secrets, + ForEachSecretFunc callback, + gpointer callback_data) +{ + GHashTableIter iter; + const char *setting_name; + GHashTable *setting_hash; + + /* Walk through the list of setting hashes */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, + (gpointer *) &setting_name, + (gpointer *) &setting_hash)) { + GHashTableIter setting_iter; + const char *secret_name; + + /* Walk through the list of keys in each setting hash */ + g_hash_table_iter_init (&setting_iter, setting_hash); + while (g_hash_table_iter_next (&setting_iter, (gpointer *) &secret_name, NULL)) { + NMSetting *setting; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + + /* Get the actual NMSetting from the connection so we can get secret flags */ + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (setting && nm_setting_get_secret_flags (setting, secret_name, &flags, NULL)) { + if (callback (&setting_iter, flags, callback_data) == FALSE) + return; + } + } + } +} + +static void +new_secrets_commit_cb (NMSettingsConnection *connection, + GError *error, + gpointer user_data) +{ + if (error) { + nm_log_warn (LOGD_SETTINGS, "Error saving new secrets to backing storage: (%d) %s", + error->code, error->message ? error->message : "(unknown)"); + } +} + +static void +get_secrets_done (NMSettingsConnection *self, + guint32 call_id, + const char *setting_name, + GHashTable *secrets, + GError *error, + NMSettingsConnectionSecretsFunc callback, + gpointer callback_data) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingConnection *s_con; + GError *local = NULL; + GHashTable *hash = NULL; + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + if (error) { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed; error: (%d) %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + error->code, + error->message ? error->message : "(unknown)"); + callback (self, call_id, setting_name, error, callback_data); + return; + } + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed successfully", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); + + /* Update the connection with our existing secrets from backing storage */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { + /* Update the connection with the agent's secrets; by this point if any + * system-owned secrets exist in 'secrets' the agent that provided them + * will have been authenticated, so those secrets can replace the existing + * system secrets. + */ + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + /* Now that all secrets are updated, copy and cache new secrets, + * then save them to backing storage. + */ + if (priv->secrets) + g_object_unref (priv->secrets); + priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); + + nm_settings_connection_commit_changes (self, new_secrets_commit_cb, NULL); + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with agent secrets: (%d) %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + local->code, + local->message ? local->message : "(unknown)"); + } + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + local->code, + local->message ? local->message : "(unknown)"); + } + + callback (self, call_id, setting_name, local, callback_data); + g_clear_error (&local); + if (hash) + g_hash_table_destroy (hash); +} + +static void +agent_secrets_modify_auth_cb (NMAuthChain *chain, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingConnection *s_con; + NMAuthCallResult result; + GHashTable *secrets = nm_auth_chain_get_data (chain, "secrets"); + const char *setting_name = nm_auth_chain_get_data (chain, "setting-name"); + guint32 call_id = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "call-id")); + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + priv->pending_auths = g_slist_remove (priv->pending_auths, chain); + + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent MODIFY check result %d", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + result); + + if (result == NM_AUTH_CALL_RESULT_YES) { + /* Agent can modify system connections; system-owned secrets it returned + * replace any secrets in backing storage. + */ + } else { + /* Agent didn't successfully authenticate; clear system-owned secrets + * from the secrets the agent returned. + */ + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent failed to authenticate after providing system secrets", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); + for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); + } + + get_secrets_done (self, + call_id, + setting_name, + secrets, + error, + nm_auth_chain_get_data (chain, "callback"), + nm_auth_chain_get_data (chain, "callback_data")); +} + static void agent_secrets_done_cb (NMAgentManager *manager, guint32 call_id, + const char *agent_dbus_owner, const char *setting_name, + guint32 flags, GHashTable *secrets, GError *error, gpointer user_data, @@ -366,29 +572,100 @@ agent_secrets_done_cb (NMAgentManager *manager, NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionSecretsFunc callback = other_data2; gpointer callback_data = other_data3; + NMSettingConnection *s_con; GError *local = NULL; - GHashTable *hash; + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); if (error) { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request error: (%d) %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + error->code, + error->message ? error->message : "(unknown)"); + callback (self, call_id, setting_name, error, callback_data); return; } - /* Update the connection with the agent's secrets */ - nm_connection_clear_secrets (NM_CONNECTION (self)); - if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { - /* FIXME: if the agent's owner has "modify" permission, then agent - * supplied secrets should overwrite existing secrets, and those agent - * supplied secrets should get written back out to persistent storage. - */ - - hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); - nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local); - g_hash_table_destroy (hash); + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { + local = g_error_new (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, + "%s.%d - Connection didn't have requested setting '%s'.", + __FILE__, __LINE__, setting_name); + callback (self, call_id, setting_name, local, callback_data); + g_clear_error (&local); + return; } - callback (self, call_id, setting_name, local, callback_data); - g_clear_error (&local); + g_assert (secrets); + if (agent_dbus_owner) { + gboolean has_system = FALSE; + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets returned from agent %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + agent_dbus_owner); + + /* If the agent returned any system-owned secrets (initial connect and no + * secrets given when the connection was created, or something like that) + * make sure the agent's UID has the 'modify' permission before we use or + * save those system-owned secrets. If not, discard them and use the + * existing secrets, or fail the connection. + */ + for_each_secret (NM_CONNECTION (self), secrets, has_system_owned_secrets, &has_system); + if (has_system) { + if (flags == 0) { /* ie SECRETS_FLAG_NONE */ + /* No user interaction was allowed when requesting secrets; the + * agent is being bad. Remove system-owned secrets. + */ + for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) interaction forbidden but agent %s returned system secrets", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + agent_dbus_owner); + } else { + NMAuthChain *chain; + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent %s returned system secrets; checking for MODIFY", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + agent_dbus_owner); + + /* User interaction was allowed, check whether the agent's UID + * has the 'modify' privilege before using the system-owned + * secrets supplied by the agent. + */ + chain = nm_auth_chain_new_dbus_sender (priv->authority, + agent_dbus_owner, + agent_secrets_modify_auth_cb, + self); + g_assert (chain); + + nm_auth_chain_set_data (chain, "call-id", GUINT_TO_POINTER (call_id), NULL); + nm_auth_chain_set_data (chain, "setting-name", g_strdup (setting_name), g_free); + nm_auth_chain_set_data (chain, "secrets", g_hash_table_ref (secrets), (GDestroyNotify) g_hash_table_unref); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); + + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + priv->pending_auths = g_slist_append (priv->pending_auths, chain); + return; + } + } + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) existing secrets returned", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); + } + + get_secrets_done (self, call_id, setting_name, secrets, error, callback, callback_data); } /** @@ -421,6 +698,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, GError **error) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingConnection *s_con; GHashTable *existing_secrets; guint32 call_id = 0; @@ -460,6 +738,14 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, callback_data); g_hash_table_unref (existing_secrets); + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets requested flags 0x%X hint '%s'", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + flags, + hint); + return call_id; } @@ -468,6 +754,12 @@ nm_settings_connection_cancel_secrets (NMSettingsConnection *self, guint32 call_id) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + NMSettingConnection *s_con; + + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + nm_log_dbg (LOGD_SETTINGS, "(%s:%u) secrets canceled", + nm_setting_connection_get_uuid (s_con), + call_id); priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id); From dc78aa19c991d1f43e4eee70805d9a7ca2e8b95c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 16:17:10 -0600 Subject: [PATCH 207/264] wifi: don't need secrets if the connection says we don't --- src/nm-device-wifi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index da1068e8d..f2ab7aff4 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2711,6 +2711,7 @@ handle_auth_or_fail (NMDeviceWifi *self, guint32 tries; NMAccessPoint *ap; NMConnection *connection; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), NM_ACT_STAGE_RETURN_FAILURE); @@ -2744,10 +2745,11 @@ handle_auth_or_fail (NMDeviceWifi *self, nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self); g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries)); - } else { + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } else nm_log_warn (LOGD_DEVICE, "Cleared secrets, but setting didn't need any secrets."); - } - return NM_ACT_STAGE_RETURN_POSTPONE; + + return ret; } /* From 77239854f42deee38b9d5d3c0d48204ad1ee0279 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 16:19:15 -0600 Subject: [PATCH 208/264] agents: send system-owned secrets to the agent if it has 'modify' permission If we can authenticate the agent for 'modify' permission, then send any existing system secrets to it as the user has permission to change those secrets. This means the agent doesn't have to call GetSecrets() itself, which means simpler code on the agent side for a slight LoC hit in NM itself. This also moves the permissions checking into the NMAgentManager to check each agent, which is sub-optimal since now the agent manager has to do PolicyKit stuff, but hey that's life. Agents need secrets, and we do need to authenticate every agent before we send secrets to them, and the NMSettingsConnection doesn't know about individual agents at all. --- introspection/nm-secret-agent.xml | 5 +- src/settings/nm-agent-manager.c | 206 +++++++++++++++++---- src/settings/nm-agent-manager.h | 1 + src/settings/nm-settings-connection.c | 253 ++++++++------------------ 4 files changed, 251 insertions(+), 214 deletions(-) diff --git a/introspection/nm-secret-agent.xml b/introspection/nm-secret-agent.xml index 8a651dd66..9655c2b9d 100644 --- a/introspection/nm-secret-agent.xml +++ b/introspection/nm-secret-agent.xml @@ -18,7 +18,10 @@ Nested settings maps containing the connection for which - secrets are being requested. + secrets are being requested. This may contain system-owned + secrets if the agent has successfully authenticated to + modify system network settings and the GetSecrets request + flags allow user interaction. diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 9979c4e88..9f10dc7b4 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -32,6 +32,8 @@ #include "nm-secret-agent.h" #include "nm-manager-auth.h" #include "nm-dbus-glib-types.h" +#include "nm-polkit-helpers.h" +#include "nm-manager-auth.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -44,6 +46,7 @@ typedef struct { NMDBusManager *dbus_mgr; NMSessionMonitor *session_monitor; + PolkitAuthority *authority; /* Hashed by owner name, not identifier, since two agents in different * sessions can use the same identifier. @@ -323,6 +326,7 @@ done: typedef void (*RequestCompleteFunc) (Request *req, GHashTable *secrets, const char *agent_dbus_owner, + gboolean agent_has_modify, GError *error, gpointer user_data); typedef void (*RequestNextFunc) (Request *req); @@ -330,6 +334,8 @@ typedef void (*RequestCancelFunc) (Request *req); struct _Request { guint32 reqid; + PolkitAuthority *authority; + NMAuthChain *chain; NMConnection *connection; gboolean filter_by_uid; @@ -341,6 +347,7 @@ struct _Request { /* Current agent being asked for secrets */ NMSecretAgent *current; gconstpointer current_call_id; + gboolean current_has_modify; /* Stores the sorted list of NMSecretAgents which will be asked for secrets */ GSList *pending; @@ -370,6 +377,7 @@ static guint32 next_req_id = 1; static Request * request_new_get (NMConnection *connection, + PolkitAuthority *authority, gboolean filter_by_uid, gulong uid_filter, GHashTable *existing_secrets, @@ -390,6 +398,7 @@ request_new_get (NMConnection *connection, req = g_malloc0 (sizeof (Request)); req->reqid = next_req_id++; req->connection = g_object_ref (connection); + req->authority = g_object_ref (authority); req->filter_by_uid = filter_by_uid; req->uid_filter = uid_filter; if (existing_secrets) @@ -446,6 +455,9 @@ request_free (Request *req) g_free (req->hint); if (req->existing_secrets) g_hash_table_unref (req->existing_secrets); + if (req->chain) + nm_auth_chain_unref (req->chain); + g_object_unref (req->authority); memset (req, 0, sizeof (Request)); g_free (req); } @@ -552,6 +564,7 @@ request_remove_agent (Request *req, NMSecretAgent *agent) /* If this agent is being asked right now, cancel the request */ if (agent == req->current) { req->cancel_callback (req); + req->current_has_modify = FALSE; req->current = NULL; req->current_call_id = NULL; try_next = TRUE; @@ -583,10 +596,11 @@ next_generic (Request *req, const char *detail) error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, NM_AGENT_MANAGER_ERROR_NO_SECRETS, "No agents were available for this request."); - req->complete_callback (req, NULL, NULL, error, req->complete_callback_data); + req->complete_callback (req, NULL, NULL, FALSE, error, req->complete_callback_data); g_error_free (error); } else { /* Send a secrets request to the next agent */ + req->current_has_modify = FALSE; req->current = req->pending->data; req->pending = g_slist_remove (req->pending, req->current); @@ -622,18 +636,21 @@ get_done_cb (NMSecretAgent *agent, Request *req = user_data; GHashTable *setting_secrets; const char *agent_dbus_owner; + gboolean agent_has_modify; g_return_if_fail (call_id == req->current_call_id); + agent_has_modify = req->current_has_modify; + req->current_has_modify = FALSE; req->current = NULL; req->current_call_id = NULL; if (error) { nm_log_dbg (LOGD_AGENTS, "(%s) agent failed secrets request %p/%s: (%d) %s", - nm_secret_agent_get_description (agent), - req, req->setting_name, - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); /* Try the next agent */ req->next_callback (req); @@ -644,8 +661,8 @@ get_done_cb (NMSecretAgent *agent, setting_secrets = g_hash_table_lookup (secrets, req->setting_name); if (!setting_secrets || !g_hash_table_size (setting_secrets)) { nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s", - nm_secret_agent_get_description (agent), - req, req->setting_name); + nm_secret_agent_get_description (agent), + req, req->setting_name); /* Try the next agent */ req->next_callback (req); @@ -653,21 +670,25 @@ get_done_cb (NMSecretAgent *agent, } nm_log_dbg (LOGD_AGENTS, "(%s) agent returned secrets for request %p/%s", - nm_secret_agent_get_description (agent), - req, req->setting_name); + nm_secret_agent_get_description (agent), + req, req->setting_name); agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); - req->complete_callback (req, secrets, agent_dbus_owner, NULL, req->complete_callback_data); + req->complete_callback (req, secrets, agent_dbus_owner, agent_has_modify, NULL, req->complete_callback_data); } static void -get_next_cb (Request *req) +get_agent_request_secrets (Request *req, gboolean include_system_secrets) { - if (!next_generic (req, "getting")) - return; + NMConnection *tmp; + + tmp = nm_connection_duplicate (req->connection); + nm_connection_clear_secrets (tmp); + if (include_system_secrets) + nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL); req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), - req->connection, + tmp, req->setting_name, req->hint, req->flags, @@ -676,9 +697,103 @@ get_next_cb (Request *req) if (req->current_call_id == NULL) { /* Shouldn't hit this, but handle it anyway */ g_warn_if_fail (req->current_call_id != NULL); + req->current_has_modify = FALSE; req->current = NULL; req->next_callback (req); } + + g_object_unref (tmp); +} + +static void +get_agent_modify_auth_cb (NMAuthChain *chain, + GError *error, + DBusGMethodInvocation *context, + gpointer user_data) +{ + Request *req = user_data; + NMAuthCallResult result; + + req->chain = NULL; + nm_auth_chain_unref (chain); + + if (error) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check error: (%d) %s", + req, req->setting_name, + error->code, error->message ? error->message : "(unknown)"); + + /* Try the next agent */ + req->next_callback (req); + } else { + + /* If the agent obtained the 'modify' permission, we send all system secrets + * to it. If it didn't, we still ask it for secrets, but we don't send + * any system secrets. + */ + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + if (result == NM_AUTH_CALL_RESULT_YES) + req->current_has_modify = TRUE; + + nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check result %d", + req, req->setting_name, result); + + get_agent_request_secrets (req, req->current_has_modify); + } +} + +static void +has_system_secrets (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + gboolean *has_system = user_data; + + if (flags & NM_SETTING_PARAM_SECRET) { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) + *has_system = TRUE; + } +} + +static void +get_next_cb (Request *req) +{ + const char *agent_dbus_owner; + + if (!next_generic (req, "getting")) + return; + + agent_dbus_owner = nm_secret_agent_get_dbus_owner (NM_SECRET_AGENT (req->current)); + + if (req->flags != 0) { + gboolean has_system = FALSE; + + /* Interaction with the user is allowed; if there are any system secrets, + * check whether the agent has the 'modify' permission before sending those + * secrets to the agent. + */ + nm_connection_for_each_setting_value (req->connection, has_system_secrets, &has_system); + if (has_system) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY", + req, req->setting_name, agent_dbus_owner); + + req->chain = nm_auth_chain_new_dbus_sender (req->authority, + agent_dbus_owner, + get_agent_modify_auth_cb, + req); + g_assert (req->chain); + nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + return; + } + } + + nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s", + req, req->setting_name, agent_dbus_owner); + + get_agent_request_secrets (req, FALSE); } static gboolean @@ -706,20 +821,20 @@ get_start (gpointer user_data) g_assert (tmp); if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) { - req->complete_callback (req, NULL, NULL, error, req->complete_callback_data); + req->complete_callback (req, NULL, NULL, FALSE, error, req->complete_callback_data); g_clear_error (&error); } else { /* Do we have everything we need? */ /* FIXME: handle second check for VPN connections */ if (nm_connection_need_secrets (tmp, NULL) == NULL) { nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets sufficient", - req, req->setting_name); + req, req->setting_name); /* Got everything, we're done */ - req->complete_callback (req, req->existing_secrets, NULL, NULL, req->complete_callback_data); + req->complete_callback (req, req->existing_secrets, NULL, FALSE, NULL, req->complete_callback_data); } else { nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents", - req, req->setting_name); + req, req->setting_name); /* We don't, so ask some agents for additional secrets */ req->next_callback (req); @@ -741,6 +856,7 @@ static void get_complete_cb (Request *req, GHashTable *secrets, const char *agent_dbus_owner, + gboolean agent_has_modify, GError *error, gpointer user_data) { @@ -751,6 +867,7 @@ get_complete_cb (Request *req, req->callback (self, req->reqid, agent_dbus_owner, + agent_has_modify, req->setting_name, req->flags, error ? NULL : secrets, @@ -797,6 +914,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self, setting_name); req = request_new_get (connection, + priv->authority, filter_by_uid, uid_filter, existing_secrets, @@ -850,10 +968,10 @@ save_done_cb (NMSecretAgent *agent, if (error) { nm_log_dbg (LOGD_AGENTS, "(%s) agent failed save secrets request %p/%s: (%d) %s", - nm_secret_agent_get_description (agent), - req, req->setting_name, - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); /* Try the next agent */ req->next_callback (req); @@ -861,11 +979,11 @@ save_done_cb (NMSecretAgent *agent, } nm_log_dbg (LOGD_AGENTS, "(%s) agent saved secrets for request %p/%s", - nm_secret_agent_get_description (agent), - req, req->setting_name); + nm_secret_agent_get_description (agent), + req, req->setting_name); agent_dbus_owner = nm_secret_agent_get_dbus_owner (agent); - req->complete_callback (req, NULL, agent_dbus_owner, NULL, req->complete_callback_data); + req->complete_callback (req, NULL, agent_dbus_owner, FALSE, NULL, req->complete_callback_data); } static void @@ -890,6 +1008,7 @@ static void save_complete_cb (Request *req, GHashTable *secrets, const char *agent_dbus_owner, + gboolean agent_has_modify, GError *error, gpointer user_data) { @@ -949,14 +1068,14 @@ delete_done_cb (NMSecretAgent *agent, if (error) { nm_log_dbg (LOGD_AGENTS, "(%s) agent failed delete secrets request %p/%s: (%d) %s", - nm_secret_agent_get_description (agent), - req, req->setting_name, - error ? error->code : -1, - (error && error->message) ? error->message : "(unknown)"); + nm_secret_agent_get_description (agent), + req, req->setting_name, + error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); } else { nm_log_dbg (LOGD_AGENTS, "(%s) agent deleted secrets for request %p/%s", - nm_secret_agent_get_description (agent), - req, req->setting_name); + nm_secret_agent_get_description (agent), + req, req->setting_name); } /* Tell the next agent to delete secrets */ @@ -985,6 +1104,7 @@ static void delete_complete_cb (Request *req, GHashTable *secrets, const char *agent_dbus_owner, + gboolean agent_has_modify, GError *error, gpointer user_data) { @@ -1077,6 +1197,15 @@ static void nm_agent_manager_init (NMAgentManager *self) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); + GError *error = NULL; + + priv->authority = polkit_authority_get_sync (NULL, &error); + if (!priv->authority) { + nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); priv->requests = g_hash_table_new_full (g_direct_hash, @@ -1090,15 +1219,16 @@ dispose (GObject *object) { NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (object); - if (priv->disposed) - return; - priv->disposed = TRUE; + if (!priv->disposed) { + priv->disposed = TRUE; - g_object_unref (priv->session_monitor); - g_object_unref (priv->dbus_mgr); + g_hash_table_destroy (priv->agents); + g_hash_table_destroy (priv->requests); - g_hash_table_destroy (priv->agents); - g_hash_table_destroy (priv->requests); + g_object_unref (priv->session_monitor); + g_object_unref (priv->dbus_mgr); + g_object_unref (priv->authority); + } G_OBJECT_CLASS (nm_agent_manager_parent_class)->dispose (object); } diff --git a/src/settings/nm-agent-manager.h b/src/settings/nm-agent-manager.h index 6771f943a..5e5dca42f 100644 --- a/src/settings/nm-agent-manager.h +++ b/src/settings/nm-agent-manager.h @@ -48,6 +48,7 @@ NMAgentManager *nm_agent_manager_get (void); typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager, guint32 call_id, const char *agent_dbus_owner, + gboolean agent_has_modify, const char *setting_name, guint32 flags, GHashTable *secrets, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index d82bb4414..d3e1bada8 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -426,140 +426,11 @@ new_secrets_commit_cb (NMSettingsConnection *connection, } } -static void -get_secrets_done (NMSettingsConnection *self, - guint32 call_id, - const char *setting_name, - GHashTable *secrets, - GError *error, - NMSettingsConnectionSecretsFunc callback, - gpointer callback_data) -{ - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMSettingConnection *s_con; - GError *local = NULL; - GHashTable *hash = NULL; - - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - - if (error) { - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed; error: (%d) %s", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - error->code, - error->message ? error->message : "(unknown)"); - callback (self, call_id, setting_name, error, callback_data); - return; - } - - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed successfully", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id); - - /* Update the connection with our existing secrets from backing storage */ - nm_connection_clear_secrets (NM_CONNECTION (self)); - hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); - if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { - /* Update the connection with the agent's secrets; by this point if any - * system-owned secrets exist in 'secrets' the agent that provided them - * will have been authenticated, so those secrets can replace the existing - * system secrets. - */ - if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { - /* Now that all secrets are updated, copy and cache new secrets, - * then save them to backing storage. - */ - if (priv->secrets) - g_object_unref (priv->secrets); - priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); - - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id); - - nm_settings_connection_commit_changes (self, new_secrets_commit_cb, NULL); - } else { - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with agent secrets: (%d) %s", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - local->code, - local->message ? local->message : "(unknown)"); - } - } else { - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - local->code, - local->message ? local->message : "(unknown)"); - } - - callback (self, call_id, setting_name, local, callback_data); - g_clear_error (&local); - if (hash) - g_hash_table_destroy (hash); -} - -static void -agent_secrets_modify_auth_cb (NMAuthChain *chain, - GError *error, - DBusGMethodInvocation *context, - gpointer user_data) -{ - NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - NMSettingConnection *s_con; - NMAuthCallResult result; - GHashTable *secrets = nm_auth_chain_get_data (chain, "secrets"); - const char *setting_name = nm_auth_chain_get_data (chain, "setting-name"); - guint32 call_id = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "call-id")); - - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - - priv->pending_auths = g_slist_remove (priv->pending_auths, chain); - - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); - - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent MODIFY check result %d", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - result); - - if (result == NM_AUTH_CALL_RESULT_YES) { - /* Agent can modify system connections; system-owned secrets it returned - * replace any secrets in backing storage. - */ - } else { - /* Agent didn't successfully authenticate; clear system-owned secrets - * from the secrets the agent returned. - */ - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent failed to authenticate after providing system secrets", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id); - for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); - } - - get_secrets_done (self, - call_id, - setting_name, - secrets, - error, - nm_auth_chain_get_data (chain, "callback"), - nm_auth_chain_get_data (chain, "callback_data")); -} - static void agent_secrets_done_cb (NMAgentManager *manager, guint32 call_id, const char *agent_dbus_owner, + gboolean agent_has_modify, const char *setting_name, guint32 flags, GHashTable *secrets, @@ -574,17 +445,18 @@ agent_secrets_done_cb (NMAgentManager *manager, gpointer callback_data = other_data3; NMSettingConnection *s_con; GError *local = NULL; + GHashTable *hash; s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); g_assert (s_con); if (error) { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request error: (%d) %s", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - error->code, - error->message ? error->message : "(unknown)"); + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + error->code, + error->message ? error->message : "(unknown)"); callback (self, call_id, setting_name, error, callback_data); return; @@ -604,10 +476,10 @@ agent_secrets_done_cb (NMAgentManager *manager, gboolean has_system = FALSE; nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets returned from agent %s", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - agent_dbus_owner); + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + agent_dbus_owner); /* If the agent returned any system-owned secrets (initial connect and no * secrets given when the connection was created, or something like that) @@ -621,51 +493,81 @@ agent_secrets_done_cb (NMAgentManager *manager, /* No user interaction was allowed when requesting secrets; the * agent is being bad. Remove system-owned secrets. */ - for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) interaction forbidden but agent %s returned system secrets", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - agent_dbus_owner); - } else { - NMAuthChain *chain; + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + agent_dbus_owner); - nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent %s returned system secrets; checking for MODIFY", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id, - agent_dbus_owner); - - /* User interaction was allowed, check whether the agent's UID - * has the 'modify' privilege before using the system-owned - * secrets supplied by the agent. + for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); + } else if (agent_has_modify == FALSE) { + /* Agent didn't successfully authenticate; clear system-owned secrets + * from the secrets the agent returned. */ - chain = nm_auth_chain_new_dbus_sender (priv->authority, - agent_dbus_owner, - agent_secrets_modify_auth_cb, - self); - g_assert (chain); + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent failed to authenticate but provided system secrets", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); - nm_auth_chain_set_data (chain, "call-id", GUINT_TO_POINTER (call_id), NULL); - nm_auth_chain_set_data (chain, "setting-name", g_strdup (setting_name), g_free); - nm_auth_chain_set_data (chain, "secrets", g_hash_table_ref (secrets), (GDestroyNotify) g_hash_table_unref); - nm_auth_chain_set_data (chain, "callback", callback, NULL); - nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); - - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); - priv->pending_auths = g_slist_append (priv->pending_auths, chain); - return; + for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); } } } else { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) existing secrets returned", - nm_setting_connection_get_uuid (s_con), - setting_name, - call_id); + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); } - get_secrets_done (self, call_id, setting_name, secrets, error, callback, callback_data); + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); + + /* Update the connection with our existing secrets from backing storage */ + nm_connection_clear_secrets (NM_CONNECTION (self)); + hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { + /* Update the connection with the agent's secrets; by this point if any + * system-owned secrets exist in 'secrets' the agent that provided them + * will have been authenticated, so those secrets can replace the existing + * system secrets. + */ + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) { + /* Now that all secrets are updated, copy and cache new secrets, + * then save them to backing storage. + */ + if (priv->secrets) + g_object_unref (priv->secrets); + priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id); + + nm_settings_connection_commit_changes (self, new_secrets_commit_cb, NULL); + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with agent secrets: (%d) %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + local->code, + local->message ? local->message : "(unknown)"); + } + } else { + nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", + nm_setting_connection_get_uuid (s_con), + setting_name, + call_id, + local->code, + local->message ? local->message : "(unknown)"); + } + + callback (self, call_id, setting_name, local, callback_data); + g_clear_error (&local); + if (hash) + g_hash_table_destroy (hash); } /** @@ -1170,7 +1072,7 @@ nm_settings_connection_init (NMSettingsConnection *self) priv->dbus_mgr = nm_dbus_manager_get (); - priv->authority = polkit_authority_get_sync (NULL, NULL); + priv->authority = polkit_authority_get_sync (NULL, &error); if (!priv->authority) { nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s", error ? error->code : -1, @@ -1222,6 +1124,7 @@ dispose (GObject *object) g_object_unref (priv->session_monitor); g_object_unref (priv->agent_mgr); g_object_unref (priv->dbus_mgr); + g_object_unref (priv->authority); out: G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); From da47a2add479b8e3a12972cbf52cc55da1a4aa97 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 16:50:58 -0600 Subject: [PATCH 209/264] ifcfg-rh: recognize WEP connections even if they dont have WEP keys yet Just because the key isn't saved (ie, the user hasn't entered it yet, or the user want to type it in every time) doesn't mean the setting isn't WEP, so recognize it as WEP if DEFAULTKEY or SECURITYMODE is set. --- system-settings/plugins/ifcfg-rh/reader.c | 19 +-- .../tests/network-scripts/Makefile.am | 3 +- .../ifcfg-test-wifi-wep-no-keys | 18 +++ .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 124 ++++++++++++++++++ system-settings/plugins/ifcfg-rh/writer.c | 7 + 5 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 141deb8d2..812955a7d 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -1697,6 +1697,7 @@ make_wep_setting (shvarFile *ifcfg, char *value; shvarFile *keys_ifcfg = NULL; int default_key_idx = 0; + gboolean has_default_key = FALSE; s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none", NULL); @@ -1707,6 +1708,7 @@ make_wep_setting (shvarFile *ifcfg, success = get_int (value, &default_key_idx); if (success && (default_key_idx >= 1) && (default_key_idx <= 4)) { + has_default_key = TRUE; default_key_idx--; /* convert to [0...3] */ g_object_set (s_wireless_sec, NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, default_key_idx, NULL); } else { @@ -1733,21 +1735,6 @@ make_wep_setting (shvarFile *ifcfg, g_assert (error == NULL || *error == NULL); } - /* If there's a default key, ensure that key exists */ - if ((default_key_idx == 1) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Default WEP key index was 2, but no valid KEY2 exists."); - goto error; - } else if ((default_key_idx == 2) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Default WEP key index was 3, but no valid KEY3 exists."); - goto error; - } else if ((default_key_idx == 3) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3)) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Default WEP key index was 4, but no valid KEY4 exists."); - goto error; - } - value = svGetValue (ifcfg, "SECURITYMODE", FALSE); if (value) { char *lcase; @@ -1773,7 +1760,7 @@ make_wep_setting (shvarFile *ifcfg, && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 1) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 2) && !nm_setting_wireless_security_get_wep_key (s_wireless_sec, 3) - && !nm_setting_wireless_security_get_wep_tx_keyidx (s_wireless_sec)) { + && (has_default_key == FALSE)) { const char *auth_alg; auth_alg = nm_setting_wireless_security_get_auth_alg (s_wireless_sec); diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 28cfb98f3..44c0099fc 100644 --- a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -69,7 +69,8 @@ EXTRA_DIST = \ ifcfg-test-wired-qeth-static \ ifcfg-test-bridge-main \ ifcfg-test-bridge-component \ - ifcfg-test-vlan-interface + ifcfg-test-vlan-interface \ + ifcfg-test-wifi-wep-no-keys check-local: @for f in $(EXTRA_DIST); do \ diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys new file mode 100644 index 000000000..cb4da43f7 --- /dev/null +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-wifi-wep-no-keys @@ -0,0 +1,18 @@ +ESSID="foobar" +MODE=Managed +TYPE=Wireless +BOOTPROTO=dhcp +DEFROUTE=yes +IPV4_FAILURE_FATAL=yes +IPV6INIT=yes +IPV6_AUTOCONF=yes +IPV6_DEFROUTE=yes +IPV6_FAILURE_FATAL=no +UUID=9c4637bd-7600-40cc-9c24-13819c5bf5dd +ONBOOT=yes +HWADDR=00:16:BB:AA:CC:DD +DEFAULTKEY=1 +PEERDNS=yes +PEERROUTES=yes +IPV6_PEERDNS=yes +IPV6_PEERROUTES=yes diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 1945fb99c..503498079 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5621,6 +5621,129 @@ test_read_wired_qeth_static (void) g_object_unref (connection); } +#define TEST_IFCFG_WIFI_WEP_NO_KEYS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-wep-no-keys" + +static void +test_read_wifi_wep_no_keys (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wireless; + NMSettingWirelessSecurity *s_wsec; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + GError *error = NULL; + const char *tmp; + const char *expected_id = "System foobar (test-wifi-wep-no-keys)"; + NMWepKeyType key_type; + + connection = connection_from_file (TEST_IFCFG_WIFI_WEP_NO_KEYS, + NULL, + TYPE_WIRELESS, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "wifi-wep-no-keys-read", "failed to read %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "wifi-wep-no-keys-verify", "failed to verify %s: %s", TEST_IFCFG_WIFI_WEP_NO_KEYS, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_CONNECTION_SETTING_NAME); + + /* ID */ + tmp = nm_setting_connection_get_id (s_con); + ASSERT (tmp != NULL, + "wifi-wep-no-keys-verify-connection", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + ASSERT (strcmp (tmp, expected_id) == 0, + "wifi-wep-no-keys-verify-connection", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_ID); + + /* UUID can't be tested if the ifcfg does not contain the UUID key, because + * the UUID is generated on the full path of the ifcfg file, which can change + * depending on where the tests are run. + */ + + /* ===== WIRELESS SETTING ===== */ + + s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); + ASSERT (s_wireless != NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SETTING_NAME); + + /* Security */ + tmp = nm_setting_wireless_get_security (s_wireless); + ASSERT (tmp != NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + ASSERT (strcmp (tmp, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SETTING_NAME, + NM_SETTING_WIRELESS_SEC); + + + /* ===== WIRELESS SECURITY SETTING ===== */ + + s_wsec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY)); + ASSERT (s_wsec != NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s setting", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + + /* Key management */ + ASSERT (strcmp (nm_setting_wireless_security_get_key_mgmt (s_wsec), "none") == 0, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT); + + /* WEP key index */ + ASSERT (nm_setting_wireless_security_get_wep_tx_keyidx (s_wsec) == 0, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected %s / %s key value", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX); + + /* WEP key type */ + key_type = nm_setting_wireless_security_get_wep_key_type (s_wsec); + ASSERT (key_type == NM_WEP_KEY_TYPE_UNKNOWN || key_type == NM_WEP_KEY_TYPE_KEY, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: unexpected WEP key type %d", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + key_type); + + /* WEP key index 0; we don't expect it to be filled */ + tmp = nm_setting_wireless_security_get_wep_key (s_wsec, 0); + ASSERT (tmp == NULL, + "wifi-wep-no-keys-verify-wireless", "failed to verify %s: missing %s / %s key", + TEST_IFCFG_WIFI_WEP_NO_KEYS, + NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, + NM_SETTING_WIRELESS_SECURITY_WEP_KEY0); + + g_object_unref (connection); +} + static void test_write_wired_static (void) { @@ -9537,6 +9660,7 @@ int main (int argc, char **argv) test_read_wifi_wpa_eap_ttls_tls (); test_read_wifi_wep_eap_ttls_chap (); test_read_wired_qeth_static (); + test_read_wifi_wep_no_keys (); test_write_wired_static (); test_write_wired_static_ip6_only (); diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index c8ef7e0ab..f7335e0bc 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -850,6 +850,13 @@ write_wireless_setting (NMConnection *connection, g_free (tmp); } + /* Ensure DEFAULTKEY and SECURITYMODE are cleared unless there's security; + * otherwise there's no way to detect WEP vs. open when WEP keys aren't + * saved. + */ + svSetValue (ifcfg, "DEFAULTKEY", NULL, FALSE); + svSetValue (ifcfg, "SECURITYMODE", NULL, FALSE); + if (nm_setting_wireless_get_security (s_wireless)) { if (!write_wireless_security_setting (connection, ifcfg, adhoc, no_8021x, error)) return FALSE; From c36c81e2b9981f9483ed75427b00cf1347de583e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 17:18:50 -0600 Subject: [PATCH 210/264] libnm-util: fix updating secrets Broken by 5dd4f1ea018b64ba7a91ff2ec024ddc9f8f809fc --- libnm-util/nm-connection.c | 23 +++++++++++++++++------ libnm-util/nm-setting.c | 9 ++++++--- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index db4ebd783..2415edf92 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -664,28 +664,39 @@ nm_connection_verify (NMConnection *connection, GError **error) gboolean nm_connection_update_secrets (NMConnection *connection, const char *setting_name, - GHashTable *secrets, + GHashTable *all_secrets, GError **error) { NMSetting *setting; gboolean success; + GHashTable *setting_secrets; g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (setting_name != NULL, FALSE); - g_return_val_if_fail (secrets != NULL, FALSE); + g_return_val_if_fail (all_secrets != NULL, FALSE); if (error) g_return_val_if_fail (*error == NULL, FALSE); setting = nm_connection_get_setting (connection, nm_connection_lookup_setting_type (setting_name)); if (!setting) { - g_set_error (error, NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, - "%s", setting_name); + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, + setting_name); return FALSE; } - success = nm_setting_update_secrets (setting, secrets, error); + setting_secrets = g_hash_table_lookup (all_secrets, setting_name); + if (!setting_secrets) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_CONNECTION_SETTING_NOT_FOUND, + setting_name); + return FALSE; + } + + success = nm_setting_update_secrets (setting, setting_secrets, error); if (success) g_signal_emit (connection, signals[SECRETS_UPDATED], 0, setting_name); return success; diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index ea02275f9..94138d0ad 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -559,15 +559,18 @@ nm_setting_update_secrets (NMSetting *setting, GHashTable *secrets, GError **err g_return_val_if_fail (*error == NULL, FALSE); g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, &key, &data) && !tmp_error) { + while (g_hash_table_iter_next (&iter, &key, &data)) { const char *secret_key = (const char *) key; GValue *secret_value = (GValue *) data; NM_SETTING_GET_CLASS (setting)->update_one_secret (setting, secret_key, secret_value, &tmp_error); + if (tmp_error) { + g_propagate_error (error, tmp_error); + break; + } } - g_propagate_error (error, tmp_error); - return !!tmp_error; + return tmp_error ? FALSE : TRUE; } static gboolean From a5103bf234b876d6e20aabf8e6966c2968deee55 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 17:25:56 -0600 Subject: [PATCH 211/264] libnm-util: silently ignore non-secrets when updating connection secrets --- libnm-util/nm-setting.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 94138d0ad..f0809f0d1 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -508,13 +508,9 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** return FALSE; } - if (!(prop_spec->flags & NM_SETTING_PARAM_SECRET)) { - g_set_error (error, - NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_NOT_SECRET, - "%s", key); - return FALSE; - } + /* Silently ignore non-secrets */ + if (!(prop_spec->flags & NM_SETTING_PARAM_SECRET)) + return TRUE; if (g_value_type_compatible (G_VALUE_TYPE (value), G_PARAM_SPEC_VALUE_TYPE (prop_spec))) { g_object_set_property (G_OBJECT (setting), prop_spec->name, value); From 2e0fb2ae4eafe0c4f396e49cb213657a9a6b9aee Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 19:32:30 -0600 Subject: [PATCH 212/264] libnm-util: private keys are now required for TLS connections to verify Since private keys are no longer secret, they must be given in the connection itself. --- libnm-util/nm-setting-8021x.c | 44 +++++--- libnm-util/tests/test-need-secrets.c | 148 ++------------------------- 2 files changed, 40 insertions(+), 152 deletions(-) diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index 341b60a53..7e32937f9 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -1847,11 +1847,6 @@ need_secrets_tls (NMSetting8021x *self, const char *path = NULL; if (phase2) { - if (!priv->phase2_private_key || !priv->phase2_private_key->len) { - g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); - return; - } - scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) path = nm_setting_802_1x_get_phase2_private_key_path (self); @@ -1866,11 +1861,6 @@ need_secrets_tls (NMSetting8021x *self, if (need_private_key_password (blob, path, priv->phase2_private_key_password)) g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); } else { - if (!priv->private_key || !priv->private_key->len) { - g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY); - return; - } - scheme = nm_setting_802_1x_get_private_key_scheme (self); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) path = nm_setting_802_1x_get_private_key_path (self); @@ -1907,8 +1897,23 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error) return FALSE; } + /* Private key is required for TLS */ + if (!priv->phase2_private_key) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } else if (!priv->phase2_private_key->len) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); + return FALSE; + } + /* If the private key is PKCS#12, check that it matches the client cert */ - if (priv->phase2_private_key && crypto_is_pkcs12_data (priv->phase2_private_key)) { + if (crypto_is_pkcs12_data (priv->phase2_private_key)) { if (priv->phase2_private_key->len != priv->phase2_client_cert->len) { g_set_error (error, NM_SETTING_802_1X_ERROR, @@ -1942,8 +1947,23 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error) return FALSE; } + /* Private key is required for TLS */ + if (!priv->private_key) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_MISSING_PROPERTY, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } else if (!priv->private_key->len) { + g_set_error (error, + NM_SETTING_802_1X_ERROR, + NM_SETTING_802_1X_ERROR_INVALID_PROPERTY, + NM_SETTING_802_1X_PRIVATE_KEY); + return FALSE; + } + /* If the private key is PKCS#12, check that it matches the client cert */ - if (priv->private_key && crypto_is_pkcs12_data (priv->private_key)) { + if (crypto_is_pkcs12_data (priv->private_key)) { if (priv->private_key->len != priv->client_cert->len) { g_set_error (error, NM_SETTING_802_1X_ERROR, diff --git a/libnm-util/tests/test-need-secrets.c b/libnm-util/tests/test-need-secrets.c index 517e2e01d..0c2634ea5 100644 --- a/libnm-util/tests/test-need-secrets.c +++ b/libnm-util/tests/test-need-secrets.c @@ -154,7 +154,6 @@ test_need_tls_secrets_path (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_connection ("need-tls-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); ASSERT (connection != NULL, @@ -170,41 +169,9 @@ test_need_tls_secrets_path (void) "need-tls-secrets-path-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then required */ + /* Connection is good; clear secrets and ensure private key password is then required */ nm_connection_clear_secrets (connection); - hints = NULL; - setting_name = nm_connection_need_secrets (connection, &hints); - ASSERT (setting_name != NULL, - "need-tls-secrets-path-key", - "unexpected secrets success"); - ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, - "need-tls-secrets-path-key", - "unexpected setting secrets required"); - - ASSERT (hints != NULL, - "need-tls-secrets-path-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY), - "need-tls-secrets-path-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_connection ("need-tls-secrets-path-key-password", NM_SETTING_802_1X_CK_SCHEME_PATH); - ASSERT (connection != NULL, - "need-tls-secrets-path-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-secrets-path-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); - hints = NULL; setting_name = nm_connection_need_secrets (connection, &hints); ASSERT (setting_name != NULL, @@ -230,7 +197,6 @@ test_need_tls_secrets_blob (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_connection ("need-tls-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); ASSERT (connection != NULL, @@ -246,42 +212,11 @@ test_need_tls_secrets_blob (void) "need-tls-secrets-blob-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then required */ + /* Connection is good; clear secrets and ensure private key password is not + * required because our blob is decrypted. + */ nm_connection_clear_secrets (connection); - hints = NULL; - setting_name = nm_connection_need_secrets (connection, &hints); - ASSERT (setting_name != NULL, - "need-tls-secrets-blob-key", - "unexpected secrets success"); - ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, - "need-tls-secrets-blob-key", - "unexpected setting secrets required"); - - ASSERT (hints != NULL, - "need-tls-secrets-blob-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PRIVATE_KEY), - "need-tls-secrets-blob-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_connection ("need-tls-secrets-blob-key-password", NM_SETTING_802_1X_CK_SCHEME_BLOB); - ASSERT (connection != NULL, - "need-tls-secrets-blob-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-secrets-blob-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD, NULL, NULL); - - /* Blobs are already decrypted and don't need a password */ hints = NULL; setting_name = nm_connection_need_secrets (connection, &hints); ASSERT (setting_name == NULL, @@ -396,7 +331,6 @@ test_need_tls_phase2_secrets_path (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key", NM_SETTING_802_1X_CK_SCHEME_PATH); @@ -413,42 +347,9 @@ test_need_tls_phase2_secrets_path (void) "need-tls-phase2-secrets-path-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then required */ + /* Connection is good; clear secrets and ensure private key password is then required */ nm_connection_clear_secrets (connection); - hints = NULL; - setting_name = nm_connection_need_secrets (connection, &hints); - ASSERT (setting_name != NULL, - "need-tls-phase2-secrets-path-key", - "unexpected secrets success"); - ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, - "need-tls-phase2-secrets-path-key", - "unexpected setting secrets required"); - - ASSERT (hints != NULL, - "need-tls-phase2-secrets-path-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), - "need-tls-phase2-secrets-path-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_phase2_connection ("need-tls-phase2-secrets-path-key-password", - NM_SETTING_802_1X_CK_SCHEME_PATH); - ASSERT (connection != NULL, - "need-tls-phase2-secrets-path-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-phase2-secrets-path-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, NULL, NULL); - hints = NULL; setting_name = nm_connection_need_secrets (connection, &hints); ASSERT (setting_name != NULL, @@ -474,7 +375,6 @@ test_need_tls_phase2_secrets_blob (void) NMConnection *connection; const char *setting_name; GPtrArray *hints = NULL; - NMSetting8021x *s_8021x; connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key", NM_SETTING_802_1X_CK_SCHEME_BLOB); @@ -491,43 +391,11 @@ test_need_tls_phase2_secrets_blob (void) "need-tls-phase2-secrets-blob-key", "hints should be NULL since no secrets were required"); - /* Connection is good; clear secrets and ensure private key is then required */ + /* Connection is good; clear secrets and ensure private key password is not + * required because our blob is decrypted. + */ nm_connection_clear_secrets (connection); - hints = NULL; - setting_name = nm_connection_need_secrets (connection, &hints); - ASSERT (setting_name != NULL, - "need-tls-phase2-secrets-blob-key", - "unexpected secrets success"); - ASSERT (strcmp (setting_name, NM_SETTING_802_1X_SETTING_NAME) == 0, - "need-tls-phase2-secrets-blob-key", - "unexpected setting secrets required"); - - ASSERT (hints != NULL, - "need-tls-phase2-secrets-blob-key", - "expected returned secrets hints"); - ASSERT (find_hints_item (hints, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY), - "need-tls-phase2-secrets-blob-key", - "expected to require private key, but it wasn't"); - - g_object_unref (connection); - - /*** Just clear the private key this time ***/ - - connection = make_tls_phase2_connection ("need-tls-phase2-secrets-blob-key-password", - NM_SETTING_802_1X_CK_SCHEME_BLOB); - ASSERT (connection != NULL, - "need-tls-phase2-secrets-blob-key-password", - "error creating test connection"); - - s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X); - ASSERT (s_8021x != NULL, - "need-tls-phase2-secrets-blob-key-password", - "error getting test 802.1x setting"); - - g_object_set (G_OBJECT (s_8021x), NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD, NULL, NULL); - - /* Blobs are already decrypted and don't need a password */ hints = NULL; setting_name = nm_connection_need_secrets (connection, &hints); ASSERT (setting_name == NULL, From e2d297e5ff2a93ad6032dbb21ef7b54e3c41ddb8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 20:32:15 -0600 Subject: [PATCH 213/264] settings: fix loading of keyfile connections Updating unmanaged specs may cause load_connections() to be called, and the keyfile plugin needs to be registered before that. --- src/settings/nm-settings.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index e47b89fb4..b28ae36dd 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1357,7 +1357,6 @@ nm_settings_new (const char *config_file, g_object_unref (self); return NULL; } - unmanaged_specs_changed (NULL, self); } /* Add the keyfile plugin last */ @@ -1365,6 +1364,8 @@ nm_settings_new (const char *config_file, g_assert (keyfile_plugin); add_plugin (self, NM_SYSTEM_CONFIG_INTERFACE (keyfile_plugin)); + unmanaged_specs_changed (NULL, self); + dbus_g_connection_register_g_object (priv->bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (self)); return self; } From 0ba142690ad5d40d188a9f4f4b4087808e4cd44c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 2 Feb 2011 21:39:03 -0600 Subject: [PATCH 214/264] build: make sure nm-secret-agent.xml gets into the tarball --- introspection/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 8b4302b21..6cf8dc606 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -26,5 +26,6 @@ EXTRA_DIST = \ nm-dhcp4-config.xml \ nm-dhcp6-config.xml \ nm-agent-manager.xml \ - nm-wimax-nsp.xml + nm-wimax-nsp.xml \ + nm-secret-agent.xml From 382cdfaf1ef186b22c4e4bb399e1190328dd9144 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 4 Feb 2011 15:59:45 -0600 Subject: [PATCH 215/264] keyfile: namespace potentially conflicting symbols Just in case. --- .../plugins/keyfile/nm-keyfile-connection.c | 4 ++-- system-settings/plugins/keyfile/plugin.c | 6 +++--- .../plugins/keyfile/tests/test-keyfile.c | 12 +++++------ system-settings/plugins/keyfile/utils.c | 2 +- system-settings/plugins/keyfile/utils.h | 2 +- system-settings/plugins/keyfile/writer.c | 20 +++++++++---------- system-settings/plugins/keyfile/writer.h | 16 +++++++-------- 7 files changed, 30 insertions(+), 32 deletions(-) diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 2e9aa0fb5..9dd2c750d 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -85,7 +85,7 @@ nm_keyfile_connection_new (const char *full_path, g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL); g_free (uuid); - if (!write_connection (NM_CONNECTION (object), KEYFILE_DIR, 0, 0, NULL, &write_error)) { + if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (object), KEYFILE_DIR, 0, 0, NULL, &write_error)) { PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Couldn't update connection %s with a UUID: (%d) %s", nm_setting_connection_get_id (s_con), @@ -117,7 +117,7 @@ commit_changes (NMSettingsConnection *connection, char *path = NULL; GError *error = NULL; - if (!write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &path, &error)) { + if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &path, &error)) { callback (connection, error, user_data); g_clear_error (&error); return; diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 819b80971..ec37ed311 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -127,7 +127,7 @@ read_connections (NMSystemConfigInterface *config) NMSettingsConnection *connection; char *full_path; - if (utils_should_ignore_file (item)) + if (nm_keyfile_plugin_utils_should_ignore_file (item)) continue; full_path = g_build_filename (KEYFILE_DIR, item, NULL); @@ -224,7 +224,7 @@ dir_changed (GFileMonitor *monitor, GError *error = NULL; full_path = g_file_get_path (file); - if (utils_should_ignore_file (full_path)) { + if (nm_keyfile_plugin_utils_should_ignore_file (full_path)) { g_free (full_path); return; } @@ -416,7 +416,7 @@ add_connection (NMSystemConfigInterface *config, char *path = NULL; /* Write it out first, then add the connection to our internal list */ - if (write_connection (connection, KEYFILE_DIR, 0, 0, &path, error)) { + if (nm_keyfile_plugin_write_connection (connection, KEYFILE_DIR, 0, 0, &path, error)) { added = _internal_new_connection (self, path, connection, NULL, error); g_free (path); } diff --git a/system-settings/plugins/keyfile/tests/test-keyfile.c b/system-settings/plugins/keyfile/tests/test-keyfile.c index 213d3e87f..e79c8a330 100644 --- a/system-settings/plugins/keyfile/tests/test-keyfile.c +++ b/system-settings/plugins/keyfile/tests/test-keyfile.c @@ -693,7 +693,7 @@ test_write_wired_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -953,7 +953,7 @@ test_write_ip6_wired_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1271,7 +1271,7 @@ test_write_wireless_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1401,7 +1401,7 @@ test_write_string_ssid (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1699,7 +1699,7 @@ test_write_bt_dun_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1961,7 +1961,7 @@ test_write_gsm_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); diff --git a/system-settings/plugins/keyfile/utils.c b/system-settings/plugins/keyfile/utils.c index de64f7913..c7cdc6310 100644 --- a/system-settings/plugins/keyfile/utils.c +++ b/system-settings/plugins/keyfile/utils.c @@ -75,7 +75,7 @@ check_suffix (const char *base, const char *tag) } gboolean -utils_should_ignore_file (const char *filename) +nm_keyfile_plugin_utils_should_ignore_file (const char *filename) { char *base; gboolean ignore = FALSE; diff --git a/system-settings/plugins/keyfile/utils.h b/system-settings/plugins/keyfile/utils.h index 3c1a6104b..68e6e56f2 100644 --- a/system-settings/plugins/keyfile/utils.h +++ b/system-settings/plugins/keyfile/utils.h @@ -24,7 +24,7 @@ #include #include "common.h" -gboolean utils_should_ignore_file (const char *filename); +gboolean nm_keyfile_plugin_utils_should_ignore_file (const char *filename); #endif /* _UTILS_H_ */ diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 550405f95..0574f90a3 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #include @@ -667,8 +667,8 @@ write_setting_value (NMSetting *setting, } } -char * -writer_id_to_filename (const char *id) +static char * +_writer_id_to_filename (const char *id) { char *filename, *f; const char *i = id; @@ -688,12 +688,12 @@ writer_id_to_filename (const char *id) } gboolean -write_connection (NMConnection *connection, - const char *keyfile_dir, - uid_t owner_uid, - pid_t owner_grp, - char **out_path, - GError **error) +nm_keyfile_plugin_write_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char **out_path, + GError **error) { NMSettingConnection *s_con; GKeyFile *key_file; @@ -716,7 +716,7 @@ write_connection (NMConnection *connection, if (!data) goto out; - filename = writer_id_to_filename (nm_setting_connection_get_id (s_con)); + filename = _writer_id_to_filename (nm_setting_connection_get_id (s_con)); path = g_build_filename (keyfile_dir, filename, NULL); g_free (filename); diff --git a/system-settings/plugins/keyfile/writer.h b/system-settings/plugins/keyfile/writer.h index fa04deef9..730a9b3bd 100644 --- a/system-settings/plugins/keyfile/writer.h +++ b/system-settings/plugins/keyfile/writer.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #ifndef _KEYFILE_PLUGIN_WRITER_H @@ -26,13 +26,11 @@ #include #include -gboolean write_connection (NMConnection *connection, - const char *keyfile_dir, - uid_t owner_uid, - pid_t owner_grp, - char **out_path, - GError **error); - -char *writer_id_to_filename (const char *id); +gboolean nm_keyfile_plugin_write_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char **out_path, + GError **error); #endif /* _KEYFILE_PLUGIN_WRITER_H */ From 899b8a40dc707211b991419f91ea2abf1d5080ed Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 6 Feb 2011 23:37:39 -0600 Subject: [PATCH 216/264] libnm-util: NM_SETTING_SECRET_FLAG_SYSTEM_OWNED -> NM_SETTING_SECRET_FLAG_NONE Make it a bit clearer that this value is not actually a value that can be used as a flag, since its 0x00. --- libnm-util/nm-setting-8021x.c | 20 ++++++++++---------- libnm-util/nm-setting-cdma.c | 6 +++--- libnm-util/nm-setting-gsm.c | 12 ++++++------ libnm-util/nm-setting-pppoe.c | 6 +++--- libnm-util/nm-setting-private.h | 2 +- libnm-util/nm-setting-vpn.c | 2 +- libnm-util/nm-setting-wireless-security.c | 18 +++++++++--------- libnm-util/nm-setting.c | 4 ++-- libnm-util/nm-setting.h | 6 +++--- src/settings/nm-agent-manager.c | 4 ++-- src/settings/nm-settings-connection.c | 18 +++++++++--------- system-settings/plugins/ifcfg-rh/writer.c | 14 +++++++------- system-settings/plugins/keyfile/writer.c | 4 ++-- 13 files changed, 58 insertions(+), 58 deletions(-) diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c index 7e32937f9..cb1c95116 100644 --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -1149,7 +1149,7 @@ nm_setting_802_1x_get_password (NMSetting8021x *setting) NMSettingSecretFlags nm_setting_802_1x_get_password_flags (NMSetting8021x *setting) { - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_802_1X_GET_PRIVATE (setting)->password_flags; } @@ -1179,7 +1179,7 @@ nm_setting_802_1x_get_pin (NMSetting8021x *setting) NMSettingSecretFlags nm_setting_802_1x_get_pin_flags (NMSetting8021x *setting) { - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_802_1X_GET_PRIVATE (setting)->pin_flags; } @@ -1434,7 +1434,7 @@ nm_setting_802_1x_get_private_key_password (NMSetting8021x *setting) NMSettingSecretFlags nm_setting_802_1x_get_private_key_password_flags (NMSetting8021x *setting) { - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_802_1X_GET_PRIVATE (setting)->private_key_password_flags; } @@ -1508,7 +1508,7 @@ nm_setting_802_1x_get_phase2_private_key_password (NMSetting8021x *setting) NMSettingSecretFlags nm_setting_802_1x_get_phase2_private_key_password_flags (NMSetting8021x *setting) { - g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_private_key_password_flags; } @@ -2975,9 +2975,9 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) g_param_spec_uint (NM_SETTING_802_1X_PASSWORD_FLAGS, "Password Flags", "Flags indicating how to handle the 802.1x password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** @@ -3059,9 +3059,9 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Private Key Password Flags", "Flags indicating how to handle the 802.1x private " "key password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** @@ -3141,9 +3141,9 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class) "Phase2 Private Key Password Flags", "Flags indicating how to handle the 802.1x phase2 " "private key password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index 1fd800d8b..4e70f1b1b 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -165,7 +165,7 @@ nm_setting_cdma_get_password (NMSettingCdma *setting) NMSettingSecretFlags nm_setting_cdma_get_password_flags (NMSettingCdma *setting) { - g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_CDMA (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_CDMA_GET_PRIVATE (setting)->password_flags; } @@ -393,8 +393,8 @@ nm_setting_cdma_class_init (NMSettingCdmaClass *setting_class) g_param_spec_uint (NM_SETTING_CDMA_PASSWORD_FLAGS, "Password Flags", "Flags indicating how to handle the CDMA password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index f0bdfee83..55369dd7f 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -152,7 +152,7 @@ nm_setting_gsm_get_password (NMSettingGsm *setting) NMSettingSecretFlags nm_setting_gsm_get_password_flags (NMSettingGsm *setting) { - g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_GSM_GET_PRIVATE (setting)->password_flags; } @@ -206,7 +206,7 @@ nm_setting_gsm_get_pin (NMSettingGsm *setting) NMSettingSecretFlags nm_setting_gsm_get_pin_flags (NMSettingGsm *setting) { - g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_GSM (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_GSM_GET_PRIVATE (setting)->pin_flags; } @@ -540,9 +540,9 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) g_param_spec_uint (NM_SETTING_GSM_PASSWORD_FLAGS, "Password Flags", "Flags indicating how to handle the GSM password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** @@ -673,9 +673,9 @@ nm_setting_gsm_class_init (NMSettingGsmClass *setting_class) g_param_spec_uint (NM_SETTING_GSM_PIN_FLAGS, "PIN Flags", "Flags indicating how to handle the GSM SIM PIN.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index ee82d8e50..7d471b0b4 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -124,7 +124,7 @@ nm_setting_pppoe_get_password (NMSettingPPPOE *setting) NMSettingSecretFlags nm_setting_pppoe_get_password_flags (NMSettingPPPOE *setting) { - g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_PPPOE (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_PPPOE_GET_PRIVATE (setting)->password_flags; } @@ -304,8 +304,8 @@ nm_setting_pppoe_class_init (NMSettingPPPOEClass *setting_class) g_param_spec_uint (NM_SETTING_PPPOE_PASSWORD_FLAGS, "Password Flags", "Flags indicating how to handle the PPPoE password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); } diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h index 0c1b0e7a0..ea43f7752 100644 --- a/libnm-util/nm-setting-private.h +++ b/libnm-util/nm-setting-private.h @@ -22,7 +22,7 @@ #define NM_SETTING_PRIVATE_H #define NM_SETTING_SECRET_FLAGS_ALL \ - (NM_SETTING_SECRET_FLAG_SYSTEM_OWNED | \ + (NM_SETTING_SECRET_FLAG_NONE | \ NM_SETTING_SECRET_FLAG_AGENT_OWNED | \ NM_SETTING_SECRET_FLAG_NOT_SAVED) diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 3b33f3c8a..a8b6cc755 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -18,7 +18,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2008 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ diff --git a/libnm-util/nm-setting-wireless-security.c b/libnm-util/nm-setting-wireless-security.c index a0ffddddd..3b4eba6f7 100644 --- a/libnm-util/nm-setting-wireless-security.c +++ b/libnm-util/nm-setting-wireless-security.c @@ -366,7 +366,7 @@ nm_setting_wireless_security_get_psk (NMSettingWirelessSecurity *setting) NMSettingSecretFlags nm_setting_wireless_security_get_psk_flags (NMSettingWirelessSecurity *setting) { - g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->psk_flags; } @@ -397,7 +397,7 @@ nm_setting_wireless_security_get_leap_password (NMSettingWirelessSecurity *setti NMSettingSecretFlags nm_setting_wireless_security_get_leap_password_flags (NMSettingWirelessSecurity *setting) { - g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->leap_password_flags; } @@ -480,7 +480,7 @@ nm_setting_wireless_security_get_auth_alg (NMSettingWirelessSecurity *setting) NMSettingSecretFlags nm_setting_wireless_security_get_wep_key_flags (NMSettingWirelessSecurity *setting) { - g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_SYSTEM_OWNED); + g_return_val_if_fail (NM_IS_SETTING_WIRELESS_SECURITY (setting), NM_SETTING_SECRET_FLAG_NONE); return NM_SETTING_WIRELESS_SECURITY_GET_PRIVATE (setting)->wep_key_flags; } @@ -1277,9 +1277,9 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, "WEP Key Flags", "Flags indicating how to handle the WEP keys.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** @@ -1316,9 +1316,9 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, "PSK Flags", "Flags indicating how to handle the WPA PSK key.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** @@ -1345,9 +1345,9 @@ nm_setting_wireless_security_class_init (NMSettingWirelessSecurityClass *setting g_param_spec_uint (NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, "LEAP Password Flags", "Flags indicating how to handle the LEAP password.", - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAGS_ALL, - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, + NM_SETTING_SECRET_FLAG_NONE, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index f0809f0d1..e8b80f452 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -602,7 +602,7 @@ get_secret_flags (NMSetting *setting, GError **error) { char *flags_prop; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; if (verify_secret) g_return_val_if_fail (is_secret_prop (setting, secret_name, error), FALSE); @@ -682,7 +682,7 @@ nm_setting_set_secret_flags (NMSetting *setting, g_return_val_if_fail (setting != NULL, FALSE); g_return_val_if_fail (NM_IS_SETTING (setting), FALSE); g_return_val_if_fail (secret_name != NULL, FALSE); - g_return_val_if_fail (flags & NM_SETTING_SECRET_FLAGS_ALL, FALSE); + g_return_val_if_fail (flags <= NM_SETTING_SECRET_FLAGS_ALL, FALSE); return NM_SETTING_GET_CLASS (setting)->set_secret_flags (setting, secret_name, TRUE, flags, error); } diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index bb5de530c..d95e558a1 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -85,8 +85,8 @@ GQuark nm_setting_error_quark (void); /** * NMSettingSecretFlags: - * @NM_SETTING_SECRET_FLAG_SYTSEM_OWNED: the system is responsible for providing - * and storing this secret (default) + * @NM_SETTING_SECRET_FLAG_NONE: the system is responsible for providing and + * storing this secret (default) * @NM_SETTING_SECRET_FLAG_AGENT_OWNED: a user secret agent is responsible * for providing and storing this secret; when it is required agents will be * asked to retrieve it @@ -99,7 +99,7 @@ GQuark nm_setting_error_quark (void); * **/ typedef enum { - NM_SETTING_SECRET_FLAG_SYSTEM_OWNED = 0x00000000, + NM_SETTING_SECRET_FLAG_NONE = 0x00000000, NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002 diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 9f10dc7b4..73bc40332 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -748,12 +748,12 @@ has_system_secrets (NMSetting *setting, GParamFlags flags, gpointer user_data) { - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; gboolean *has_system = user_data; if (flags & NM_SETTING_PARAM_SECRET) { nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); - if (secret_flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) + if (!(secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) *has_system = TRUE; } } diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index d3e1bada8..8f92afa9b 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -358,11 +358,11 @@ typedef gboolean (*ForEachSecretFunc) (GHashTableIter *iter, gpointer user_data); static gboolean -clear_system_owned_secrets (GHashTableIter *iter, - NMSettingSecretFlags flags, - gpointer user_data) +clear_nonagent_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) { - if (flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) + if (flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) g_hash_table_iter_remove (iter); return TRUE; } @@ -374,7 +374,7 @@ has_system_owned_secrets (GHashTableIter *iter, { gboolean *has_system_owned = user_data; - if (flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) { + if (!(flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) { *has_system_owned = TRUE; return FALSE; } @@ -403,7 +403,7 @@ for_each_secret (NMConnection *connection, g_hash_table_iter_init (&setting_iter, setting_hash); while (g_hash_table_iter_next (&setting_iter, (gpointer *) &secret_name, NULL)) { NMSetting *setting; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; /* Get the actual NMSetting from the connection so we can get secret flags */ setting = nm_connection_get_setting_by_name (connection, setting_name); @@ -499,7 +499,7 @@ agent_secrets_done_cb (NMAgentManager *manager, call_id, agent_dbus_owner); - for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); + for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL); } else if (agent_has_modify == FALSE) { /* Agent didn't successfully authenticate; clear system-owned secrets * from the secrets the agent returned. @@ -509,7 +509,7 @@ agent_secrets_done_cb (NMAgentManager *manager, setting_name, call_id); - for_each_secret (NM_CONNECTION (self), secrets, clear_system_owned_secrets, NULL); + for_each_secret (NM_CONNECTION (self), secrets, clear_nonagent_secrets, NULL); } } } else { @@ -865,7 +865,7 @@ only_agent_secrets_cb (NMSetting *setting, gpointer user_data) { if (flags & NM_SETTING_PARAM_SECRET) { - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; /* Clear out system-owned or always-ask secrets */ nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index f7335e0bc..a2d44c12f 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -69,7 +69,7 @@ set_secret (shvarFile *ifcfg, svSetValue (keyfile, key, NULL, FALSE); /* Only write the secret if it's system owned */ - if (flags == NM_SETTING_SECRET_FLAG_SYSTEM_OWNED) + if (flags == NM_SETTING_SECRET_FLAG_NONE) svSetValue (keyfile, key, value, verbatim); if (svWriteFile (keyfile, 0600)) { @@ -349,7 +349,7 @@ write_8021x_certs (NMSetting8021x *s_8021x, gboolean success = FALSE, is_pkcs12 = FALSE; const ObjectType *otype = NULL; const GByteArray *blob = NULL; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; /* CA certificate */ if (phase2) @@ -397,7 +397,7 @@ write_8021x_certs (NMSetting8021x *s_8021x, if (generated_pw) { password = generated_pw; - flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + flags = NM_SETTING_SECRET_FLAG_NONE; } } @@ -600,16 +600,16 @@ write_wireless_security_setting (NMConnection *connection, /* WEP keys */ /* Clear any default key */ - set_secret (ifcfg, "KEY", NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); + set_secret (ifcfg, "KEY", NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); /* Clear existing keys */ for (i = 0; i < 4; i++) { tmp = g_strdup_printf ("KEY_PASSPHRASE%d", i + 1); - set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); + set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); g_free (tmp); tmp = g_strdup_printf ("KEY%d", i + 1); - set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); + set_secret (ifcfg, tmp, NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); g_free (tmp); } @@ -715,7 +715,7 @@ write_wireless_security_setting (NMConnection *connection, if (quoted) g_string_free (quoted, TRUE); } else - set_secret (ifcfg, "WPA_PSK", NULL, NM_SETTING_SECRET_FLAG_SYSTEM_OWNED, FALSE); + set_secret (ifcfg, "WPA_PSK", NULL, NM_SETTING_SECRET_FLAG_NONE, FALSE); return TRUE; } diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 0574f90a3..a09215d62 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -564,7 +564,7 @@ write_setting_value (NMSetting *setting, GType type = G_VALUE_TYPE (value); KeyWriter *writer = &key_writers[0]; GParamSpec *pspec; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_SYSTEM_OWNED; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; /* Setting name gets picked up from the keyfile's section name instead */ if (!strcmp (key, NM_SETTING_NAME)) @@ -591,7 +591,7 @@ write_setting_value (NMSetting *setting, */ if ( (pspec->flags & NM_SETTING_PARAM_SECRET) && nm_setting_get_secret_flags (setting, key, &flags, NULL) - && (flags != NM_SETTING_SECRET_FLAG_SYSTEM_OWNED)) + && (flags != NM_SETTING_SECRET_FLAG_NONE)) return; /* Look through the list of handlers for non-standard format key values */ From ad56cfa914d6a0f49b51e917ce89001f19c72d9f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 13:44:28 -0600 Subject: [PATCH 217/264] libnm-util: don't return empty hashes from nm_setting_to_hash() --- libnm-util/nm-setting.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index e8b80f452..b5a8b71f6 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -162,8 +162,14 @@ nm_setting_to_hash (NMSetting *setting, NMSettingHashFlags flags) else destroy_gvalue (value); } - g_free (property_specs); + + /* Don't return empty hashes */ + if (g_hash_table_size (hash) < 1) { + g_hash_table_destroy (hash); + hash = NULL; + } + return hash; } From ac208cafbdf7d1e8eb0908bb42d686a73083c139 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 13:50:40 -0600 Subject: [PATCH 218/264] libnm-util: add NM_SETTING_SECRET_FLAG_NOT_REQUIRED Not all connections will require every secret, and sometimes we can't automatically figure out whether we need the secret. For vpnc sometimes the group password isn't used, and sometimes PPP providers require a username but don't want a password, etc. --- libnm-util/nm-setting-private.h | 3 ++- libnm-util/nm-setting.h | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libnm-util/nm-setting-private.h b/libnm-util/nm-setting-private.h index ea43f7752..5c4e0a5ed 100644 --- a/libnm-util/nm-setting-private.h +++ b/libnm-util/nm-setting-private.h @@ -24,7 +24,8 @@ #define NM_SETTING_SECRET_FLAGS_ALL \ (NM_SETTING_SECRET_FLAG_NONE | \ NM_SETTING_SECRET_FLAG_AGENT_OWNED | \ - NM_SETTING_SECRET_FLAG_NOT_SAVED) + NM_SETTING_SECRET_FLAG_NOT_SAVED | \ + NM_SETTING_SECRET_FLAG_NOT_REQUIRED) #endif /* NM_SETTING_PRIVATE_H */ diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index d95e558a1..067db14cb 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -92,6 +92,10 @@ GQuark nm_setting_error_quark (void); * asked to retrieve it * @NM_SETTING_SECRET_FLAG_NOT_SAVED: this secret should not be saved, but * should be requested from the user each time it is needed + * @NM_SETTING_SECRET_FLAG_NOT_REQUIRED: in situations where it cannot be + * automatically determined that the secret is required (some VPNs and PPP + * providers dont require all secrets) this flag indicates that the specific + * secret is not required * * These flags indicate specific behavior related to handling of a secret. Each * secret has a corresponding set of these flags which indicate how the secret @@ -101,7 +105,8 @@ GQuark nm_setting_error_quark (void); typedef enum { NM_SETTING_SECRET_FLAG_NONE = 0x00000000, NM_SETTING_SECRET_FLAG_AGENT_OWNED = 0x00000001, - NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002 + NM_SETTING_SECRET_FLAG_NOT_SAVED = 0x00000002, + NM_SETTING_SECRET_FLAG_NOT_REQUIRED = 0x00000004 /* NOTE: if adding flags, update nm-setting-private.h as well */ } NMSettingSecretFlags; From d8cbecec8bfc20968e1c9364b36d09faeab93f21 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 13:58:05 -0600 Subject: [PATCH 219/264] settings: streamline system-owned secret handling during agent requests Do the check for system-owned secrets once, before kicking off the request, instead of each time we ask an agent. As a bonus, this change ensures priv->secrets doesn't store anything except system-owned secrets too, simplifying some checks later on. --- src/settings/nm-agent-manager.c | 64 ++++++++++----------------- src/settings/nm-settings-connection.c | 64 ++++++++++++++++++--------- 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 73bc40332..8c47de973 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -741,23 +741,6 @@ get_agent_modify_auth_cb (NMAuthChain *chain, } } -static void -has_system_secrets (NMSetting *setting, - const char *key, - const GValue *value, - GParamFlags flags, - gpointer user_data) -{ - NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - gboolean *has_system = user_data; - - if (flags & NM_SETTING_PARAM_SECRET) { - nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); - if (!(secret_flags & NM_SETTING_SECRET_FLAG_AGENT_OWNED)) - *has_system = TRUE; - } -} - static void get_next_cb (Request *req) { @@ -768,32 +751,27 @@ get_next_cb (Request *req) agent_dbus_owner = nm_secret_agent_get_dbus_owner (NM_SECRET_AGENT (req->current)); - if (req->flags != 0) { - gboolean has_system = FALSE; + /* If the request flags allow user interaction, and there are system secrets, + * check whether the agent has the 'modify' permission before sending those + * secrets to the agent. We shouldn't leak system-owned secrets to + * unprivileged users. + */ + if ((req->flags != 0) && (req->existing_secrets != NULL)) { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY", + req, req->setting_name, agent_dbus_owner); - /* Interaction with the user is allowed; if there are any system secrets, - * check whether the agent has the 'modify' permission before sending those - * secrets to the agent. - */ - nm_connection_for_each_setting_value (req->connection, has_system_secrets, &has_system); - if (has_system) { - nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY", - req, req->setting_name, agent_dbus_owner); + req->chain = nm_auth_chain_new_dbus_sender (req->authority, + agent_dbus_owner, + get_agent_modify_auth_cb, + req); + g_assert (req->chain); + nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + } else { + nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s", + req, req->setting_name, agent_dbus_owner); - req->chain = nm_auth_chain_new_dbus_sender (req->authority, - agent_dbus_owner, - get_agent_modify_auth_cb, - req); - g_assert (req->chain); - nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); - return; - } + get_agent_request_secrets (req, FALSE); } - - nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s", - req, req->setting_name, agent_dbus_owner); - - get_agent_request_secrets (req, FALSE); } static gboolean @@ -913,6 +891,12 @@ nm_agent_manager_get_secrets (NMAgentManager *self, nm_connection_get_path (connection), setting_name); + /* NOTE: a few things in the Request handling depend on existing_secrets + * being NULL if there aren't any system-owned secrets for this connection. + * This in turn depends on nm_connection_to_hash() and nm_setting_to_hash() + * both returning NULL if they didn't hash anything. + */ + req = request_new_get (connection, priv->authority, filter_by_uid, diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 8f92afa9b..bae5fbb9b 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -187,6 +187,35 @@ session_changed_cb (NMSessionMonitor *self, gpointer user_data) /**************************************************************/ +static void +only_system_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + if (flags & NM_SETTING_PARAM_SECRET) { + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + g_object_set (G_OBJECT (setting), key, NULL, NULL); + } +} + +static void +update_secrets_cache (NMSettingsConnection *self) +{ + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + if (priv->secrets) + g_object_unref (priv->secrets); + priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + + /* Clear out non-system-owned and not-saved secrets */ + nm_connection_for_each_setting_value (priv->secrets, only_system_secrets_cb, NULL); +} + /* Update the settings of this connection to match that of 'new', taking care to * make a private copy of secrets. */ gboolean @@ -211,9 +240,7 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, /* Copy the connection to keep its secrets around even if NM * calls nm_connection_clear_secrets(). */ - if (priv->secrets) - g_object_unref (priv->secrets); - priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + update_secrets_cache (self); nm_settings_connection_recheck_visibility (self); success = TRUE; @@ -537,9 +564,7 @@ agent_secrets_done_cb (NMAgentManager *manager, /* Now that all secrets are updated, copy and cache new secrets, * then save them to backing storage. */ - if (priv->secrets) - g_object_unref (priv->secrets); - priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); + update_secrets_cache (self); nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage", nm_setting_connection_get_uuid (s_con), @@ -616,9 +641,8 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, return 0; } - /* FIXME: if setting_name is empty, return all secrets */ - - if (!nm_connection_get_setting_by_name (priv->secrets, setting_name)) { + /* Make sure the request actually requests something we can return */ + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); @@ -995,21 +1019,19 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); - /* The connection's secrets will have been updated by the agent manager, - * so we want to refresh the secrets cache. Note that we will never save - * new secrets to backing storage here because D-Bus initated requests will - * never ask for completely new secrets from agents. Thus system-owned - * secrets should not have changed from backing storage. We also don't - * send agent-owned back out to be saved since we assume the agent that - * provided the secrets saved them itself. - */ - if (priv->secrets) - g_object_unref (priv->secrets); - priv->secrets = nm_connection_duplicate (NM_CONNECTION (self)); - if (error) dbus_g_method_return_error (context, error); else { + /* The connection's secrets will have been updated by the agent manager, + * so we want to refresh the secrets cache. Note that we will never save + * new secrets to backing storage here because D-Bus initated requests will + * never ask for completely new secrets from agents. Thus system-owned + * secrets should not have changed from backing storage. We also don't + * send agent-owned secrets back out to be saved since we assume the agent + * that provided the secrets saved them itself. + */ + update_secrets_cache (self); + hash = nm_connection_to_hash (NM_CONNECTION (self), NM_SETTING_HASH_FLAG_ONLY_SECRETS); dbus_g_method_return (context, hash); g_hash_table_destroy (hash); From 75a1ab9a43d38f833311a5dce4864e23cd0c3690 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 17:24:50 -0600 Subject: [PATCH 220/264] libnm-util: add utility functions for adding/removing permissions --- libnm-util/libnm-util.ver | 2 + libnm-util/nm-setting-connection.c | 98 +++++++++++++++++++++++++++--- libnm-util/nm-setting-connection.h | 14 +++-- libnm-util/tests/test-general.c | 71 ++++++++++++++++++++++ 4 files changed, 171 insertions(+), 14 deletions(-) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 1f98a083d..0b7557a33 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -106,6 +106,7 @@ global: nm_setting_cdma_get_password_flags; nm_setting_clear_secrets; nm_setting_compare; + nm_setting_connection_add_permission; nm_setting_connection_error_get_type; nm_setting_connection_error_quark; nm_setting_connection_get_type; @@ -119,6 +120,7 @@ global: nm_setting_connection_get_num_permissions; nm_setting_connection_get_permission; nm_setting_connection_permissions_user_allowed; + nm_setting_connection_remove_permission; nm_setting_duplicate; nm_setting_enumerate_values; nm_setting_error_get_type; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index 79bd73f00..da5bd806f 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -190,7 +190,7 @@ nm_setting_connection_get_num_permissions (NMSettingConnection *setting) /** * nm_setting_connection_get_permission: * @setting: the #NMSettingConnection - * @index: the zero-based index of the permissions entry + * @idx: the zero-based index of the permissions entry * * Retrieve one of the entries of the #NMSettingConnection:permissions property * of this setting. @@ -211,8 +211,6 @@ nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 i) return (const char *) g_slist_nth_data (priv->permissions, i); } -#define USER_TAG "user:" - /* Extract the username from the permission string and dump to a buffer */ static gboolean perm_to_user (const char *perm, char *out_user, gsize out_user_size) @@ -223,9 +221,9 @@ perm_to_user (const char *perm, char *out_user, gsize out_user_size) g_return_val_if_fail (perm != NULL, FALSE); g_return_val_if_fail (out_user != NULL, FALSE); - if (!g_str_has_prefix (perm, USER_TAG)) + if (!g_str_has_prefix (perm, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER)) return FALSE; - perm += strlen (USER_TAG); + perm += strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER); /* Look for trailing ':' */ end = strchr (perm, ':'); @@ -285,6 +283,84 @@ nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, return FALSE; } +/** + * nm_setting_connection_add_permission: + * @setting: the #NMSettingConnection + * @ptype: the permission type; at this time only "user" is supported + * @pitem: the permission item formatted as required for @ptype + * @detail: unused at this time; must be %NULL + * + * Adds a permission to the connection's permission list. At this time, only + * the "user" permission type is supported, and @pitem must be a username. See + * #NMSettingConnection:permissions: for more details. + * + * Returns: TRUE if the permission was unique and was successfully added to the + * list, FALSE if @ptype or @pitem was invalid or it the permission was already + * present in the list + */ +gboolean +nm_setting_connection_add_permission (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + char *perm; + + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); + g_return_val_if_fail (ptype, FALSE); + g_return_val_if_fail (strlen (ptype) > 0, FALSE); + g_return_val_if_fail (pitem, FALSE); + g_return_val_if_fail (strlen (pitem) > 0, FALSE); + g_return_val_if_fail (strchr (pitem, ':') == NULL, FALSE); + g_return_val_if_fail (g_utf8_validate (pitem, -1, NULL) == TRUE, FALSE); + g_return_val_if_fail (detail == NULL, FALSE); + + /* Only "user" for now... */ + g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + + perm = g_strdup_printf ("%s:%s:", ptype, pitem); + + /* No dupes */ + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + if (strcmp ((const char *) iter->data, perm) == 0) { + g_free (perm); + return FALSE; + } + } + + priv->permissions = g_slist_append (priv->permissions, perm); + return TRUE; +} + +/** + * nm_setting_connection_remove_permission: + * @setting: the #NMSettingConnection + * @idx: the zero-based index of the permission to remove + * + * Removes the permission at index @idx from the connection. + */ +void +nm_setting_connection_remove_permission (NMSettingConnection *setting, + guint32 idx) +{ + NMSettingConnectionPrivate *priv; + GSList *iter; + + g_return_if_fail (NM_IS_SETTING_CONNECTION (setting)); + + priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); + iter = g_slist_nth (priv->permissions, idx); + g_return_if_fail (iter != NULL); + + g_free (iter->data); + priv->permissions = g_slist_delete_link (priv->permissions, iter); +} + + /** * nm_setting_connection_get_autoconnect: * @setting: the #NMSettingConnection @@ -641,8 +717,9 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * * At this time only the 'user' [type] is allowed. Any other values are * ignored and reserved for future use. [id] is the username that this - * permission refers to. Any [reserved] information present must be - * ignored and is reserved for future use. + * permission refers to, which may not contain the ':' character. Any + * [reserved] information present must be ignored and is reserved for + * future use. */ g_object_class_install_property (object_class, PROP_PERMISSIONS, @@ -658,9 +735,10 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) "\"user:dcbw:blah\" At this time only the 'user' " "[type] is allowed. Any other values are ignored and " "reserved for future use. [id] is the username that " - "this permission refers to. Any [reserved] " - "information (if present) must be ignored and is " - "reserved for future use.", + "this permission refers to, which may not contain the " + "':' character. Any [reserved] information (if " + "present) must be ignored and is reserved for future " + "use.", DBUS_TYPE_G_LIST_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index e62263c2d..c44f6cfb6 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -105,11 +105,17 @@ const char *nm_setting_connection_get_connection_type (NMSettingConnection *set gboolean nm_setting_connection_get_autoconnect (NMSettingConnection *setting); guint64 nm_setting_connection_get_timestamp (NMSettingConnection *setting); gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); -guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); -const char *nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 index); -gboolean nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname); -/* FIXME: need add/remove calls for permissions */ +guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); +const char *nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx); +gboolean nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname); +gboolean nm_setting_connection_add_permission (NMSettingConnection *setting, + const char *ptype, + const char *pitem, + const char *detail); +void nm_setting_connection_remove_permission (NMSettingConnection *setting, + guint32 idx); G_END_DECLS diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 1d23d99b9..55f0ee6fa 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -407,6 +407,76 @@ test_connection_to_hash_setting_name (void) g_object_unref (connection); } +#define TEST_UNAME "asdfasfasdf" + +static void +test_setting_connection_permissions (void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[12] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + const char *perm; + const char *expected_perm = "user:" TEST_UNAME ":"; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + success = nm_setting_connection_add_permission (s_con, "foobar", "blah", NULL); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", NULL, NULL); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", "", NULL); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", "ad:asdf", NULL); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad permission item #3"); + + /* Ensure a non-UTF-8 [item] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", buf, NULL); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad permission item #4"); + + /* Ensure a non-NULL [detail] is rejected */ + success = nm_setting_connection_add_permission (s_con, "user", "dafasdf", "asdf"); + ASSERT (success == FALSE, + "setting-connection-add-permission", "unexpected success adding bad detail"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); + ASSERT (success == TRUE, + "setting-connection-add-permission", "unexpected failure adding valid user permisson"); + + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "setting-connection-add-permission", "unexpected failure getting number of permissions"); + + perm = nm_setting_connection_get_permission (s_con, 0); + ASSERT (perm != NULL, + "setting-connection-add-permission", "unexpected failure getting added permission"); + ASSERT (strcmp (perm, expected_perm) == 0, + "setting-connection-add-permission", "retrieved permission did not match added permission"); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission (s_con, 0); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-add-permission", "unexpected failure removing permission"); + + g_object_unref (s_con); +} + int main (int argc, char **argv) { GError *error = NULL; @@ -428,6 +498,7 @@ int main (int argc, char **argv) test_setting_to_hash_no_secrets (); test_setting_to_hash_only_secrets (); test_connection_to_hash_setting_name (); + test_setting_connection_permissions (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); From 1c97de837a3404aa04a56b959fd1fc671f174a78 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 18:35:48 -0600 Subject: [PATCH 221/264] libnm-util: rework permissions helpers to be more useful Add add/remove helpers, and make get more useful by actually breaking down the specifics for us. --- libnm-util/nm-setting-connection.c | 269 ++++++++++++++++++----------- libnm-util/nm-setting-connection.h | 7 +- libnm-util/tests/test-general.c | 165 ++++++++++++++++-- 3 files changed, 316 insertions(+), 125 deletions(-) diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index da5bd806f..d63fdf6dc 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -19,7 +19,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * - * (C) Copyright 2007 - 2010 Red Hat, Inc. + * (C) Copyright 2007 - 2011 Red Hat, Inc. * (C) Copyright 2007 - 2008 Novell, Inc. */ @@ -30,8 +30,6 @@ #include "nm-param-spec-specialized.h" #include "nm-setting-connection.h" -#define NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER "user:" - /** * SECTION:nm-setting-connection * @short_description: Describes general connection properties @@ -86,11 +84,20 @@ G_DEFINE_TYPE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) #define NM_SETTING_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate)) +typedef enum { + PERM_TYPE_USER = 0, +} PermType; + +typedef struct { + guint8 ptype; + char *item; +} Permission; + typedef struct { char *id; char *uuid; char *type; - GSList *permissions; + GSList *permissions; /* list of Permission structs */ gboolean autoconnect; guint64 timestamp; gboolean read_only; @@ -109,6 +116,86 @@ enum { LAST_PROP }; +/***********************************************************************/ + +#define PERM_USER_PREFIX "user:" + +static Permission * +permission_new_from_str (const char *str) +{ + Permission *p; + const char *last_colon; + size_t ulen = 0, i; + + g_return_val_if_fail (strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0, NULL); + str += strlen (PERM_USER_PREFIX); + + last_colon = strrchr (str, ':'); + if (last_colon) { + /* Ensure that somebody didn't pass "user::" */ + g_return_val_if_fail (last_colon > str, NULL); + + /* Make sure we don't include detail in the username */ + ulen = (last_colon - str) + 1; + } else + ulen = strlen (str); + + /* Sanity check the length of the username */ + g_return_val_if_fail (ulen < 100, NULL); + + /* Make sure there's no ':' in the username */ + for (i = 0; i < ulen; i++) + g_return_val_if_fail (str[i] != ':', NULL); + + /* And the username must be valid UTF-8 */ + g_return_val_if_fail (g_utf8_validate (str, -1, NULL) == TRUE, NULL); + + /* Yay, valid... create the new permission */ + p = g_slice_new0 (Permission); + p->ptype = PERM_TYPE_USER; + if (last_colon) { + p->item = g_malloc (ulen + 1); + memcpy (p->item, str, ulen); + p->item[ulen] = '\0'; + } else + p->item = g_strdup (str); + + return p; +} + +static Permission * +permission_new (const char *uname) +{ + Permission *p; + + g_return_val_if_fail (uname, NULL); + g_return_val_if_fail (uname[0] != '\0', NULL); + g_return_val_if_fail (strchr (uname, ':') == NULL, NULL); + g_return_val_if_fail (g_utf8_validate (uname, -1, NULL) == TRUE, NULL); + + /* Yay, valid... create the new permission */ + p = g_slice_new0 (Permission); + p->ptype = PERM_TYPE_USER; + p->item = g_strdup (uname); + return p; +} + +static char * +permission_to_string (Permission *p) +{ + return g_strdup_printf (PERM_USER_PREFIX "%s:", p->item); +} + +static void +permission_free (Permission *p) +{ + g_free (p->item); + memset (p, 0, sizeof (*p)); + g_slice_free (Permission, p); +} + +/***********************************************************************/ + /** * nm_setting_connection_new: * @@ -191,50 +278,40 @@ nm_setting_connection_get_num_permissions (NMSettingConnection *setting) * nm_setting_connection_get_permission: * @setting: the #NMSettingConnection * @idx: the zero-based index of the permissions entry + * @out_ptype: on return, the permission type (at this time, always "user") + * @out_pitem: on return, the permission item (formatted accoring to @ptype, see + * #NMSettingConnection:permissions for more detail + * @out_detail: on return, the permission detail (at this time, always NULL) * * Retrieve one of the entries of the #NMSettingConnection:permissions property * of this setting. * - * Returns: the entry at the specified index + * Returns: %TRUE if a permission was returned, %FALSE if @idx was invalid */ -const char * -nm_setting_connection_get_permission (NMSettingConnection *setting, guint32 i) +gboolean +nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx, + const char **out_ptype, + const char **out_pitem, + const char **out_detail) { NMSettingConnectionPrivate *priv; + Permission *p; - g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL); + g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); - g_return_val_if_fail (i < g_slist_length (priv->permissions), NULL); + g_return_val_if_fail (idx < g_slist_length (priv->permissions), FALSE); - return (const char *) g_slist_nth_data (priv->permissions, i); -} + p = g_slist_nth_data (priv->permissions, idx); + if (out_ptype) + *out_ptype = "user"; + if (out_pitem) + *out_pitem = p->item; + if (out_detail) + *out_detail = NULL; -/* Extract the username from the permission string and dump to a buffer */ -static gboolean -perm_to_user (const char *perm, char *out_user, gsize out_user_size) -{ - const char *end; - gsize userlen; - - g_return_val_if_fail (perm != NULL, FALSE); - g_return_val_if_fail (out_user != NULL, FALSE); - - if (!g_str_has_prefix (perm, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER)) - return FALSE; - perm += strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER); - - /* Look for trailing ':' */ - end = strchr (perm, ':'); - if (!end) - end = perm + strlen (perm); - - userlen = end - perm; - if (userlen > (out_user_size + 1)) - return FALSE; - memcpy (out_user, perm, userlen); - out_user[userlen] = '\0'; return TRUE; } @@ -253,7 +330,7 @@ nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname) { NMSettingConnectionPrivate *priv; - guint32 num, i; + GSList *iter; g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); g_return_val_if_fail (uname != NULL, FALSE); @@ -261,23 +338,16 @@ nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); - /* Match the username returned by the session check to a user in the ACL */ - num = nm_setting_connection_get_num_permissions (setting); - if (num == 0) - return TRUE; /* visible to all */ + /* If no permissions, visible to all */ + if (priv->permissions == NULL) + return TRUE; - for (i = 0; i < num; i++) { - const char *perm; - char buf[75]; + /* Find the username in the permissions list */ + for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { + Permission *p = iter->data; - perm = nm_setting_connection_get_permission (setting, i); - g_assert (perm); - if (perm_to_user (perm, buf, sizeof (buf))) { - if (strcmp (buf, uname) == 0) { - /* Yay, permitted */ - return TRUE; - } - } + if (strcmp (uname, p->item) == 0) + return TRUE; } return FALSE; @@ -305,16 +375,12 @@ nm_setting_connection_add_permission (NMSettingConnection *setting, const char *detail) { NMSettingConnectionPrivate *priv; + Permission *p; GSList *iter; - char *perm; g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE); g_return_val_if_fail (ptype, FALSE); g_return_val_if_fail (strlen (ptype) > 0, FALSE); - g_return_val_if_fail (pitem, FALSE); - g_return_val_if_fail (strlen (pitem) > 0, FALSE); - g_return_val_if_fail (strchr (pitem, ':') == NULL, FALSE); - g_return_val_if_fail (g_utf8_validate (pitem, -1, NULL) == TRUE, FALSE); g_return_val_if_fail (detail == NULL, FALSE); /* Only "user" for now... */ @@ -322,17 +388,17 @@ nm_setting_connection_add_permission (NMSettingConnection *setting, priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); - perm = g_strdup_printf ("%s:%s:", ptype, pitem); - /* No dupes */ for (iter = priv->permissions; iter; iter = g_slist_next (iter)) { - if (strcmp ((const char *) iter->data, perm) == 0) { - g_free (perm); + p = iter->data; + if (strcmp (pitem, p->item) == 0) return FALSE; - } } - priv->permissions = g_slist_append (priv->permissions, perm); + p = permission_new (pitem); + g_return_val_if_fail (p != NULL, FALSE); + priv->permissions = g_slist_append (priv->permissions, p); + return TRUE; } @@ -356,7 +422,7 @@ nm_setting_connection_remove_permission (NMSettingConnection *setting, iter = g_slist_nth (priv->permissions, idx); g_return_if_fail (iter != NULL); - g_free (iter->data); + permission_free ((Permission *) iter->data); priv->permissions = g_slist_delete_link (priv->permissions, iter); } @@ -434,34 +500,6 @@ validate_uuid (const char *uuid) return TRUE; } -/* Check that every entry in the given permissions array is of proper form. - * Report a descriptive error if it's not. */ -static gboolean -validate_permissions (GSList *permissions, GError **error) -{ - GSList *iter; - - for (iter = permissions; iter; iter = iter->next) { - const char *entry = iter->data; - const char *usr_start = NULL; - - if (!g_str_has_prefix (entry, NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER)) - continue; - - usr_start = entry + strlen (NM_SETTINGS_CONNECTION_PERMISSION_PREFIX_USER); - if (!strchr (usr_start, ':')) { - g_set_error (error, - NM_SETTING_CONNECTION_ERROR, - NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, - "permissions: entry '%s': two few ':' characters", entry); - return FALSE; - } - /* We don't (yet) care about what comes afterwards. */ - } - - return TRUE; -} - static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { @@ -518,11 +556,6 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (priv->permissions) { - if (!validate_permissions (priv->permissions, error)) - return FALSE; - } - return TRUE; } @@ -540,14 +573,30 @@ finalize (GObject *object) g_free (priv->id); g_free (priv->uuid); g_free (priv->type); - nm_utils_slist_free (priv->permissions, g_free); + nm_utils_slist_free (priv->permissions, (GDestroyNotify) permission_free); G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object); } +static GSList * +perm_stringlist_to_permlist (GSList *strlist) +{ + GSList *list = NULL, *iter; + + for (iter = strlist; iter; iter = g_slist_next (iter)) { + Permission *p; + + p = permission_new_from_str ((const char *) iter->data); + if (p) + list = g_slist_append (list, p); + } + + return list; +} + static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (object); @@ -565,8 +614,8 @@ set_property (GObject *object, guint prop_id, priv->type = g_value_dup_string (value); break; case PROP_PERMISSIONS: - nm_utils_slist_free (priv->permissions, g_free); - priv->permissions = g_value_dup_boxed (value); + nm_utils_slist_free (priv->permissions, (GDestroyNotify) permission_free); + priv->permissions = perm_stringlist_to_permlist (g_value_get_boxed (value)); break; case PROP_AUTOCONNECT: priv->autoconnect = g_value_get_boolean (value); @@ -583,11 +632,22 @@ set_property (GObject *object, guint prop_id, } } +static GSList * +perm_permlist_to_stringlist (GSList *permlist) +{ + GSList *list = NULL, *iter; + + for (iter = permlist; iter; iter = g_slist_next (iter)) + list = g_slist_append (list, permission_to_string ((Permission *) iter->data)); + return list; +} + static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) + GValue *value, GParamSpec *pspec) { NMSettingConnection *setting = NM_SETTING_CONNECTION (object); + NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting); switch (prop_id) { case PROP_ID: @@ -600,7 +660,7 @@ get_property (GObject *object, guint prop_id, g_value_set_string (value, nm_setting_connection_get_connection_type (setting)); break; case PROP_PERMISSIONS: - g_value_set_boxed (value, NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions); + g_value_take_boxed (value, perm_permlist_to_stringlist (priv->permissions)); break; case PROP_AUTOCONNECT: g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting)); @@ -719,7 +779,7 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) * ignored and reserved for future use. [id] is the username that this * permission refers to, which may not contain the ':' character. Any * [reserved] information present must be ignored and is reserved for - * future use. + * future use. All of [type], [id], and [reserved] must be valid UTF-8. */ g_object_class_install_property (object_class, PROP_PERMISSIONS, @@ -738,7 +798,8 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) "this permission refers to, which may not contain the " "':' character. Any [reserved] information (if " "present) must be ignored and is reserved for future " - "use.", + "use. All of [type], [id], and [reserved] must be " + "valid UTF-8.", DBUS_TYPE_G_LIST_OF_STRING, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index c44f6cfb6..1ec5bf120 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -107,8 +107,11 @@ guint64 nm_setting_connection_get_timestamp (NMSettingConnection *set gboolean nm_setting_connection_get_read_only (NMSettingConnection *setting); guint32 nm_setting_connection_get_num_permissions (NMSettingConnection *setting); -const char *nm_setting_connection_get_permission (NMSettingConnection *setting, - guint32 idx); +gboolean nm_setting_connection_get_permission (NMSettingConnection *setting, + guint32 idx, + const char **out_ptype, + const char **out_pitem, + const char **out_detail); gboolean nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting, const char *uname); gboolean nm_setting_connection_add_permission (NMSettingConnection *setting, const char *ptype, diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 55f0ee6fa..2431947bf 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -407,15 +407,38 @@ test_connection_to_hash_setting_name (void) g_object_unref (connection); } +static void +check_permission (NMSettingConnection *s_con, + guint32 idx, + const char *expected_uname, + const char *tag) +{ + gboolean success; + const char *ptype = NULL, *pitem = NULL, *detail = NULL; + + success = nm_setting_connection_get_permission (s_con, 0, &ptype, &pitem, &detail); + ASSERT (success == TRUE, tag, "unexpected failure getting added permission"); + + /* Permission type */ + ASSERT (ptype != NULL, tag, "unexpected failure getting permission type"); + ASSERT (strcmp (ptype, "user") == 0, tag, "retrieved unexpected permission type"); + + /* Permission item */ + ASSERT (pitem != NULL, tag, "unexpected failure getting permission item"); + ASSERT (strcmp (pitem, expected_uname) == 0, tag, "retrieved unexpected permission item"); + + ASSERT (detail == NULL, tag, "unexpected success getting permission detail"); +} + #define TEST_UNAME "asdfasfasdf" static void -test_setting_connection_permissions (void) +test_setting_connection_permissions_helpers (void) { NMSettingConnection *s_con; gboolean success; - char buf[12] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; - const char *perm; + char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + GSList *list = NULL; const char *expected_perm = "user:" TEST_UNAME ":"; s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); @@ -423,56 +446,159 @@ test_setting_connection_permissions (void) /* Ensure a bad [type] is rejected */ success = nm_setting_connection_add_permission (s_con, "foobar", "blah", NULL); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad permission type #1"); + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #1"); /* Ensure a bad [type] is rejected */ success = nm_setting_connection_add_permission (s_con, NULL, "blah", NULL); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad permission type #2"); + "setting-connection-permissions-helpers", "unexpected success adding bad permission type #2"); /* Ensure a bad [item] is rejected */ success = nm_setting_connection_add_permission (s_con, "user", NULL, NULL); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad permission item #1"); + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #1"); /* Ensure a bad [item] is rejected */ success = nm_setting_connection_add_permission (s_con, "user", "", NULL); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad permission item #2"); + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #2"); /* Ensure an [item] with ':' is rejected */ success = nm_setting_connection_add_permission (s_con, "user", "ad:asdf", NULL); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad permission item #3"); + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #3"); /* Ensure a non-UTF-8 [item] is rejected */ success = nm_setting_connection_add_permission (s_con, "user", buf, NULL); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad permission item #4"); + "setting-connection-permissions-helpers", "unexpected success adding bad permission item #4"); /* Ensure a non-NULL [detail] is rejected */ success = nm_setting_connection_add_permission (s_con, "user", "dafasdf", "asdf"); ASSERT (success == FALSE, - "setting-connection-add-permission", "unexpected success adding bad detail"); + "setting-connection-permissions-helpers", "unexpected success adding bad detail"); /* Ensure a valid call results in success */ success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); ASSERT (success == TRUE, - "setting-connection-add-permission", "unexpected failure adding valid user permisson"); + "setting-connection-permissions-helpers", "unexpected failure adding valid user permisson"); ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, - "setting-connection-add-permission", "unexpected failure getting number of permissions"); + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions"); - perm = nm_setting_connection_get_permission (s_con, 0); - ASSERT (perm != NULL, - "setting-connection-add-permission", "unexpected failure getting added permission"); - ASSERT (strcmp (perm, expected_perm) == 0, - "setting-connection-add-permission", "retrieved permission did not match added permission"); + check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-helpers"); + + /* Check the actual GObject property just to be paranoid */ + g_object_get (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, &list, NULL); + ASSERT (list != NULL, + "setting-connection-permissions-helpers", "unexpected failure getting permissions list"); + ASSERT (g_slist_length (list) == 1, + "setting-connection-permissions-helpers", "unexpected failure getting number of permissions in list"); + ASSERT (strcmp (list->data, expected_perm) == 0, + "setting-connection-permissions-helpers", "unexpected permission property data"); /* Now remove that permission and ensure we have 0 permissions */ nm_setting_connection_remove_permission (s_con, 0); ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, - "setting-connection-add-permission", "unexpected failure removing permission"); + "setting-connection-permissions-helpers", "unexpected failure removing permission"); + + g_object_unref (s_con); +} + +static void +add_permission_property (NMSettingConnection *s_con, + const char *ptype, + const char *pitem, + int pitem_len, + const char *detail) +{ + GString *str; + GSList *list = NULL; + + str = g_string_sized_new (50); + if (ptype) + g_string_append (str, ptype); + g_string_append_c (str, ':'); + + if (pitem) { + if (pitem_len >= 0) + g_string_append_len (str, pitem, pitem_len); + else + g_string_append (str, pitem); + } + + g_string_append_c (str, ':'); + + if (detail) + g_string_append (str, detail); + + list = g_slist_append (list, str->str); + g_object_set (G_OBJECT (s_con), NM_SETTING_CONNECTION_PERMISSIONS, list, NULL); + + g_string_free (str, TRUE); + g_slist_free (list); +} + +static void +test_setting_connection_permissions_property (void) +{ + NMSettingConnection *s_con; + gboolean success; + char buf[9] = { 0x61, 0x62, 0x63, 0xff, 0xfe, 0xfd, 0x23, 0x01, 0x00 }; + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + /* Ensure a bad [type] is rejected */ + add_permission_property (s_con, "foobar", "blah", -1, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission type #1"); + + /* Ensure a bad [type] is rejected */ + add_permission_property (s_con, NULL, "blah", -1, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission type #2"); + + /* Ensure a bad [item] is rejected */ + add_permission_property (s_con, "user", NULL, -1, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #1"); + + /* Ensure a bad [item] is rejected */ + add_permission_property (s_con, "user", "", -1, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #2"); + + /* Ensure an [item] with ':' in the middle is rejected */ + add_permission_property (s_con, "user", "ad:asdf", -1, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #3"); + + /* Ensure an [item] with ':' at the end is rejected */ + add_permission_property (s_con, "user", "adasdfaf:", -1, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #4"); + + /* Ensure a non-UTF-8 [item] is rejected */ + add_permission_property (s_con, "user", buf, (int) sizeof (buf), NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad permission item #5"); + + /* Ensure a non-NULL [detail] is rejected */ + add_permission_property (s_con, "user", "dafasdf", -1, "asdf"); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected success adding bad detail"); + + /* Ensure a valid call results in success */ + success = nm_setting_connection_add_permission (s_con, "user", TEST_UNAME, NULL); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 1, + "setting-connection-permissions-property", "unexpected failure adding valid user permisson"); + + check_permission (s_con, 0, TEST_UNAME, "setting-connection-permissions-property"); + + /* Now remove that permission and ensure we have 0 permissions */ + nm_setting_connection_remove_permission (s_con, 0); + ASSERT (nm_setting_connection_get_num_permissions (s_con) == 0, + "setting-connection-permissions-property", "unexpected failure removing permission"); g_object_unref (s_con); } @@ -498,7 +624,8 @@ int main (int argc, char **argv) test_setting_to_hash_no_secrets (); test_setting_to_hash_only_secrets (); test_connection_to_hash_setting_name (); - test_setting_connection_permissions (); + test_setting_connection_permissions_helpers (); + test_setting_connection_permissions_property (); base = g_path_get_basename (argv[0]); fprintf (stdout, "%s: SUCCESS\n", base); From 007ca5bf1fda7c068dbbad3b6ddebf0a510b7523 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 18:43:08 -0600 Subject: [PATCH 222/264] settings: use new NMSettingConnection permissions helpers --- src/settings/nm-settings-connection.c | 40 ++------------------------- 1 file changed, 3 insertions(+), 37 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index bae5fbb9b..f7190f277 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -90,37 +90,6 @@ typedef struct { /**************************************************************/ -#define USER_TAG "user:" - -/* Extract the username from the permission string and dump to a buffer */ -static gboolean -perm_to_user (const char *perm, char *out_user, gsize out_user_size) -{ - const char *end; - gsize userlen; - - g_return_val_if_fail (perm != NULL, FALSE); - g_return_val_if_fail (out_user != NULL, FALSE); - - if (!g_str_has_prefix (perm, USER_TAG)) - return FALSE; - perm += strlen (USER_TAG); - - /* Look for trailing ':' */ - end = strchr (perm, ':'); - if (!end) - end = perm + strlen (perm); - - userlen = end - perm; - if (userlen > (out_user_size + 1)) - return FALSE; - memcpy (out_user, perm, userlen); - out_user[userlen] = '\0'; - return TRUE; -} - -/**************************************************************/ - static void set_visible (NMSettingsConnection *self, gboolean new_visible) { @@ -163,13 +132,10 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self) } for (i = 0; i < num; i++) { - const char *perm; - char buf[75]; + const char *puser; - perm = nm_setting_connection_get_permission (s_con, i); - g_assert (perm); - if (perm_to_user (perm, buf, sizeof (buf))) { - if (nm_session_monitor_user_has_session (priv->session_monitor, buf, NULL, NULL)) { + if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) { + if (nm_session_monitor_user_has_session (priv->session_monitor, puser, NULL, NULL)) { set_visible (self, TRUE); return; } From 99766efbdc255fa9e9339f96692b8605c12fb891 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 18:58:19 -0600 Subject: [PATCH 223/264] ifcfg-rh: read and write connection permissions --- system-settings/plugins/ifcfg-rh/reader.c | 14 ++ .../tests/network-scripts/Makefile.am | 3 +- .../network-scripts/ifcfg-test-permissions | 8 + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 194 ++++++++++++++++++ system-settings/plugins/ifcfg-rh/writer.c | 26 ++- 5 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index 812955a7d..ca4042ff2 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -182,6 +182,20 @@ make_connection_setting (const char *file, g_free (value); } + value = svGetValue (ifcfg, "USERS", FALSE); + if (value) { + char **items, **iter; + + items = g_strsplit_set (value, " ", -1); + for (iter = items; iter && *iter; iter++) { + if (strlen (*iter)) { + if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL)) + PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: invalid USERS item '%s'", *iter); + } + } + g_free (value); + } + return NM_SETTING (s_con); } diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 44c0099fc..a2caf8793 100644 --- a/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -70,7 +70,8 @@ EXTRA_DIST = \ ifcfg-test-bridge-main \ ifcfg-test-bridge-component \ ifcfg-test-vlan-interface \ - ifcfg-test-wifi-wep-no-keys + ifcfg-test-wifi-wep-no-keys \ + ifcfg-test-permissions check-local: @for f in $(EXTRA_DIST); do \ diff --git a/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions new file mode 100644 index 000000000..5b413aa97 --- /dev/null +++ b/system-settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-permissions @@ -0,0 +1,8 @@ +# Intel Corporation 82540EP Gigabit Ethernet Controller (Mobile) +TYPE=Ethernet +DEVICE=eth0 +HWADDR=00:11:22:33:44:ee +BOOTPROTO=dhcp +ONBOOT=yes +USERS="dcbw ssmith johnny5" + diff --git a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 503498079..49a07c233 100644 --- a/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -5744,6 +5744,76 @@ test_read_wifi_wep_no_keys (void) g_object_unref (connection); } +#define TEST_IFCFG_PERMISSIONS TEST_IFCFG_DIR"/network-scripts/ifcfg-test-permissions" + +static void +test_read_permissions (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE, success; + GError *error = NULL; + guint32 num; + const char *tmp; + + connection = connection_from_file (TEST_IFCFG_PERMISSIONS, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + ASSERT (connection != NULL, + "permissions-read", "failed to read %s: %s", TEST_IFCFG_PERMISSIONS, error->message); + + ASSERT (nm_connection_verify (connection, &error), + "permissions-verify", "failed to verify %s: %s", TEST_IFCFG_PERMISSIONS, error->message); + + /* ===== CONNECTION SETTING ===== */ + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + ASSERT (s_con != NULL, + "permissions-verify-connection", "failed to verify %s: missing %s setting", + TEST_IFCFG_PERMISSIONS, + NM_SETTING_CONNECTION_SETTING_NAME); + + num = nm_setting_connection_get_num_permissions (s_con); + ASSERT (num == 3, + "permissions-verify-permissions", "unexpected number of permissions (%d, expected 3)", + num); + + /* verify each permission */ + tmp = NULL; + success = nm_setting_connection_get_permission (s_con, 0, NULL, &tmp, NULL); + ASSERT (success == TRUE, + "permissions-verify-permissions", "unexpected failure getting permission #1"); + ASSERT (strcmp (tmp, "dcbw") == 0, + "permissions-verify-permissions", "unexpected permission #1"); + + tmp = NULL; + success = nm_setting_connection_get_permission (s_con, 1, NULL, &tmp, NULL); + ASSERT (success == TRUE, + "permissions-verify-permissions", "unexpected failure getting permission #2"); + ASSERT (strcmp (tmp, "ssmith") == 0, + "permissions-verify-permissions", "unexpected permission #2"); + + tmp = NULL; + success = nm_setting_connection_get_permission (s_con, 2, NULL, &tmp, NULL); + ASSERT (success == TRUE, + "permissions-verify-permissions", "unexpected failure getting permission #3"); + ASSERT (strcmp (tmp, "johnny5") == 0, + "permissions-verify-permissions", "unexpected permission #3"); + + g_object_unref (connection); +} + static void test_write_wired_static (void) { @@ -9246,6 +9316,128 @@ test_write_wired_qeth_dhcp (void) g_object_unref (reread); } +static void +test_write_permissions (void) +{ + NMConnection *connection; + NMConnection *reread; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + NMSettingIP4Config *s_ip4; + NMSettingIP6Config *s_ip6; + char *uuid; + gboolean success; + GError *error = NULL; + char *testfile = NULL; + char *unmanaged = NULL; + char *keyfile = NULL; + char *routefile = NULL; + char *route6file = NULL; + gboolean ignore_error = FALSE; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "permissions-write", "failed to allocate new connection"); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + ASSERT (s_con != NULL, + "permissions-write", "failed to allocate new %s setting", + NM_SETTING_CONNECTION_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Permissions", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + nm_setting_connection_add_permission (s_con, "user", "blahblah", NULL); + nm_setting_connection_add_permission (s_con, "user", "foobar", NULL); + nm_setting_connection_add_permission (s_con, "user", "asdfasdf", NULL); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + ASSERT (s_wired != NULL, + "permissions-write", "failed to allocate new %s setting", + NM_SETTING_WIRED_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* IP4 setting */ + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + ASSERT (s_ip4 != NULL, + "permissions-write", "failed to allocate new %s setting", + NM_SETTING_IP4_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); + + g_object_set (s_ip4, + NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, + NULL); + + /* IP6 setting */ + s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new (); + ASSERT (s_ip6 != NULL, + "wired-qeth-dhcp-write", "failed to allocate new %s setting", + NM_SETTING_IP6_CONFIG_SETTING_NAME); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); + + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + + /* Verify */ + ASSERT (nm_connection_verify (connection, &error) == TRUE, + "permissions-write", "failed to verify connection: %s", + (error && error->message) ? error->message : "(unknown)"); + + /* Save the ifcfg */ + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &testfile, + &error); + ASSERT (success == TRUE, + "permissions-write", "failed to write connection to disk: %s", + (error && error->message) ? error->message : "(unknown)"); + + ASSERT (testfile != NULL, + "permissions-write", "didn't get ifcfg file path back after writing connection"); + + /* re-read the connection for comparison */ + reread = connection_from_file (testfile, + NULL, + TYPE_ETHERNET, + NULL, + &unmanaged, + &keyfile, + &routefile, + &route6file, + &error, + &ignore_error); + unlink (testfile); + + ASSERT (reread != NULL, + "permissions-write-reread", "failed to read %s: %s", testfile, error->message); + + ASSERT (nm_connection_verify (reread, &error), + "permissions-write-reread-verify", "failed to verify %s: %s", testfile, error->message); + + ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "permissions-write", "written and re-read connection weren't the same."); + + if (route6file) + unlink (route6file); + + g_free (testfile); + g_free (keyfile); + g_free (routefile); + g_free (route6file); + g_object_unref (connection); + g_object_unref (reread); +} + static void test_write_wired_pppoe (void) { @@ -9661,6 +9853,7 @@ int main (int argc, char **argv) test_read_wifi_wep_eap_ttls_chap (); test_read_wired_qeth_static (); test_read_wifi_wep_no_keys (); + test_read_permissions (); test_write_wired_static (); test_write_wired_static_ip6_only (); @@ -9711,6 +9904,7 @@ int main (int argc, char **argv) test_write_wifi_wpa_eap_ttls_tls (); test_write_wifi_wpa_eap_ttls_mschapv2 (); test_write_wired_qeth_dhcp (); + test_write_permissions (); /* iSCSI / ibft */ test_read_ibft_dhcp (); diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index a2d44c12f..f66a1ec6b 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -68,7 +68,7 @@ set_secret (shvarFile *ifcfg, svSetValue (ifcfg, key, NULL, FALSE); svSetValue (keyfile, key, NULL, FALSE); - /* Only write the secret if it's system owned */ + /* Only write the secret if it's system owned and supposed to be saved */ if (flags == NM_SETTING_SECRET_FLAG_NONE) svSetValue (keyfile, key, value, verbatim); @@ -969,6 +969,8 @@ static void write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) { char *tmp; + guint32 n, i; + GString *str; svSetValue (ifcfg, "NAME", nm_setting_connection_get_id (s_con), FALSE); svSetValue (ifcfg, "UUID", nm_setting_connection_get_uuid (s_con), FALSE); @@ -982,6 +984,28 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) svSetValue (ifcfg, "LAST_CONNECT", tmp, FALSE); g_free (tmp); } + + /* Permissions */ + svSetValue (ifcfg, "USERS", NULL, FALSE); + n = nm_setting_connection_get_num_permissions (s_con); + if (n > 0) { + str = g_string_sized_new (n * 20); + + for (i = 0; i < n; i++) { + const char *puser = NULL; + + /* Items separated by space for consistency with eg + * IPV6ADDR_SECONDARIES and DOMAIN. + */ + if (str->len) + g_string_append_c (str, ' '); + + if (nm_setting_connection_get_permission (s_con, i, NULL, &puser, NULL)) + g_string_append (str, puser); + } + svSetValue (ifcfg, "USERS", str->str, FALSE); + g_string_free (str, TRUE); + } } static gboolean From bad3377131c01907345a16de8f78c1fb45ed00e1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 19:16:54 -0600 Subject: [PATCH 224/264] libnm-util: update CDMA, GSM, and PPPoE settings for NOT_REQUIRED secrets --- libnm-util/nm-setting-cdma.c | 6 ++++-- libnm-util/nm-setting-gsm.c | 6 ++++-- libnm-util/nm-setting-pppoe.c | 8 +++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/libnm-util/nm-setting-cdma.c b/libnm-util/nm-setting-cdma.c index 4e70f1b1b..86f2d7bd6 100644 --- a/libnm-util/nm-setting-cdma.c +++ b/libnm-util/nm-setting-cdma.c @@ -237,8 +237,10 @@ need_secrets (NMSetting *setting) return NULL; if (priv->username) { - secrets = g_ptr_array_sized_new (1); - g_ptr_array_add (secrets, NM_SETTING_CDMA_PASSWORD); + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_CDMA_PASSWORD); + } } return secrets; diff --git a/libnm-util/nm-setting-gsm.c b/libnm-util/nm-setting-gsm.c index 55369dd7f..aeac11644 100644 --- a/libnm-util/nm-setting-gsm.c +++ b/libnm-util/nm-setting-gsm.c @@ -327,8 +327,10 @@ need_secrets (NMSetting *setting) return NULL; if (priv->username) { - secrets = g_ptr_array_sized_new (1); - g_ptr_array_add (secrets, NM_SETTING_GSM_PASSWORD); + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_GSM_PASSWORD); + } } return secrets; diff --git a/libnm-util/nm-setting-pppoe.c b/libnm-util/nm-setting-pppoe.c index 7d471b0b4..18dd7983a 100644 --- a/libnm-util/nm-setting-pppoe.c +++ b/libnm-util/nm-setting-pppoe.c @@ -163,13 +163,15 @@ static GPtrArray * need_secrets (NMSetting *setting) { NMSettingPPPOEPrivate *priv = NM_SETTING_PPPOE_GET_PRIVATE (setting); - GPtrArray *secrets; + GPtrArray *secrets = NULL; if (priv->password) return NULL; - secrets = g_ptr_array_sized_new (1); - g_ptr_array_add (secrets, NM_SETTING_PPPOE_PASSWORD); + if (!(priv->password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { + secrets = g_ptr_array_sized_new (1); + g_ptr_array_add (secrets, NM_SETTING_PPPOE_PASSWORD); + } return secrets; } From b94fb0319757c82e6b5547a24798fa7e47c912fc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 7 Feb 2011 23:45:19 -0600 Subject: [PATCH 225/264] settings: mark secrets as not required if they aren't sent to an agent If the agent doesn't have privileges for secrets, mark them as not required to help any UI validation the agent might have to do. --- src/settings/nm-agent-manager.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 8c47de973..ffdd19e8d 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -677,6 +677,31 @@ get_done_cb (NMSecretAgent *agent, req->complete_callback (req, secrets, agent_dbus_owner, agent_has_modify, NULL, req->complete_callback_data); } +static void +set_secrets_not_required (NMConnection *connection, GHashTable *hash) +{ + GHashTableIter iter, setting_iter; + const char *setting_name = NULL; + GHashTable *setting_hash = NULL; + + /* Iterate through the settings hashes */ + g_hash_table_iter_init (&iter, hash); + while (g_hash_table_iter_next (&iter, + (gpointer *) &setting_name, + (gpointer *) &setting_hash)) { + const char *key_name = NULL; + NMSetting *setting; + + setting = nm_connection_get_setting_by_name (connection, setting_name); + if (setting) { + /* Now through each secret in the setting and mark it as not required */ + g_hash_table_iter_init (&setting_iter, setting_hash); + while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, NULL)) + nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); + } + } +} + static void get_agent_request_secrets (Request *req, gboolean include_system_secrets) { @@ -686,6 +711,13 @@ get_agent_request_secrets (Request *req, gboolean include_system_secrets) nm_connection_clear_secrets (tmp); if (include_system_secrets) nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL); + else { + /* Update secret flags in the temporary connection to indicate that + * the system secrets we're not sending to the agent aren't required, + * so the agent can properly validate UI controls and such. + */ + set_secrets_not_required (tmp, req->existing_secrets); + } req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), tmp, @@ -725,7 +757,6 @@ get_agent_modify_auth_cb (NMAuthChain *chain, /* Try the next agent */ req->next_callback (req); } else { - /* If the agent obtained the 'modify' permission, we send all system secrets * to it. If it didn't, we still ask it for secrets, but we don't send * any system secrets. From d7a86ffd0480f4c7277f560d807a7058befff094 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 8 Feb 2011 20:04:12 -0600 Subject: [PATCH 226/264] libnm-util: fix VPN update_one_secret() The old function took a string value, which wasn't really correct as the property type is a GHashTable of string:string. For whatever reason this is how nm-applet passed VPN secrets back to NM in the return from the GetSecrets() D-Bus call. This was probably easier or something but it was a special case that's magic and quite unclear. Since we use nm_connection_update_secrets() more these days, and we depend on the GValue types we pass into it matching the property types of the setting property the secret is for, we need to fix that up for VPN connections. But keep the old code for backwards compatibility. In the future secret agents should pass back VPN secrets in the same form as the VPN setting specifies them for the "secrets" property: a GHashTable of string:string. But the old mechanism of just dumping the key/value pairs into the returned VPN hash as string:string will still work. --- libnm-util/nm-setting-vpn.c | 83 +++++++++++++++++++++++++++------ libnm-util/tests/test-general.c | 62 +++++++++++++++++++++++- 2 files changed, 131 insertions(+), 14 deletions(-) diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index a8b6cc755..512c2b420 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -264,34 +264,91 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } static gboolean -update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +update_secret_string (NMSetting *setting, + const char *key, + const char *value, + GError **error) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); - char *str; g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); - if (!G_VALUE_HOLDS_STRING (value)) { - g_set_error (error, NM_SETTING_ERROR, - NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, - "%s", key); - return FALSE; - } - - str = g_value_dup_string (value); - if (!str || !strlen (str)) { + if (!value || !strlen (value)) { g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, "Secret %s was empty", key); - g_free (str); return FALSE; } - g_hash_table_insert (priv->secrets, g_strdup (key), str); + g_hash_table_insert (priv->secrets, g_strdup (key), g_strdup (value)); return TRUE; } +static gboolean +update_secret_hash (NMSetting *setting, + GHashTable *secrets, + GError **error) +{ + NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + GHashTableIter iter; + const char *name, *value; + + g_return_val_if_fail (secrets != NULL, FALSE); + + /* Make sure the items are valid */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + if (!name || !strlen (name)) { + g_set_error_literal (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret name was empty"); + return FALSE; + } + + if (!value || !strlen (value)) { + g_set_error (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret %s value was empty", name); + return FALSE; + } + } + + /* Now add the items to the settings' secrets list */ + g_hash_table_iter_init (&iter, secrets); + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) + g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); + + return TRUE; +} + +static gboolean +update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) +{ + gboolean success = FALSE; + + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + if (G_VALUE_HOLDS_STRING (value)) { + /* Passing the string properties individually isn't correct, and won't + * produce the correct result, but for some reason that's how it used + * to be done. So even though it's not correct, keep the code around + * for compatibility's sake. + */ + success = update_secret_string (setting, key, g_value_get_string (value), error); + } else if (G_VALUE_HOLDS (value, DBUS_TYPE_G_MAP_OF_STRING)) { + if (strcmp (key, NM_SETTING_VPN_SECRETS) != 0) { + g_set_error (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_NOT_SECRET, + "Property %s not a secret property", key); + } else + success = update_secret_hash (setting, g_value_get_boxed (value), error); + } else + g_set_error_literal (error, NM_SETTING_ERROR, NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, key); + + return success; +} + static gboolean get_secret_flags (NMSetting *setting, const char *secret_name, diff --git a/libnm-util/tests/test-general.c b/libnm-util/tests/test-general.c index 2431947bf..a2c7b2dcb 100644 --- a/libnm-util/tests/test-general.c +++ b/libnm-util/tests/test-general.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. * */ @@ -131,6 +131,65 @@ test_setting_vpn_items (void) g_object_unref (s_vpn); } +static void +test_setting_vpn_update_secrets (void) +{ + NMConnection *connection; + NMSettingVPN *s_vpn; + GHashTable *settings, *vpn, *secrets; + GValue val = { 0 }; + gboolean success; + GError *error = NULL; + const char *tmp; + const char *key1 = "foobar"; + const char *key2 = "blahblah"; + const char *val1 = "value1"; + const char *val2 = "value2"; + + connection = nm_connection_new (); + ASSERT (connection != NULL, + "vpn-update-secrets", + "error creating connection"); + + s_vpn = (NMSettingVPN *) nm_setting_vpn_new (); + ASSERT (s_vpn != NULL, + "vpn-update-secrets", + "error creating vpn setting"); + nm_connection_add_setting (connection, NM_SETTING (s_vpn)); + + settings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_destroy); + vpn = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_value_unset); + g_hash_table_insert (settings, NM_SETTING_VPN_SETTING_NAME, vpn); + + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + g_value_init (&val, DBUS_TYPE_G_MAP_OF_STRING); + g_value_take_boxed (&val, secrets); + g_hash_table_insert (vpn, NM_SETTING_VPN_SECRETS, &val); + + /* Add some secrets */ + g_hash_table_insert (secrets, (char *) key1, (char *) val1); + g_hash_table_insert (secrets, (char *) key2, (char *) val2); + + success = nm_connection_update_secrets (connection, NM_SETTING_VPN_SETTING_NAME, settings, &error); + ASSERT (success == TRUE, + "vpn-update-secrets", "failed to update VPN secrets: %s", error->message); + + /* Read the secrets back out */ + tmp = nm_setting_vpn_get_secret (s_vpn, key1); + ASSERT (tmp != NULL, + "vpn-update-secrets", "unexpected failure getting key #1"); + ASSERT (strcmp (tmp, val1) == 0, + "vpn-update-secrets", "unexpected key #1 value"); + + tmp = nm_setting_vpn_get_secret (s_vpn, key2); + ASSERT (tmp != NULL, + "vpn-update-secrets", "unexpected failure getting key #2"); + ASSERT (strcmp (tmp, val2) == 0, + "vpn-update-secrets", "unexpected key #2 value"); + + g_object_unref (connection); +} + #define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) #define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS)) @@ -617,6 +676,7 @@ int main (int argc, char **argv) /* The tests */ test_setting_vpn_items (); + test_setting_vpn_update_secrets (); test_setting_ip6_config_old_address_array (); test_setting_gsm_apn_spaces (); test_setting_gsm_apn_bad_chars (); From b04d9e46756f373e7d33cd0d804e26f4beaf1bee Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 00:52:47 -0600 Subject: [PATCH 227/264] libnm-util: assume VPN connections need secrets Because most of the time they will. They need special handling all around anyway because only the VPN plugin itself knows whether the connection needs secrets. --- libnm-util/nm-setting-vpn.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 512c2b420..d249e0301 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -399,6 +399,13 @@ set_secret_flags (NMSetting *setting, return TRUE; } +static GPtrArray * +need_secrets (NMSetting *setting) +{ + /* Assume that VPN connections need secrets since they almost always will */ + return g_ptr_array_sized_new (1); +} + static void destroy_one_secret (gpointer data) { @@ -517,6 +524,7 @@ nm_setting_vpn_class_init (NMSettingVPNClass *setting_class) parent_class->update_one_secret = update_one_secret; parent_class->get_secret_flags = get_secret_flags; parent_class->set_secret_flags = set_secret_flags; + parent_class->need_secrets = need_secrets; /* Properties */ /** From aafe74ee340873bae691453de7e925d8f1f888c3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 00:54:00 -0600 Subject: [PATCH 228/264] vpn: get existing secrets before asking VPN service if we need more This allows administrators to define VPN connections that use all or partial system-owned secrets that users aren't allowed to modify. --- src/vpn-manager/nm-vpn-connection.c | 66 ++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 7081f227a..15a60cec2 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -837,18 +837,62 @@ connection_need_secrets_cb (DBusGProxy *proxy, } static void -call_need_secrets (NMVPNConnection *vpn_connection) +existing_secrets_cb (NMSettingsConnection *connection, + guint32 call_id, + const char *setting_name, + GError *error, + gpointer user_data) { - NMVPNConnectionPrivate *priv; - GHashTable *settings; + NMVPNConnection *self = NM_VPN_CONNECTION (user_data); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + GHashTable *hash; - priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); - settings = nm_connection_to_hash (priv->connection, NM_SETTING_HASH_FLAG_ALL); - org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy, - settings, - connection_need_secrets_cb, - vpn_connection); - g_hash_table_destroy (settings); + g_return_if_fail (NM_CONNECTION (connection) == priv->connection); + g_return_if_fail (call_id == priv->secrets_id); + + priv->secrets_id = 0; + + if (error) { + nm_log_err (LOGD_VPN, "Failed to request existing VPN secrets #2: (%s) %s", + g_quark_to_string (error->domain), + error->message); + nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + } else { + /* Ask the VPN service if more secrets are required */ + hash = nm_connection_to_hash (priv->connection, NM_SETTING_HASH_FLAG_ALL); + org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy, + hash, + connection_need_secrets_cb, + self); + g_hash_table_destroy (hash); + } +} + +static void +get_existing_secrets (NMVPNConnection *self) +{ + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; + + /* Just get existing secrets if any so we can ask the VPN service if + * any more are required. + */ + priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), + priv->user_requested, + priv->user_uid, + NM_SETTING_VPN_SETTING_NAME, + NM_ACT_REQUEST_GET_SECRETS_FLAG_NONE, + NULL, + existing_secrets_cb, + self, + &error); + if (priv->secrets_id == 0) { + nm_log_err (LOGD_VPN, "Failed to request existing VPN secrets #1: (%s) %s", + g_quark_to_string (error->domain), + error->message); + g_error_free (error); + nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); + } } static void @@ -921,7 +965,7 @@ connection_state_changed (NMVPNConnection *self, switch (state) { case NM_VPN_CONNECTION_STATE_NEED_AUTH: - call_need_secrets (self); + get_existing_secrets (self); break; case NM_VPN_CONNECTION_STATE_DISCONNECTED: case NM_VPN_CONNECTION_STATE_FAILED: From be628d9f9b3d0bf6b0288197490140cc189cdb48 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 16:28:57 -0600 Subject: [PATCH 229/264] trivial: spacing cleanups --- libnm-util/nm-connection.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 2a51428fc..02266b1ff 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -89,8 +89,10 @@ NMConnection *nm_connection_new_from_hash (GHashTable *hash, GError **error); NMConnection *nm_connection_duplicate (NMConnection *connection); +NMSetting *nm_connection_create_setting (const char *name); + void nm_connection_add_setting (NMConnection *connection, - NMSetting *setting); + NMSetting *setting); void nm_connection_remove_setting (NMConnection *connection, GType setting_type); @@ -99,7 +101,7 @@ NMSetting *nm_connection_get_setting (NMConnection *connection, GType setting_type); NMSetting *nm_connection_get_setting_by_name (NMConnection *connection, - const char *name); + const char *name); gboolean nm_connection_replace_settings (NMConnection *connection, GHashTable *new_settings, @@ -121,10 +123,10 @@ gboolean nm_connection_update_secrets (NMConnection *connection, GHashTable *secrets, GError **error); -void nm_connection_set_path (NMConnection *connection, - const char *path); +void nm_connection_set_path (NMConnection *connection, + const char *path); -const char * nm_connection_get_path (NMConnection *connection); +const char * nm_connection_get_path (NMConnection *connection); void nm_connection_for_each_setting_value (NMConnection *connection, NMSettingValueIterFn func, @@ -135,11 +137,9 @@ GHashTable *nm_connection_to_hash (NMConnection *connection, void nm_connection_dump (NMConnection *connection); -NMSetting *nm_connection_create_setting (const char *name); +GType nm_connection_lookup_setting_type (const char *name); -GType nm_connection_lookup_setting_type (const char *name); - -GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark); +GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark); G_END_DECLS From 09d608b99ca533c973e2fe1b0b3cd2ed0203a997 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 16:30:30 -0600 Subject: [PATCH 230/264] trivial: more spacing cleanups --- libnm-util/nm-connection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 2415edf92..908a93e9b 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -225,9 +225,9 @@ register_default_settings (void) 1); register_one_setting (NM_SETTING_BLUETOOTH_SETTING_NAME, - NM_TYPE_SETTING_BLUETOOTH, - NM_SETTING_BLUETOOTH_ERROR, - 1); + NM_TYPE_SETTING_BLUETOOTH, + NM_SETTING_BLUETOOTH_ERROR, + 1); register_one_setting (NM_SETTING_WIMAX_SETTING_NAME, NM_TYPE_SETTING_WIMAX, From c5235f87db7354aa24b8ef0c9c7854d0d50108c6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 16:34:42 -0600 Subject: [PATCH 231/264] libnm-util: add connection helpers for ID and UUID Shortcuts. Getting the ID and UUID is used in a ton of places and this helps cut down on code. --- libnm-util/libnm-util.ver | 2 ++ libnm-util/nm-connection.c | 45 ++++++++++++++++++++++++++++++++++++++ libnm-util/nm-connection.h | 5 +++++ 3 files changed, 52 insertions(+) diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 0b7557a33..22bd5a140 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -9,9 +9,11 @@ global: nm_connection_error_get_type; nm_connection_error_quark; nm_connection_for_each_setting_value; + nm_connection_get_id; nm_connection_get_path; nm_connection_get_setting; nm_connection_get_setting_by_name; + nm_connection_get_uuid; nm_connection_get_type; nm_connection_lookup_setting_type; nm_connection_lookup_setting_type_by_quark; diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index 908a93e9b..ec3390720 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -1040,6 +1040,51 @@ nm_connection_duplicate (NMConnection *connection) return dup; } +/** + * nm_connection_get_uuid: + * @connection: the #NMConnection + * + * A shortcut to return the UUID from the connections #NMSettingConnection. + * + * Returns: the UUID from the connection's 'connection' setting + **/ +const char * +nm_connection_get_uuid (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_uuid (s_con); +} + +/** + * nm_connection_get_uuid: + * @connection: the #NMConnection + * + * A shortcut to return the UUID from the connections #NMSettingConnection. + * + * Returns: the UUID from the connection's 'connection' setting + **/ +const char *nm_connection_get_id (NMConnection *connection) +{ + NMSettingConnection *s_con; + + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_return_val_if_fail (s_con != NULL, NULL); + + return nm_setting_connection_get_id (s_con); +} + +/*************************************************************/ + static void nm_connection_init (NMConnection *connection) { diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 02266b1ff..fce715ab1 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -141,6 +141,11 @@ GType nm_connection_lookup_setting_type (const char *name); GType nm_connection_lookup_setting_type_by_quark (GQuark error_quark); +/* Helpers */ +const char * nm_connection_get_uuid (NMConnection *connection); + +const char * nm_connection_get_id (NMConnection *connection); + G_END_DECLS #endif /* NM_CONNECTION_H */ From 3ea94580169ba22b55e040607703ae765581f69c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 16:41:33 -0600 Subject: [PATCH 232/264] keyfile: use nm_connection_get_id() and nm_connection_get_uuid() --- system-settings/plugins/keyfile/plugin.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index ec37ed311..b72ec1051 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -77,7 +77,6 @@ _internal_new_connection (SCPluginKeyfile *self, GError **error) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - NMSettingConnection *s_con; const char *cid, *uuid; NMKeyfileConnection *connection; @@ -87,13 +86,9 @@ _internal_new_connection (SCPluginKeyfile *self, if (!connection) return NULL; - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), - NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - - cid = nm_setting_connection_get_id (s_con); + cid = nm_connection_get_id (NM_CONNECTION (connection)); g_assert (cid); - uuid = nm_setting_connection_get_uuid (s_con); + uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); g_assert (uuid); g_hash_table_insert (priv->hash, @@ -199,11 +194,8 @@ find_by_uuid (SCPluginKeyfile *self, const char *uuid) g_hash_table_iter_init (&iter, priv->hash); while (g_hash_table_iter_next (&iter, NULL, &data)) { NMConnection *candidate = NM_CONNECTION (data); - NMSettingConnection *s_con; - s_con = (NMSettingConnection *) nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - if (strcmp (uuid, nm_setting_connection_get_uuid (s_con)) == 0) + if (strcmp (uuid, nm_connection_get_uuid (candidate)) == 0) return NM_KEYFILE_CONNECTION (candidate); } return NULL; From a96b4c50827da4e6e47057677d819b27059a2c7c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 17:07:24 -0600 Subject: [PATCH 233/264] keyfile: use nm_connection_get_id() more --- system-settings/plugins/keyfile/writer.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index a09215d62..2fc880e18 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -695,20 +695,23 @@ nm_keyfile_plugin_write_connection (NMConnection *connection, char **out_path, GError **error) { - NMSettingConnection *s_con; GKeyFile *key_file; char *data; gsize len; gboolean success = FALSE; char *filename, *path; int err; + const char *id; if (out_path) g_return_val_if_fail (*out_path == NULL, FALSE); - s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); - if (!s_con) - return success; + id = nm_connection_get_id (connection); + if (!id) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: connection had no ID", __FILE__, __LINE__); + return FALSE; + } key_file = g_key_file_new (); nm_connection_for_each_setting_value (connection, write_setting_value, key_file); @@ -716,7 +719,7 @@ nm_keyfile_plugin_write_connection (NMConnection *connection, if (!data) goto out; - filename = _writer_id_to_filename (nm_setting_connection_get_id (s_con)); + filename = _writer_id_to_filename (id); path = g_build_filename (keyfile_dir, filename, NULL); g_free (filename); From d654836c6ff9d05fd4f37ec929eb8ea8f35d692e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 17:07:43 -0600 Subject: [PATCH 234/264] keyfile: require a UUID in the connection settings The connection needs a UUID, period. --- .../plugins/keyfile/nm-keyfile-connection.c | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 9dd2c750d..0c9912e21 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -47,8 +47,8 @@ nm_keyfile_connection_new (const char *full_path, { GObject *object; NMKeyfileConnectionPrivate *priv; - NMSettingConnection *s_con; NMConnection *tmp; + const char *uuid; g_return_val_if_fail (full_path != NULL, NULL); @@ -75,24 +75,12 @@ nm_keyfile_connection_new (const char *full_path, goto out; } - /* if for some reason the connection didn't have a UUID, add one */ - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (object), NM_TYPE_SETTING_CONNECTION); - if (s_con && !nm_setting_connection_get_uuid (s_con)) { - GError *write_error = NULL; - char *uuid; - - uuid = nm_utils_uuid_generate (); - g_object_set (s_con, NM_SETTING_CONNECTION_UUID, uuid, NULL); - g_free (uuid); - - if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (object), KEYFILE_DIR, 0, 0, NULL, &write_error)) { - PLUGIN_WARN (KEYFILE_PLUGIN_NAME, - "Couldn't update connection %s with a UUID: (%d) %s", - nm_setting_connection_get_id (s_con), - write_error ? write_error->code : -1, - (write_error && write_error->message) ? write_error->message : "(unknown)"); - g_propagate_error (error, write_error); - } + uuid = nm_connection_get_uuid (NM_CONNECTION (object)); + if (!uuid) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Connection in file %s had no UUID", full_path); + g_object_unref (object); + object = NULL; } out: From f1d02935174b9d1fc5f89702da018450d5b9325c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 17:11:13 -0600 Subject: [PATCH 235/264] keyfile: trivial code simplification --- system-settings/plugins/keyfile/writer.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 2fc880e18..2fcd306e0 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -700,7 +700,6 @@ nm_keyfile_plugin_write_connection (NMConnection *connection, gsize len; gboolean success = FALSE; char *filename, *path; - int err; const char *id; if (out_path) @@ -730,8 +729,7 @@ nm_keyfile_plugin_write_connection (NMConnection *connection, path, errno); unlink (path); } else { - err = chmod (path, S_IRUSR | S_IWUSR); - if (err) { + if (chmod (path, S_IRUSR | S_IWUSR) < 0) { g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, "%s.%d: error setting permissions on '%s': %d", __FILE__, __LINE__, path, errno); From eddc66e36dcd70d2ba4251356ee526f2813b23b5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 17:23:10 -0600 Subject: [PATCH 236/264] keyfile: split nm_keyfile_plugin_write_connection() The non-test function doesn't need to take as many arguments, which makes the code a lot cleaner to look at in the plugin and connection subclass. --- .../plugins/keyfile/nm-keyfile-connection.c | 5 +- system-settings/plugins/keyfile/plugin.c | 33 +++++-------- .../plugins/keyfile/tests/test-keyfile.c | 12 ++--- system-settings/plugins/keyfile/writer.c | 48 ++++++++++++++++--- system-settings/plugins/keyfile/writer.h | 11 +++-- 5 files changed, 71 insertions(+), 38 deletions(-) diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 0c9912e21..048cd0cd4 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -105,7 +105,10 @@ commit_changes (NMSettingsConnection *connection, char *path = NULL; GError *error = NULL; - if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection), KEYFILE_DIR, 0, 0, &path, &error)) { + if (!nm_keyfile_plugin_write_connection (NM_CONNECTION (connection), + priv->path, + &path, + &error)) { callback (connection, error, user_data); g_clear_error (&error); return; diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index b72ec1051..ba56467d7 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -73,31 +73,21 @@ static NMSettingsConnection * _internal_new_connection (SCPluginKeyfile *self, const char *full_path, NMConnection *source, - const char **out_cid, GError **error) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - const char *cid, *uuid; NMKeyfileConnection *connection; g_return_val_if_fail (full_path != NULL, NULL); connection = nm_keyfile_connection_new (full_path, source, error); - if (!connection) - return NULL; + if (connection) { + g_hash_table_insert (priv->hash, + (gpointer) nm_keyfile_connection_get_path (connection), + connection); + } - cid = nm_connection_get_id (NM_CONNECTION (connection)); - g_assert (cid); - uuid = nm_connection_get_uuid (NM_CONNECTION (connection)); - g_assert (uuid); - - g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_path (connection), - connection); - - if (out_cid) - *out_cid = cid; - return NM_SETTINGS_CONNECTION (connection); + return (NMSettingsConnection *) connection; } static void @@ -106,7 +96,7 @@ read_connections (NMSystemConfigInterface *config) SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); GDir *dir; GError *error = NULL; - const char *item, *cid; + const char *item; dir = g_dir_open (KEYFILE_DIR, 0, &error); if (!dir) { @@ -128,9 +118,10 @@ read_connections (NMSystemConfigInterface *config) full_path = g_build_filename (KEYFILE_DIR, item, NULL); PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item); - connection = _internal_new_connection (self, full_path, NULL, &cid, &error); + connection = _internal_new_connection (self, full_path, NULL, &error); if (connection) { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", cid); + PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", + nm_connection_get_id (NM_CONNECTION (connection))); } else { PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", (error && error->message) ? error->message : "(unknown)"); @@ -408,8 +399,8 @@ add_connection (NMSystemConfigInterface *config, char *path = NULL; /* Write it out first, then add the connection to our internal list */ - if (nm_keyfile_plugin_write_connection (connection, KEYFILE_DIR, 0, 0, &path, error)) { - added = _internal_new_connection (self, path, connection, NULL, error); + if (nm_keyfile_plugin_write_connection (connection, NULL, &path, error)) { + added = _internal_new_connection (self, path, connection, error); g_free (path); } return added; diff --git a/system-settings/plugins/keyfile/tests/test-keyfile.c b/system-settings/plugins/keyfile/tests/test-keyfile.c index e79c8a330..1aed7a0e6 100644 --- a/system-settings/plugins/keyfile/tests/test-keyfile.c +++ b/system-settings/plugins/keyfile/tests/test-keyfile.c @@ -693,7 +693,7 @@ test_write_wired_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -953,7 +953,7 @@ test_write_ip6_wired_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1271,7 +1271,7 @@ test_write_wireless_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1401,7 +1401,7 @@ test_write_string_ssid (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1699,7 +1699,7 @@ test_write_bt_dun_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); @@ -1961,7 +1961,7 @@ test_write_gsm_connection (void) /* Write out the connection */ owner_uid = geteuid (); owner_grp = getegid (); - success = nm_keyfile_plugin_write_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); ASSERT (success == TRUE, "connection-write", "failed to allocate write keyfile: %s", error ? error->message : "(none)"); diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 2fcd306e0..87772cdf8 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -687,13 +687,14 @@ _writer_id_to_filename (const char *id) return filename; } -gboolean -nm_keyfile_plugin_write_connection (NMConnection *connection, - const char *keyfile_dir, - uid_t owner_uid, - pid_t owner_grp, - char **out_path, - GError **error) +static gboolean +_internal_write_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + const char *existing_path, + char **out_path, + GError **error) { GKeyFile *key_file; char *data; @@ -722,6 +723,8 @@ nm_keyfile_plugin_write_connection (NMConnection *connection, path = g_build_filename (keyfile_dir, filename, NULL); g_free (filename); + /* If the file already exists */ + g_file_set_contents (path, data, len, error); if (chown (path, owner_uid, owner_grp) < 0) { g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, @@ -747,3 +750,34 @@ out: g_key_file_free (key_file); return success; } + +gboolean +nm_keyfile_plugin_write_connection (NMConnection *connection, + const char *existing_path, + char **out_path, + GError **error) +{ + return _internal_write_connection (connection, + KEYFILE_DIR, + 0, 0, + existing_path, + out_path, + error); +} + +gboolean +nm_keyfile_plugin_write_test_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char **out_path, + GError **error) +{ + return _internal_write_connection (connection, + keyfile_dir, + owner_uid, owner_grp, + NULL, + out_path, + error); +} + diff --git a/system-settings/plugins/keyfile/writer.h b/system-settings/plugins/keyfile/writer.h index 730a9b3bd..a602f2f4a 100644 --- a/system-settings/plugins/keyfile/writer.h +++ b/system-settings/plugins/keyfile/writer.h @@ -27,10 +27,15 @@ #include gboolean nm_keyfile_plugin_write_connection (NMConnection *connection, - const char *keyfile_dir, - uid_t owner_uid, - pid_t owner_grp, + const char *existing_path, char **out_path, GError **error); +gboolean nm_keyfile_plugin_write_test_connection (NMConnection *connection, + const char *keyfile_dir, + uid_t owner_uid, + pid_t owner_grp, + char **out_path, + GError **error); + #endif /* _KEYFILE_PLUGIN_WRITER_H */ From 275e5c5e62c2ac41512924f8459e4cd4855a4487 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 18:09:47 -0600 Subject: [PATCH 237/264] keyfile: handle different connections with the same ID Since keyfile uses the connection's ID as the filename by default, we could run into a situation where two connections with the same ID are visible to different users. We don't want one connection overwriting the other in that case, so we need to pick a new name for one of them. Append the connection's UUID to the end to minimize the risk of further conflicts for that name. --- .../plugins/keyfile/nm-keyfile-connection.c | 7 ++-- system-settings/plugins/keyfile/writer.c | 32 ++++++++++++++++--- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 048cd0cd4..23618f7c2 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -114,12 +114,11 @@ commit_changes (NMSettingsConnection *connection, return; } - if (g_strcmp0 (priv->path, path)) { - /* Update the filename if it changed */ + /* Update the filename if it changed */ + if (path) { g_free (priv->path); priv->path = path; - } else - g_free (path); + } NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->commit_changes (connection, callback, diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 87772cdf8..5bea8348d 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -700,7 +700,7 @@ _internal_write_connection (NMConnection *connection, char *data; gsize len; gboolean success = FALSE; - char *filename, *path; + char *filename = NULL, *path; const char *id; if (out_path) @@ -721,9 +721,28 @@ _internal_write_connection (NMConnection *connection, filename = _writer_id_to_filename (id); path = g_build_filename (keyfile_dir, filename, NULL); - g_free (filename); - /* If the file already exists */ + /* If a file with this path already exists (but isn't the existing path + * of the connection) then we need another name. Multiple connections + * can have the same ID (ie if two connections with the same ID are visible + * to different users) but of course can't have the same path. Yeah, + * there's a race here, but there's not a lot we can do about it, and + * we shouldn't get more than one connection with the same UUID either. + */ + if (g_file_test (path, G_FILE_TEST_EXISTS) && (g_strcmp0 (path, existing_path) != 0)) { + /* A keyfile with this connection's ID already exists. Pick another name. */ + g_free (path); + + path = g_strdup_printf ("%s/%s-%s", keyfile_dir, filename, nm_connection_get_uuid (connection)); + if (g_file_test (path, G_FILE_TEST_EXISTS)) { + /* Hmm, this is odd. Give up. */ + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "%s.%d: could not find suitable keyfile file name (%s already used)", + __FILE__, __LINE__, path); + g_free (path); + goto out; + } + } g_file_set_contents (path, data, len, error); if (chown (path, owner_uid, owner_grp) < 0) { @@ -738,14 +757,17 @@ _internal_write_connection (NMConnection *connection, __LINE__, path, errno); unlink (path); } else { - if (out_path) - *out_path = g_strdup (path); + if (out_path && g_strcmp0 (existing_path, path)) { + *out_path = path; /* pass path out to caller */ + path = NULL; + } success = TRUE; } } g_free (path); out: + g_free (filename); g_free (data); g_key_file_free (key_file); return success; From db41fe3cf2b8048eda0229a0b541a441a558d85e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 18:41:17 -0600 Subject: [PATCH 238/264] settings: add error for already existing UUID --- src/settings/nm-settings-error.c | 12 ++++++++++-- src/settings/nm-settings-error.h | 7 ++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/settings/nm-settings-error.c b/src/settings/nm-settings-error.c index 025ae581a..7e24fb71f 100644 --- a/src/settings/nm-settings-error.c +++ b/src/settings/nm-settings-error.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #include "nm-settings-error.h" @@ -57,14 +57,22 @@ nm_settings_error_get_type (void) ENUM_ENTRY (NM_SETTINGS_ERROR_PERMISSION_DENIED, "PermissionDenied"), /* The requested setting does not existing in this connection. */ ENUM_ENTRY (NM_SETTINGS_ERROR_INVALID_SETTING, "InvalidSetting"), - + /* The caller does not have permission to perform this operation */ ENUM_ENTRY (NM_SETTINGS_ERROR_NOT_PRIVILEGED, "NotPrivileged"), + /* No plugin supports adding new connections */ ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_NOT_SUPPORTED, "AddNotSupported"), + /* The plugin providing this connection does not support updating it */ ENUM_ENTRY (NM_SETTINGS_ERROR_UPDATE_NOT_SUPPORTED, "UpdateNotSupported"), + /* The plugin providing this connection does not support deleting it */ ENUM_ENTRY (NM_SETTINGS_ERROR_DELETE_NOT_SUPPORTED, "DeleteNotSupported"), + /* Failed to add the connection */ ENUM_ENTRY (NM_SETTINGS_ERROR_ADD_FAILED, "AddFailed"), + /* No plugin supports modifying the system hostname */ ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, "SaveHostnameNotSupported"), + /* Saving the system hostname failed */ ENUM_ENTRY (NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, "SaveHostnameFailed"), + /* A connection with this UUID already exists */ + ENUM_ENTRY (NM_SETTINGS_ERROR_UUID_EXISTS, "UuidExists"), { 0, 0, 0 } }; diff --git a/src/settings/nm-settings-error.h b/src/settings/nm-settings-error.h index 45996a2f2..b782a7791 100644 --- a/src/settings/nm-settings-error.h +++ b/src/settings/nm-settings-error.h @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. + * Copyright (C) 2008 - 2011 Red Hat, Inc. */ #ifndef NM_SETTINGS_ERROR_H @@ -41,12 +41,13 @@ enum { NM_SETTINGS_ERROR_ADD_FAILED, NM_SETTINGS_ERROR_SAVE_HOSTNAME_NOT_SUPPORTED, NM_SETTINGS_ERROR_SAVE_HOSTNAME_FAILED, + NM_SETTINGS_ERROR_UUID_EXISTS, }; #define NM_SETTINGS_ERROR (nm_settings_error_quark ()) -#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) +GQuark nm_settings_error_quark (void); -GQuark nm_settings_error_quark (void); +#define NM_TYPE_SETTINGS_ERROR (nm_settings_error_get_type ()) GType nm_settings_error_get_type (void); #endif /* NM_SETTINGS_ERROR_H */ From 1f313f36f09a0f0bbbfcae485e6f1e622a682ac8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 18:41:48 -0600 Subject: [PATCH 239/264] settings: do some basic validate in AddConnection Like making sure the connection verifies, and making sure the new connection's UUID is indeed unique. --- src/settings/nm-settings.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index b28ae36dd..7276094fa 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -749,6 +749,21 @@ add_new_connection (NMSettings *self, NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GSList *iter; NMSettingsConnection *added = NULL; + GHashTableIter citer; + NMConnection *candidate = NULL; + + /* Make sure a connection with this UUID doesn't already exist */ + g_hash_table_iter_init (&citer, priv->connections); + while (g_hash_table_iter_next (&citer, NULL, (gpointer *) &candidate)) { + if (g_strcmp0 (nm_connection_get_uuid (connection), + nm_connection_get_uuid (candidate)) == 0) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_UUID_EXISTS, + "A connection with this UUID already exists."); + return NULL; + } + } /* 1) plugin writes the NMConnection to disk * 2) plugin creates a new NMSettingsConnection subclass with the settings @@ -881,7 +896,20 @@ nm_settings_add_connection (NMSettings *self, { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMAuthChain *chain; - GError *error; + GError *error = NULL, *tmp_error = NULL; + + /* Connection must be valid, of course */ + if (!nm_connection_verify (connection, &tmp_error)) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_INVALID_CONNECTION, + "The connection was invalid: %s", + tmp_error ? tmp_error->message : "(unknown)"); + g_error_free (tmp_error); + + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } /* Do any of the plugins support adding? */ if (!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) { From d8715124677bb3a4443c127bc987575d075fba03 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 9 Feb 2011 20:44:27 -0600 Subject: [PATCH 240/264] ifcfg-rh: handle different connections with the same ID Since ifcfg-rh uses the connection's ID as the filename by default, we could run into a situation where two connections with the same ID are visible to different users. We don't want one connection overwriting the other in that case, so we need to pick a new name for the one we're about to write. --- system-settings/plugins/ifcfg-rh/writer.c | 27 ++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/system-settings/plugins/ifcfg-rh/writer.c b/system-settings/plugins/ifcfg-rh/writer.c index f66a1ec6b..ccb4676b5 100644 --- a/system-settings/plugins/ifcfg-rh/writer.c +++ b/system-settings/plugins/ifcfg-rh/writer.c @@ -1603,8 +1603,33 @@ write_connection (NMConnection *connection, escaped = escape_id (nm_setting_connection_get_id (s_con)); ifcfg_name = g_strdup_printf ("%s/ifcfg-%s", ifcfg_dir, escaped); - ifcfg = svCreateFile (ifcfg_name); + + /* If a file with this path already exists then we need another name. + * Multiple connections can have the same ID (ie if two connections with + * the same ID are visible to different users) but of course can't have + * the same path. + */ + if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS)) { + guint32 idx = 0; + + g_free (ifcfg_name); + while (idx++ < 500) { + ifcfg_name = g_strdup_printf ("%s/ifcfg-%s %u", ifcfg_dir, escaped, idx); + if (g_file_test (ifcfg_name, G_FILE_TEST_EXISTS) == FALSE) + break; + g_free (ifcfg_name); + ifcfg_name = NULL; + } + } g_free (escaped); + + if (ifcfg_name == NULL) { + g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, + "Failed to find usable ifcfg file name"); + return FALSE; + } + + ifcfg = svCreateFile (ifcfg_name); } if (!ifcfg) { From a6edda0b136c7a93e6bdb03bc7ceec8782bff044 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 11:34:13 -0600 Subject: [PATCH 241/264] vpn: more logging during secrets requests --- src/vpn-manager/nm-vpn-connection.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 15a60cec2..7503d24fc 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -814,11 +814,20 @@ connection_need_secrets_cb (DBusGProxy *proxy, } if (!setting_name || !strlen (setting_name)) { + nm_log_dbg (LOGD_VPN, "(%s/%s) service indicated no additional secrets required", + nm_connection_get_uuid (priv->connection), + nm_connection_get_id (priv->connection)); + /* No secrets required */ really_activate (self); return; } + nm_log_dbg (LOGD_VPN, "(%s/%s) service indicated additional '%s' secrets required", + nm_connection_get_uuid (priv->connection), + nm_connection_get_id (priv->connection), + setting_name); + priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->user_requested, priv->user_uid, @@ -858,6 +867,10 @@ existing_secrets_cb (NMSettingsConnection *connection, error->message); nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); } else { + nm_log_dbg (LOGD_VPN, "(%s/%s) asking service if additional secrets are required", + nm_connection_get_uuid (priv->connection), + nm_connection_get_id (priv->connection)); + /* Ask the VPN service if more secrets are required */ hash = nm_connection_to_hash (priv->connection, NM_SETTING_HASH_FLAG_ALL); org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy, @@ -874,6 +887,10 @@ get_existing_secrets (NMVPNConnection *self) NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); GError *error = NULL; + nm_log_dbg (LOGD_VPN, "(%s/%s) requesting existing VPN secrets", + nm_connection_get_uuid (priv->connection), + nm_connection_get_id (priv->connection)); + /* Just get existing secrets if any so we can ask the VPN service if * any more are required. */ From 9d2889a4a7f2766e1559f66cfacf87f4e89d7513 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 11:34:35 -0600 Subject: [PATCH 242/264] agents: send available secrets to the agents The caller has already taken care of making sure that the agent is privileged enough to have secrets, so send them along if the caller gave them to us. --- src/settings/nm-secret-agent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 03f9a2323..67aea821c 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -187,7 +187,7 @@ nm_secret_agent_get_secrets (NMSecretAgent *self, priv = NM_SECRET_AGENT_GET_PRIVATE (self); - hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_NO_SECRETS); + hash = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); r->call = dbus_g_proxy_begin_call_with_timeout (priv->proxy, From ee2c19a64f2675e6b8e7d89ec206f1e3017dd8f0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 11:36:00 -0600 Subject: [PATCH 243/264] agents: correctly handle VPN secrets when marking them as not required We need to iterate through each item in the VPN's 'secrets' property and mark it as not required, instead of just marking the 'secrets' property itself as not required. Yeah, VPN secrets are a bit annoying. --- src/settings/nm-agent-manager.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index ffdd19e8d..fc4c7e6a5 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -34,6 +34,7 @@ #include "nm-dbus-glib-types.h" #include "nm-polkit-helpers.h" #include "nm-manager-auth.h" +#include "nm-setting-vpn.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -691,13 +692,29 @@ set_secrets_not_required (NMConnection *connection, GHashTable *hash) (gpointer *) &setting_hash)) { const char *key_name = NULL; NMSetting *setting; + GValue *val; setting = nm_connection_get_setting_by_name (connection, setting_name); if (setting) { /* Now through each secret in the setting and mark it as not required */ g_hash_table_iter_init (&setting_iter, setting_hash); - while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, NULL)) - nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); + while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, (gpointer *) &val)) { + /* For each secret, set the flag that it's not required; VPN + * secrets need slightly different treatment here since the + * "secrets" property is actually a hash table of secrets. + */ + if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 + && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0 + && G_VALUE_HOLDS (val, DBUS_TYPE_G_MAP_OF_STRING)) { + GHashTableIter vpn_secret_iter; + const char *secret_name; + + g_hash_table_iter_init (&vpn_secret_iter, g_value_get_boxed (val)); + while (g_hash_table_iter_next (&vpn_secret_iter, (gpointer *) &secret_name, NULL)) + nm_setting_set_secret_flags (setting, secret_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); + } else + nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); + } } } } From 2ec115bb64f8f2abd435d0fba2579d928ef21a79 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 18:07:04 -0600 Subject: [PATCH 244/264] vpn: clear secrets after successful activation We're already connected; shouldn't need secrets again but if we do, we'll ask for them again. Fixes an issue where reconnect would use an old one-time-password. --- src/vpn-manager/nm-vpn-connection.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 7503d24fc..e84c35320 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -984,6 +984,10 @@ connection_state_changed (NMVPNConnection *self, case NM_VPN_CONNECTION_STATE_NEED_AUTH: get_existing_secrets (self); break; + case NM_VPN_CONNECTION_STATE_ACTIVATED: + /* Secrets no longer needed now that we're connected */ + nm_connection_clear_secrets (priv->connection); + break; case NM_VPN_CONNECTION_STATE_DISCONNECTED: case NM_VPN_CONNECTION_STATE_FAILED: if (priv->proxy) { From 67051f644534ffdbdb4b2eaac7c203bcb39607ac Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 18:43:20 -0600 Subject: [PATCH 245/264] keyfile: don't write not-saved or not-required VPN secrets VPN secrets need special handling here since they are in a 3rd level hash. --- system-settings/plugins/keyfile/writer.c | 50 +++++++++++------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c index 5bea8348d..0887730a3 100644 --- a/system-settings/plugins/keyfile/writer.c +++ b/system-settings/plugins/keyfile/writer.c @@ -415,43 +415,37 @@ mac_address_writer (GKeyFile *file, g_key_file_set_string (file, setting_name, key, mac); } -typedef struct { - GKeyFile *file; - const char *setting_name; -} WriteStringHashInfo; - -static void -write_hash_of_string_helper (gpointer key, gpointer data, gpointer user_data) -{ - WriteStringHashInfo *info = (WriteStringHashInfo *) user_data; - const char *property = (const char *) key; - const char *value = (const char *) data; - - g_key_file_set_string (info->file, - info->setting_name, - property, - value); -} - static void write_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key, const GValue *value) { - GHashTable *hash = g_value_get_boxed (value); - WriteStringHashInfo info; - - info.file = file; + GHashTableIter iter; + const char *property = NULL, *data = NULL; + const char *group_name = nm_setting_get_name (setting); + gboolean vpn_secrets = FALSE; /* Write VPN secrets out to a different group to keep them separate */ - if ( (G_OBJECT_TYPE (setting) == NM_TYPE_SETTING_VPN) - && !strcmp (key, NM_SETTING_VPN_SECRETS)) { - info.setting_name = VPN_SECRETS_GROUP; - } else - info.setting_name = nm_setting_get_name (setting); + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + group_name = VPN_SECRETS_GROUP; + vpn_secrets = TRUE; + } - g_hash_table_foreach (hash, write_hash_of_string_helper, &info); + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &property, (gpointer *) &data)) { + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + + /* Handle VPN secrets specially; they are nested in the property's hash; + * we don't want to write them if the secret is not saved or not required. + */ + if (vpn_secrets && nm_setting_get_secret_flags (setting, property, &flags, NULL)) { + if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + continue; + } + + g_key_file_set_string (file, group_name, property, data); + } } static void From e42e3924187b99186d8c651847e4b2ce5e9fc228 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 18:45:13 -0600 Subject: [PATCH 246/264] settings: ensure not-saved or not-required VPN secrets don't propagate We don't want these secrets in the NMSettingsConnection's internal secrets cache since they shoulnd't ever be read off-disk, and they should be discarded immedaitely after use. Similarly, we want to remove any of these secrets that do come through from a secrets request that doesn't allow user-interaction, since not-saved secrets aren't allowed there. --- src/settings/nm-settings-connection.c | 57 ++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index f7190f277..eaafcfe88 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "nm-settings-connection.h" @@ -163,9 +164,23 @@ only_system_secrets_cb (NMSetting *setting, if (flags & NM_SETTING_PARAM_SECRET) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; - nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); - if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) - g_object_set (G_OBJECT (setting), key, NULL, NULL); + /* VPNs are special; need to handle each secret separately */ + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + GHashTableIter iter; + const char *secret_name = NULL; + + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { + if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); + } + } + } else { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_NONE) + g_object_set (G_OBJECT (setting), key, NULL, NULL); + } } } @@ -360,6 +375,16 @@ clear_nonagent_secrets (GHashTableIter *iter, return TRUE; } +static gboolean +clear_unsaved_secrets (GHashTableIter *iter, + NMSettingSecretFlags flags, + gpointer user_data) +{ + if (flags & (NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) + g_hash_table_iter_remove (iter); + return TRUE; +} + static gboolean has_system_owned_secrets (GHashTableIter *iter, NMSettingSecretFlags flags, @@ -517,6 +542,12 @@ agent_secrets_done_cb (NMAgentManager *manager, setting_name, call_id); + /* If no user interaction was allowed, make sure that no "unsaved" secrets + * came back. Unsaved secrets by definition require user interaction. + */ + if (flags == 0) /* ie SECRETS_FLAG_NONE */ + for_each_secret (NM_CONNECTION (self), secrets, clear_unsaved_secrets, NULL); + /* Update the connection with our existing secrets from backing storage */ nm_connection_clear_secrets (NM_CONNECTION (self)); hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); @@ -858,9 +889,23 @@ only_agent_secrets_cb (NMSetting *setting, NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; /* Clear out system-owned or always-ask secrets */ - nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); - if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) - g_object_set (G_OBJECT (setting), key, NULL, NULL); + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + GHashTableIter iter; + const char *secret_name = NULL; + + /* VPNs are special; need to handle each secret separately */ + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { + if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + nm_setting_vpn_remove_secret (NM_SETTING_VPN (setting), secret_name); + } + } + } else { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED) + g_object_set (G_OBJECT (setting), key, NULL, NULL); + } } } From 76467e53e5c7ae55683491e71f6cae8048a7d874 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 10 Feb 2011 18:48:32 -0600 Subject: [PATCH 247/264] libnm-glib-vpn: add some helpers for auth dialogs The helpers read and return the data items and secrets that the applet sends to the auth dialog. --- libnm-glib/Makefile.am | 8 +- libnm-glib/libnm-glib-vpn.ver | 2 + libnm-glib/nm-vpn-plugin-utils.c | 188 +++++++++++++++++++++++++++++++ libnm-glib/nm-vpn-plugin-utils.h | 39 +++++++ 4 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 libnm-glib/nm-vpn-plugin-utils.c create mode 100644 libnm-glib/nm-vpn-plugin-utils.h diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index b6949781b..7dbd6103b 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -90,7 +90,8 @@ libnminclude_HEADERS = \ libnmvpn_HEADERS = \ nm-vpn-plugin.h \ - nm-vpn-plugin-ui-interface.h + nm-vpn-plugin-ui-interface.h \ + nm-vpn-plugin-utils.h libnm_glib_la_csources = \ nm-object.c \ @@ -148,7 +149,10 @@ libnm_glib_test_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS) libnm_glib_test_LDADD = libnm-glib.la $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS) -libnm_glib_vpn_la_SOURCES = nm-vpn-plugin.c nm-vpn-plugin-ui-interface.c +libnm_glib_vpn_la_SOURCES = \ + nm-vpn-plugin.c \ + nm-vpn-plugin-ui-interface.c \ + nm-vpn-plugin-utils.c libnm_glib_vpn_la_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS) libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS) libnm_glib_vpn_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib-vpn.ver \ diff --git a/libnm-glib/libnm-glib-vpn.ver b/libnm-glib/libnm-glib-vpn.ver index 16643d2ea..9d2bad5e2 100644 --- a/libnm-glib/libnm-glib-vpn.ver +++ b/libnm-glib/libnm-glib-vpn.ver @@ -21,6 +21,8 @@ global: nm_vpn_plugin_ui_widget_interface_get_widget; nm_vpn_plugin_ui_widget_interface_save_secrets; nm_vpn_plugin_ui_widget_interface_update_connection; + nm_vpn_plugin_utils_get_secret_flags; + nm_vpn_plugin_utils_read_vpn_details; local: *; }; diff --git a/libnm-glib/nm-vpn-plugin-utils.c b/libnm-glib/nm-vpn-plugin-utils.c new file mode 100644 index 000000000..8234a9197 --- /dev/null +++ b/libnm-glib/nm-vpn-plugin-utils.c @@ -0,0 +1,188 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#include +#include +#include +#include + +#include "nm-vpn-plugin-utils.h" +#include "nm-setting-private.h" + +#define DATA_KEY_TAG "DATA_KEY=" +#define DATA_VAL_TAG "DATA_VAL=" +#define SECRET_KEY_TAG "SECRET_KEY=" +#define SECRET_VAL_TAG "SECRET_VAL=" + +static void +free_secret (gpointer data) +{ + char *secret = data; + + memset (secret, 0, strlen (secret)); + g_free (secret); +} + +/** + * nm_vpn_plugin_utils_read_vpn_details: + * @fd: file descriptor to read from, usually stdin (0) + * @out_data: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairs of VPN data items + * @out_secrets: (out) (transfer full): on successful return, a hash table + * (mapping char*:char*) containing the key/value pairsof VPN secrets + * + * Parses key/value pairs from a file descriptor (normally stdin) passed by + * an applet when the applet calls the authentication dialog of the VPN plugin. + * + * Returns: %TRUE if reading values was successful, %FALSE if not + **/ +gboolean +nm_vpn_plugin_utils_read_vpn_details (int fd, + GHashTable **out_data, + GHashTable **out_secrets) +{ + GHashTable *data, *secrets; + gboolean success = FALSE; + char *key = NULL, *val = NULL; + GString *line; + gchar c; + + if (out_data) + g_return_val_if_fail (*out_data == NULL, FALSE); + if (out_secrets) + g_return_val_if_fail (*out_secrets == NULL, FALSE); + + data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + secrets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_secret); + + line = g_string_new (NULL); + + /* Read stdin for data and secret items until we get a DONE */ + while (1) { + ssize_t nr; + GHashTable *hash = NULL; + + errno = 0; + nr = read (fd, &c, 1); + if (nr == -1) { + if (errno == EAGAIN) { + g_usleep (100); + continue; + } + break; + } + + if (c != '\n') { + g_string_append_c (line, c); + continue; + } + + /* Check for the finish marker */ + if (strcmp (line->str, "DONE") == 0) + break; + + /* Otherwise it's a data/secret item */ + if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) { + hash = data; + key = g_strdup (line->str + strlen (DATA_KEY_TAG)); + } else if (strncmp (line->str, DATA_VAL_TAG, strlen (DATA_VAL_TAG)) == 0) { + hash = data; + val = g_strdup (line->str + strlen (DATA_VAL_TAG)); + } else if (strncmp (line->str, SECRET_KEY_TAG, strlen (SECRET_KEY_TAG)) == 0) { + hash = secrets; + key = g_strdup (line->str + strlen (SECRET_KEY_TAG)); + } else if (strncmp (line->str, SECRET_VAL_TAG, strlen (SECRET_VAL_TAG)) == 0) { + hash = secrets; + val = g_strdup (line->str + strlen (SECRET_VAL_TAG)); + } + g_string_truncate (line, 0); + + if (key && val && hash) { + g_hash_table_insert (hash, key, val); + key = NULL; + val = NULL; + success = TRUE; /* Got at least one value */ + } + } + + if (success) { + if (out_data) + *out_data = data; + else + g_hash_table_destroy (data); + + if (out_secrets) + *out_secrets = secrets; + else + g_hash_table_destroy (secrets); + } else { + g_hash_table_destroy (data); + g_hash_table_destroy (secrets); + } + + g_string_free (line, TRUE); + return success; +} + +/** + * nm_vpn_plugin_utils_get_secret_flags: + * @data: hash table containing VPN key/value pair data items + * @secret_name: VPN secret key name for which to retrieve flags for + * @out_flags: (out): on success, the flags associated with @secret_name + * + * Given a VPN secret key name, attempts to find the corresponding flags data + * item in @data. If found, converts the flags data item to + * #NMSettingSecretFlags and returns it. + * + * Returns: %TRUE if the flag data item was found and successfully converted + * to flags, %FALSE if not + **/ +gboolean +nm_vpn_plugin_utils_get_secret_flags (GHashTable *data, + const char *secret_name, + NMSettingSecretFlags *out_flags) +{ + char *flag_name; + const char *val; + unsigned long tmp; + gboolean success = FALSE; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (secret_name != NULL, FALSE); + g_return_val_if_fail (out_flags != NULL, FALSE); + g_return_val_if_fail (*out_flags == NM_SETTING_SECRET_FLAG_NONE, FALSE); + + flag_name = g_strdup_printf ("%s-flags", secret_name); + + /* Try new flags value first */ + val = g_hash_table_lookup (data, flag_name); + if (val) { + errno = 0; + tmp = strtoul (val, NULL, 10); + if (errno == 0 && tmp <= NM_SETTING_SECRET_FLAGS_ALL) { + *out_flags = (NMSettingSecretFlags) tmp; + success = TRUE; + } + } + + g_free (flag_name); + return success; +} + diff --git a/libnm-glib/nm-vpn-plugin-utils.h b/libnm-glib/nm-vpn-plugin-utils.h new file mode 100644 index 000000000..aab73c4e6 --- /dev/null +++ b/libnm-glib/nm-vpn-plugin-utils.h @@ -0,0 +1,39 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright (C) 2011 Red Hat, Inc. + */ + +#ifndef NM_VPN_PLUGIN_UTILS_H +#define NM_VPN_PLUGIN_UTILS_H + +#include +#include + +G_BEGIN_DECLS + +gboolean nm_vpn_plugin_utils_read_vpn_details (int fd, + GHashTable **out_data, + GHashTable **out_secrets); + +gboolean nm_vpn_plugin_utils_get_secret_flags (GHashTable *data, + const char *secret_name, + NMSettingSecretFlags *out_flags); + +G_END_DECLS + +#endif /* NM_VPN_PLUGIN_UTILS_H */ From f2c317e3d2ba3acbe73bf060d767115b2421db69 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 11:19:02 -0600 Subject: [PATCH 248/264] policy: rename "modfiy" permission to "modify system" Meaning stays the same, but this will allow us to differentiate in the future between personal connections (ie, just visible to one user) and system connections (visible to more than one user). --- libnm-glib/nm-client.c | 6 +++--- libnm-glib/nm-client.h | 2 +- policy/org.freedesktop.NetworkManager.policy.in | 8 ++++---- src/nm-manager-auth.h | 2 +- src/nm-manager.c | 4 ++-- src/settings/nm-agent-manager.c | 4 ++-- src/settings/nm-settings-connection.c | 4 ++-- src/settings/nm-settings.c | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index bbc0c91f6..34e98aa97 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -335,7 +335,7 @@ register_for_property_changed (NMClient *client) #define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" #define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" #define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" -#define NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY "org.freedesktop.NetworkManager.settings.modify" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" #define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" static NMClientPermission @@ -357,8 +357,8 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED; else if (!strcmp (nm, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN)) return NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN; - else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY)) - return NM_CLIENT_PERMISSION_SETTINGS_CONNECTION_MODIFY; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM)) + return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM; else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY)) return NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY; diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index bdc5ab81f..b0b59930f 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -62,7 +62,7 @@ typedef enum { NM_CLIENT_PERMISSION_NETWORK_CONTROL = 5, NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 6, NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 7, - NM_CLIENT_PERMISSION_SETTINGS_CONNECTION_MODIFY = 8, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 8, NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY = 9, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 10, diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index acdee8829..7cc72c2ce 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -81,12 +81,12 @@ - - <_description>Modify system connections - <_message>System policy prevents modification of system settings + + <_description>Modify network connections for all users + <_message>System policy prevents modification of network settings for all users no - auth_admin_keep + yes diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 15b8cde13..f5f6c2cb8 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -37,7 +37,7 @@ #define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" #define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" #define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" -#define NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY "org.freedesktop.NetworkManager.settings.modify" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" #define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" diff --git a/src/nm-manager.c b/src/nm-manager.c index a7adb13ad..65ba95fb7 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2730,7 +2730,7 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (chain, results, NM_AUTH_PERMISSION_NETWORK_CONTROL); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN); - get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); dbus_g_method_return (context, results); g_hash_table_destroy (results); @@ -2761,7 +2761,7 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, FALSE); } diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index fc4c7e6a5..d094c4ffc 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -778,7 +778,7 @@ get_agent_modify_auth_cb (NMAuthChain *chain, * to it. If it didn't, we still ask it for secrets, but we don't send * any system secrets. */ - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); if (result == NM_AUTH_CALL_RESULT_YES) req->current_has_modify = TRUE; @@ -813,7 +813,7 @@ get_next_cb (Request *req) get_agent_modify_auth_cb, req); g_assert (req->chain); - nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE); } else { nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s", req, req->setting_name, agent_dbus_owner); diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index eaafcfe88..b8afed23a 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -723,7 +723,7 @@ pk_auth_cb (NMAuthChain *chain, "Error checking authorization: %s", chain_error->message ? chain_error->message : "(unknown)"); } else { - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { @@ -787,7 +787,7 @@ auth_start (NMSettingsConnection *self, info->sender_uid = sender_uid; nm_auth_chain_set_data (chain, "pk-auth-info", info, g_free); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE); priv->pending_auths = g_slist_append (priv->pending_auths, chain); } else { /* Don't need polkit auth, automatic success */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 7276094fa..3c1d97275 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -815,7 +815,7 @@ pk_add_cb (NMAuthChain *chain, goto done; } - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { @@ -925,7 +925,7 @@ nm_settings_add_connection (NMSettings *self, chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self); g_assert (chain); priv->auths = g_slist_append (priv->auths, chain); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_CONNECTION_MODIFY, TRUE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE); nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref); nm_auth_chain_set_data (chain, "callback", callback, NULL); nm_auth_chain_set_data (chain, "callback-data", user_data, NULL); From ba8f56283613f64ae893398bc21e12cc1be2d13d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 11:27:08 -0600 Subject: [PATCH 249/264] policy: add a "modify own" permission for single-user-visible connections This policy will allow users to modify their personal connections (ie maybe VPN connections, etc) distinctly from system-wide connections that affect more than just their user. It makes sense to be more lenient when making changes to settings that don't affect other users. --- libnm-glib/nm-client.c | 3 +++ libnm-glib/nm-client.h | 17 +++++++++-------- policy/org.freedesktop.NetworkManager.policy.in | 9 +++++++++ src/nm-manager-auth.h | 1 + src/nm-manager.c | 2 ++ 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 34e98aa97..7b6e0b713 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -336,6 +336,7 @@ register_for_property_changed (NMClient *client) #define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" #define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" #define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" static NMClientPermission @@ -359,6 +360,8 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN; else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM)) return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN)) + return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN; else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY)) return NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY; diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index b0b59930f..919a0c17e 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -58,15 +58,16 @@ typedef enum { NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK = 1, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, - NM_CLIENT_PERMISSION_SLEEP_WAKE = 4, - NM_CLIENT_PERMISSION_NETWORK_CONTROL = 5, - NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 6, - NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 7, - NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 8, - NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY = 9, - NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 10, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 4, + NM_CLIENT_PERMISSION_SLEEP_WAKE = 5, + NM_CLIENT_PERMISSION_NETWORK_CONTROL = 6, + NM_CLIENT_PERMISSION_WIFI_SHARE_PROTECTED = 7, + NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 8, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 9, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN = 10, + NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY = 11, - NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX + NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY } NMClientPermission; typedef enum { diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index 7cc72c2ce..00740bf51 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -81,6 +81,15 @@ + + <_description>Modify personal network connections + <_message>System policy prevents modification of personal network settings + + no + yes + + + <_description>Modify network connections for all users <_message>System policy prevents modification of network settings for all users diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index f5f6c2cb8..88938862c 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -38,6 +38,7 @@ #define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected" #define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" #define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" diff --git a/src/nm-manager.c b/src/nm-manager.c index 65ba95fb7..08d585c80 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2731,6 +2731,7 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); dbus_g_method_return (context, results); g_hash_table_destroy (results); @@ -2762,6 +2763,7 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, FALSE); } From 016c56078d5bc57d5e75035537401ab964314225 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 11:32:57 -0600 Subject: [PATCH 250/264] policy: rename HOSTNAME_MODIFY -> MODIFY_HOSTNAME for consistency --- libnm-glib/nm-client.c | 6 +++--- libnm-glib/nm-client.h | 4 ++-- policy/org.freedesktop.NetworkManager.policy.in | 2 +- src/nm-manager-auth.h | 2 +- src/nm-manager.c | 4 ++-- src/settings/nm-settings.c | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 7b6e0b713..847e87d2d 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -337,7 +337,7 @@ register_for_property_changed (NMClient *client) #define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" -#define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname" static NMClientPermission nm_permission_to_client (const char *nm) @@ -362,8 +362,8 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM; else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN)) return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN; - else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY)) - return NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY; + else if (!strcmp (nm, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME)) + return NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME; return NM_CLIENT_PERMISSION_NONE; } diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 919a0c17e..1885f8fab 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -65,9 +65,9 @@ typedef enum { NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 8, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_SYSTEM = 9, NM_CLIENT_PERMISSION_SETTINGS_MODIFY_OWN = 10, - NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY = 11, + NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME = 11, - NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY + NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_SETTINGS_MODIFY_HOSTNAME } NMClientPermission; typedef enum { diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index 00740bf51..a7d5202fb 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -99,7 +99,7 @@ - + <_description>Modify persistent system hostname <_message>System policy prevents modification of the persistent system hostname diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 88938862c..473eacd0b 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -39,7 +39,7 @@ #define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM "org.freedesktop.NetworkManager.settings.modify.system" #define NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN "org.freedesktop.NetworkManager.settings.modify.own" -#define NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY "org.freedesktop.NetworkManager.settings.hostname.modify" +#define NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME "org.freedesktop.NetworkManager.settings.modify.hostname" typedef struct NMAuthChain NMAuthChain; diff --git a/src/nm-manager.c b/src/nm-manager.c index 08d585c80..4b2332b84 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2732,7 +2732,7 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN); - get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME); dbus_g_method_return (context, results); g_hash_table_destroy (results); } @@ -2764,7 +2764,7 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN, FALSE); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, FALSE); } /* Legacy 0.6 compatibility interface */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 3c1d97275..3e38a2f04 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -975,7 +975,7 @@ pk_hostname_cb (NMAuthChain *chain, goto done; } - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY); + result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME); /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { @@ -1036,7 +1036,7 @@ impl_settings_save_hostname (NMSettings *self, chain = nm_auth_chain_new (priv->authority, context, NULL, pk_hostname_cb, self); g_assert (chain); priv->auths = g_slist_append (priv->auths, chain); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_HOSTNAME_MODIFY, TRUE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_HOSTNAME, TRUE); nm_auth_chain_set_data (chain, "hostname", g_strdup (hostname), g_free); } From 2e2b4373eb638c2f274fff16110f77d6e3ea4456 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 16:43:03 -0600 Subject: [PATCH 251/264] core: add ulong data helpers to NMAuthChain Otherwise callers would have to do the work themselves to ensure that the top 32 bits of the ulong didn't get chopped off on 32-bit platorms. --- src/nm-manager-auth.c | 28 ++++++++++++++++++++++++++++ src/nm-manager-auth.h | 6 ++++++ 2 files changed, 34 insertions(+) diff --git a/src/nm-manager-auth.c b/src/nm-manager-auth.c index ea56f10f7..8515959eb 100644 --- a/src/nm-manager-auth.c +++ b/src/nm-manager-auth.c @@ -178,6 +178,34 @@ nm_auth_chain_set_data (NMAuthChain *self, } } +gulong +nm_auth_chain_get_data_ulong (NMAuthChain *self, const char *tag) +{ + gulong *ptr; + + g_return_val_if_fail (self != NULL, 0); + g_return_val_if_fail (tag != NULL, 0); + + ptr = nm_auth_chain_get_data (self, tag); + return *ptr; +} + + +void +nm_auth_chain_set_data_ulong (NMAuthChain *self, + const char *tag, + gulong data) +{ + gulong *ptr; + + g_return_if_fail (self != NULL); + g_return_if_fail (tag != NULL); + + ptr = g_malloc (sizeof (*ptr)); + *ptr = data; + nm_auth_chain_set_data (self, tag, ptr, g_free); +} + NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *self, const char *permission) { diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 473eacd0b..7e7ff7a12 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -85,6 +85,12 @@ void nm_auth_chain_set_data (NMAuthChain *chain, gpointer data, GDestroyNotify data_destroy); +void nm_auth_chain_set_data_ulong (NMAuthChain *chain, + const char *tag, + gulong data); + +gulong nm_auth_chain_get_data_ulong (NMAuthChain *chain, const char *tag); + NMAuthCallResult nm_auth_chain_get_result (NMAuthChain *chain, const char *permission); From 562dc6e0b624327969bf3ac7c9a2107f5cc12c7b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 17:06:57 -0600 Subject: [PATCH 252/264] settings: check modify 'own' not 'system' for personal connections When a connection is visible only to one user, check 'own' instead of 'system', allowing 'own' to be less restrictive since the change won't affect any other users. --- src/settings/nm-agent-manager.c | 26 +++++++-- src/settings/nm-settings-connection.c | 48 +++++++++------ src/settings/nm-settings.c | 84 ++++++++++++++++----------- 3 files changed, 103 insertions(+), 55 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index d094c4ffc..2e0772e9e 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -35,6 +35,7 @@ #include "nm-polkit-helpers.h" #include "nm-manager-auth.h" #include "nm-setting-vpn.h" +#include "nm-setting-connection.h" G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT) @@ -762,9 +763,9 @@ get_agent_modify_auth_cb (NMAuthChain *chain, { Request *req = user_data; NMAuthCallResult result; + const char *perm; req->chain = NULL; - nm_auth_chain_unref (chain); if (error) { nm_log_dbg (LOGD_AGENTS, "(%p/%s) agent MODIFY check error: (%d) %s", @@ -778,7 +779,9 @@ get_agent_modify_auth_cb (NMAuthChain *chain, * to it. If it didn't, we still ask it for secrets, but we don't send * any system secrets. */ - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); if (result == NM_AUTH_CALL_RESULT_YES) req->current_has_modify = TRUE; @@ -787,12 +790,14 @@ get_agent_modify_auth_cb (NMAuthChain *chain, get_agent_request_secrets (req, req->current_has_modify); } + nm_auth_chain_unref (chain); } static void get_next_cb (Request *req) { - const char *agent_dbus_owner; + NMSettingConnection *s_con; + const char *agent_dbus_owner, *perm; if (!next_generic (req, "getting")) return; @@ -813,7 +818,20 @@ get_next_cb (Request *req) get_agent_modify_auth_cb, req); g_assert (req->chain); - nm_auth_chain_add_call (req->chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE); + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (req->connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + nm_auth_chain_set_data (req->chain, "perm", (gpointer) perm, NULL); + + nm_auth_chain_add_call (req->chain, perm, TRUE); } else { nm_log_dbg (LOGD_AGENTS, "(%p/%s) requesting user-owned secrets from agent %s", req, req->setting_name, agent_dbus_owner); diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index b8afed23a..c26daeda8 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -696,12 +696,6 @@ typedef void (*AuthCallback) (NMSettingsConnection *connection, GError *error, gpointer data); -typedef struct { - AuthCallback callback; - gpointer callback_data; - gulong sender_uid; -} PkAuthInfo; - static void pk_auth_cb (NMAuthChain *chain, GError *chain_error, @@ -712,7 +706,10 @@ pk_auth_cb (NMAuthChain *chain, NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); GError *error = NULL; NMAuthCallResult result; - PkAuthInfo *info; + const char *perm; + AuthCallback callback; + gpointer callback_data; + gulong sender_uid; priv->pending_auths = g_slist_remove (priv->pending_auths, chain); @@ -723,7 +720,9 @@ pk_auth_cb (NMAuthChain *chain, "Error checking authorization: %s", chain_error->message ? chain_error->message : "(unknown)"); } else { - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { @@ -733,8 +732,10 @@ pk_auth_cb (NMAuthChain *chain, } } - info = nm_auth_chain_get_data (chain, "pk-auth-info"); - info->callback (self, context, info->sender_uid, error, info->callback_data); + callback = nm_auth_chain_get_data (chain, "callback"); + callback_data = nm_auth_chain_get_data (chain, "callback-data"); + sender_uid = nm_auth_chain_get_data_ulong (chain, "sender-uid"); + callback (self, context, sender_uid, error, callback_data); g_clear_error (&error); nm_auth_chain_unref (chain); @@ -750,7 +751,6 @@ auth_start (NMSettingsConnection *self, NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMAuthChain *chain; gulong sender_uid = G_MAXULONG; - PkAuthInfo *info; GError *error = NULL; char *error_desc = NULL; @@ -778,16 +778,28 @@ auth_start (NMSettingsConnection *self, } if (check_modify) { + NMSettingConnection *s_con; + const char *perm; + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self); g_assert (chain); + nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL); + nm_auth_chain_set_data (chain, "callback", callback, NULL); + nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); + nm_auth_chain_set_data_ulong (chain, "sender-uid", sender_uid); - info = g_malloc0 (sizeof (*info)); - info->callback = callback; - info->callback_data = callback_data; - info->sender_uid = sender_uid; - nm_auth_chain_set_data (chain, "pk-auth-info", info, g_free); - - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE); + nm_auth_chain_add_call (chain, perm, TRUE); priv->pending_auths = g_slist_append (priv->pending_auths, chain); } else { /* Don't need polkit auth, automatic success */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 3e38a2f04..7f705d9f0 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -800,10 +800,9 @@ pk_add_cb (NMAuthChain *chain, GError *error = NULL, *add_error = NULL; NMConnection *connection; NMSettingsConnection *added = NULL; - gulong caller_uid = G_MAXULONG; - char *error_desc = NULL; NMSettingsAddCallback callback; gpointer callback_data; + const char *perm; priv->auths = g_slist_remove (priv->auths, chain); @@ -815,7 +814,9 @@ pk_add_cb (NMAuthChain *chain, goto done; } - result = nm_auth_chain_get_result (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM); + perm = nm_auth_chain_get_data (chain, "perm"); + g_assert (perm); + result = nm_auth_chain_get_result (chain, perm); /* Caller didn't successfully authenticate */ if (result != NM_AUTH_CALL_RESULT_YES) { @@ -825,35 +826,8 @@ pk_add_cb (NMAuthChain *chain, goto done; } - /* If the caller isn't root, make sure the connection can be viewed by - * the user that's adding it. - */ - if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) { - error = g_error_new (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - "Unable to determine UID of request: %s.", - error_desc ? error_desc : "(unknown)"); - g_free (error_desc); - goto done; - } - connection = nm_auth_chain_get_data (chain, "connection"); - - /* Ensure the caller's username exists in the connection's permissions, - * or that the permissions is empty (ie, visible by everyone). - */ - if (0 != caller_uid) { - if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_NOT_PRIVILEGED, - error_desc); - g_free (error_desc); - goto done; - } - - /* Caller is allowed to add this connection */ - } - + g_assert (connection); added = add_new_connection (self, connection, &add_error); if (!added) { error = g_error_new (NM_SETTINGS_ERROR, @@ -895,8 +869,12 @@ nm_settings_add_connection (NMSettings *self, gpointer user_data) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + NMSettingConnection *s_con; NMAuthChain *chain; GError *error = NULL, *tmp_error = NULL; + gulong caller_uid = G_MAXULONG; + char *error_desc = NULL; + const char *perm; /* Connection must be valid, of course */ if (!nm_connection_verify (connection, &tmp_error)) { @@ -905,7 +883,6 @@ nm_settings_add_connection (NMSettings *self, "The connection was invalid: %s", tmp_error ? tmp_error->message : "(unknown)"); g_error_free (tmp_error); - callback (self, NULL, error, context, user_data); g_error_free (error); return; @@ -921,11 +898,52 @@ nm_settings_add_connection (NMSettings *self, return; } + /* Get the caller's UID */ + if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &caller_uid, &error_desc)) { + error = g_error_new (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + "Unable to determine UID of request: %s.", + error_desc ? error_desc : "(unknown)"); + g_free (error_desc); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + + /* Ensure the caller's username exists in the connection's permissions, + * or that the permissions is empty (ie, visible by everyone). + */ + if (0 != caller_uid) { + if (!nm_auth_uid_in_acl (connection, priv->session_monitor, caller_uid, &error_desc)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_PRIVILEGED, + error_desc); + g_free (error_desc); + callback (self, NULL, error, context, user_data); + g_error_free (error); + return; + } + + /* Caller is allowed to add this connection */ + } + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + else + perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; + /* Otherwise validate the user request */ chain = nm_auth_chain_new (priv->authority, context, NULL, pk_add_cb, self); g_assert (chain); priv->auths = g_slist_append (priv->auths, chain); - nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM, TRUE); + nm_auth_chain_add_call (chain, perm, TRUE); + nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL); nm_auth_chain_set_data (chain, "connection", g_object_ref (connection), g_object_unref); nm_auth_chain_set_data (chain, "callback", callback, NULL); nm_auth_chain_set_data (chain, "callback-data", user_data, NULL); From dede4d3948c60c9e39035eb96accd12aae0aad76 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 17:11:58 -0600 Subject: [PATCH 253/264] settings: fix warnings when no existing secrets are present Since the hash table will be NULL in that case, don't try to do anything with it. --- src/settings/nm-agent-manager.c | 3 ++- src/settings/nm-settings-connection.c | 35 ++++++++++++--------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 2e0772e9e..a9f8c09bf 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -734,7 +734,8 @@ get_agent_request_secrets (Request *req, gboolean include_system_secrets) * the system secrets we're not sending to the agent aren't required, * so the agent can properly validate UI controls and such. */ - set_secrets_not_required (tmp, req->existing_secrets); + if (req->existing_secrets) + set_secrets_not_required (tmp, req->existing_secrets); } req->current_call_id = nm_secret_agent_get_secrets (NM_SECRET_AGENT (req->current), diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index c26daeda8..833b57048 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -461,16 +461,12 @@ agent_secrets_done_cb (NMAgentManager *manager, NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionSecretsFunc callback = other_data2; gpointer callback_data = other_data3; - NMSettingConnection *s_con; GError *local = NULL; GHashTable *hash; - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - if (error) { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request error: (%d) %s", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id, error->code, @@ -494,7 +490,7 @@ agent_secrets_done_cb (NMAgentManager *manager, gboolean has_system = FALSE; nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets returned from agent %s", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id, agent_dbus_owner); @@ -512,7 +508,7 @@ agent_secrets_done_cb (NMAgentManager *manager, * agent is being bad. Remove system-owned secrets. */ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) interaction forbidden but agent %s returned system secrets", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id, agent_dbus_owner); @@ -523,7 +519,7 @@ agent_secrets_done_cb (NMAgentManager *manager, * from the secrets the agent returned. */ nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) agent failed to authenticate but provided system secrets", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id); @@ -532,13 +528,13 @@ agent_secrets_done_cb (NMAgentManager *manager, } } else { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) existing secrets returned", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id); } nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets request completed", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id); @@ -551,7 +547,7 @@ agent_secrets_done_cb (NMAgentManager *manager, /* Update the connection with our existing secrets from backing storage */ nm_connection_clear_secrets (NM_CONNECTION (self)); hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS); - if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { + if (!hash || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local)) { /* Update the connection with the agent's secrets; by this point if any * system-owned secrets exist in 'secrets' the agent that provided them * will have been authenticated, so those secrets can replace the existing @@ -564,26 +560,26 @@ agent_secrets_done_cb (NMAgentManager *manager, update_secrets_cache (self); nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) saving new secrets to backing storage", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id); nm_settings_connection_commit_changes (self, new_secrets_commit_cb, NULL); } else { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with agent secrets: (%d) %s", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id, - local->code, - local->message ? local->message : "(unknown)"); + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); } } else { nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) failed to update with existing secrets: (%d) %s", - nm_setting_connection_get_uuid (s_con), + nm_connection_get_uuid (NM_CONNECTION (self)), setting_name, call_id, - local->code, - local->message ? local->message : "(unknown)"); + local ? local->code : -1, + (local && local->message) ? local->message : "(unknown)"); } callback (self, call_id, setting_name, local, callback_data); @@ -659,7 +655,8 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, self, callback, callback_data); - g_hash_table_unref (existing_secrets); + if (existing_secrets) + g_hash_table_unref (existing_secrets); s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); nm_log_dbg (LOGD_SETTINGS, "(%s/%s:%u) secrets requested flags 0x%X hint '%s'", From a21c01a243a901e7f91359088f22d572965f5e0e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 17:49:27 -0600 Subject: [PATCH 254/264] settings: check harder for system-owned secrets when validating agents Can't just check whether we have existing system secrets, because that doesn't catch the case for a completely new connection where there may not be any secrets yet, but any that we do get should be system-owned. --- src/settings/nm-agent-manager.c | 47 +++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index a9f8c09bf..0ffcfd454 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -794,6 +794,48 @@ get_agent_modify_auth_cb (NMAuthChain *chain, nm_auth_chain_unref (chain); } +static void +check_system_secrets_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; + gboolean *has_system = user_data; + + if (!(flags & NM_SETTING_PARAM_SECRET)) + return; + + /* Clear out system-owned or always-ask secrets */ + if (NM_IS_SETTING_VPN (setting) && !strcmp (key, NM_SETTING_VPN_SECRETS)) { + GHashTableIter iter; + const char *secret_name = NULL; + + /* VPNs are special; need to handle each secret separately */ + g_hash_table_iter_init (&iter, (GHashTable *) g_value_get_boxed (value)); + while (g_hash_table_iter_next (&iter, (gpointer *) &secret_name, NULL)) { + if (nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + *has_system = TRUE; + } + } + } else { + nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); + if (secret_flags == NM_SETTING_SECRET_FLAG_NONE) + *has_system = TRUE; + } +} + +static gboolean +has_system_secrets (NMConnection *connection) +{ + gboolean has_system = FALSE; + + nm_connection_for_each_setting_value (connection, check_system_secrets_cb, &has_system); + return has_system; +} + static void get_next_cb (Request *req) { @@ -805,12 +847,13 @@ get_next_cb (Request *req) agent_dbus_owner = nm_secret_agent_get_dbus_owner (NM_SECRET_AGENT (req->current)); - /* If the request flags allow user interaction, and there are system secrets, + /* If the request flags allow user interaction, and there are existing + * system secrets (or blank secrets that are supposed to be system-owned), * check whether the agent has the 'modify' permission before sending those * secrets to the agent. We shouldn't leak system-owned secrets to * unprivileged users. */ - if ((req->flags != 0) && (req->existing_secrets != NULL)) { + if ((req->flags != 0) && (req->existing_secrets || has_system_secrets (req->connection))) { nm_log_dbg (LOGD_AGENTS, "(%p/%s) request has system secrets; checking agent %s for MODIFY", req, req->setting_name, agent_dbus_owner); From 76147fc5e1bd01b8c5c4d80e73c65ae02b11d662 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 18:14:18 -0600 Subject: [PATCH 255/264] settings: use the right permission for connection updates that change visibility Make sure to use modify.system if the Update request changes the visibility of the connection, since that update request would affect more users than just the caller. --- src/settings/nm-settings-connection.c | 177 ++++++++++++++++++-------- 1 file changed, 127 insertions(+), 50 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 833b57048..5c7a14273 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -738,10 +738,52 @@ pk_auth_cb (NMAuthChain *chain, nm_auth_chain_unref (chain); } +static gboolean +check_user_in_acl (NMConnection *connection, + DBusGMethodInvocation *context, + NMDBusManager *dbus_mgr, + NMSessionMonitor *session_monitor, + gulong *out_sender_uid, + GError **error) +{ + gulong sender_uid = G_MAXULONG; + char *error_desc = NULL; + + g_return_val_if_fail (connection != NULL, FALSE); + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (session_monitor != NULL, FALSE); + + /* Get the caller's UID */ + if (!nm_auth_get_caller_uid (context, dbus_mgr, &sender_uid, &error_desc)) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); + return FALSE; + } + + /* Make sure the UID can view this connection */ + if (0 != sender_uid) { + if (!nm_auth_uid_in_acl (connection, session_monitor, sender_uid, &error_desc)) { + g_set_error_literal (error, + NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_PERMISSION_DENIED, + error_desc); + g_free (error_desc); + return FALSE; + } + } + + if (out_sender_uid) + *out_sender_uid = sender_uid; + return TRUE; +} + static void auth_start (NMSettingsConnection *self, DBusGMethodInvocation *context, - gboolean check_modify, + const char *check_permission, AuthCallback callback, gpointer callback_data) { @@ -749,65 +791,32 @@ auth_start (NMSettingsConnection *self, NMAuthChain *chain; gulong sender_uid = G_MAXULONG; GError *error = NULL; - char *error_desc = NULL; - /* Get the caller's UID */ - if (!nm_auth_get_caller_uid (context, NULL, &sender_uid, &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); - goto error; + if (!check_user_in_acl (NM_CONNECTION (self), + context, + priv->dbus_mgr, + priv->session_monitor, + &sender_uid, + &error)) { + callback (self, context, G_MAXULONG, error, callback_data); + g_clear_error (&error); + return; } - /* Make sure the UID can view this connection */ - if (0 != sender_uid) { - if (!nm_auth_uid_in_acl (NM_CONNECTION (self), - priv->session_monitor, - sender_uid, - &error_desc)) { - error = g_error_new_literal (NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_PERMISSION_DENIED, - error_desc); - g_free (error_desc); - goto error; - } - } - - if (check_modify) { - NMSettingConnection *s_con; - const char *perm; - - /* If the caller is the only user in the connection's permissions, then - * we use the 'modify.own' permission instead of 'modify.system'. If the - * request affects more than just the caller, require 'modify.system'. - */ - s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - if (nm_setting_connection_get_num_permissions (s_con) == 1) - perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; - else - perm = NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; - + if (check_permission) { chain = nm_auth_chain_new (priv->authority, context, NULL, pk_auth_cb, self); g_assert (chain); - nm_auth_chain_set_data (chain, "perm", (gpointer) perm, NULL); + nm_auth_chain_set_data (chain, "perm", (gpointer) check_permission, NULL); nm_auth_chain_set_data (chain, "callback", callback, NULL); nm_auth_chain_set_data (chain, "callback-data", callback_data, NULL); nm_auth_chain_set_data_ulong (chain, "sender-uid", sender_uid); - nm_auth_chain_add_call (chain, perm, TRUE); + nm_auth_chain_add_call (chain, check_permission, TRUE); priv->pending_auths = g_slist_append (priv->pending_auths, chain); } else { /* Don't need polkit auth, automatic success */ callback (self, context, sender_uid, NULL, callback_data); } - - return; - -error: - callback (self, context, G_MAXULONG, error, callback_data); - g_error_free (error); } /**** DBus method handlers ************************************/ @@ -871,7 +880,7 @@ static void impl_settings_connection_get_settings (NMSettingsConnection *self, DBusGMethodInvocation *context) { - auth_start (self, context, FALSE, get_settings_auth_cb, NULL); + auth_start (self, context, NULL, get_settings_auth_cb, NULL); } static void @@ -951,11 +960,38 @@ update_auth_cb (NMSettingsConnection *self, g_object_unref (new_settings); } +static const char * +get_modify_permission_update (NMConnection *old, NMConnection *new) +{ + NMSettingConnection *s_con; + guint32 orig_num = 0, new_num = 0; + + s_con = (NMSettingConnection *) nm_connection_get_setting (old, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + orig_num = nm_setting_connection_get_num_permissions (s_con); + + s_con = (NMSettingConnection *) nm_connection_get_setting (new, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + new_num = nm_setting_connection_get_num_permissions (s_con); + + /* If the caller is the only user in either connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. + */ + if (orig_num == 1 && new_num == 1) + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + + /* If the update request affects more than just the caller (ie if the old + * settings were system-wide, or the new ones are), require 'modify.system'. + */ + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; +} + static void impl_settings_connection_update (NMSettingsConnection *self, GHashTable *new_settings, DBusGMethodInvocation *context) { + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMConnection *tmp; GError *error = NULL; @@ -978,7 +1014,27 @@ impl_settings_connection_update (NMSettingsConnection *self, return; } - auth_start (self, context, TRUE, update_auth_cb, tmp); + /* And that the new connection settings will be visible to the user + * that's sending the update request. You can't make a connection + * invisible to yourself. + */ + if (!check_user_in_acl (tmp, + context, + priv->dbus_mgr, + priv->session_monitor, + NULL, + &error)) { + dbus_g_method_return_error (context, error); + g_clear_error (&error); + g_object_unref (tmp); + return; + } + + auth_start (self, + context, + get_modify_permission_update (NM_CONNECTION (self), tmp), + update_auth_cb, + tmp); } static void @@ -1009,6 +1065,23 @@ delete_auth_cb (NMSettingsConnection *self, nm_settings_connection_delete (self, con_delete_cb, context); } +static const char * +get_modify_permission_basic (NMSettingsConnection *connection) +{ + NMSettingConnection *s_con; + + /* If the caller is the only user in the connection's permissions, then + * we use the 'modify.own' permission instead of 'modify.system'. If the + * request affects more than just the caller, require 'modify.system'. + */ + s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + if (nm_setting_connection_get_num_permissions (s_con) == 1) + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; + + return NM_AUTH_PERMISSION_SETTINGS_MODIFY_SYSTEM; +} + static void impl_settings_connection_delete (NMSettingsConnection *self, DBusGMethodInvocation *context) @@ -1021,7 +1094,7 @@ impl_settings_connection_delete (NMSettingsConnection *self, return; } - auth_start (self, context, TRUE, delete_auth_cb, NULL); + auth_start (self, context, get_modify_permission_basic (self), delete_auth_cb, NULL); } /**************************************************************/ @@ -1099,7 +1172,11 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, const gchar *setting_name, DBusGMethodInvocation *context) { - auth_start (self, context, TRUE, dbus_secrets_auth_cb, g_strdup (setting_name)); + auth_start (self, + context, + get_modify_permission_basic (self), + dbus_secrets_auth_cb, + g_strdup (setting_name)); } /**************************************************************/ From cba20a98ca15b7a2bfd7f9263bb625b3a4d6527a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 18:25:40 -0600 Subject: [PATCH 256/264] keyfile: use defines instead of strings for Removed signal --- system-settings/plugins/keyfile/plugin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index ba56467d7..2c2494e4f 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -143,7 +143,7 @@ update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, error ? error->code : -1); g_clear_error (&error); - g_signal_emit_by_name (orig, "removed"); + g_signal_emit_by_name (orig, NM_SETTINGS_CONNECTION_REMOVED); } } @@ -169,7 +169,7 @@ remove_connection (SCPluginKeyfile *self, /* Removing from the hash table should drop the last reference */ g_object_ref (connection); g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->hash, name); - g_signal_emit_by_name (connection, "removed"); + g_signal_emit_by_name (connection, NM_SETTINGS_CONNECTION_REMOVED); g_object_unref (connection); } From e386ebef39262184c261b8cc8fa04e47c1cca2fc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 18:26:59 -0600 Subject: [PATCH 257/264] libnm-glib: use define instead of string for Removed signal Less error-prone and makes a mistype a compile error. --- libnm-glib/nm-remote-settings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 8e5ffb118..2c2bf6947 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -291,7 +291,7 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) /* Create a new connection object for it */ connection = nm_remote_connection_new (priv->bus, path); if (connection) { - g_signal_connect (connection, "removed", + g_signal_connect (connection, NM_REMOTE_CONNECTION_REMOVED, G_CALLBACK (connection_removed_cb), self); @@ -473,7 +473,7 @@ clear_one_hash (GHashTable *table) list = g_slist_prepend (list, NM_REMOTE_CONNECTION (value)); for (list_iter = list; list_iter; list_iter = g_slist_next (list_iter)) - g_signal_emit_by_name (NM_REMOTE_CONNECTION (list_iter->data), "removed"); + g_signal_emit_by_name (NM_REMOTE_CONNECTION (list_iter->data), NM_REMOTE_CONNECTION_REMOVED); g_slist_free (list); g_hash_table_remove_all (table); From 4d2957b3ae930eb49078254eb799caeba2bbe370 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 21:29:41 -0600 Subject: [PATCH 258/264] settings: fix NMSettingsConnection D-Bus Remove signal emission We can't unregister the object with the bus during the remove signal, because dbus-glib doesn't send the signal out over the bus until late in the signal emission process, after we've unregisterd the object. Thus the signal doesn't go out. Fix that. --- src/settings/nm-settings-connection.c | 25 +++++++++++++++++++ src/settings/nm-settings-connection.h | 2 ++ src/settings/nm-settings.c | 30 +++++++++++++++++------ system-settings/plugins/ifcfg-rh/plugin.c | 4 +-- system-settings/plugins/ifnet/plugin.c | 4 +-- system-settings/plugins/keyfile/plugin.c | 4 +-- 6 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 5c7a14273..4c059df86 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -68,6 +68,7 @@ enum { enum { UPDATED, REMOVED, + UNREGISTER, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -1181,6 +1182,20 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self, /**************************************************************/ +void +nm_settings_connection_signal_remove (NMSettingsConnection *self) +{ + /* Emit removed first */ + g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_REMOVED); + + /* And unregistered last to ensure the removed signal goes out before + * we take the connection off the bus. + */ + g_signal_emit_by_name (self, "unregister"); +} + +/**************************************************************/ + static void nm_settings_connection_init (NMSettingsConnection *self) { @@ -1314,6 +1329,16 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /* Not exported */ + signals[UNREGISTER] = + g_signal_new ("unregister", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class), &dbus_glib_nm_settings_connection_object_info); } diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 643b1756e..190923c9f 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -114,6 +114,8 @@ gboolean nm_settings_connection_is_visible (NMSettingsConnection *self); void nm_settings_connection_recheck_visibility (NMSettingsConnection *self); +void nm_settings_connection_signal_remove (NMSettingsConnection *self); + G_END_DECLS #endif /* NM_SETTINGS_CONNECTION_H */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 7f705d9f0..83c45b3a2 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -587,11 +587,11 @@ load_plugins (NMSettings *self, const char *plugins, GError **error) #define REMOVED_ID_TAG "removed-id-tag" #define UPDATED_ID_TAG "updated-id-tag" #define VISIBLE_ID_TAG "visible-id-tag" +#define UNREG_ID_TAG "unreg-id-tag" static void connection_removed (NMSettingsConnection *obj, gpointer user_data) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data); GObject *connection = G_OBJECT (obj); guint id; @@ -614,20 +614,31 @@ connection_removed (NMSettingsConnection *obj, gpointer user_data) if (id) g_signal_handler_disconnect (connection, id); - /* Unregister the connection with D-Bus and forget about it */ - dbus_g_connection_unregister_g_object (priv->bus, connection); + /* Forget about the connection internall */ g_hash_table_remove (NM_SETTINGS_GET_PRIVATE (user_data)->connections, (gpointer) nm_connection_get_path (NM_CONNECTION (connection))); /* Re-emit for listeners like NMPolicy */ - g_signal_emit (NM_SETTINGS (user_data), - signals[CONNECTION_REMOVED], - 0, - connection); + g_signal_emit (NM_SETTINGS (user_data), signals[CONNECTION_REMOVED], 0, connection); g_object_unref (connection); } +static void +connection_unregister (NMSettingsConnection *obj, gpointer user_data) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (user_data); + GObject *connection = G_OBJECT (obj); + guint id; + + /* Make sure it's unregistered from the bus now that's removed */ + dbus_g_connection_unregister_g_object (priv->bus, connection); + + id = GPOINTER_TO_UINT (g_object_get_data (connection, UNREG_ID_TAG)); + if (id) + g_signal_handler_disconnect (connection, id); +} + static void connection_updated (NMSettingsConnection *connection, gpointer user_data) { @@ -689,6 +700,11 @@ claim_connection (NMSettings *self, self); g_object_set_data (G_OBJECT (connection), REMOVED_ID_TAG, GUINT_TO_POINTER (id)); + id = g_signal_connect (connection, "unregister", + G_CALLBACK (connection_unregister), + self); + g_object_set_data (G_OBJECT (connection), UNREG_ID_TAG, GUINT_TO_POINTER (id)); + id = g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED, G_CALLBACK (connection_updated), self); diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 24e271df3..3e2e03462 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -221,7 +221,7 @@ remove_connection (SCPluginIfcfg *self, NMIfcfgConnection *connection) g_object_ref (connection); g_hash_table_remove (priv->connections, path); - g_signal_emit_by_name (connection, NM_SETTINGS_CONNECTION_REMOVED); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); g_object_unref (connection); /* Emit unmanaged changes _after_ removing the connection */ @@ -294,7 +294,7 @@ connection_new_or_changed (SCPluginIfcfg *self, * been removed, and notify the settings service by signalling that * unmanaged specs have changed. */ - g_signal_emit_by_name (existing, NM_SETTINGS_CONNECTION_REMOVED); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (existing)); g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } } else { diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index f7cc6b394..f71acf6cf 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -287,7 +287,7 @@ reload_connections (gpointer config) PLUGIN_PRINT (IFNET_PLUGIN_NAME, "Auto refreshing %s", conn_name); /* Remove and re-add to disconnect and reconnect with new settings */ - g_signal_emit_by_name (old, NM_SETTINGS_CONNECTION_REMOVED); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (old)); g_hash_table_remove (priv->config_connections, conn_name); g_hash_table_insert (priv->config_connections, g_strdup (conn_name), new); if (is_managed (conn_name)) @@ -313,7 +313,7 @@ reload_connections (gpointer config) g_hash_table_iter_init (&iter, priv->config_connections); while (g_hash_table_iter_next (&iter, &key, &value)) { if (!g_hash_table_lookup (new_conn_names, key)) { - g_signal_emit_by_name (value, NM_SETTINGS_CONNECTION_REMOVED); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (value)); g_hash_table_remove (priv->config_connections, key); } } diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 2c2494e4f..68f51dc4a 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -143,7 +143,7 @@ update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, error ? error->code : -1); g_clear_error (&error); - g_signal_emit_by_name (orig, NM_SETTINGS_CONNECTION_REMOVED); + nm_settings_connection_signal_remove (orig); } } @@ -169,7 +169,7 @@ remove_connection (SCPluginKeyfile *self, /* Removing from the hash table should drop the last reference */ g_object_ref (connection); g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->hash, name); - g_signal_emit_by_name (connection, NM_SETTINGS_CONNECTION_REMOVED); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); g_object_unref (connection); } From f82f0aa65406d5aedec83c75d50e38694a40a82e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 22:03:10 -0600 Subject: [PATCH 259/264] settings: fix NewConnection signal emission --- src/settings/nm-settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 83c45b3a2..169936c39 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1629,7 +1629,7 @@ nm_settings_class_init (NMSettingsClass *class) G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 0); + G_TYPE_NONE, 1, G_TYPE_OBJECT); dbus_g_error_domain_register (NM_SETTINGS_ERROR, NM_DBUS_IFACE_SETTINGS, From 2ef55166c8384eb70370d6d21a54320f40bfddf6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 11 Feb 2011 23:05:53 -0600 Subject: [PATCH 260/264] libnm-util: fix parsing permission if it includes detail --- libnm-util/nm-setting-connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index d63fdf6dc..27e7913a7 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -136,7 +136,7 @@ permission_new_from_str (const char *str) g_return_val_if_fail (last_colon > str, NULL); /* Make sure we don't include detail in the username */ - ulen = (last_colon - str) + 1; + ulen = last_colon - str; } else ulen = strlen (str); From d94590a52cd81f8099cac2db7cd1de29418e0080 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 12 Feb 2011 21:48:30 -0600 Subject: [PATCH 261/264] libnm-glib: fix connection visibility handling When the connection becomes invisible to a user (ie, the permissions of the connection no longer allow that user to view the connection) then we have to hid the connection from clients. But we can't just dispose of it, because visibility changes are signaled with Update signals on the connection itself, and thus we need to keep the connection around just in case it becomes visible to the user again. But if it's invisible, make sure we clear out the settings since they may have changed. --- libnm-glib/nm-remote-connection.c | 33 ++- libnm-glib/nm-remote-settings.c | 48 ++++- .../tests/test-remote-settings-client.c | 193 +++++++++++++++--- .../tests/test-remote-settings-service.py | 15 ++ 4 files changed, 262 insertions(+), 27 deletions(-) diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index 64f032577..cf1cc5418 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -46,6 +46,7 @@ enum { enum { UPDATED, REMOVED, + VISIBLE, LAST_SIGNAL }; @@ -65,6 +66,7 @@ typedef struct { GSList *calls; NMRemoteConnectionInitResult init_result; + gboolean visible; gboolean disposed; } NMRemoteConnectionPrivate; @@ -263,6 +265,7 @@ init_get_settings_cb (DBusGProxy *proxy, priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_ERROR; g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_INIT_RESULT); } else { + priv->visible = TRUE; replace_settings (self, new_settings); g_hash_table_destroy (new_settings); priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS; @@ -277,15 +280,31 @@ updated_get_settings_cb (DBusGProxy *proxy, gpointer user_data) { NMRemoteConnection *self = user_data; + NMRemoteConnectionPrivate *priv = NM_REMOTE_CONNECTION_GET_PRIVATE (self); if (error) { - /* The connection no longer exists, or is no longer visible to this - * user; we must remove it. + GHashTable *hash; + + /* Connection is no longer visible to this user. Let the settings + * service handle this via 'visible'. The settings service will emit + * the "removed" signal for us since it handles the lifetime of this + * object. */ - g_signal_emit (self, signals[REMOVED], 0); + hash = g_hash_table_new (g_str_hash, g_str_equal); + nm_connection_replace_settings (NM_CONNECTION (self), hash, NULL); + g_hash_table_destroy (hash); + + priv->visible = FALSE; + g_signal_emit (self, signals[VISIBLE], 0, FALSE); } else { replace_settings (self, new_settings); g_hash_table_destroy (new_settings); + + /* Settings service will handle announcing the connection to clients */ + if (priv->visible == FALSE) { + priv->visible = TRUE; + g_signal_emit (self, signals[VISIBLE], 0, TRUE); + } } } @@ -474,4 +493,12 @@ nm_remote_connection_class_init (NMRemoteConnectionClass *remote_class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signals[VISIBLE] = + g_signal_new ("visible", + G_TYPE_FROM_CLASS (remote_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); } diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 2c2bf6947..9469cefa6 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -18,7 +18,7 @@ * Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2009 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. */ #include @@ -205,6 +205,48 @@ connection_removed_cb (NMRemoteConnection *remote, gpointer user_data) g_hash_table_remove (priv->pending, path); } +static void +connection_visible_cb (NMRemoteConnection *remote, + gboolean visible, + gpointer user_data) +{ + NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); + const char *path; + + path = nm_connection_get_path (NM_CONNECTION (remote)); + g_assert (path); + + /* When a connection becomes invisible, we put it back in the pending + * hash until it becomes visible again. When it does, we move it back to + * the normal connections hash. + */ + if (visible) { + /* Connection visible to this user again */ + if (g_hash_table_lookup (priv->pending, path)) { + /* Move connection from pending to visible hash; emit for clients */ + g_hash_table_insert (priv->connections, g_strdup (path), g_object_ref (remote)); + g_hash_table_remove (priv->pending, path); + g_signal_emit (self, signals[NEW_CONNECTION], 0, remote); + } + } else { + /* Connection now invisible to this user */ + if (g_hash_table_lookup (priv->connections, path)) { + /* Move connection to pending hash and wait for it to become visible again */ + g_hash_table_insert (priv->pending, g_strdup (path), g_object_ref (remote)); + g_hash_table_remove (priv->connections, path); + + /* Signal to clients that the connection is gone; but we have to + * block our connection removed handler so we don't destroy + * the connection when the signal is emitted. + */ + g_signal_handlers_block_by_func (remote, connection_removed_cb, self); + g_signal_emit_by_name (remote, NM_REMOTE_CONNECTION_REMOVED); + g_signal_handlers_unblock_by_func (remote, connection_removed_cb, self); + } + } +} + static void connection_init_result_cb (NMRemoteConnection *remote, GParamSpec *pspec, @@ -295,6 +337,10 @@ new_connection_cb (DBusGProxy *proxy, const char *path, gpointer user_data) G_CALLBACK (connection_removed_cb), self); + g_signal_connect (connection, "visible", + G_CALLBACK (connection_visible_cb), + self); + g_signal_connect (connection, "notify::" NM_REMOTE_CONNECTION_INIT_RESULT, G_CALLBACK (connection_init_result_cb), self); diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c index 619b86d8d..ad62075d4 100644 --- a/libnm-glib/tests/test-remote-settings-client.c +++ b/libnm-glib/tests/test-remote-settings-client.c @@ -14,7 +14,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. * */ @@ -36,6 +36,8 @@ static GPid spid = 0; static NMRemoteSettings *settings = NULL; +DBusGConnection *bus = NULL; +NMRemoteConnection *remote = NULL; /*******************************************************************/ @@ -56,26 +58,21 @@ do { \ /*******************************************************************/ -typedef struct { - gboolean done; - NMRemoteConnection *connection; -} AddInfo; - static void add_cb (NMRemoteSettings *s, NMRemoteConnection *connection, GError *error, gpointer user_data) { - AddInfo *info = user_data; - if (error) g_warning ("Add error: %s", error->message); - info->done = TRUE; - info->connection = connection; + *((gboolean *) user_data) = TRUE; + remote = connection; } +#define TEST_CON_ID "blahblahblah" + static void test_add_connection (void) { @@ -85,14 +82,14 @@ test_add_connection (void) char *uuid; gboolean success; time_t start, now; - AddInfo info = { FALSE, NULL }; + gboolean done = FALSE; connection = nm_connection_new (); s_con = (NMSettingConnection *) nm_setting_connection_new (); uuid = nm_utils_uuid_generate (); g_object_set (G_OBJECT (s_con), - NM_SETTING_CONNECTION_ID, "blahblahblah", + NM_SETTING_CONNECTION_ID, TEST_CON_ID, NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, NULL); @@ -105,25 +102,176 @@ test_add_connection (void) success = nm_remote_settings_add_connection (settings, connection, add_cb, - &info); + &done); test_assert (success == TRUE); start = time (NULL); do { now = time (NULL); g_main_context_iteration (NULL, FALSE); - } while ((info.done == FALSE) && (now - start < 5)); - test_assert (info.done == TRUE); - test_assert (info.connection != NULL); + } while ((done == FALSE) && (now - start < 5)); + test_assert (done == TRUE); + test_assert (remote != NULL); /* Make sure the connection is the same as what we added */ test_assert (nm_connection_compare (connection, - NM_CONNECTION (info.connection), + NM_CONNECTION (remote), NM_SETTING_COMPARE_FLAG_EXACT) == TRUE); } /*******************************************************************/ +static void +set_visible_cb (DBusGProxy *proxy, + DBusGProxyCall *call, + gpointer user_data) +{ + GError *error = NULL; + gboolean success; + + success = dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); + if (!success) + g_warning ("Failed to change connection visibility: %s", error->message); + test_assert (success == TRUE); + test_assert (error == NULL); +} + +static void +invis_removed_cb (NMRemoteConnection *connection, gboolean *done) +{ + *done = TRUE; +} + +static void +invis_has_settings_cb (NMSetting *setting, + const char *key, + const GValue *value, + GParamFlags flags, + gpointer user_data) +{ + *((gboolean *) user_data) = TRUE; +} + +static void +test_make_invisible (void) +{ + time_t start, now; + GSList *list, *iter; + DBusGProxy *proxy; + gboolean done = FALSE, has_settings = FALSE; + char *path; + + test_assert (remote != NULL); + + /* Listen for the remove event when the connection becomes invisible */ + g_signal_connect (remote, "removed", G_CALLBACK (invis_removed_cb), &done); + + path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + test_assert (proxy != NULL); + + /* Bypass the NMRemoteSettings object so we can test it independently */ + dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, + G_TYPE_BOOLEAN, FALSE, G_TYPE_INVALID); + + /* Wait for the connection to be removed */ + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((done == FALSE) && (now - start < 5)); + test_assert (done == TRUE); + + /* Ensure NMRemoteSettings no longer has the connection */ + list = nm_remote_settings_list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + test_assert ((gpointer) remote != (gpointer) candidate); + test_assert (strcmp (path, nm_connection_get_path (candidate)) != 0); + } + + /* And ensure the invisible connection no longer has any settings */ + nm_connection_for_each_setting_value (NM_CONNECTION (remote), + invis_has_settings_cb, + &has_settings); + test_assert (has_settings == FALSE); + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + +static void +vis_new_connection_cb (NMRemoteSettings *foo, + NMRemoteConnection *connection, + NMRemoteConnection **new) +{ + *new = connection; +} + +static void +test_make_visible (void) +{ + time_t start, now; + GSList *list, *iter; + DBusGProxy *proxy; + gboolean found = FALSE; + char *path; + NMRemoteConnection *new = NULL; + + test_assert (remote != NULL); + + /* Wait for the new-connection signal when the connection is visible again */ + g_signal_connect (settings, NM_REMOTE_SETTINGS_NEW_CONNECTION, + G_CALLBACK (vis_new_connection_cb), &new); + + path = g_strdup (nm_connection_get_path (NM_CONNECTION (remote))); + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + test_assert (proxy != NULL); + + /* Bypass the NMRemoteSettings object so we can test it independently */ + dbus_g_proxy_begin_call (proxy, "SetVisible", set_visible_cb, NULL, NULL, + G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID); + + + /* Wait for the settings service to announce the connection again */ + start = time (NULL); + do { + now = time (NULL); + g_main_context_iteration (NULL, FALSE); + } while ((new == NULL) && (now - start < 5)); + + /* Ensure the new connection is the same as the one we made visible again */ + test_assert (new == remote); + + /* Ensure NMRemoteSettings has the connection */ + list = nm_remote_settings_list_connections (settings); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMConnection *candidate = NM_CONNECTION (iter->data); + + if ((gpointer) remote == (gpointer) candidate) { + test_assert (strcmp (path, nm_connection_get_path (candidate)) == 0); + test_assert (strcmp (TEST_CON_ID, nm_connection_get_id (candidate)) == 0); + found = TRUE; + break; + } + } + test_assert (found == TRUE); + + g_free (path); + g_object_unref (proxy); +} + +/*******************************************************************/ + static void deleted_cb (DBusGProxy *proxy, DBusGProxyCall *call, @@ -140,15 +288,13 @@ deleted_cb (DBusGProxy *proxy, } static void -removed_cb (NMRemoteConnection *connection, gpointer user_data) +removed_cb (NMRemoteConnection *connection, gboolean *done) { - gboolean *done = user_data; - *done = TRUE; } static void -test_remove_connection (DBusGConnection *bus) +test_remove_connection (void) { NMRemoteConnection *connection; time_t start, now; @@ -210,7 +356,6 @@ int main (int argc, char **argv) char *service_argv[3] = { NULL, NULL, NULL }; int ret; GError *error = NULL; - DBusGConnection *bus; int i = 100; g_assert (argc == 3); @@ -248,7 +393,9 @@ int main (int argc, char **argv) suite = g_test_get_root (); g_test_suite_add (suite, TESTCASE (test_add_connection, NULL)); - g_test_suite_add (suite, TESTCASE (test_remove_connection, bus)); + g_test_suite_add (suite, TESTCASE (test_make_invisible, NULL)); + g_test_suite_add (suite, TESTCASE (test_make_visible, NULL)); + g_test_suite_add (suite, TESTCASE (test_remove_connection, NULL)); ret = g_test_run (); diff --git a/libnm-glib/tests/test-remote-settings-service.py b/libnm-glib/tests/test-remote-settings-service.py index 1f4f9af07..e6bd798f9 100755 --- a/libnm-glib/tests/test-remote-settings-service.py +++ b/libnm-glib/tests/test-remote-settings-service.py @@ -18,6 +18,9 @@ class UnknownInterfaceException(dbus.DBusException): class UnknownPropertyException(dbus.DBusException): _dbus_error_name = IFACE_DBUS + '.UnknownProperty' +class PermissionDeniedException(dbus.DBusException): + _dbus_error_name = IFACE_SETTINGS + '.PermissionDenied' + mainloop = gobject.MainLoop() class Connection(dbus.service.Object): @@ -26,11 +29,19 @@ class Connection(dbus.service.Object): self.path = object_path self.settings = settings self.remove_func = remove_func + self.visible = True @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') def GetSettings(self): + if not self.visible: + raise PermissionDeniedException() return self.settings + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='b', out_signature='') + def SetVisible(self, vis): + self.visible = vis + self.Updated() + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='') def Delete(self): self.remove_func(self) @@ -40,6 +51,10 @@ class Connection(dbus.service.Object): def Removed(self): pass + @dbus.service.signal(IFACE_CONNECTION, signature='') + def Updated(self): + pass + class Settings(dbus.service.Object): def __init__(self, bus, object_path): dbus.service.Object.__init__(self, bus, object_path) From c7ec68e0bad9937f5c932c39465d7b6e98f545ba Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 12 Feb 2011 22:00:30 -0600 Subject: [PATCH 262/264] libnm-glib: handle initially invisible connections correctly Don't delete them if we don't have permission for them, since we may get permission for them later via Update. But to listen for Update we need the connection around. --- libnm-glib/nm-remote-connection-private.h | 3 ++- libnm-glib/nm-remote-connection.c | 6 +++++- libnm-glib/nm-remote-settings.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libnm-glib/nm-remote-connection-private.h b/libnm-glib/nm-remote-connection-private.h index 22d84ae74..3df576062 100644 --- a/libnm-glib/nm-remote-connection-private.h +++ b/libnm-glib/nm-remote-connection-private.h @@ -28,7 +28,8 @@ typedef enum { NM_REMOTE_CONNECTION_INIT_RESULT_UNKNOWN = 0, NM_REMOTE_CONNECTION_INIT_RESULT_SUCCESS, - NM_REMOTE_CONNECTION_INIT_RESULT_ERROR + NM_REMOTE_CONNECTION_INIT_RESULT_ERROR, + NM_REMOTE_CONNECTION_INIT_RESULT_INVISIBLE, } NMRemoteConnectionInitResult; #endif /* __NM_REMOTE_CONNECTION_PRIVATE__ */ diff --git a/libnm-glib/nm-remote-connection.c b/libnm-glib/nm-remote-connection.c index cf1cc5418..09c711259 100644 --- a/libnm-glib/nm-remote-connection.c +++ b/libnm-glib/nm-remote-connection.c @@ -262,7 +262,11 @@ init_get_settings_cb (DBusGProxy *proxy, if (error) { /* Connection doesn't exist, or isn't visible to this user */ - priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_ERROR; + if (dbus_g_error_has_name (error, "org.freedesktop.NetworkManager.Settings.PermissionDenied")) + priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_INVISIBLE; + else + priv->init_result = NM_REMOTE_CONNECTION_INIT_RESULT_ERROR; + g_object_notify (G_OBJECT (self), NM_REMOTE_CONNECTION_INIT_RESULT); } else { priv->visible = TRUE; diff --git a/libnm-glib/nm-remote-settings.c b/libnm-glib/nm-remote-settings.c index 9469cefa6..8bfa0d924 100644 --- a/libnm-glib/nm-remote-settings.c +++ b/libnm-glib/nm-remote-settings.c @@ -42,6 +42,7 @@ typedef struct { GHashTable *connections; GHashTable *pending; /* Connections we don't have settings for yet */ gboolean service_running; + guint32 init_left; /* AddConnectionInfo objects that are waiting for the connection to become initialized */ GSList *add_list; @@ -258,6 +259,7 @@ connection_init_result_cb (NMRemoteConnection *remote, AddConnectionInfo *addinfo; const char *path; GError *add_error = NULL; + gboolean remove_from_pending = TRUE; /* Disconnect from the init-result signal just to be safe */ g_signal_handlers_disconnect_matched (remote, @@ -294,6 +296,9 @@ connection_init_result_cb (NMRemoteConnection *remote, */ g_signal_emit (self, signals[NEW_CONNECTION], 0, remote); break; + case NM_REMOTE_CONNECTION_INIT_RESULT_INVISIBLE: + remove_from_pending = FALSE; + /* fall through */ case NM_REMOTE_CONNECTION_INIT_RESULT_ERROR: /* Complete pending AddConnection callbacks */ if (addinfo) { @@ -308,10 +313,12 @@ connection_init_result_cb (NMRemoteConnection *remote, break; } - g_hash_table_remove (priv->pending, path); + if (remove_from_pending) + g_hash_table_remove (priv->pending, path); /* Let listeners know that all connections have been found */ - if (!g_hash_table_size (priv->pending)) + priv->init_left--; + if (priv->init_left == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); } @@ -361,6 +368,7 @@ fetch_connections_done (DBusGProxy *proxy, gpointer user_data) { NMRemoteSettings *self = NM_REMOTE_SETTINGS (user_data); + NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self); int i; if (error) { @@ -383,6 +391,7 @@ fetch_connections_done (DBusGProxy *proxy, if (connections->len == 0) g_signal_emit (self, signals[CONNECTIONS_READ], 0); else { + priv->init_left = connections->len; for (i = 0; i < connections->len; i++) { char *path = g_ptr_array_index (connections, i); From d61a312ca2c8297c4ac2c278f4f3c1e0139b2692 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 12 Feb 2011 22:26:48 -0600 Subject: [PATCH 263/264] libnm-util: make sure NULL secrets don't slip in via g_object_set() We already do this for nm_setting_vpn_add_secret() --- libnm-util/nm-setting-vpn.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index d249e0301..7cf247027 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -442,6 +442,8 @@ finalize (GObject *object) static void copy_hash (gpointer key, gpointer value, gpointer user_data) { + g_return_if_fail (value != NULL); + g_return_if_fail (strlen (value)); g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), g_strdup (value)); } From e08db5cae5873b0ad68e6be7d87e5a1d9ae0cb14 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 12 Feb 2011 22:37:33 -0600 Subject: [PATCH 264/264] libnm-util: warn if trying to set NULL VPN secrets --- libnm-util/nm-setting-vpn.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index 7cf247027..53884f9db 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -316,8 +316,18 @@ update_secret_hash (NMSetting *setting, /* Now add the items to the settings' secrets list */ g_hash_table_iter_init (&iter, secrets); - while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) + while (g_hash_table_iter_next (&iter, (gpointer *) &name, (gpointer *) &value)) { + if (value == NULL) { + g_warn_if_fail (value != NULL); + continue; + } + if (strlen (value) == 0) { + g_warn_if_fail (strlen (value) > 0); + continue; + } + g_hash_table_insert (priv->secrets, g_strdup (name), g_strdup (value)); + } return TRUE; }