settings: port to gdbus

This commit is contained in:
Dan Winship
2015-04-15 14:53:30 -04:00
parent 9f8de603e3
commit df6706813a
10 changed files with 427 additions and 550 deletions

View File

@@ -8,8 +8,6 @@
Called by secret Agents to register their ability to provide and save Called by secret Agents to register their ability to provide and save
network secrets. network secrets.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_agent_manager_register"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="identifier" type="s" direction="in"> <arg name="identifier" type="s" direction="in">
<tp:docstring> <tp:docstring>
Identifies this agent; only one agent in each user session may use the Identifies this agent; only one agent in each user session may use the
@@ -27,8 +25,6 @@
<tp:docstring> <tp:docstring>
Like Register() but indicates agent capabilities to NetworkManager. Like Register() but indicates agent capabilities to NetworkManager.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_agent_manager_register_with_capabilities"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="identifier" type="s" direction="in"> <arg name="identifier" type="s" direction="in">
<tp:docstring> <tp:docstring>
See the Register() method's identifier argument. See the Register() method's identifier argument.
@@ -47,8 +43,6 @@
longer handle requests for network secrets. Agents are automatically longer handle requests for network secrets. Agents are automatically
unregistered when they disconnect from D-Bus. unregistered when they disconnect from D-Bus.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_agent_manager_unregister"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method> </method>
</interface> </interface>

View File

@@ -15,8 +15,6 @@
stored in persistent storage or sent to a Secret Agent for storage, stored in persistent storage or sent to a Secret Agent for storage,
depending on the flags associated with each secret. depending on the flags associated with each secret.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_update"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="properties" type="a{sa{sv}}" direction="in"> <arg name="properties" type="a{sa{sv}}" direction="in">
<tp:docstring> <tp:docstring>
New connection settings, properties, and (optionally) secrets. New connection settings, properties, and (optionally) secrets.
@@ -37,8 +35,6 @@
reloaded from disk (either automatically on file change or reloaded from disk (either automatically on file change or
due to an explicit ReloadConnections call). due to an explicit ReloadConnections call).
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_update_unsaved"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="properties" type="a{sa{sv}}" direction="in"> <arg name="properties" type="a{sa{sv}}" direction="in">
<tp:docstring> <tp:docstring>
New connection settings, properties, and (optionally) secrets. New connection settings, properties, and (optionally) secrets.
@@ -50,8 +46,6 @@
<tp:docstring> <tp:docstring>
Delete the connection. Delete the connection.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_delete"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method> </method>
<method name="GetSettings"> <method name="GetSettings">
@@ -61,8 +55,6 @@
to the network, as those are often protected. Secrets must to the network, as those are often protected. Secrets must
be requested separately using the GetSecrets() call. be requested separately using the GetSecrets() call.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_get_settings"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="settings" type="a{sa{sv}}" direction="out" tp:type="String_String_Variant_Map_Map"> <arg name="settings" type="a{sa{sv}}" direction="out" tp:type="String_String_Variant_Map_Map">
<tp:docstring> <tp:docstring>
The nested settings maps describing this object. The nested settings maps describing this object.
@@ -77,8 +69,6 @@
the requestor's session will be returned. The user will never the requestor's session will be returned. The user will never
be prompted for secrets as a result of this request. be prompted for secrets as a result of this request.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_get_secrets"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="setting_name" type="s" direction="in"> <arg name="setting_name" type="s" direction="in">
<tp:docstring> <tp:docstring>
Name of the setting to return secrets for. If empty, all Name of the setting to return secrets for. If empty, all
@@ -97,8 +87,6 @@
<tp:docstring> <tp:docstring>
Clear the secrets belonging to this network connection profile. Clear the secrets belonging to this network connection profile.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_clear_secrets"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method> </method>
<method name="Save"> <method name="Save">
@@ -106,8 +94,6 @@
Saves a "dirty" connection (that had previously been Saves a "dirty" connection (that had previously been
updated with UpdateUnsaved) to persistent storage. updated with UpdateUnsaved) to persistent storage.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_connection_save"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
</method> </method>
<signal name="Updated"> <signal name="Updated">

View File

@@ -10,7 +10,6 @@
<tp:docstring> <tp:docstring>
List the saved network connections known to NetworkManager. List the saved network connections known to NetworkManager.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_list_connections"/>
<arg name="connections" type="ao" direction="out"> <arg name="connections" type="ao" direction="out">
<tp:docstring> <tp:docstring>
List of connections. List of connections.
@@ -22,8 +21,6 @@
<tp:docstring> <tp:docstring>
Retrieve the object path of a connection, given that connection's UUID. Retrieve the object path of a connection, given that connection's UUID.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_get_connection_by_uuid"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="uuid" type="s" direction="in"> <arg name="uuid" type="s" direction="in">
<tp:docstring> <tp:docstring>
The UUID to find the connection object path for. The UUID to find the connection object path for.
@@ -43,8 +40,6 @@
the network described by the new connection, and (2) the connection the network described by the new connection, and (2) the connection
is allowed to be started automatically. is allowed to be started automatically.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="connection" type="a{sa{sv}}" direction="in"> <arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring> <tp:docstring>
Connection settings and properties. Connection settings and properties.
@@ -69,8 +64,6 @@
connection is reloaded from disk (either automatically on file connection is reloaded from disk (either automatically on file
change or due to an explicit ReloadConnections call). change or due to an explicit ReloadConnections call).
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_add_connection_unsaved"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="connection" type="a{sa{sv}}" direction="in"> <arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring> <tp:docstring>
Connection settings and properties. Connection settings and properties.
@@ -93,8 +86,6 @@
harmless.) As with AddConnection(), this operation does not harmless.) As with AddConnection(), this operation does not
necessarily start the network connection. necessarily start the network connection.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_load_connections"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="filenames" type="as" direction="in"> <arg name="filenames" type="as" direction="in">
<tp:docstring> <tp:docstring>
Array of paths to on-disk connection profiles in directories Array of paths to on-disk connection profiles in directories
@@ -125,8 +116,6 @@
change, so you only need to use this command if you have set change, so you only need to use this command if you have set
"monitor-connection-files=false" in NetworkManager.conf. "monitor-connection-files=false" in NetworkManager.conf.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_reload_connections"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="status" type="b" direction="out"> <arg name="status" type="b" direction="out">
<tp:docstring> <tp:docstring>
Success or failure. Success or failure.
@@ -138,8 +127,6 @@
<tp:docstring> <tp:docstring>
Save the hostname to persistent configuration. Save the hostname to persistent configuration.
</tp:docstring> </tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_settings_save_hostname"/>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="hostname" type="s" direction="in"> <arg name="hostname" type="s" direction="in">
<tp:docstring> <tp:docstring>
The hostname to save to persistent configuration. If blank, the persistent hostname is cleared. The hostname to save to persistent configuration. If blank, the persistent hostname is cleared.

View File

@@ -23,16 +23,11 @@
#include <string.h> #include <string.h>
#include <pwd.h> #include <pwd.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-default.h" #include "nm-default.h"
#include "nm-dbus-interface.h" #include "nm-dbus-interface.h"
#include "nm-agent-manager.h" #include "nm-agent-manager.h"
#include "nm-secret-agent.h" #include "nm-secret-agent.h"
#include "nm-auth-utils.h" #include "nm-auth-utils.h"
#include "nm-dbus-glib-types.h"
#include "nm-auth-utils.h"
#include "nm-setting-vpn.h" #include "nm-setting-vpn.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "nm-enum-types.h" #include "nm-enum-types.h"
@@ -41,6 +36,9 @@
#include "nm-session-monitor.h" #include "nm-session-monitor.h"
#include "nm-simple-connection.h" #include "nm-simple-connection.h"
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "nm-core-internal.h"
#include "nmdbus-agent-manager.h"
G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_OBJECT) G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, NM_TYPE_EXPORTED_OBJECT)
@@ -78,20 +76,6 @@ static void request_remove_agent (Request *req, NMSecretAgent *agent, GSList **p
static void request_next_agent (Request *req); static void request_next_agent (Request *req);
static void impl_agent_manager_register (NMAgentManager *self,
const char *identifier,
DBusGMethodInvocation *context);
static void impl_agent_manager_register_with_capabilities (NMAgentManager *self,
const char *identifier,
NMSecretAgentCapabilities capabilities,
DBusGMethodInvocation *context);
static void impl_agent_manager_unregister (NMAgentManager *self,
DBusGMethodInvocation *context);
#include "nm-agent-manager-glue.h"
/*************************************************************/ /*************************************************************/
static gboolean static gboolean
@@ -130,6 +114,17 @@ remove_agent (NMAgentManager *self, const char *owner)
return TRUE; return TRUE;
} }
/* Call this *after* calling request_next_agent() */
static void
maybe_remove_agent_on_error (NMSecretAgent *agent,
GError *error)
{
if ( g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CLOSED)
|| g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_DISCONNECTED)
|| g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
remove_agent (nm_agent_manager_get (), nm_secret_agent_get_dbus_owner (agent));
}
/*************************************************************/ /*************************************************************/
static gboolean static gboolean
@@ -190,7 +185,7 @@ validate_identifier (const char *identifier, GError **error)
static void static void
agent_register_permissions_done (NMAuthChain *chain, agent_register_permissions_done (NMAuthChain *chain,
GError *error, GError *error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
gpointer user_data) gpointer user_data)
{ {
NMAgentManager *self = NM_AGENT_MANAGER (user_data); NMAgentManager *self = NM_AGENT_MANAGER (user_data);
@@ -211,8 +206,7 @@ agent_register_permissions_done (NMAuthChain *chain,
NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED, NM_AGENT_MANAGER_ERROR_PERMISSION_DENIED,
"Failed to request agent permissions: (%d) %s", "Failed to request agent permissions: (%d) %s",
error->code, error->message); error->code, error->message);
dbus_g_method_return_error (context, local); g_dbus_method_invocation_take_error (context, local);
g_error_free (local);
} else { } else {
agent = nm_auth_chain_steal_data (chain, "agent"); agent = nm_auth_chain_steal_data (chain, "agent");
g_assert (agent); g_assert (agent);
@@ -229,7 +223,7 @@ agent_register_permissions_done (NMAuthChain *chain,
g_hash_table_insert (priv->agents, g_strdup (sender), agent); g_hash_table_insert (priv->agents, g_strdup (sender), agent);
nm_log_dbg (LOGD_AGENTS, "(%s) agent registered", nm_log_dbg (LOGD_AGENTS, "(%s) agent registered",
nm_secret_agent_get_description (agent)); nm_secret_agent_get_description (agent));
dbus_g_method_return (context); g_dbus_method_invocation_return_value (context, NULL);
/* Signal an agent was registered */ /* Signal an agent was registered */
g_signal_emit (self, signals[AGENT_REGISTERED], 0, agent); g_signal_emit (self, signals[AGENT_REGISTERED], 0, agent);
@@ -271,9 +265,9 @@ agent_disconnected_cb (NMSecretAgent *agent, gpointer user_data)
static void static void
impl_agent_manager_register_with_capabilities (NMAgentManager *self, impl_agent_manager_register_with_capabilities (NMAgentManager *self,
GDBusMethodInvocation *context,
const char *identifier, const char *identifier,
NMSecretAgentCapabilities capabilities, guint32 capabilities)
DBusGMethodInvocation *context)
{ {
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self); NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
NMAuthSubject *subject; NMAuthSubject *subject;
@@ -334,22 +328,21 @@ impl_agent_manager_register_with_capabilities (NMAgentManager *self,
done: done:
if (error) if (error)
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_clear_error (&error);
g_clear_object (&subject); g_clear_object (&subject);
} }
static void static void
impl_agent_manager_register (NMAgentManager *self, impl_agent_manager_register (NMAgentManager *self,
const char *identifier, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) const char *identifier)
{ {
impl_agent_manager_register_with_capabilities (self, identifier, 0, context); impl_agent_manager_register_with_capabilities (self, context, identifier, 0);
} }
static void static void
impl_agent_manager_unregister (NMAgentManager *self, impl_agent_manager_unregister (NMAgentManager *self,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
GError *error = NULL; GError *error = NULL;
char *sender = NULL; char *sender = NULL;
@@ -373,19 +366,18 @@ impl_agent_manager_unregister (NMAgentManager *self,
goto done; goto done;
} }
dbus_g_method_return (context); g_dbus_method_invocation_return_value (context, NULL);
done: done:
if (error) if (error)
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_clear_error (&error);
g_free (sender); g_free (sender);
} }
/*************************************************************/ /*************************************************************/
typedef void (*RequestCompleteFunc) (Request *req, typedef void (*RequestCompleteFunc) (Request *req,
GHashTable *secrets, GVariant *secrets,
const char *agent_dbus_owner, const char *agent_dbus_owner,
const char *agent_username, const char *agent_username,
GError *error, GError *error,
@@ -481,7 +473,7 @@ request_free (Request *req)
static void static void
req_complete_success (Request *req, req_complete_success (Request *req,
GHashTable *secrets, GVariant *secrets,
const char *agent_dbus_owner, const char *agent_dbus_owner,
const char *agent_uname) const char *agent_uname)
{ {
@@ -658,7 +650,7 @@ typedef struct {
char *setting_name; char *setting_name;
char **hints; char **hints;
GHashTable *existing_secrets; GVariant *existing_secrets;
NMAgentSecretsResultFunc callback; NMAgentSecretsResultFunc callback;
gpointer callback_data; gpointer callback_data;
@@ -682,7 +674,7 @@ connection_request_free (gpointer data)
g_free (req->setting_name); g_free (req->setting_name);
g_strfreev (req->hints); g_strfreev (req->hints);
if (req->existing_secrets) if (req->existing_secrets)
g_hash_table_unref (req->existing_secrets); g_variant_unref (req->existing_secrets);
if (req->chain) if (req->chain)
nm_auth_chain_unref (req->chain); nm_auth_chain_unref (req->chain);
} }
@@ -710,7 +702,7 @@ connection_request_add_agent (Request *parent, NMSecretAgent *agent)
static ConnectionRequest * static ConnectionRequest *
connection_request_new_get (NMConnection *connection, connection_request_new_get (NMConnection *connection,
NMAuthSubject *subject, NMAuthSubject *subject,
GHashTable *existing_secrets, GVariant *existing_secrets,
const char *setting_name, const char *setting_name,
const char *verb, const char *verb,
NMSecretAgentGetSecretsFlags flags, NMSecretAgentGetSecretsFlags flags,
@@ -740,7 +732,7 @@ connection_request_new_get (NMConnection *connection,
req->connection = g_object_ref (connection); req->connection = g_object_ref (connection);
if (existing_secrets) if (existing_secrets)
req->existing_secrets = g_hash_table_ref (existing_secrets); req->existing_secrets = g_variant_ref (existing_secrets);
req->setting_name = g_strdup (setting_name); req->setting_name = g_strdup (setting_name);
req->hints = g_strdupv ((char **) hints); req->hints = g_strdupv ((char **) hints);
req->flags = flags; req->flags = flags;
@@ -779,13 +771,13 @@ connection_request_new_other (NMConnection *connection,
static void static void
get_done_cb (NMSecretAgent *agent, get_done_cb (NMSecretAgent *agent,
gconstpointer call_id, gconstpointer call_id,
GHashTable *secrets, GVariant *secrets,
GError *error, GError *error,
gpointer user_data) gpointer user_data)
{ {
Request *parent = user_data; Request *parent = user_data;
ConnectionRequest *req = user_data; ConnectionRequest *req = user_data;
GHashTable *setting_secrets; GVariant *setting_secrets;
const char *agent_dbus_owner; const char *agent_dbus_owner;
struct passwd *pw; struct passwd *pw;
char *agent_uname = NULL; char *agent_uname = NULL;
@@ -799,7 +791,7 @@ get_done_cb (NMSecretAgent *agent,
error ? error->code : -1, error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)"); (error && error->message) ? error->message : "(unknown)");
if (dbus_g_error_has_name (error, NM_DBUS_INTERFACE_SECRET_AGENT ".UserCanceled")) { if (_nm_dbus_error_has_name (error, NM_DBUS_INTERFACE_SECRET_AGENT ".UserCanceled")) {
error = g_error_new_literal (NM_AGENT_MANAGER_ERROR, error = g_error_new_literal (NM_AGENT_MANAGER_ERROR,
NM_AGENT_MANAGER_ERROR_USER_CANCELED, NM_AGENT_MANAGER_ERROR_USER_CANCELED,
"User canceled the secrets request."); "User canceled the secrets request.");
@@ -808,13 +800,14 @@ get_done_cb (NMSecretAgent *agent,
} else { } else {
/* Try the next agent */ /* Try the next agent */
request_next_agent (parent); request_next_agent (parent);
maybe_remove_agent_on_error (agent, error);
} }
return; return;
} }
/* Ensure the setting we wanted secrets for got returned and has something in it */ /* Ensure the setting we wanted secrets for got returned and has something in it */
setting_secrets = g_hash_table_lookup (secrets, req->setting_name); setting_secrets = g_variant_lookup_value (secrets, req->setting_name, NM_VARIANT_TYPE_SETTING);
if (!setting_secrets || !g_hash_table_size (setting_secrets)) { if (!setting_secrets || !g_variant_n_children (setting_secrets)) {
nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s/%s", nm_log_dbg (LOGD_AGENTS, "(%s) agent returned no secrets for request %p/%s/%s",
nm_secret_agent_get_description (agent), nm_secret_agent_get_description (agent),
req, parent->detail, req->setting_name); req, parent->detail, req->setting_name);
@@ -841,40 +834,40 @@ get_done_cb (NMSecretAgent *agent,
} }
static void static void
set_secrets_not_required (NMConnection *connection, GHashTable *hash) set_secrets_not_required (NMConnection *connection, GVariant *dict)
{ {
GHashTableIter iter, setting_iter; GVariantIter iter, setting_iter;
const char *setting_name = NULL; const char *setting_name = NULL;
GHashTable *setting_hash = NULL; GVariant *setting_dict = NULL;
/* Iterate through the settings hashes */ /* Iterate through the settings dicts */
g_hash_table_iter_init (&iter, hash); g_variant_iter_init (&iter, dict);
while (g_hash_table_iter_next (&iter, while (g_variant_iter_next (&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) {
(gpointer *) &setting_name,
(gpointer *) &setting_hash)) {
const char *key_name = NULL; const char *key_name = NULL;
NMSetting *setting; NMSetting *setting;
GValue *val; GVariant *val;
setting = nm_connection_get_setting_by_name (connection, setting_name); setting = nm_connection_get_setting_by_name (connection, setting_name);
if (setting) { if (setting) {
/* Now through each secret in the setting and mark it as not required */ /* Now through each secret in the setting and mark it as not required */
g_hash_table_iter_init (&setting_iter, setting_hash); g_variant_iter_init (&setting_iter, setting_dict);
while (g_hash_table_iter_next (&setting_iter, (gpointer *) &key_name, (gpointer *) &val)) { while (g_variant_iter_next (&setting_iter, "{&sv}", &key_name, &val)) {
/* For each secret, set the flag that it's not required; VPN /* For each secret, set the flag that it's not required; VPN
* secrets need slightly different treatment here since the * secrets need slightly different treatment here since the
* "secrets" property is actually a hash table of secrets. * "secrets" property is actually a dictionary of secrets.
*/ */
if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0 if ( strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME) == 0
&& strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0) { && strcmp (key_name, NM_SETTING_VPN_SECRETS) == 0
GHashTableIter vpn_secret_iter; && g_variant_is_of_type (val, G_VARIANT_TYPE ("a{ss}"))) {
const char *secret_name; GVariantIter vpn_secret_iter;
const char *secret_name, *secret;
g_hash_table_iter_init (&vpn_secret_iter, g_value_get_boxed (val)); g_variant_iter_init (&vpn_secret_iter, val);
while (g_hash_table_iter_next (&vpn_secret_iter, (gpointer *) &secret_name, NULL)) while (g_variant_iter_next (&vpn_secret_iter, "{&s&s}", &secret_name, &secret))
nm_setting_set_secret_flags (setting, secret_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); nm_setting_set_secret_flags (setting, secret_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL);
} else } else
nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL); nm_setting_set_secret_flags (setting, key_name, NM_SETTING_SECRET_FLAG_NOT_REQUIRED, NULL);
g_variant_unref (val);
} }
} }
} }
@@ -889,13 +882,8 @@ get_agent_request_secrets (ConnectionRequest *req, gboolean include_system_secre
tmp = nm_simple_connection_new_clone (req->connection); tmp = nm_simple_connection_new_clone (req->connection);
nm_connection_clear_secrets (tmp); nm_connection_clear_secrets (tmp);
if (include_system_secrets) { if (include_system_secrets) {
if (req->existing_secrets) { if (req->existing_secrets)
GVariant *secrets_dict; (void) nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, NULL);
secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets);
(void) nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, NULL);
g_variant_unref (secrets_dict);
}
} else { } else {
/* Update secret flags in the temporary connection to indicate that /* Update secret flags in the temporary connection to indicate that
* the system secrets we're not sending to the agent aren't required, * the system secrets we're not sending to the agent aren't required,
@@ -924,7 +912,7 @@ get_agent_request_secrets (ConnectionRequest *req, gboolean include_system_secre
static void static void
get_agent_modify_auth_cb (NMAuthChain *chain, get_agent_modify_auth_cb (NMAuthChain *chain,
GError *error, GError *error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
gpointer user_data) gpointer user_data)
{ {
Request *parent = user_data; Request *parent = user_data;
@@ -1058,19 +1046,18 @@ get_start (gpointer user_data)
{ {
Request *parent = user_data; Request *parent = user_data;
ConnectionRequest *req = user_data; ConnectionRequest *req = user_data;
GHashTable *setting_secrets = NULL; GVariant *setting_secrets = NULL;
parent->idle_id = 0; parent->idle_id = 0;
/* Check if there are any existing secrets */ /* Check if there are any existing secrets */
if (req->existing_secrets) if (req->existing_secrets)
setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name); setting_secrets = g_variant_lookup_value (req->existing_secrets, req->setting_name, NM_VARIANT_TYPE_SETTING);
if (setting_secrets && g_hash_table_size (setting_secrets)) { if (setting_secrets && g_variant_n_children (setting_secrets)) {
NMConnection *tmp; NMConnection *tmp;
GError *error = NULL; GError *error = NULL;
gboolean new_secrets = (req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW); gboolean new_secrets = (req->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
GVariant *secrets_dict;
/* The connection already had secrets; check if any more are required. /* The connection already had secrets; check if any more are required.
* If no more are required, we're done. If secrets are still needed, * If no more are required, we're done. If secrets are still needed,
@@ -1080,8 +1067,7 @@ get_start (gpointer user_data)
tmp = nm_simple_connection_new_clone (req->connection); tmp = nm_simple_connection_new_clone (req->connection);
g_assert (tmp); g_assert (tmp);
secrets_dict = nm_utils_connection_hash_to_dict (req->existing_secrets); if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) {
if (!nm_connection_update_secrets (tmp, req->setting_name, secrets_dict, &error)) {
req_complete_error (parent, error); req_complete_error (parent, error);
g_clear_error (&error); g_clear_error (&error);
} else { } else {
@@ -1107,7 +1093,6 @@ get_start (gpointer user_data)
request_next_agent (parent); request_next_agent (parent);
} }
} }
g_variant_unref (secrets_dict);
g_object_unref (tmp); g_object_unref (tmp);
} else { } else {
/* Couldn't get secrets from system settings, so now we ask the /* Couldn't get secrets from system settings, so now we ask the
@@ -1117,12 +1102,15 @@ get_start (gpointer user_data)
request_next_agent (parent); request_next_agent (parent);
} }
if (setting_secrets)
g_variant_unref (setting_secrets);
return FALSE; return FALSE;
} }
static void static void
get_complete_cb (Request *parent, get_complete_cb (Request *parent,
GHashTable *secrets, GVariant *secrets,
const char *agent_dbus_owner, const char *agent_dbus_owner,
const char *agent_username, const char *agent_username,
GError *error, GError *error,
@@ -1163,7 +1151,7 @@ guint32
nm_agent_manager_get_secrets (NMAgentManager *self, nm_agent_manager_get_secrets (NMAgentManager *self,
NMConnection *connection, NMConnection *connection,
NMAuthSubject *subject, NMAuthSubject *subject,
GHashTable *existing_secrets, GVariant *existing_secrets,
const char *setting_name, const char *setting_name,
NMSecretAgentGetSecretsFlags flags, NMSecretAgentGetSecretsFlags flags,
const char **hints, const char **hints,
@@ -1233,7 +1221,7 @@ nm_agent_manager_cancel_secrets (NMAgentManager *self,
static void static void
save_done_cb (NMSecretAgent *agent, save_done_cb (NMSecretAgent *agent,
gconstpointer call_id, gconstpointer call_id,
GHashTable *secrets, GVariant *secrets,
GError *error, GError *error,
gpointer user_data) gpointer user_data)
{ {
@@ -1251,6 +1239,7 @@ save_done_cb (NMSecretAgent *agent,
(error && error->message) ? error->message : "(unknown)"); (error && error->message) ? error->message : "(unknown)");
/* Try the next agent */ /* Try the next agent */
request_next_agent (parent); request_next_agent (parent);
maybe_remove_agent_on_error (agent, error);
return; return;
} }
@@ -1280,7 +1269,7 @@ save_next_cb (Request *parent)
static void static void
save_complete_cb (Request *req, save_complete_cb (Request *req,
GHashTable *secrets, GVariant *secrets,
const char *agent_dbus_owner, const char *agent_dbus_owner,
const char *agent_username, const char *agent_username,
GError *error, GError *error,
@@ -1327,7 +1316,7 @@ nm_agent_manager_save_secrets (NMAgentManager *self,
static void static void
delete_done_cb (NMSecretAgent *agent, delete_done_cb (NMSecretAgent *agent,
gconstpointer call_id, gconstpointer call_id,
GHashTable *secrets, GVariant *secrets,
GError *error, GError *error,
gpointer user_data) gpointer user_data)
{ {
@@ -1347,6 +1336,8 @@ delete_done_cb (NMSecretAgent *agent,
/* Tell the next agent to delete secrets */ /* Tell the next agent to delete secrets */
request_next_agent (req); request_next_agent (req);
if (error)
maybe_remove_agent_on_error (agent, error);
} }
static void static void
@@ -1367,7 +1358,7 @@ delete_next_cb (Request *parent)
static void static void
delete_complete_cb (Request *req, delete_complete_cb (Request *req,
GHashTable *secrets, GVariant *secrets,
const char *agent_dbus_owner, const char *agent_dbus_owner,
const char *agent_username, const char *agent_username,
GError *error, GError *error,
@@ -1460,7 +1451,7 @@ nm_agent_manager_all_agents_have_capability (NMAgentManager *manager,
static void static void
agent_permissions_changed_done (NMAuthChain *chain, agent_permissions_changed_done (NMAuthChain *chain,
GError *error, GError *error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
gpointer user_data) gpointer user_data)
{ {
NMAgentManager *self = NM_AGENT_MANAGER (user_data); NMAgentManager *self = NM_AGENT_MANAGER (user_data);
@@ -1609,9 +1600,9 @@ nm_agent_manager_class_init (NMAgentManagerClass *agent_manager_class)
G_TYPE_OBJECT); G_TYPE_OBJECT);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (agent_manager_class), nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (agent_manager_class),
&dbus_glib_nm_agent_manager_object_info); NMDBUS_TYPE_AGENT_MANAGER_SKELETON,
"Register", impl_agent_manager_register,
dbus_g_error_domain_register (NM_AGENT_MANAGER_ERROR, "RegisterWithCapabilities", impl_agent_manager_register_with_capabilities,
NM_DBUS_INTERFACE_AGENT_MANAGER, "Unregister", impl_agent_manager_unregister,
NM_TYPE_AGENT_MANAGER_ERROR); NULL);
} }

View File

@@ -56,7 +56,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
gboolean agent_has_modify, gboolean agent_has_modify,
const char *setting_name, const char *setting_name,
NMSecretAgentGetSecretsFlags flags, NMSecretAgentGetSecretsFlags flags,
GHashTable *secrets, GVariant *secrets,
GError *error, GError *error,
gpointer user_data, gpointer user_data,
gpointer other_data2, gpointer other_data2,
@@ -65,7 +65,7 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
guint32 nm_agent_manager_get_secrets (NMAgentManager *manager, guint32 nm_agent_manager_get_secrets (NMAgentManager *manager,
NMConnection *connection, NMConnection *connection,
NMAuthSubject *subject, NMAuthSubject *subject,
GHashTable *existing_secrets, GVariant *existing_secrets,
const char *setting_name, const char *setting_name,
NMSecretAgentGetSecretsFlags flags, NMSecretAgentGetSecretsFlags flags,
const char **hints, const char **hints,

View File

@@ -23,17 +23,14 @@
#include <sys/types.h> #include <sys/types.h>
#include <pwd.h> #include <pwd.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-default.h" #include "nm-default.h"
#include "nm-dbus-interface.h" #include "nm-dbus-interface.h"
#include "nm-secret-agent.h" #include "nm-secret-agent.h"
#include "nm-bus-manager.h" #include "nm-bus-manager.h"
#include "nm-dbus-glib-types.h"
#include "nm-auth-subject.h" #include "nm-auth-subject.h"
#include "nm-simple-connection.h" #include "nm-simple-connection.h"
#include "NetworkManagerUtils.h"
#include "nmdbus-secret-agent.h"
G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT) G_DEFINE_TYPE (NMSecretAgent, nm_secret_agent, G_TYPE_OBJECT)
@@ -52,7 +49,7 @@ typedef struct {
GSList *permissions; GSList *permissions;
DBusGProxy *proxy; NMDBusSecretAgent *proxy;
GHashTable *requests; GHashTable *requests;
} NMSecretAgentPrivate; } NMSecretAgentPrivate;
@@ -68,7 +65,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct { typedef struct {
NMSecretAgent *agent; NMSecretAgent *agent;
DBusGProxyCall *call; GCancellable *cancellable;
char *path; char *path;
char *setting_name; char *setting_name;
NMSecretAgentCallback callback; NMSecretAgentCallback callback;
@@ -90,6 +87,7 @@ request_new (NMSecretAgent *agent,
r->setting_name = g_strdup (setting_name); r->setting_name = g_strdup (setting_name);
r->callback = callback; r->callback = callback;
r->callback_data = callback_data; r->callback_data = callback_data;
r->cancellable = g_cancellable_new ();
return r; return r;
} }
@@ -98,6 +96,7 @@ request_free (Request *r)
{ {
g_free (r->path); g_free (r->path);
g_free (r->setting_name); g_free (r->setting_name);
g_object_unref (r->cancellable);
g_slice_free (Request, r); g_slice_free (Request, r);
} }
@@ -258,25 +257,26 @@ nm_secret_agent_has_permission (NMSecretAgent *agent, const char *permission)
/*************************************************************/ /*************************************************************/
static void static void
get_callback (DBusGProxy *proxy, get_callback (GObject *proxy,
DBusGProxyCall *call, GAsyncResult *result,
void *user_data) gpointer user_data)
{ {
Request *r = user_data; Request *r = user_data;
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
GVariant *secrets = NULL;
GError *error = NULL; GError *error = NULL;
GHashTable *secrets = NULL;
g_return_if_fail (call == r->call); if (!g_cancellable_is_cancelled (r->cancellable)) {
nmdbus_secret_agent_call_get_secrets_finish (priv->proxy, &secrets, result, &error);
if (error)
g_dbus_error_strip_remote_error (error);
dbus_g_proxy_end_call (proxy, call, &error, r->callback (r->agent, r, secrets, error, r->callback_data);
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &secrets, g_clear_pointer (&secrets, g_variant_unref);
G_TYPE_INVALID); g_clear_error (&error);
r->callback (r->agent, r->call, secrets, error, r->callback_data); }
if (secrets)
g_hash_table_unref (secrets); g_hash_table_remove (priv->requests, r);
g_clear_error (&error);
g_hash_table_remove (priv->requests, call);
} }
gconstpointer gconstpointer
@@ -289,8 +289,8 @@ nm_secret_agent_get_secrets (NMSecretAgent *self,
gpointer callback_data) gpointer callback_data)
{ {
NMSecretAgentPrivate *priv; NMSecretAgentPrivate *priv;
static const char *no_hints[] = { NULL };
GVariant *dict; GVariant *dict;
GHashTable *hash;
Request *r; Request *r;
g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (self != NULL, NULL);
@@ -301,123 +301,81 @@ nm_secret_agent_get_secrets (NMSecretAgent *self,
g_return_val_if_fail (priv->proxy != NULL, NULL); g_return_val_if_fail (priv->proxy != NULL, NULL);
dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL); dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
hash = nm_utils_connection_dict_to_hash (dict);
g_variant_unref (dict);
/* Mask off the private flags if present */ /* Mask off the private flags if present */
flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM; flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM;
flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS; flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS;
r = request_new (self, nm_connection_get_path (connection), setting_name, callback, callback_data); 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, nmdbus_secret_agent_call_get_secrets (priv->proxy,
"GetSecrets", dict,
get_callback, nm_connection_get_path (connection),
r, setting_name,
NULL, hints ? hints : no_hints,
120000, /* 120 seconds */ flags,
DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, hash, r->cancellable,
DBUS_TYPE_G_OBJECT_PATH, nm_connection_get_path (connection), get_callback, r);
G_TYPE_STRING, setting_name, g_hash_table_insert (priv->requests, r, r);
G_TYPE_STRV, hints,
G_TYPE_UINT, flags,
G_TYPE_INVALID);
g_hash_table_insert (priv->requests, r->call, r);
g_hash_table_destroy (hash); return r;
return r->call;
} }
static void static void
cancel_done (DBusGProxy *proxy, DBusGProxyCall *call_id, void *user_data) cancel_done (GObject *proxy, GAsyncResult *result, gpointer user_data)
{ {
char *description = user_data;
GError *error = NULL; GError *error = NULL;
if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { if (!nmdbus_secret_agent_call_cancel_get_secrets_finish (NMDBUS_SECRET_AGENT (proxy), result, &error)) {
nm_log_dbg (LOGD_AGENTS, "(%s): agent failed to cancel secrets: (%d) %s", g_dbus_error_strip_remote_error (error);
(const char *) user_data, nm_log_dbg (LOGD_AGENTS, "(%s): agent failed to cancel secrets: %s",
error ? error->code : -1, description, error->message);
error && error->message ? error->message : "(unknown)");
g_clear_error (&error); g_clear_error (&error);
} }
g_free (description);
} }
void void
nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call) nm_secret_agent_cancel_secrets (NMSecretAgent *self, gconstpointer call)
{ {
NMSecretAgentPrivate *priv; NMSecretAgentPrivate *priv;
Request *r; Request *r = (gpointer) call;
g_return_if_fail (self != NULL); g_return_if_fail (self != NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self); priv = NM_SECRET_AGENT_GET_PRIVATE (self);
g_return_if_fail (priv->proxy != NULL); g_return_if_fail (priv->proxy != NULL);
r = g_hash_table_lookup (priv->requests, call);
g_return_if_fail (r != NULL); g_return_if_fail (r != NULL);
dbus_g_proxy_cancel_call (priv->proxy, (gpointer) call); g_cancellable_cancel (r->cancellable);
dbus_g_proxy_begin_call (priv->proxy, nmdbus_secret_agent_call_cancel_get_secrets (priv->proxy,
"CancelGetSecrets", r->path, r->setting_name,
cancel_done, NULL,
g_strdup (nm_secret_agent_get_description (self)), cancel_done,
g_free, g_strdup (nm_secret_agent_get_description (self)));
DBUS_TYPE_G_OBJECT_PATH, r->path,
G_TYPE_STRING, r->setting_name,
G_TYPE_INVALID);
g_hash_table_remove (priv->requests, call);
} }
/*************************************************************/ /*************************************************************/
static void static void
agent_save_delete_cb (DBusGProxy *proxy, agent_save_cb (GObject *proxy,
DBusGProxyCall *call, GAsyncResult *result,
void *user_data) gpointer user_data)
{ {
Request *r = user_data; Request *r = user_data;
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
GError *error = NULL; GError *error = NULL;
g_return_if_fail (call == r->call); if (!g_cancellable_is_cancelled (r->cancellable)) {
nmdbus_secret_agent_call_save_secrets_finish (priv->proxy, result, &error);
if (error)
g_dbus_error_strip_remote_error (error);
r->callback (r->agent, r, NULL, error, r->callback_data);
g_clear_error (&error);
}
dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID); g_hash_table_remove (priv->requests, r);
r->callback (r->agent, r->call, NULL, error, r->callback_data);
g_clear_error (&error);
g_hash_table_remove (priv->requests, call);
}
static gpointer
agent_new_save_delete (NMSecretAgent *self,
NMConnection *connection,
NMConnectionSerializationFlags flags,
const char *method,
NMSecretAgentCallback callback,
gpointer callback_data)
{
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
GVariant *dict;
GHashTable *hash;
Request *r;
const char *cpath = nm_connection_get_path (connection);
dict = nm_connection_to_dbus (connection, flags);
hash = nm_utils_connection_dict_to_hash (dict);
g_variant_unref (dict);
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 gconstpointer
@@ -426,16 +384,46 @@ nm_secret_agent_save_secrets (NMSecretAgent *self,
NMSecretAgentCallback callback, NMSecretAgentCallback callback,
gpointer callback_data) gpointer callback_data)
{ {
NMSecretAgentPrivate *priv;
GVariant *dict;
Request *r;
const char *cpath;
g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
cpath = nm_connection_get_path (connection);
/* Caller should have ensured that only agent-owned secrets exist in 'connection' */ /* Caller should have ensured that only agent-owned secrets exist in 'connection' */
return agent_new_save_delete (self, dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
connection,
NM_CONNECTION_SERIALIZE_ALL, r = request_new (self, cpath, NULL, callback, callback_data);
"SaveSecrets", nmdbus_secret_agent_call_save_secrets (priv->proxy,
callback, dict, cpath,
callback_data); NULL,
agent_save_cb, r);
g_hash_table_insert (priv->requests, r, r);
return r;
}
static void
agent_delete_cb (GObject *proxy,
GAsyncResult *result,
gpointer user_data)
{
Request *r = user_data;
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (r->agent);
GError *error = NULL;
if (!g_cancellable_is_cancelled (r->cancellable)) {
nmdbus_secret_agent_call_delete_secrets_finish (priv->proxy, result, &error);
r->callback (r->agent, r, NULL, error, r->callback_data);
g_clear_error (&error);
}
g_hash_table_remove (priv->requests, r);
} }
gconstpointer gconstpointer
@@ -444,54 +432,54 @@ nm_secret_agent_delete_secrets (NMSecretAgent *self,
NMSecretAgentCallback callback, NMSecretAgentCallback callback,
gpointer callback_data) gpointer callback_data)
{ {
NMSecretAgentPrivate *priv;
GVariant *dict;
Request *r;
const char *cpath;
g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
priv = NM_SECRET_AGENT_GET_PRIVATE (self);
cpath = nm_connection_get_path (connection);
/* No secrets sent; agents must be smart enough to track secrets using the UUID or something */ /* No secrets sent; agents must be smart enough to track secrets using the UUID or something */
return agent_new_save_delete (self, dict = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
connection,
NM_CONNECTION_SERIALIZE_NO_SECRETS, r = request_new (self, cpath, NULL, callback, callback_data);
"DeleteSecrets", nmdbus_secret_agent_call_delete_secrets (priv->proxy,
callback, dict, cpath,
callback_data); NULL,
agent_delete_cb, r);
g_hash_table_insert (priv->requests, r, r);
return r;
} }
static void proxy_cleanup (NMSecretAgent *self);
static void static void
name_owner_changed_cb (NMBusManager *dbus_mgr, name_owner_changed_cb (GObject *proxy,
const char *name, GParamSpec *pspec,
const char *old_owner,
const char *new_owner,
gpointer user_data) gpointer user_data)
{ {
NMSecretAgent *self = NM_SECRET_AGENT (user_data); NMSecretAgent *self = NM_SECRET_AGENT (user_data);
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
char *owner;
if (!new_owner && !g_strcmp0 (old_owner, priv->dbus_owner)) owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy));
proxy_cleanup (self); if (!owner) {
} g_signal_handlers_disconnect_by_func (priv->proxy, name_owner_changed_cb, self);
static void
proxy_cleanup (NMSecretAgent *self)
{
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (self);
if (priv->proxy) {
g_signal_handlers_disconnect_by_func (priv->proxy, proxy_cleanup, self);
g_clear_object (&priv->proxy); g_clear_object (&priv->proxy);
g_signal_handlers_disconnect_by_func (nm_bus_manager_get (), name_owner_changed_cb, self);
g_signal_emit (self, signals[DISCONNECTED], 0); g_signal_emit (self, signals[DISCONNECTED], 0);
g_clear_pointer (&priv->dbus_owner, g_free); g_clear_pointer (&priv->dbus_owner, g_free);
} } else
g_free (owner);
} }
/*************************************************************/ /*************************************************************/
NMSecretAgent * NMSecretAgent *
nm_secret_agent_new (DBusGMethodInvocation *context, nm_secret_agent_new (GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
const char *identifier, const char *identifier,
NMSecretAgentCapabilities capabilities) NMSecretAgentCapabilities capabilities)
@@ -500,6 +488,7 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
NMSecretAgentPrivate *priv; NMSecretAgentPrivate *priv;
char *hash_str; char *hash_str;
struct passwd *pw; struct passwd *pw;
GDBusProxy *proxy;
g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (context != NULL, NULL);
g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL);
@@ -523,18 +512,17 @@ nm_secret_agent_new (DBusGMethodInvocation *context,
priv->hash = g_str_hash (hash_str); priv->hash = g_str_hash (hash_str);
g_free (hash_str); g_free (hash_str);
priv->proxy = nm_bus_manager_new_proxy (nm_bus_manager_get (), proxy = nm_bus_manager_new_proxy (nm_bus_manager_get (),
context, context,
priv->dbus_owner, NMDBUS_TYPE_SECRET_AGENT_PROXY,
NM_DBUS_PATH_SECRET_AGENT, priv->dbus_owner,
NM_DBUS_INTERFACE_SECRET_AGENT); NM_DBUS_PATH_SECRET_AGENT,
g_assert (priv->proxy); NM_DBUS_INTERFACE_SECRET_AGENT);
g_signal_connect_swapped (priv->proxy, "destroy", g_assert (proxy);
G_CALLBACK (proxy_cleanup), self); g_signal_connect (proxy, "notify::g-name-owner",
g_signal_connect (nm_bus_manager_get (),
NM_BUS_MANAGER_NAME_OWNER_CHANGED,
G_CALLBACK (name_owner_changed_cb), G_CALLBACK (name_owner_changed_cb),
self); self);
priv->proxy = NMDBUS_SECRET_AGENT (proxy);
return self; return self;
} }
@@ -553,7 +541,7 @@ dispose (GObject *object)
{ {
NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object); NMSecretAgentPrivate *priv = NM_SECRET_AGENT_GET_PRIVATE (object);
proxy_cleanup (NM_SECRET_AGENT (object)); g_clear_object (&priv->proxy);
g_clear_object (&priv->subject); g_clear_object (&priv->subject);
G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object); G_OBJECT_CLASS (nm_secret_agent_parent_class)->dispose (object);

View File

@@ -21,7 +21,6 @@
#ifndef __NETWORKMANAGER_SECRET_AGENT_H__ #ifndef __NETWORKMANAGER_SECRET_AGENT_H__
#define __NETWORKMANAGER_SECRET_AGENT_H__ #define __NETWORKMANAGER_SECRET_AGENT_H__
#include <nm-connection.h> #include <nm-connection.h>
#include "nm-default.h" #include "nm-default.h"
@@ -46,7 +45,7 @@ typedef struct {
GType nm_secret_agent_get_type (void); GType nm_secret_agent_get_type (void);
NMSecretAgent *nm_secret_agent_new (DBusGMethodInvocation *context, NMSecretAgent *nm_secret_agent_new (GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
const char *identifier, const char *identifier,
NMSecretAgentCapabilities capabilities); NMSecretAgentCapabilities capabilities);
@@ -78,7 +77,7 @@ gboolean nm_secret_agent_has_permission (NMSecretAgent *agent,
typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent, typedef void (*NMSecretAgentCallback) (NMSecretAgent *agent,
gconstpointer call, gconstpointer call,
GHashTable *new_secrets, /* NULL for save & delete */ GVariant *new_secrets, /* NULL for save & delete */
GError *error, GError *error,
gpointer user_data); gpointer user_data);

View File

@@ -24,12 +24,10 @@
#include <string.h> #include <string.h>
#include <nm-dbus-interface.h> #include <nm-dbus-interface.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "nm-default.h" #include "nm-default.h"
#include "nm-settings-connection.h" #include "nm-settings-connection.h"
#include "nm-session-monitor.h" #include "nm-session-monitor.h"
#include "nm-dbus-glib-types.h"
#include "nm-auth-utils.h" #include "nm-auth-utils.h"
#include "nm-auth-subject.h" #include "nm-auth-subject.h"
#include "nm-agent-manager.h" #include "nm-agent-manager.h"
@@ -37,10 +35,11 @@
#include "nm-core-internal.h" #include "nm-core-internal.h"
#include "nm-audit-manager.h" #include "nm-audit-manager.h"
#include "nmdbus-settings-connection.h"
#define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps" #define SETTINGS_TIMESTAMPS_FILE NMSTATEDIR "/timestamps"
#define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids" #define SETTINGS_SEEN_BSSIDS_FILE NMSTATEDIR "/seen-bssids"
#define _LOG_DOMAIN LOGD_SETTINGS #define _LOG_DOMAIN LOGD_SETTINGS
#define _LOG_PREFIX_NAME "settings-connection" #define _LOG_PREFIX_NAME "settings-connection"
@@ -81,33 +80,6 @@
#define _LOGW(...) _LOG (LOGL_WARN , _LOG_DOMAIN, self, __VA_ARGS__) #define _LOGW(...) _LOG (LOGL_WARN , _LOG_DOMAIN, self, __VA_ARGS__)
#define _LOGE(...) _LOG (LOGL_ERR , _LOG_DOMAIN, self, __VA_ARGS__) #define _LOGE(...) _LOG (LOGL_ERR , _LOG_DOMAIN, self, __VA_ARGS__)
static void impl_settings_connection_get_settings (NMSettingsConnection *self,
DBusGMethodInvocation *context);
static void impl_settings_connection_update (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context);
static void impl_settings_connection_update_unsaved (NMSettingsConnection *self,
GHashTable *new_settings,
DBusGMethodInvocation *context);
static void impl_settings_connection_save (NMSettingsConnection *self,
DBusGMethodInvocation *context);
static void impl_settings_connection_delete (NMSettingsConnection *self,
DBusGMethodInvocation *context);
static void impl_settings_connection_get_secrets (NMSettingsConnection *self,
const gchar *setting_name,
DBusGMethodInvocation *context);
static void impl_settings_connection_clear_secrets (NMSettingsConnection *self,
DBusGMethodInvocation *context);
#include "nm-settings-connection-glue.h"
static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface); static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_EXPORTED_OBJECT, G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_EXPORTED_OBJECT,
@@ -183,88 +155,93 @@ typedef struct {
typedef gboolean (*ForEachSecretFunc) (NMSettingSecretFlags flags, typedef gboolean (*ForEachSecretFunc) (NMSettingSecretFlags flags,
gpointer user_data); gpointer user_data);
static void static GVariant *
for_each_secret (NMConnection *self, for_each_secret (NMConnection *self,
GHashTable *secrets, GVariant *secrets,
gboolean remove_non_secrets, gboolean remove_non_secrets,
ForEachSecretFunc callback, ForEachSecretFunc callback,
gpointer callback_data) gpointer callback_data)
{ {
GHashTableIter iter; GVariantBuilder secrets_builder, setting_builder;
GVariantIter secrets_iter, *setting_iter;
const char *setting_name; const char *setting_name;
GHashTable *setting_hash;
/* This function, given a hash of hashes representing new secrets of /* This function, given a dict of dicts representing new secrets of
* an NMConnection, walks through each toplevel hash (which represents a * an NMConnection, walks through each toplevel dict (which represents a
* NMSetting), and for each setting, walks through that setting hash's * NMSetting), and for each setting, walks through that setting dict's
* properties. For each property that's a secret, it will check that * properties. For each property that's a secret, it will check that
* secret's flags in the backing NMConnection object, and call a supplied * secret's flags in the backing NMConnection object, and call a supplied
* callback. * callback.
* *
* The one complexity is that the VPN setting's 'secrets' property is * The one complexity is that the VPN setting's 'secrets' property is
* *also* a hash table (since the key/value pairs are arbitrary and known * *also* a dict (since the key/value pairs are arbitrary and known
* only to the VPN plugin itself). That means we have three levels of * only to the VPN plugin itself). That means we have three levels of
* GHashTables that we potentially have to traverse here. When we hit the * dicts that we potentially have to traverse here. When we hit the
* VPN setting's 'secrets' property, we special-case that and iterate over * VPN setting's 'secrets' property, we special-case that and iterate over
* each item in that 'secrets' hash table, calling the supplied callback * each item in that 'secrets' dict, calling the supplied callback
* each time. * each time.
*/ */
g_return_if_fail (callback); g_return_val_if_fail (callback, NULL);
/* Walk through the list of setting hashes */ g_variant_iter_init (&secrets_iter, secrets);
g_hash_table_iter_init (&iter, secrets); g_variant_builder_init (&secrets_builder, NM_VARIANT_TYPE_CONNECTION);
while (g_hash_table_iter_next (&iter, (gpointer) &setting_name, (gpointer) &setting_hash)) { while (g_variant_iter_next (&secrets_iter, "{&sa{sv}}", &setting_name, &setting_iter)) {
NMSetting *setting; NMSetting *setting;
GHashTableIter secret_iter;
const char *secret_name; const char *secret_name;
GValue *val; GVariant *val;
if (g_hash_table_size (setting_hash) == 0)
continue;
/* Get the actual NMSetting from the connection so we can get secret flags
* from the connection data, since flags aren't secrets. What we're
* iterating here is just the secrets, not a whole connection.
*/
setting = nm_connection_get_setting_by_name (self, setting_name); setting = nm_connection_get_setting_by_name (self, setting_name);
if (setting == NULL) if (setting == NULL) {
g_variant_iter_free (setting_iter);
continue; continue;
}
/* Walk through the list of keys in each setting hash */ g_variant_builder_init (&setting_builder, NM_VARIANT_TYPE_SETTING);
g_hash_table_iter_init (&secret_iter, setting_hash); while (g_variant_iter_next (setting_iter, "{sv}", &secret_name, &val)) {
while (g_hash_table_iter_next (&secret_iter, (gpointer) &secret_name, (gpointer) &val)) {
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
/* VPN secrets need slightly different treatment here since the /* VPN secrets need slightly different treatment here since the
* "secrets" property is actually a hash table of secrets. * "secrets" property is actually a hash table of secrets.
*/ */
if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS) == 0)) { if (NM_IS_SETTING_VPN (setting) && !g_strcmp0 (secret_name, NM_SETTING_VPN_SECRETS)) {
GHashTableIter vpn_secrets_iter; GVariantBuilder vpn_secrets_builder;
GVariantIter vpn_secrets_iter;
const char *vpn_secret_name, *secret;
/* Iterate through each secret from the VPN hash in the overall secrets hash */ /* Iterate through each secret from the VPN dict in the overall secrets dict */
g_hash_table_iter_init (&vpn_secrets_iter, g_value_get_boxed (val)); g_variant_builder_init (&vpn_secrets_builder, G_VARIANT_TYPE ("a{ss}"));
while (g_hash_table_iter_next (&vpn_secrets_iter, (gpointer) &secret_name, NULL)) { g_variant_iter_init (&vpn_secrets_iter, val);
secret_flags = NM_SETTING_SECRET_FLAG_NONE; while (g_variant_iter_next (&vpn_secrets_iter, "{&s&s}", &vpn_secret_name, &secret)) {
if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { if (!nm_setting_get_secret_flags (setting, vpn_secret_name, &secret_flags, NULL)) {
if (remove_non_secrets) if (!remove_non_secrets)
g_hash_table_iter_remove (&vpn_secrets_iter); g_variant_builder_add (&vpn_secrets_builder, "{ss}", vpn_secret_name, secret);
continue; continue;
} }
if (!callback (secret_flags, callback_data))
g_hash_table_iter_remove (&vpn_secrets_iter); if (callback (secret_flags, callback_data))
g_variant_builder_add (&vpn_secrets_builder, "{ss}", vpn_secret_name, secret);
} }
g_variant_builder_add (&setting_builder, "{sv}",
secret_name, g_variant_builder_end (&vpn_secrets_builder));
} else { } else {
if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) { if (!nm_setting_get_secret_flags (setting, secret_name, &secret_flags, NULL)) {
if (remove_non_secrets) if (!remove_non_secrets)
g_hash_table_iter_remove (&secret_iter); g_variant_builder_add (&setting_builder, "{sv}", secret_name, val);
continue; continue;
} }
if (!callback (secret_flags, callback_data)) if (callback (secret_flags, callback_data))
g_hash_table_iter_remove (&secret_iter); g_variant_builder_add (&setting_builder, "{sv}", secret_name, val);
} }
g_variant_unref (val);
} }
g_variant_iter_free (setting_iter);
g_variant_builder_add (&secrets_builder, "{sa{sv}}", setting_name, &setting_builder);
} }
return g_variant_builder_end (&secrets_builder);
} }
typedef gboolean (*FindSecretFunc) (NMSettingSecretFlags flags, typedef gboolean (*FindSecretFunc) (NMSettingSecretFlags flags,
@@ -284,22 +261,24 @@ find_secret_for_each_func (NMSettingSecretFlags flags,
if (!data->found) if (!data->found)
data->found = data->find_func (flags, data->find_func_data); data->found = data->find_func (flags, data->find_func_data);
return TRUE; return FALSE;
} }
static gboolean static gboolean
find_secret (NMConnection *self, find_secret (NMConnection *self,
GHashTable *secrets, GVariant *secrets,
FindSecretFunc callback, FindSecretFunc callback,
gpointer callback_data) gpointer callback_data)
{ {
FindSecretData data; FindSecretData data;
GVariant *dummy;
data.find_func = callback; data.find_func = callback;
data.find_func_data = callback_data; data.find_func_data = callback_data;
data.found = FALSE; data.found = FALSE;
for_each_secret (self, secrets, FALSE, find_secret_for_each_func, &data); dummy = for_each_secret (self, secrets, FALSE, find_secret_for_each_func, &data);
g_variant_unref (dummy);
return data.found; return data.found;
} }
@@ -836,7 +815,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
gboolean agent_has_modify, gboolean agent_has_modify,
const char *setting_name, const char *setting_name,
NMSecretAgentGetSecretsFlags flags, NMSecretAgentGetSecretsFlags flags,
GHashTable *secrets, GVariant *secrets,
GError *error, GError *error,
gpointer user_data, gpointer user_data,
gpointer other_data2, gpointer other_data2,
@@ -925,21 +904,19 @@ agent_secrets_done_cb (NMAgentManager *manager,
| NM_SETTING_SECRET_FLAG_NOT_REQUIRED); | NM_SETTING_SECRET_FLAG_NOT_REQUIRED);
} }
for_each_secret (NM_CONNECTION (self), secrets, TRUE, validate_secret_flags, &cmp_flags);
/* Update the connection with our existing secrets from backing storage */ /* Update the connection with our existing secrets from backing storage */
nm_connection_clear_secrets (NM_CONNECTION (self)); nm_connection_clear_secrets (NM_CONNECTION (self));
dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) { if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) {
GVariant *secrets_dict; GVariant *filtered_secrets;
/* Update the connection with the agent's secrets; by this point if any /* Update the connection with the agent's secrets; by this point if any
* system-owned secrets exist in 'secrets' the agent that provided them * system-owned secrets exist in 'secrets' the agent that provided them
* will have been authenticated, so those secrets can replace the existing * will have been authenticated, so those secrets can replace the existing
* system secrets. * system secrets.
*/ */
secrets_dict = nm_utils_connection_hash_to_dict (secrets); filtered_secrets = for_each_secret (NM_CONNECTION (self), secrets, TRUE, validate_secret_flags, &cmp_flags);
if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets_dict, &local)) { if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, filtered_secrets, &local)) {
/* Now that all secrets are updated, copy and cache new secrets, /* Now that all secrets are updated, copy and cache new secrets,
* then save them to backing storage. * then save them to backing storage.
*/ */
@@ -962,6 +939,8 @@ agent_secrets_done_cb (NMAgentManager *manager,
setting_name, setting_name,
call_id); call_id);
} }
g_variant_unref (filtered_secrets);
} else { } else {
_LOGD ("(%s:%u) failed to update with agent secrets: (%d) %s", _LOGD ("(%s:%u) failed to update with agent secrets: (%d) %s",
setting_name, setting_name,
@@ -969,7 +948,6 @@ agent_secrets_done_cb (NMAgentManager *manager,
local ? local->code : -1, local ? local->code : -1,
(local && local->message) ? local->message : "(unknown)"); (local && local->message) ? local->message : "(unknown)");
} }
g_variant_unref (secrets_dict);
} else { } else {
_LOGD ("(%s:%u) failed to update with existing secrets: (%d) %s", _LOGD ("(%s:%u) failed to update with existing secrets: (%d) %s",
setting_name, setting_name,
@@ -1012,7 +990,6 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
{ {
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
GVariant *existing_secrets; GVariant *existing_secrets;
GHashTable *existing_secrets_hash;
guint32 call_id = 0; guint32 call_id = 0;
gs_free char *joined_hints = NULL; gs_free char *joined_hints = NULL;
@@ -1035,11 +1012,12 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
} }
existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
existing_secrets_hash = nm_utils_connection_dict_to_hash (existing_secrets); if (existing_secrets)
g_variant_ref_sink (existing_secrets);
call_id = nm_agent_manager_get_secrets (priv->agent_mgr, call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
NM_CONNECTION (self), NM_CONNECTION (self),
subject, subject,
existing_secrets_hash, existing_secrets,
setting_name, setting_name,
flags, flags,
hints, hints,
@@ -1047,8 +1025,6 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
self, self,
callback, callback,
callback_data); callback_data);
if (existing_secrets_hash)
g_hash_table_unref (existing_secrets_hash);
if (existing_secrets) if (existing_secrets)
g_variant_unref (existing_secrets); g_variant_unref (existing_secrets);
@@ -1077,7 +1053,7 @@ nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
/**** User authorization **************************************/ /**** User authorization **************************************/
typedef void (*AuthCallback) (NMSettingsConnection *self, typedef void (*AuthCallback) (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
GError *error, GError *error,
gpointer data); gpointer data);
@@ -1085,7 +1061,7 @@ typedef void (*AuthCallback) (NMSettingsConnection *self,
static void static void
pk_auth_cb (NMAuthChain *chain, pk_auth_cb (NMAuthChain *chain,
GError *chain_error, GError *chain_error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
gpointer user_data) gpointer user_data)
{ {
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data); NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data);
@@ -1134,7 +1110,7 @@ pk_auth_cb (NMAuthChain *chain,
* Returns: the #NMAuthSubject on success, or %NULL on failure and sets @error * Returns: the #NMAuthSubject on success, or %NULL on failure and sets @error
*/ */
static NMAuthSubject * static NMAuthSubject *
_new_auth_subject (DBusGMethodInvocation *context, GError **error) _new_auth_subject (GDBusMethodInvocation *context, GError **error)
{ {
NMAuthSubject *subject; NMAuthSubject *subject;
@@ -1151,7 +1127,7 @@ _new_auth_subject (DBusGMethodInvocation *context, GError **error)
static void static void
auth_start (NMSettingsConnection *self, auth_start (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
const char *check_permission, const char *check_permission,
AuthCallback callback, AuthCallback callback,
@@ -1239,16 +1215,15 @@ check_writable (NMConnection *self, GError **error)
static void static void
get_settings_auth_cb (NMSettingsConnection *self, get_settings_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
GError *error, GError *error,
gpointer data) gpointer data)
{ {
if (error) if (error)
dbus_g_method_return_error (context, error); g_dbus_method_invocation_return_gerror (context, error);
else { else {
GVariant *settings; GVariant *settings;
GHashTable *settings_hash;
NMConnection *dupl_con; NMConnection *dupl_con;
NMSettingConnection *s_con; NMSettingConnection *s_con;
NMSettingWireless *s_wifi; NMSettingWireless *s_wifi;
@@ -1286,17 +1261,15 @@ get_settings_auth_cb (NMSettingsConnection *self,
*/ */
settings = nm_connection_to_dbus (NM_CONNECTION (dupl_con), NM_CONNECTION_SERIALIZE_NO_SECRETS); settings = nm_connection_to_dbus (NM_CONNECTION (dupl_con), NM_CONNECTION_SERIALIZE_NO_SECRETS);
g_assert (settings); g_assert (settings);
settings_hash = nm_utils_connection_dict_to_hash (settings); g_dbus_method_invocation_return_value (context,
dbus_g_method_return (context, settings_hash); g_variant_new ("(@a{sa{sv}})", settings));
g_hash_table_destroy (settings_hash);
g_variant_unref (settings);
g_object_unref (dupl_con); g_object_unref (dupl_con);
} }
} }
static void static void
impl_settings_connection_get_settings (NMSettingsConnection *self, impl_settings_connection_get_settings (NMSettingsConnection *self,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
NMAuthSubject *subject; NMAuthSubject *subject;
GError *error = NULL; GError *error = NULL;
@@ -1305,14 +1278,12 @@ impl_settings_connection_get_settings (NMSettingsConnection *self,
if (subject) { if (subject) {
auth_start (self, context, subject, NULL, get_settings_auth_cb, NULL); auth_start (self, context, subject, NULL, get_settings_auth_cb, NULL);
g_object_unref (subject); g_object_unref (subject);
} else { } else
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_error_free (error);
}
} }
typedef struct { typedef struct {
DBusGMethodInvocation *context; GDBusMethodInvocation *context;
NMAgentManager *agent_mgr; NMAgentManager *agent_mgr;
NMAuthSubject *subject; NMAuthSubject *subject;
NMConnection *new_settings; NMConnection *new_settings;
@@ -1320,7 +1291,7 @@ typedef struct {
} UpdateInfo; } UpdateInfo;
typedef struct { typedef struct {
DBusGMethodInvocation *context; GDBusMethodInvocation *context;
NMAuthSubject *subject; NMAuthSubject *subject;
} CallbackInfo; } CallbackInfo;
@@ -1384,9 +1355,9 @@ update_complete (NMSettingsConnection *self,
GError *error) GError *error)
{ {
if (error) if (error)
dbus_g_method_return_error (info->context, error); g_dbus_method_invocation_return_gerror (info->context, error);
else else
dbus_g_method_return (info->context); g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, NM_CONNECTION (self), !error, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_UPDATE, NM_CONNECTION (self), !error,
info->subject, error ? error->message : NULL); info->subject, error ? error->message : NULL);
@@ -1424,7 +1395,7 @@ con_update_cb (NMSettingsConnection *self,
static void static void
update_auth_cb (NMSettingsConnection *self, update_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
GError *error, GError *error,
gpointer data) gpointer data)
@@ -1492,8 +1463,8 @@ get_update_modify_permission (NMConnection *old, NMConnection *new)
static void static void
impl_settings_connection_update_helper (NMSettingsConnection *self, impl_settings_connection_update_helper (NMSettingsConnection *self,
GHashTable *new_settings, GDBusMethodInvocation *context,
DBusGMethodInvocation *context, GVariant *new_settings,
gboolean save_to_disk) gboolean save_to_disk)
{ {
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
@@ -1515,14 +1486,9 @@ impl_settings_connection_update_helper (NMSettingsConnection *self,
/* Check if the settings are valid first */ /* Check if the settings are valid first */
if (new_settings) { if (new_settings) {
GVariant *new_settings_dict = nm_utils_connection_hash_to_dict (new_settings); tmp = nm_simple_connection_new_from_dbus (new_settings, &error);
if (!tmp)
tmp = nm_simple_connection_new_from_dbus (new_settings_dict, &error);
g_variant_unref (new_settings_dict);
if (!tmp) {
g_assert (error);
goto error; goto error;
}
} }
subject = _new_auth_subject (context, &error); subject = _new_auth_subject (context, &error);
@@ -1562,37 +1528,34 @@ error:
g_clear_object (&tmp); g_clear_object (&tmp);
g_clear_object (&subject); g_clear_object (&subject);
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_clear_error (&error);
} }
static void static void
impl_settings_connection_update (NMSettingsConnection *self, impl_settings_connection_update (NMSettingsConnection *self,
GHashTable *new_settings, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) GVariant *new_settings)
{ {
g_assert (new_settings); impl_settings_connection_update_helper (self, context, new_settings, TRUE);
impl_settings_connection_update_helper (self, new_settings, context, TRUE);
} }
static void static void
impl_settings_connection_update_unsaved (NMSettingsConnection *self, impl_settings_connection_update_unsaved (NMSettingsConnection *self,
GHashTable *new_settings, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) GVariant *new_settings)
{ {
g_assert (new_settings); impl_settings_connection_update_helper (self, context, new_settings, FALSE);
impl_settings_connection_update_helper (self, new_settings, context, FALSE);
} }
static void static void
impl_settings_connection_save (NMSettingsConnection *self, impl_settings_connection_save (NMSettingsConnection *self,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
/* Do nothing if the connection is already synced with disk */ /* Do nothing if the connection is already synced with disk */
if (nm_settings_connection_get_unsaved (self)) if (nm_settings_connection_get_unsaved (self))
impl_settings_connection_update_helper (self, NULL, context, TRUE); impl_settings_connection_update_helper (self, context, NULL, TRUE);
else else
dbus_g_method_return (context); g_dbus_method_invocation_return_value (context, NULL);
} }
static void static void
@@ -1603,9 +1566,9 @@ con_delete_cb (NMSettingsConnection *self,
CallbackInfo *info = user_data; CallbackInfo *info = user_data;
if (error) if (error)
dbus_g_method_return_error (info->context, error); g_dbus_method_invocation_return_gerror (info->context, error);
else else
dbus_g_method_return (info->context); g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self),
!error, info->subject, error ? error->message : NULL); !error, info->subject, error ? error->message : NULL);
@@ -1614,7 +1577,7 @@ con_delete_cb (NMSettingsConnection *self,
static void static void
delete_auth_cb (NMSettingsConnection *self, delete_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
GError *error, GError *error,
gpointer data) gpointer data)
@@ -1624,7 +1587,7 @@ delete_auth_cb (NMSettingsConnection *self,
if (error) { if (error) {
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject,
error->message); error->message);
dbus_g_method_return_error (context, error); g_dbus_method_invocation_return_gerror (context, error);
return; return;
} }
@@ -1654,7 +1617,7 @@ get_modify_permission_basic (NMSettingsConnection *self)
static void static void
impl_settings_connection_delete (NMSettingsConnection *self, impl_settings_connection_delete (NMSettingsConnection *self,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
NMAuthSubject *subject = NULL; NMAuthSubject *subject = NULL;
GError *error = NULL; GError *error = NULL;
@@ -1671,9 +1634,8 @@ impl_settings_connection_delete (NMSettingsConnection *self,
return; return;
out_err: out_err:
dbus_g_method_return_error (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject, error->message); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DELETE, NM_CONNECTION (self), FALSE, subject, error->message);
g_error_free (error); g_dbus_method_invocation_take_error (context, error);
} }
/**************************************************************/ /**************************************************************/
@@ -1687,14 +1649,13 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
gpointer user_data) gpointer user_data)
{ {
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
DBusGMethodInvocation *context = user_data; GDBusMethodInvocation *context = user_data;
GVariant *dict; GVariant *dict;
GHashTable *hash;
priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id)); priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
if (error) if (error)
dbus_g_method_return_error (context, error); g_dbus_method_invocation_return_gerror (context, error);
else { else {
/* Return secrets from agent and backing storage to the D-Bus caller; /* Return secrets from agent and backing storage to the D-Bus caller;
* nm_settings_connection_get_secrets() will have updated itself with * nm_settings_connection_get_secrets() will have updated itself with
@@ -1702,20 +1663,15 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
* by the time we get here. * by the time we get here.
*/ */
dict = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); dict = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
if (dict) if (!dict)
hash = nm_utils_connection_dict_to_hash (dict); dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
else g_dbus_method_invocation_return_value (context, g_variant_new ("(@a{s{a{sv}}})", dict));
hash = g_hash_table_new (NULL, NULL);
dbus_g_method_return (context, hash);
g_hash_table_destroy (hash);
if (dict)
g_variant_unref (dict);
} }
} }
static void static void
dbus_get_secrets_auth_cb (NMSettingsConnection *self, dbus_get_secrets_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
GError *error, GError *error,
gpointer user_data) gpointer user_data)
@@ -1742,7 +1698,7 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self,
} }
if (error || local) { if (error || local) {
dbus_g_method_return_error (context, error ? error : local); g_dbus_method_invocation_return_gerror (context, error ? error : local);
g_clear_error (&local); g_clear_error (&local);
} }
@@ -1751,8 +1707,8 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self,
static void static void
impl_settings_connection_get_secrets (NMSettingsConnection *self, impl_settings_connection_get_secrets (NMSettingsConnection *self,
const gchar *setting_name, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) const gchar *setting_name)
{ {
NMAuthSubject *subject; NMAuthSubject *subject;
GError *error = NULL; GError *error = NULL;
@@ -1766,10 +1722,8 @@ impl_settings_connection_get_secrets (NMSettingsConnection *self,
dbus_get_secrets_auth_cb, dbus_get_secrets_auth_cb,
g_strdup (setting_name)); g_strdup (setting_name));
g_object_unref (subject); g_object_unref (subject);
} else { } else
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_error_free (error);
}
} }
static void static void
@@ -1780,9 +1734,9 @@ clear_secrets_cb (NMSettingsConnection *self,
CallbackInfo *info = user_data; CallbackInfo *info = user_data;
if (error) if (error)
dbus_g_method_return_error (info->context, error); g_dbus_method_invocation_return_gerror (info->context, error);
else else
dbus_g_method_return (info->context); g_dbus_method_invocation_return_value (info->context, NULL);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self), nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self),
!error, info->subject, error ? error->message : NULL); !error, info->subject, error ? error->message : NULL);
@@ -1791,7 +1745,7 @@ clear_secrets_cb (NMSettingsConnection *self,
static void static void
dbus_clear_secrets_auth_cb (NMSettingsConnection *self, dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
GError *error, GError *error,
gpointer user_data) gpointer user_data)
@@ -1800,7 +1754,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
CallbackInfo *info; CallbackInfo *info;
if (error) { if (error) {
dbus_g_method_return_error (context, error); g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self), nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self),
FALSE, subject, error->message); FALSE, subject, error->message);
} else { } else {
@@ -1824,7 +1778,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self,
static void static void
impl_settings_connection_clear_secrets (NMSettingsConnection *self, impl_settings_connection_clear_secrets (NMSettingsConnection *self,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
NMAuthSubject *subject; NMAuthSubject *subject;
GError *error = NULL; GError *error = NULL;
@@ -1839,10 +1793,9 @@ impl_settings_connection_clear_secrets (NMSettingsConnection *self,
NULL); NULL);
g_object_unref (subject); g_object_unref (subject);
} else { } else {
dbus_g_method_return_error (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self), nm_audit_log_connection_op (NM_AUDIT_OP_CONN_CLEAR_SECRETS, NM_CONNECTION (self),
FALSE, NULL, error->message); FALSE, NULL, error->message);
g_error_free (error); g_dbus_method_invocation_take_error (context, error);
} }
} }
@@ -2586,7 +2539,15 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class),
&dbus_glib_nm_settings_connection_object_info); NMDBUS_TYPE_SETTINGS_CONNECTION_SKELETON,
"Update", impl_settings_connection_update,
"UpdateUnsaved", impl_settings_connection_update_unsaved,
"Delete", impl_settings_connection_delete,
"GetSettings", impl_settings_connection_get_settings,
"GetSecrets", impl_settings_connection_get_secrets,
"ClearSecrets", impl_settings_connection_clear_secrets,
"Save", impl_settings_connection_save,
NULL);
} }
static void static void

View File

@@ -31,8 +31,6 @@
#include <string.h> #include <string.h>
#include <gmodule.h> #include <gmodule.h>
#include <pwd.h> #include <pwd.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#if HAVE_SELINUX #if HAVE_SELINUX
#include <selinux/selinux.h> #include <selinux/selinux.h>
@@ -61,7 +59,6 @@
#include "nm-core-internal.h" #include "nm-core-internal.h"
#include "nm-device-ethernet.h" #include "nm-device-ethernet.h"
#include "nm-dbus-glib-types.h"
#include "nm-settings.h" #include "nm-settings.h"
#include "nm-settings-connection.h" #include "nm-settings-connection.h"
#include "nm-system-config-interface.h" #include "nm-system-config-interface.h"
@@ -78,6 +75,8 @@
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "nm-dispatcher.h" #include "nm-dispatcher.h"
#include "nmdbus-settings.h"
#define LOG(level, ...) \ #define LOG(level, ...) \
G_STMT_START { \ G_STMT_START { \
nm_log ((level), LOGD_CORE, \ nm_log ((level), LOGD_CORE, \
@@ -122,35 +121,6 @@ EXPORT(nm_settings_connection_replace_and_commit)
static void claim_connection (NMSettings *self, static void claim_connection (NMSettings *self,
NMSettingsConnection *connection); NMSettingsConnection *connection);
static gboolean impl_settings_list_connections (NMSettings *self,
GPtrArray **connections,
GError **error);
static void impl_settings_get_connection_by_uuid (NMSettings *self,
const char *uuid,
DBusGMethodInvocation *context);
static void impl_settings_add_connection (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
static void impl_settings_add_connection_unsaved (NMSettings *self,
GHashTable *settings,
DBusGMethodInvocation *context);
static void impl_settings_load_connections (NMSettings *self,
char **filenames,
DBusGMethodInvocation *context);
static void impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context);
static void impl_settings_save_hostname (NMSettings *self,
const char *hostname,
DBusGMethodInvocation *context);
#include "nm-settings-glue.h"
static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data); static void unmanaged_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
static void unrecognized_specs_changed (NMSystemConfigInterface *config, gpointer user_data); static void unrecognized_specs_changed (NMSystemConfigInterface *config, gpointer user_data);
@@ -161,8 +131,6 @@ G_DEFINE_TYPE_EXTENDED (NMSettings, nm_settings, NM_TYPE_EXPORTED_OBJECT, 0,
typedef struct { typedef struct {
NMBusManager *dbus_mgr;
NMAgentManager *agent_mgr; NMAgentManager *agent_mgr;
NMConfig *config; NMConfig *config;
@@ -310,20 +278,24 @@ nm_settings_for_each_connection (NMSettings *self,
for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data); for_each_func (self, NM_SETTINGS_CONNECTION (data), user_data);
} }
static gboolean static void
impl_settings_list_connections (NMSettings *self, impl_settings_list_connections (NMSettings *self,
GPtrArray **connections, GDBusMethodInvocation *context)
GError **error)
{ {
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GPtrArray *connections;
GHashTableIter iter; GHashTableIter iter;
gpointer key; gpointer key;
*connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1); connections = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
g_hash_table_iter_init (&iter, priv->connections); g_hash_table_iter_init (&iter, priv->connections);
while (g_hash_table_iter_next (&iter, &key, NULL)) while (g_hash_table_iter_next (&iter, &key, NULL))
g_ptr_array_add (*connections, g_strdup ((const char *) key)); g_ptr_array_add (connections, key);
return TRUE; g_ptr_array_add (connections, NULL);
g_dbus_method_invocation_return_value (context,
g_variant_new ("(^ao)", connections->pdata));
g_ptr_array_unref (connections);
} }
NMSettingsConnection * NMSettingsConnection *
@@ -349,8 +321,8 @@ nm_settings_get_connection_by_uuid (NMSettings *self, const char *uuid)
static void static void
impl_settings_get_connection_by_uuid (NMSettings *self, impl_settings_get_connection_by_uuid (NMSettings *self,
const char *uuid, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) const char *uuid)
{ {
NMSettingsConnection *connection = NULL; NMSettingsConnection *connection = NULL;
NMAuthSubject *subject = NULL; NMAuthSubject *subject = NULL;
@@ -384,13 +356,14 @@ impl_settings_get_connection_by_uuid (NMSettings *self,
} }
g_clear_object (&subject); g_clear_object (&subject);
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection))); g_dbus_method_invocation_return_value (
context,
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
return; return;
error: error:
g_assert (error); g_assert (error);
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_error_free (error);
g_clear_object (&subject); g_clear_object (&subject);
} }
@@ -1189,7 +1162,7 @@ send_agent_owned_secrets (NMSettings *self,
static void static void
pk_add_cb (NMAuthChain *chain, pk_add_cb (NMAuthChain *chain,
GError *chain_error, GError *chain_error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
gpointer user_data) gpointer user_data)
{ {
NMSettings *self = NM_SETTINGS (user_data); NMSettings *self = NM_SETTINGS (user_data);
@@ -1277,11 +1250,11 @@ is_adhoc_wpa (NMConnection *connection)
void void
nm_settings_add_connection_dbus (NMSettings *self, nm_settings_add_connection_dbus (NMSettings *self,
NMConnection *connection, NMConnection *connection,
gboolean save_to_disk, gboolean save_to_disk,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMSettingsAddCallback callback, NMSettingsAddCallback callback,
gpointer user_data) gpointer user_data)
{ {
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMSettingConnection *s_con; NMSettingConnection *s_con;
@@ -1385,15 +1358,17 @@ static void
impl_settings_add_connection_add_cb (NMSettings *self, impl_settings_add_connection_add_cb (NMSettings *self,
NMSettingsConnection *connection, NMSettingsConnection *connection,
GError *error, GError *error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
gpointer user_data) gpointer user_data)
{ {
if (error) { if (error) {
dbus_g_method_return_error (context, error); g_dbus_method_invocation_return_gerror (context, error);
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, subject, error->message); nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, subject, error->message);
} else { } else {
dbus_g_method_return (context, nm_connection_get_path (NM_CONNECTION (connection))); g_dbus_method_invocation_return_value (
context,
g_variant_new ("(o)", nm_connection_get_path (NM_CONNECTION (connection))));
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NM_CONNECTION (connection), TRUE, nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NM_CONNECTION (connection), TRUE,
subject, NULL); subject, NULL);
} }
@@ -1401,17 +1376,14 @@ impl_settings_add_connection_add_cb (NMSettings *self,
static void static void
impl_settings_add_connection_helper (NMSettings *self, impl_settings_add_connection_helper (NMSettings *self,
GHashTable *settings, GDBusMethodInvocation *context,
gboolean save_to_disk, GVariant *settings,
DBusGMethodInvocation *context) gboolean save_to_disk)
{ {
NMConnection *connection; NMConnection *connection;
GVariant *dict;
GError *error = NULL; GError *error = NULL;
dict = nm_utils_connection_hash_to_dict (settings); connection = nm_simple_connection_new_from_dbus (settings, &error);
connection = nm_simple_connection_new_from_dbus (dict, &error);
g_variant_unref (dict);
if (connection) { if (connection) {
nm_settings_add_connection_dbus (self, nm_settings_add_connection_dbus (self,
connection, connection,
@@ -1422,30 +1394,29 @@ impl_settings_add_connection_helper (NMSettings *self,
g_object_unref (connection); g_object_unref (connection);
} else { } else {
g_assert (error); g_assert (error);
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_error_free (error);
} }
} }
static void static void
impl_settings_add_connection (NMSettings *self, impl_settings_add_connection (NMSettings *self,
GHashTable *settings, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) GVariant *settings)
{ {
impl_settings_add_connection_helper (self, settings, TRUE, context); impl_settings_add_connection_helper (self, context, settings, TRUE);
} }
static void static void
impl_settings_add_connection_unsaved (NMSettings *self, impl_settings_add_connection_unsaved (NMSettings *self,
GHashTable *settings, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) GVariant *settings)
{ {
impl_settings_add_connection_helper (self, settings, FALSE, context); impl_settings_add_connection_helper (self, context, settings, FALSE);
} }
static gboolean static gboolean
ensure_root (NMBusManager *dbus_mgr, ensure_root (NMBusManager *dbus_mgr,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
gulong caller_uid; gulong caller_uid;
GError *error = NULL; GError *error = NULL;
@@ -1454,16 +1425,14 @@ ensure_root (NMBusManager *dbus_mgr,
error = g_error_new_literal (NM_SETTINGS_ERROR, error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_PERMISSION_DENIED, NM_SETTINGS_ERROR_PERMISSION_DENIED,
"Unable to determine request UID."); "Unable to determine request UID.");
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_error_free (error);
return FALSE; return FALSE;
} }
if (caller_uid != 0) { if (caller_uid != 0) {
error = g_error_new_literal (NM_SETTINGS_ERROR, error = g_error_new_literal (NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_PERMISSION_DENIED, NM_SETTINGS_ERROR_PERMISSION_DENIED,
"Permission denied"); "Permission denied");
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_error_free (error);
return FALSE; return FALSE;
} }
@@ -1472,15 +1441,15 @@ ensure_root (NMBusManager *dbus_mgr,
static void static void
impl_settings_load_connections (NMSettings *self, impl_settings_load_connections (NMSettings *self,
char **filenames, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) char **filenames)
{ {
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GPtrArray *failures; GPtrArray *failures;
GSList *iter; GSList *iter;
int i; int i;
if (!ensure_root (priv->dbus_mgr, context)) if (!ensure_root (nm_bus_manager_get (), context))
return; return;
failures = g_ptr_array_new (); failures = g_ptr_array_new ();
@@ -1501,18 +1470,22 @@ impl_settings_load_connections (NMSettings *self,
} }
g_ptr_array_add (failures, NULL); g_ptr_array_add (failures, NULL);
dbus_g_method_return (context, failures->len == 1, failures->pdata); g_dbus_method_invocation_return_value (
context,
g_variant_new ("(b^as)",
failures->len == 1,
failures->pdata));
g_ptr_array_unref (failures); g_ptr_array_unref (failures);
} }
static void static void
impl_settings_reload_connections (NMSettings *self, impl_settings_reload_connections (NMSettings *self,
DBusGMethodInvocation *context) GDBusMethodInvocation *context)
{ {
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
GSList *iter; GSList *iter;
if (!ensure_root (priv->dbus_mgr, context)) if (!ensure_root (nm_bus_manager_get (), context))
return; return;
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) { for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
@@ -1521,7 +1494,7 @@ impl_settings_reload_connections (NMSettings *self,
nm_system_config_interface_reload_connections (plugin); nm_system_config_interface_reload_connections (plugin);
} }
dbus_g_method_return (context, TRUE); g_dbus_method_invocation_return_value (context, g_variant_new ("(b)", TRUE));
} }
static gboolean static gboolean
@@ -1594,7 +1567,7 @@ write_hostname (NMSettingsPrivate *priv, const char *hostname)
static void static void
pk_hostname_cb (NMAuthChain *chain, pk_hostname_cb (NMAuthChain *chain,
GError *chain_error, GError *chain_error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
gpointer user_data) gpointer user_data)
{ {
NMSettings *self = NM_SETTINGS (user_data); NMSettings *self = NM_SETTINGS (user_data);
@@ -1630,11 +1603,10 @@ pk_hostname_cb (NMAuthChain *chain,
} }
if (error) if (error)
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
else else
dbus_g_method_return (context); g_dbus_method_invocation_return_value (context, NULL);
g_clear_error (&error);
nm_auth_chain_unref (chain); nm_auth_chain_unref (chain);
} }
@@ -1667,8 +1639,8 @@ validate_hostname (const char *hostname)
static void static void
impl_settings_save_hostname (NMSettings *self, impl_settings_save_hostname (NMSettings *self,
const char *hostname, GDBusMethodInvocation *context,
DBusGMethodInvocation *context) const char *hostname)
{ {
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
NMAuthChain *chain; NMAuthChain *chain;
@@ -1696,8 +1668,7 @@ impl_settings_save_hostname (NMSettings *self,
done: done:
if (error) if (error)
dbus_g_method_return_error (context, error); g_dbus_method_invocation_take_error (context, error);
g_clear_error (&error);
} }
static void static void
@@ -2108,7 +2079,6 @@ nm_settings_new (void)
priv = NM_SETTINGS_GET_PRIVATE (self); priv = NM_SETTINGS_GET_PRIVATE (self);
priv->config = nm_config_get (); priv->config = nm_config_get ();
priv->dbus_mgr = nm_bus_manager_get ();
nm_exported_object_export (NM_EXPORTED_OBJECT (self)); nm_exported_object_export (NM_EXPORTED_OBJECT (self));
return self; return self;
@@ -2198,8 +2168,6 @@ dispose (GObject *object)
g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref); g_slist_free_full (priv->auths, (GDestroyNotify) nm_auth_chain_unref);
priv->auths = NULL; priv->auths = NULL;
priv->dbus_mgr = NULL;
g_object_unref (priv->agent_mgr); g_object_unref (priv->agent_mgr);
if (priv->hostname.hostnamed_proxy) { if (priv->hostname.hostnamed_proxy) {
@@ -2255,17 +2223,18 @@ get_property (GObject *object, guint prop_id,
NMSettings *self = NM_SETTINGS (object); NMSettings *self = NM_SETTINGS (object);
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self);
const GSList *specs, *iter; const GSList *specs, *iter;
GSList *copy = NULL;
GHashTableIter citer; GHashTableIter citer;
GPtrArray *array; GPtrArray *array;
const char *path; const char *path;
switch (prop_id) { switch (prop_id) {
case PROP_UNMANAGED_SPECS: case PROP_UNMANAGED_SPECS:
array = g_ptr_array_new ();
specs = nm_settings_get_unmanaged_specs (self); specs = nm_settings_get_unmanaged_specs (self);
for (iter = specs; iter; iter = g_slist_next (iter)) for (iter = specs; iter; iter = g_slist_next (iter))
copy = g_slist_append (copy, g_strdup (iter->data)); g_ptr_array_add (array, g_strdup (iter->data));
g_value_take_boxed (value, copy); g_ptr_array_add (array, NULL);
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
break; break;
case PROP_HOSTNAME: case PROP_HOSTNAME:
g_value_take_string (value, nm_settings_get_hostname (self)); g_value_take_string (value, nm_settings_get_hostname (self));
@@ -2278,11 +2247,12 @@ get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)); g_value_set_boolean (value, !!get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS));
break; break;
case PROP_CONNECTIONS: case PROP_CONNECTIONS:
array = g_ptr_array_sized_new (g_hash_table_size (priv->connections)); array = g_ptr_array_sized_new (g_hash_table_size (priv->connections) + 1);
g_hash_table_iter_init (&citer, priv->connections); g_hash_table_iter_init (&citer, priv->connections);
while (g_hash_table_iter_next (&citer, (gpointer) &path, NULL)) while (g_hash_table_iter_next (&citer, (gpointer) &path, NULL))
g_ptr_array_add (array, g_strdup (path)); g_ptr_array_add (array, g_strdup (path));
g_value_take_boxed (value, array); g_ptr_array_add (array, NULL);
g_value_take_boxed (value, (char **) g_ptr_array_free (array, FALSE));
break; break;
case PROP_STARTUP_COMPLETE: case PROP_STARTUP_COMPLETE:
g_value_set_boolean (value, nm_settings_get_startup_complete (self)); g_value_set_boolean (value, nm_settings_get_startup_complete (self));
@@ -2313,7 +2283,7 @@ nm_settings_class_init (NMSettingsClass *class)
g_object_class_install_property g_object_class_install_property
(object_class, PROP_UNMANAGED_SPECS, (object_class, PROP_UNMANAGED_SPECS,
g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "", "", g_param_spec_boxed (NM_SETTINGS_UNMANAGED_SPECS, "", "",
DBUS_TYPE_G_LIST_OF_STRING, G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
@@ -2334,7 +2304,7 @@ nm_settings_class_init (NMSettingsClass *class)
g_object_class_install_property g_object_class_install_property
(object_class, PROP_CONNECTIONS, (object_class, PROP_CONNECTIONS,
g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, "", "", g_param_spec_boxed (NM_SETTINGS_CONNECTIONS, "", "",
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, G_TYPE_STRV,
G_PARAM_READABLE | G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS)); G_PARAM_STATIC_STRINGS));
@@ -2346,7 +2316,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_added), G_STRUCT_OFFSET (NMSettingsClass, connection_added),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_UPDATED] = signals[CONNECTION_UPDATED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED, g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
@@ -2355,7 +2325,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_updated), G_STRUCT_OFFSET (NMSettingsClass, connection_updated),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_UPDATED_BY_USER] = signals[CONNECTION_UPDATED_BY_USER] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER, g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_UPDATED_BY_USER,
@@ -2364,7 +2334,7 @@ nm_settings_class_init (NMSettingsClass *class)
0, 0,
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_REMOVED] = signals[CONNECTION_REMOVED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
@@ -2373,7 +2343,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_removed), G_STRUCT_OFFSET (NMSettingsClass, connection_removed),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[CONNECTION_VISIBILITY_CHANGED] = signals[CONNECTION_VISIBILITY_CHANGED] =
g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED, g_signal_new (NM_SETTINGS_SIGNAL_CONNECTION_VISIBILITY_CHANGED,
@@ -2382,7 +2352,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed), G_STRUCT_OFFSET (NMSettingsClass, connection_visibility_changed),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
signals[AGENT_REGISTERED] = signals[AGENT_REGISTERED] =
g_signal_new (NM_SETTINGS_SIGNAL_AGENT_REGISTERED, g_signal_new (NM_SETTINGS_SIGNAL_AGENT_REGISTERED,
@@ -2391,7 +2361,7 @@ nm_settings_class_init (NMSettingsClass *class)
G_STRUCT_OFFSET (NMSettingsClass, agent_registered), G_STRUCT_OFFSET (NMSettingsClass, agent_registered),
NULL, NULL, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SECRET_AGENT);
signals[NEW_CONNECTION] = signals[NEW_CONNECTION] =
@@ -2399,16 +2369,17 @@ nm_settings_class_init (NMSettingsClass *class)
G_OBJECT_CLASS_TYPE (object_class), G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT); G_TYPE_NONE, 1, NM_TYPE_SETTINGS_CONNECTION);
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class), nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (class),
&dbus_glib_nm_settings_object_info); NMDBUS_TYPE_SETTINGS_SKELETON,
"ListConnections", impl_settings_list_connections,
dbus_g_error_domain_register (NM_SETTINGS_ERROR, "GetConnectionByUuid", impl_settings_get_connection_by_uuid,
NM_DBUS_INTERFACE_SETTINGS, "AddConnection", impl_settings_add_connection,
NM_TYPE_SETTINGS_ERROR); "AddConnectionUnsaved", impl_settings_add_connection_unsaved,
dbus_g_error_domain_register (NM_CONNECTION_ERROR, "LoadConnections", impl_settings_load_connections,
NM_DBUS_INTERFACE_SETTINGS_CONNECTION, "ReloadConnections", impl_settings_reload_connections,
NM_TYPE_CONNECTION_ERROR); "SaveHostname", impl_settings_save_hostname,
NULL);
} }

View File

@@ -87,14 +87,14 @@ void nm_settings_for_each_connection (NMSettings *settings,
typedef void (*NMSettingsAddCallback) (NMSettings *settings, typedef void (*NMSettingsAddCallback) (NMSettings *settings,
NMSettingsConnection *connection, NMSettingsConnection *connection,
GError *error, GError *error,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMAuthSubject *subject, NMAuthSubject *subject,
gpointer user_data); gpointer user_data);
void nm_settings_add_connection_dbus (NMSettings *self, void nm_settings_add_connection_dbus (NMSettings *self,
NMConnection *connection, NMConnection *connection,
gboolean save_to_disk, gboolean save_to_disk,
DBusGMethodInvocation *context, GDBusMethodInvocation *context,
NMSettingsAddCallback callback, NMSettingsAddCallback callback,
gpointer user_data); gpointer user_data);