mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-06 17:14:02 +00:00
core: move secrets handling to NMSettingsConnection
It's the thing that owns the secrets anyway, and it simplifies things to have the secrets handling there instead of half in NMActRequest and half in NMManager. It also means we can get rid of the ugly signals that NMSettingsConnection had to emit to get agent's secrets, and we can consolidate the requests for the persistent secrets that the NMSettingsConnection owned into NMSettingsConnection itself instead of also in NMAgentManager. Since the NMActRequest and the NMVPNConnection classes already tracked the underlying NMSettingsConnection representing the activation, its trivial to just have them ask the NMSettingsConnection for secrets instead of talking to the NMAgentManager. Thus, only the NMSettingsConnection now has to know about the agent manager, and it presents a cleaner interface to other objects further up the chain, instead of having bits of the secrets request splattered around the activation request, the VPN connection, the NMManager, etc.
This commit is contained in:
parent
37a9303c2e
commit
0e6a5365d4
|
@ -516,12 +516,12 @@ nm_modem_get_secrets (NMModem *self,
|
|||
const char *hint)
|
||||
{
|
||||
NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self);
|
||||
guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
|
||||
cancel_get_secrets (self);
|
||||
|
||||
if (request_new)
|
||||
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
priv->secrets_id = nm_act_request_get_secrets (priv->act_request,
|
||||
setting_name,
|
||||
flags,
|
||||
|
@ -554,7 +554,7 @@ nm_modem_act_stage1_prepare (NMModem *self,
|
|||
NMActStageReturn ret;
|
||||
GPtrArray *hints = NULL;
|
||||
const char *setting_name = NULL;
|
||||
guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
|
||||
if (priv->act_request)
|
||||
g_object_unref (priv->act_request);
|
||||
|
@ -567,7 +567,7 @@ nm_modem_act_stage1_prepare (NMModem *self,
|
|||
reason);
|
||||
if ((ret == NM_ACT_STAGE_RETURN_POSTPONE) && setting_name) {
|
||||
if (priv->secrets_tries++)
|
||||
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
|
||||
priv->secrets_id = nm_act_request_get_secrets (req,
|
||||
setting_name,
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "nm-active-connection.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
#include "nm-active-connection-glue.h"
|
||||
#include "nm-settings-connection.h"
|
||||
|
||||
|
||||
G_DEFINE_TYPE (NMActRequest, nm_act_request, G_TYPE_OBJECT)
|
||||
|
@ -60,7 +61,6 @@ typedef struct {
|
|||
|
||||
NMConnection *connection;
|
||||
|
||||
NMAgentManager *agent_mgr;
|
||||
GSList *secrets_calls;
|
||||
|
||||
char *specific_object;
|
||||
|
@ -94,66 +94,28 @@ enum {
|
|||
|
||||
/*******************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMActRequest *self;
|
||||
guint32 call_id;
|
||||
NMActRequestSecretsFunc callback;
|
||||
gpointer callback_data;
|
||||
} GetSecretsInfo;
|
||||
|
||||
static void
|
||||
get_secrets_cb (NMAgentManager *manager,
|
||||
get_secrets_cb (NMSettingsConnection *connection,
|
||||
guint32 call_id,
|
||||
NMConnection *connection,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
gpointer user_data,
|
||||
gpointer user_data2,
|
||||
gpointer user_data3)
|
||||
gpointer user_data)
|
||||
{
|
||||
NMActRequest *self = NM_ACT_REQUEST (user_data);
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
NMActRequestSecretsFunc callback = user_data2;
|
||||
GetSecretsInfo *info = user_data;
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self);
|
||||
|
||||
priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id));
|
||||
g_return_if_fail (info->call_id == call_id);
|
||||
priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
|
||||
|
||||
callback (self, call_id, connection, error, user_data3);
|
||||
}
|
||||
|
||||
static guint32
|
||||
_internal_get_secrets (NMActRequest *self,
|
||||
NMConnection *connection,
|
||||
gboolean filter_by_uid,
|
||||
gulong uid,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NMActRequestPrivate *priv;
|
||||
guint32 call_id;
|
||||
|
||||
g_return_val_if_fail (self, 0);
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0);
|
||||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
|
||||
/* If given a connection (ie, called from an NMVpnConnection) then
|
||||
* use that, otherwise use the private connection.
|
||||
*
|
||||
* FIXME: this is icky, and should go away when NMVPNConnection finally
|
||||
* uses NMActRequest for activation tracking instead of impersonating one
|
||||
* itself.
|
||||
*/
|
||||
call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
|
||||
connection,
|
||||
filter_by_uid,
|
||||
uid,
|
||||
setting_name,
|
||||
flags,
|
||||
hint,
|
||||
get_secrets_cb,
|
||||
self,
|
||||
callback,
|
||||
callback_data);
|
||||
if (call_id > 0)
|
||||
priv->secrets_calls = g_slist_append (priv->secrets_calls, GUINT_TO_POINTER (call_id));
|
||||
|
||||
return call_id;
|
||||
info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
guint32
|
||||
|
@ -164,41 +126,43 @@ nm_act_request_get_secrets (NMActRequest *self,
|
|||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
NMActRequestPrivate *priv;
|
||||
GetSecretsInfo *info;
|
||||
guint32 call_id;
|
||||
|
||||
/* non-VPN requests use the activation request's internal connection, and
|
||||
* also the user-requested status and user_uid if the activation was
|
||||
* requested by a user.
|
||||
*/
|
||||
return _internal_get_secrets (self, priv->connection, priv->user_requested,
|
||||
priv->user_uid, setting_name, flags, hint,
|
||||
callback, callback_data);
|
||||
}
|
||||
g_return_val_if_fail (self, 0);
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (self), 0);
|
||||
|
||||
guint32
|
||||
nm_act_request_get_secrets_vpn (NMActRequest *self,
|
||||
NMConnection *connection,
|
||||
gboolean user_requested,
|
||||
gulong user_uid,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
g_return_val_if_fail (connection != NULL, 0);
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
|
||||
/* VPN requests use the VPN's connection, and also the VPN's user-requested
|
||||
* status and user_uid if the activation was requested by a user.
|
||||
*/
|
||||
return _internal_get_secrets (self, connection, user_requested, user_uid,
|
||||
setting_name, flags, hint, callback, callback_data);
|
||||
info = g_malloc0 (sizeof (GetSecretsInfo));
|
||||
info->self = self;
|
||||
info->callback = callback;
|
||||
info->callback_data = callback_data;
|
||||
|
||||
call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection),
|
||||
priv->user_requested,
|
||||
priv->user_uid,
|
||||
setting_name,
|
||||
flags,
|
||||
hint,
|
||||
get_secrets_cb,
|
||||
info,
|
||||
NULL);
|
||||
if (call_id > 0) {
|
||||
info->call_id = call_id;
|
||||
priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
|
||||
} else
|
||||
g_free (info);
|
||||
|
||||
return call_id;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
|
||||
{
|
||||
NMActRequestPrivate *priv;
|
||||
GSList *iter;
|
||||
|
||||
g_return_if_fail (self);
|
||||
g_return_if_fail (NM_IS_ACT_REQUEST (self));
|
||||
|
@ -206,9 +170,18 @@ nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
|
|||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
|
||||
if (g_slist_find (priv->secrets_calls, GUINT_TO_POINTER (call_id))) {
|
||||
priv->secrets_calls = g_slist_remove (priv->secrets_calls, GUINT_TO_POINTER (call_id));
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id);
|
||||
for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
|
||||
GetSecretsInfo *info = iter->data;
|
||||
|
||||
/* Remove the matching info */
|
||||
if (info->call_id == call_id) {
|
||||
priv->secrets_calls = g_slist_remove_link (priv->secrets_calls, iter);
|
||||
g_slist_free (iter);
|
||||
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), call_id);
|
||||
g_free (info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,7 +463,6 @@ device_state_changed (NMDevice *device,
|
|||
NMActRequest *
|
||||
nm_act_request_new (NMConnection *connection,
|
||||
const char *specific_object,
|
||||
NMAgentManager *agent_mgr,
|
||||
gboolean user_requested,
|
||||
gulong user_uid,
|
||||
gboolean assumed,
|
||||
|
@ -500,7 +472,6 @@ nm_act_request_new (NMConnection *connection,
|
|||
NMActRequestPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
g_return_val_if_fail (NM_IS_AGENT_MANAGER (agent_mgr), NULL);
|
||||
g_return_val_if_fail (NM_DEVICE (device), NULL);
|
||||
|
||||
object = g_object_new (NM_TYPE_ACT_REQUEST, NULL);
|
||||
|
@ -513,8 +484,6 @@ nm_act_request_new (NMConnection *connection,
|
|||
if (specific_object)
|
||||
priv->specific_object = g_strdup (specific_object);
|
||||
|
||||
priv->agent_mgr = g_object_ref (agent_mgr);
|
||||
|
||||
priv->device = NM_DEVICE (device);
|
||||
g_signal_connect (device, "state-changed",
|
||||
G_CALLBACK (device_state_changed),
|
||||
|
@ -595,8 +564,6 @@ dispose (GObject *object)
|
|||
}
|
||||
priv->disposed = TRUE;
|
||||
|
||||
g_assert (priv->connection);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (G_OBJECT (priv->device),
|
||||
G_CALLBACK (device_state_changed),
|
||||
NM_ACT_REQUEST (object));
|
||||
|
@ -604,14 +571,17 @@ dispose (GObject *object)
|
|||
/* Clear any share rules */
|
||||
nm_act_request_set_shared (NM_ACT_REQUEST (object), FALSE);
|
||||
|
||||
g_object_unref (priv->connection);
|
||||
|
||||
/* Kill any in-progress secrets requests */
|
||||
g_assert (priv->connection);
|
||||
for (iter = priv->secrets_calls; iter; iter = g_slist_next (iter)) {
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr,
|
||||
GPOINTER_TO_UINT (iter->data));
|
||||
GetSecretsInfo *info = iter->data;
|
||||
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), info->call_id);
|
||||
g_free (info);
|
||||
}
|
||||
g_slist_free (priv->secrets_calls);
|
||||
g_object_unref (priv->agent_mgr);
|
||||
|
||||
g_object_unref (priv->connection);
|
||||
|
||||
G_OBJECT_CLASS (nm_act_request_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include <glib-object.h>
|
||||
#include "nm-connection.h"
|
||||
#include "nm-active-connection.h"
|
||||
#include "nm-agent-manager.h"
|
||||
|
||||
#define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ())
|
||||
#define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest))
|
||||
|
@ -49,7 +48,6 @@ GType nm_act_request_get_type (void);
|
|||
|
||||
NMActRequest *nm_act_request_new (NMConnection *connection,
|
||||
const char *specific_object,
|
||||
NMAgentManager *agent_mgr,
|
||||
gboolean user_requested,
|
||||
gulong user_uid,
|
||||
gboolean assumed,
|
||||
|
@ -93,22 +91,21 @@ typedef void (*NMActRequestSecretsFunc) (NMActRequest *req,
|
|||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
guint32 nm_act_request_get_secrets (NMActRequest *req,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data);
|
||||
/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in
|
||||
* the nm-secret-agent.xml introspection file.
|
||||
*/
|
||||
enum {
|
||||
NM_ACT_REQUEST_GET_SECRETS_FLAG_NONE = 0x0,
|
||||
NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1,
|
||||
NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW = 0x2
|
||||
};
|
||||
|
||||
guint32 nm_act_request_get_secrets_vpn (NMActRequest *req,
|
||||
NMConnection *connection,
|
||||
gboolean user_requested,
|
||||
gulong user_uid,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data);
|
||||
guint32 nm_act_request_get_secrets (NMActRequest *req,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data);
|
||||
|
||||
void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id);
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "nm-agent-manager.h"
|
||||
#include "nm-secret-agent.h"
|
||||
#include "nm-manager-auth.h"
|
||||
#include "nm-settings-connection.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
|
||||
G_DEFINE_TYPE (NMAgentManager, nm_agent_manager, G_TYPE_OBJECT)
|
||||
|
@ -353,7 +352,7 @@ struct _Request {
|
|||
|
||||
guint32 idle_id;
|
||||
|
||||
GHashTable *settings_secrets;
|
||||
GHashTable *existing_secrets;
|
||||
|
||||
NMAgentSecretsResultFunc callback;
|
||||
gpointer callback_data;
|
||||
|
@ -368,6 +367,7 @@ static Request *
|
|||
request_new (NMConnection *connection,
|
||||
gboolean filter_by_uid,
|
||||
gulong uid_filter,
|
||||
GHashTable *existing_secrets,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
|
@ -386,6 +386,7 @@ request_new (NMConnection *connection,
|
|||
req->connection = g_object_ref (connection);
|
||||
req->filter_by_uid = filter_by_uid;
|
||||
req->uid_filter = uid_filter;
|
||||
req->existing_secrets = g_hash_table_ref (existing_secrets);
|
||||
req->setting_name = g_strdup (setting_name);
|
||||
req->flags = flags;
|
||||
req->hint = g_strdup (hint);
|
||||
|
@ -413,60 +414,14 @@ request_free (Request *req)
|
|||
g_object_unref (req->connection);
|
||||
g_free (req->setting_name);
|
||||
g_free (req->hint);
|
||||
if (req->settings_secrets)
|
||||
g_hash_table_unref (req->settings_secrets);
|
||||
if (req->existing_secrets)
|
||||
g_hash_table_unref (req->existing_secrets);
|
||||
memset (req, 0, sizeof (Request));
|
||||
g_free (req);
|
||||
}
|
||||
|
||||
static void request_next (Request *req);
|
||||
|
||||
static void
|
||||
destroy_gvalue (gpointer data)
|
||||
{
|
||||
GValue *value = (GValue *) data;
|
||||
|
||||
g_value_unset (value);
|
||||
g_slice_free (GValue, value);
|
||||
}
|
||||
|
||||
static void
|
||||
merge_secrets (GHashTable *src, GHashTable *dest)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, data;
|
||||
|
||||
g_hash_table_iter_init (&iter, src);
|
||||
while (g_hash_table_iter_next (&iter, &key, &data)) {
|
||||
const char *setting_name = key;
|
||||
GHashTable *dstsetting;
|
||||
GHashTableIter subiter;
|
||||
gpointer subkey, subval;
|
||||
|
||||
/* Find the corresponding setting in the merged secrets hash, or create
|
||||
* it if it doesn't exist.
|
||||
*/
|
||||
dstsetting = g_hash_table_lookup (dest, setting_name);
|
||||
if (!dstsetting) {
|
||||
dstsetting = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) destroy_gvalue);
|
||||
g_hash_table_insert (dest, (gpointer) setting_name, dstsetting);
|
||||
}
|
||||
|
||||
/* And copy in each secret from src */
|
||||
g_hash_table_iter_init (&subiter, (GHashTable *) data);
|
||||
while (g_hash_table_iter_next (&subiter, &subkey, &subval)) {
|
||||
const char *keyname = subkey;
|
||||
GValue *srcval = subval, *dstval;
|
||||
|
||||
dstval = g_slice_new0 (GValue);
|
||||
g_value_init (dstval, G_VALUE_TYPE (srcval));
|
||||
g_value_copy (srcval, dstval);
|
||||
|
||||
g_hash_table_insert (dstsetting, (gpointer) keyname, dstval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
request_secrets_done_cb (NMSecretAgent *agent,
|
||||
gconstpointer call_id,
|
||||
|
@ -475,7 +430,7 @@ request_secrets_done_cb (NMSecretAgent *agent,
|
|||
gpointer user_data)
|
||||
{
|
||||
Request *req = user_data;
|
||||
GHashTable *setting_secrets, *merged;
|
||||
GHashTable *setting_secrets;
|
||||
|
||||
g_return_if_fail (call_id == req->current_call_id);
|
||||
|
||||
|
@ -510,20 +465,7 @@ request_secrets_done_cb (NMSecretAgent *agent,
|
|||
nm_secret_agent_get_description (agent),
|
||||
req, req->setting_name);
|
||||
|
||||
/* Success! If we got some secrets from the settings service, merge those
|
||||
* with the ones from the secret agent.
|
||||
*/
|
||||
if (req->settings_secrets) {
|
||||
merged = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) g_hash_table_unref);
|
||||
|
||||
/* Copy agent secrets first, then overwrite with settings secrets */
|
||||
merge_secrets (secrets, merged);
|
||||
merge_secrets (req->settings_secrets, merged);
|
||||
|
||||
req->complete_callback (req, merged, NULL, req->complete_callback_data);
|
||||
g_hash_table_destroy (merged);
|
||||
} else
|
||||
req->complete_callback (req, secrets, NULL, req->complete_callback_data);
|
||||
req->complete_callback (req, secrets, NULL, req->complete_callback_data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -568,23 +510,17 @@ static gboolean
|
|||
request_start_secrets (gpointer user_data)
|
||||
{
|
||||
Request *req = user_data;
|
||||
GHashTable *secrets, *setting_secrets = NULL;
|
||||
GError *error = NULL;
|
||||
GHashTable *setting_secrets = NULL;
|
||||
|
||||
req->idle_id = 0;
|
||||
|
||||
nm_log_dbg (LOGD_AGENTS, "(%p/%s) getting secrets from system settings",
|
||||
req, req->setting_name);
|
||||
|
||||
/* Grab any secrets from persistent storage */
|
||||
secrets = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (req->connection),
|
||||
req->setting_name,
|
||||
&error);
|
||||
if (secrets)
|
||||
setting_secrets = g_hash_table_lookup (secrets, req->setting_name);
|
||||
/* Check if there are any existing secrets */
|
||||
if (req->existing_secrets)
|
||||
setting_secrets = g_hash_table_lookup (req->existing_secrets, req->setting_name);
|
||||
|
||||
if (setting_secrets && g_hash_table_size (setting_secrets)) {
|
||||
NMConnection *tmp;
|
||||
GError *error = NULL;
|
||||
|
||||
/* The connection already had secrets; check if any more are required.
|
||||
* If no more are required, we're done. If secrets are still needed,
|
||||
|
@ -594,7 +530,7 @@ request_start_secrets (gpointer user_data)
|
|||
tmp = nm_connection_duplicate (req->connection);
|
||||
g_assert (tmp);
|
||||
|
||||
if (!nm_connection_update_secrets (tmp, req->setting_name, secrets, &error)) {
|
||||
if (!nm_connection_update_secrets (tmp, req->setting_name, req->existing_secrets, &error)) {
|
||||
req->complete_callback (req, NULL, error, req->complete_callback_data);
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
|
@ -605,26 +541,16 @@ request_start_secrets (gpointer user_data)
|
|||
req, req->setting_name);
|
||||
|
||||
/* Got everything, we're done */
|
||||
req->complete_callback (req, secrets, NULL, req->complete_callback_data);
|
||||
req->complete_callback (req, req->existing_secrets, NULL, req->complete_callback_data);
|
||||
} else {
|
||||
nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings secrets insufficient, asking agents",
|
||||
req, req->setting_name);
|
||||
|
||||
/* We don't, so ask some agents for additional secrets */
|
||||
req->settings_secrets = g_hash_table_ref (secrets);
|
||||
request_next (req);
|
||||
}
|
||||
}
|
||||
g_object_unref (tmp);
|
||||
} else if (error) {
|
||||
nm_log_dbg (LOGD_AGENTS, "(%p/%s) system settings returned error: (%d) %s",
|
||||
req, req->setting_name, error->code, error->message);
|
||||
|
||||
/* Errors from the system settings are hard errors; we don't go on
|
||||
* to ask agents for secrets if the settings service failed.
|
||||
*/
|
||||
req->complete_callback (req, NULL, error, req->complete_callback_data);
|
||||
g_error_free (error);
|
||||
} else {
|
||||
/* Couldn't get secrets from system settings, so now we ask the
|
||||
* agents for secrets. Let the Agent Manager handle which agents
|
||||
|
@ -633,9 +559,6 @@ request_start_secrets (gpointer user_data)
|
|||
request_next (req);
|
||||
}
|
||||
|
||||
if (secrets)
|
||||
g_hash_table_unref (secrets);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -759,38 +682,18 @@ mgr_req_complete_cb (Request *req,
|
|||
{
|
||||
NMAgentManager *self = NM_AGENT_MANAGER (user_data);
|
||||
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
|
||||
GError *local = NULL;
|
||||
|
||||
if (error)
|
||||
local = g_error_copy (error);
|
||||
else {
|
||||
/* Save the secrets into the connection */
|
||||
nm_connection_update_secrets (req->connection,
|
||||
req->setting_name,
|
||||
secrets,
|
||||
&local);
|
||||
}
|
||||
|
||||
if (local) {
|
||||
nm_log_warn (LOGD_SETTINGS,
|
||||
"Failed to %s connection secrets: (%d) %s",
|
||||
error ? "get" : "update",
|
||||
local->code,
|
||||
local->message ? local->message : "(none)");
|
||||
}
|
||||
|
||||
/* Call the activation requests' secrets callback */
|
||||
/* Send secrets back to the requesting object */
|
||||
req->callback (self,
|
||||
req->reqid,
|
||||
req->connection,
|
||||
req->setting_name,
|
||||
local,
|
||||
error ? NULL : secrets,
|
||||
error,
|
||||
req->callback_data,
|
||||
req->other_data2,
|
||||
req->other_data3);
|
||||
|
||||
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid));
|
||||
g_clear_error (&local);
|
||||
}
|
||||
|
||||
guint32
|
||||
|
@ -798,6 +701,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self,
|
|||
NMConnection *connection,
|
||||
gboolean filter_by_uid,
|
||||
gulong uid_filter,
|
||||
GHashTable *existing_secrets,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
|
@ -813,7 +717,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self,
|
|||
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
g_return_val_if_fail (connection != NULL, 0);
|
||||
g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), 0);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), 0);
|
||||
g_return_val_if_fail (callback != NULL, 0);
|
||||
|
||||
nm_log_dbg (LOGD_SETTINGS,
|
||||
|
@ -824,6 +728,7 @@ nm_agent_manager_get_secrets (NMAgentManager *self,
|
|||
req = request_new (connection,
|
||||
filter_by_uid,
|
||||
uid_filter,
|
||||
existing_secrets,
|
||||
setting_name,
|
||||
flags,
|
||||
hint,
|
||||
|
@ -875,30 +780,33 @@ name_owner_changed_cb (NMDBusManager *dbus_mgr,
|
|||
/*************************************************************/
|
||||
|
||||
NMAgentManager *
|
||||
nm_agent_manager_new (NMDBusManager *dbus_mgr)
|
||||
nm_agent_manager_get (void)
|
||||
{
|
||||
NMAgentManager *self;
|
||||
static NMAgentManager *singleton = NULL;
|
||||
NMAgentManagerPrivate *priv;
|
||||
DBusGConnection *connection;
|
||||
|
||||
g_return_val_if_fail (dbus_mgr != NULL, NULL);
|
||||
if (singleton)
|
||||
return g_object_ref (singleton);
|
||||
|
||||
self = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL);
|
||||
if (self) {
|
||||
priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
|
||||
singleton = (NMAgentManager *) g_object_new (NM_TYPE_AGENT_MANAGER, NULL);
|
||||
g_assert (singleton);
|
||||
|
||||
priv->session_monitor = nm_session_monitor_get ();
|
||||
priv->dbus_mgr = g_object_ref (dbus_mgr);
|
||||
connection = nm_dbus_manager_get_connection (dbus_mgr);
|
||||
dbus_g_connection_register_g_object (connection, NM_DBUS_PATH_AGENT_MANAGER, G_OBJECT (self));
|
||||
priv = NM_AGENT_MANAGER_GET_PRIVATE (singleton);
|
||||
priv->session_monitor = nm_session_monitor_get ();
|
||||
priv->dbus_mgr = nm_dbus_manager_get ();
|
||||
|
||||
g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
|
||||
G_CALLBACK (name_owner_changed_cb),
|
||||
self);
|
||||
}
|
||||
connection = nm_dbus_manager_get_connection (priv->dbus_mgr);
|
||||
dbus_g_connection_register_g_object (connection,
|
||||
NM_DBUS_PATH_AGENT_MANAGER,
|
||||
G_OBJECT (singleton));
|
||||
|
||||
return self;
|
||||
g_signal_connect (priv->dbus_mgr,
|
||||
NM_DBUS_MANAGER_NAME_OWNER_CHANGED,
|
||||
G_CALLBACK (name_owner_changed_cb),
|
||||
singleton);
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -23,12 +23,8 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <nm-connection.h>
|
||||
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-secret-agent.h"
|
||||
|
||||
#define NM_TYPE_AGENT_MANAGER (nm_agent_manager_get_type ())
|
||||
#define NM_AGENT_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManager))
|
||||
#define NM_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass))
|
||||
|
@ -46,21 +42,22 @@ typedef struct {
|
|||
|
||||
GType nm_agent_manager_get_type (void);
|
||||
|
||||
NMAgentManager *nm_agent_manager_new (NMDBusManager *dbus_mgr);
|
||||
NMAgentManager *nm_agent_manager_get (void);
|
||||
|
||||
typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
|
||||
guint32 call_id,
|
||||
NMConnection *connection,
|
||||
const char *setting_name,
|
||||
GHashTable *secrets,
|
||||
GError *error,
|
||||
gpointer user_data,
|
||||
gpointer user_data2,
|
||||
gpointer user_data3);
|
||||
gpointer other_data2,
|
||||
gpointer other_data3);
|
||||
|
||||
guint32 nm_agent_manager_get_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection,
|
||||
gboolean filter_by_uid,
|
||||
gulong uid,
|
||||
GHashTable *existing_secrets,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
|
|
|
@ -1056,7 +1056,7 @@ link_timeout_cb (gpointer user_data)
|
|||
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
nm_act_request_get_secrets (req,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW,
|
||||
NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW,
|
||||
NULL,
|
||||
wired_secrets_cb,
|
||||
self);
|
||||
|
@ -1237,13 +1237,13 @@ handle_auth_or_fail (NMDeviceEthernet *self,
|
|||
nm_connection_clear_secrets (connection);
|
||||
setting_name = nm_connection_need_secrets (connection, NULL);
|
||||
if (setting_name) {
|
||||
guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
|
||||
/* If the caller doesn't necessarily want completely new secrets,
|
||||
* only ask for new secrets after the first failure.
|
||||
*/
|
||||
if (new_secrets || tries)
|
||||
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
nm_act_request_get_secrets (req, setting_name, flags, NULL, wired_secrets_cb, self);
|
||||
|
||||
g_object_set_data (G_OBJECT (connection), WIRED_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
|
||||
|
|
|
@ -2496,7 +2496,7 @@ link_timeout_cb (gpointer user_data)
|
|||
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
nm_act_request_get_secrets (req,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW,
|
||||
NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW,
|
||||
NULL,
|
||||
wifi_secrets_cb,
|
||||
self);
|
||||
|
@ -2734,13 +2734,13 @@ handle_auth_or_fail (NMDeviceWifi *self,
|
|||
nm_connection_clear_secrets (connection);
|
||||
setting_name = nm_connection_need_secrets (connection, NULL);
|
||||
if (setting_name) {
|
||||
guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
|
||||
/* If the caller doesn't necessarily want completely new secrets,
|
||||
* only ask for new secrets after the first failure.
|
||||
*/
|
||||
if (new_secrets || tries)
|
||||
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
nm_act_request_get_secrets (req, setting_name, flags, NULL, wifi_secrets_cb, self);
|
||||
|
||||
g_object_set_data (G_OBJECT (connection), WIRELESS_SECRETS_TRIES, GUINT_TO_POINTER (++tries));
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
#include "nm-settings.h"
|
||||
#include "nm-settings-connection.h"
|
||||
#include "nm-manager-auth.h"
|
||||
#include "nm-agent-manager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
#define NM_AUTOIP_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
|
||||
|
@ -213,7 +212,6 @@ typedef struct {
|
|||
|
||||
NMSettings *settings;
|
||||
char *hostname;
|
||||
NMAgentManager *agent_mgr;
|
||||
|
||||
RadioState radio_states[RFKILL_TYPE_MAX];
|
||||
gboolean sleeping;
|
||||
|
@ -925,86 +923,6 @@ connections_changed (NMSettings *settings,
|
|||
bluez_manager_resync_devices (manager);
|
||||
}
|
||||
|
||||
static void
|
||||
secrets_result_cb (NMAgentManager *manager,
|
||||
guint32 call_id,
|
||||
NMConnection *connection,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
gpointer user_data,
|
||||
gpointer user_data2,
|
||||
gpointer user_data3)
|
||||
{
|
||||
NMSettingsConnectionSecretsUpdatedFunc callback = user_data2;
|
||||
gpointer callback_data = user_data3;
|
||||
|
||||
callback (NM_SETTINGS_CONNECTION (connection), setting_name, call_id, error, callback_data);
|
||||
}
|
||||
|
||||
static guint32
|
||||
system_connection_get_secrets_cb (NMSettingsConnection *connection,
|
||||
const char *sender,
|
||||
const char *setting_name,
|
||||
NMSettingsConnectionSecretsUpdatedFunc callback,
|
||||
gpointer callback_data,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
gboolean call_id = 0;
|
||||
DBusError error;
|
||||
gulong sender_uid;
|
||||
|
||||
/* Get the unix user of the requestor */
|
||||
dbus_error_init (&error);
|
||||
sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr),
|
||||
sender,
|
||||
&error);
|
||||
if (dbus_error_is_set (&error))
|
||||
dbus_error_free (&error);
|
||||
else {
|
||||
call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
|
||||
NM_CONNECTION (connection),
|
||||
TRUE,
|
||||
sender_uid,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE,
|
||||
NULL,
|
||||
secrets_result_cb,
|
||||
self,
|
||||
callback,
|
||||
callback_data);
|
||||
}
|
||||
|
||||
return call_id;
|
||||
}
|
||||
|
||||
static void
|
||||
system_connection_cancel_secrets_cb (NMSettingsConnection *connection,
|
||||
guint32 call_id,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
|
||||
nm_agent_manager_cancel_secrets (NM_MANAGER_GET_PRIVATE (self)->agent_mgr, call_id);
|
||||
}
|
||||
|
||||
static void
|
||||
connection_added (NMSettings *settings,
|
||||
NMSettingsConnection *connection,
|
||||
NMManager *manager)
|
||||
{
|
||||
/* Hook up secrets request listeners */
|
||||
g_signal_connect (connection, NM_SETTINGS_CONNECTION_GET_SECRETS,
|
||||
G_CALLBACK (system_connection_get_secrets_cb),
|
||||
manager);
|
||||
g_signal_connect (connection, NM_SETTINGS_CONNECTION_CANCEL_SECRETS,
|
||||
G_CALLBACK (system_connection_cancel_secrets_cb),
|
||||
manager);
|
||||
|
||||
connections_changed (settings, connection, manager);
|
||||
}
|
||||
|
||||
static void
|
||||
system_unmanaged_devices_changed_cb (NMSettings *settings,
|
||||
GParamSpec *pspec,
|
||||
|
@ -1953,7 +1871,6 @@ internal_activate_device (NMManager *manager,
|
|||
|
||||
req = nm_act_request_new (connection,
|
||||
specific_object,
|
||||
NM_MANAGER_GET_PRIVATE (manager)->agent_mgr,
|
||||
user_requested,
|
||||
sender_uid,
|
||||
assumed,
|
||||
|
@ -3190,8 +3107,6 @@ nm_manager_get (NMSettings *settings,
|
|||
|
||||
priv->settings = g_object_ref (settings);
|
||||
|
||||
priv->agent_mgr = nm_agent_manager_new (priv->dbus_mgr);
|
||||
|
||||
priv->config_file = g_strdup (config_file);
|
||||
priv->state_file = g_strdup (state_file);
|
||||
|
||||
|
@ -3206,7 +3121,7 @@ nm_manager_get (NMSettings *settings,
|
|||
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_HOSTNAME,
|
||||
G_CALLBACK (system_hostname_changed_cb), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_ADDED,
|
||||
G_CALLBACK (connection_added), singleton);
|
||||
G_CALLBACK (connections_changed), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_UPDATED,
|
||||
G_CALLBACK (connections_changed), singleton);
|
||||
g_signal_connect (priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED,
|
||||
|
@ -3275,8 +3190,6 @@ dispose (GObject *object)
|
|||
|
||||
g_object_unref (priv->settings);
|
||||
|
||||
g_object_unref (priv->agent_mgr);
|
||||
|
||||
if (priv->vpn_manager_id) {
|
||||
g_source_remove (priv->vpn_manager_id);
|
||||
priv->vpn_manager_id = 0;
|
||||
|
|
|
@ -29,15 +29,6 @@
|
|||
#include <nm-connection.h>
|
||||
#include "nm-dbus-manager.h"
|
||||
|
||||
/* NOTE: these values should match the NM_SECRET_AGENT_GET_SECRETS_FLAGS in
|
||||
* the nm-secret-agent.xml introspection file.
|
||||
*/
|
||||
enum {
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE = 0x0,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION = 0x1,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW = 0x2
|
||||
};
|
||||
|
||||
#define NM_TYPE_SECRET_AGENT (nm_secret_agent_get_type ())
|
||||
#define NM_SECRET_AGENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SECRET_AGENT, NMSecretAgent))
|
||||
#define NM_SECRET_AGENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SECRET_AGENT, NMSecretAgentClass))
|
||||
|
|
|
@ -442,7 +442,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager,
|
|||
guint32 tries;
|
||||
GPtrArray *hints = NULL;
|
||||
GError *error = NULL;
|
||||
guint32 flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
guint32 flags = NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION;
|
||||
|
||||
connection = nm_act_request_get_connection (priv->act_req);
|
||||
|
||||
|
@ -468,7 +468,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager,
|
|||
*/
|
||||
tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES));
|
||||
if (tries > 1)
|
||||
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
flags |= NM_ACT_REQUEST_GET_SECRETS_FLAG_REQUEST_NEW;
|
||||
|
||||
priv->secrets_id = nm_act_request_get_secrets (priv->act_req,
|
||||
setting_name,
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "nm-logging.h"
|
||||
#include "nm-manager-auth.h"
|
||||
#include "nm-marshal.h"
|
||||
#include "nm-agent-manager.h"
|
||||
|
||||
static void impl_settings_connection_get_settings (NMSettingsConnection *connection,
|
||||
DBusGMethodInvocation *context);
|
||||
|
@ -66,8 +67,6 @@ enum {
|
|||
enum {
|
||||
UPDATED,
|
||||
REMOVED,
|
||||
GET_SECRETS,
|
||||
CANCEL_SECRETS,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -75,6 +74,9 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
|||
typedef struct {
|
||||
gboolean disposed;
|
||||
|
||||
NMDBusManager *dbus_mgr;
|
||||
NMAgentManager *agent_mgr;
|
||||
|
||||
PolkitAuthority *authority;
|
||||
GSList *pending_auths; /* List of pending authentication requests */
|
||||
NMConnection *secrets;
|
||||
|
@ -340,25 +342,77 @@ supports_secrets (NMSettingsConnection *connection, const char *setting_name)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
agent_secrets_done_cb (NMAgentManager *manager,
|
||||
guint32 call_id,
|
||||
const char *setting_name,
|
||||
GHashTable *secrets,
|
||||
GError *error,
|
||||
gpointer user_data,
|
||||
gpointer other_data2,
|
||||
gpointer other_data3)
|
||||
{
|
||||
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data);
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
NMSettingsConnectionSecretsFunc callback = other_data2;
|
||||
gpointer callback_data = other_data3;
|
||||
GError *local = NULL;
|
||||
GHashTable *hash;
|
||||
|
||||
if (error) {
|
||||
callback (self, call_id, setting_name, error, callback_data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update the connection with the agent's secrets */
|
||||
nm_connection_clear_secrets (NM_CONNECTION (self));
|
||||
if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, &local)) {
|
||||
/* FIXME: if the agent's owner has "modify" permission, then agent
|
||||
* supplied secrets should overwrite existing secrets, and those agent
|
||||
* supplied secrets should get written back out to persistent storage.
|
||||
*/
|
||||
|
||||
hash = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
|
||||
nm_connection_update_secrets (NM_CONNECTION (self), setting_name, hash, &local);
|
||||
g_hash_table_destroy (hash);
|
||||
}
|
||||
|
||||
callback (self, call_id, setting_name, local, callback_data);
|
||||
g_clear_error (&local);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_settings_connection_get_secrets:
|
||||
* @connection: the #NMSettingsConnection
|
||||
* @filter_by_uid: if TRUE, only request secrets from agents registered by the
|
||||
* same UID as @uid.
|
||||
* @uid: when @filter_by_uid is TRUE, only request secrets from agents belonging
|
||||
* to this UID
|
||||
* @setting_name: the setting to return secrets for
|
||||
* @error: an error on return, if an error occured
|
||||
* @flags: flags to modify the secrets request
|
||||
* @hint: the name of a key in @setting_name for which a secret may be required
|
||||
* @callback: the function to call with returned secrets
|
||||
* @callback_data: user data to pass to @callback
|
||||
*
|
||||
* Return secrets in persistent storage, if any. Does not query any Secret
|
||||
* Agents for secrets.
|
||||
* Retrieves secrets from persistent storage and queries any secret agents for
|
||||
* additional secrets.
|
||||
*
|
||||
* Returns: a hash mapping setting names to hash tables, each inner hash
|
||||
* containing string:value mappings of secrets
|
||||
* Returns: a call ID which may be used to cancel the ongoing secrets request
|
||||
**/
|
||||
GHashTable *
|
||||
nm_settings_connection_get_secrets (NMSettingsConnection *connection,
|
||||
guint32
|
||||
nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
||||
gboolean filter_by_uid,
|
||||
gulong uid,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMSettingsConnectionSecretsFunc callback,
|
||||
gpointer callback_data,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection);
|
||||
NMSetting *setting;
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
GHashTable *existing_secrets;
|
||||
guint32 call_id = 0;
|
||||
|
||||
/* Use priv->secrets to work around the fact that nm_connection_clear_secrets()
|
||||
* will clear secrets on this object's settings. priv->secrets should be
|
||||
|
@ -369,20 +423,44 @@ nm_settings_connection_get_secrets (NMSettingsConnection *connection,
|
|||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION,
|
||||
"%s.%d - Internal error; secrets cache invalid.",
|
||||
__FILE__, __LINE__);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: if setting_name is empty, return all secrets */
|
||||
|
||||
setting = nm_connection_get_setting_by_name (priv->secrets, setting_name);
|
||||
if (!setting) {
|
||||
if (!nm_connection_get_setting_by_name (priv->secrets, setting_name)) {
|
||||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_SETTING,
|
||||
"%s.%d - Connection didn't have requested setting '%s'.",
|
||||
__FILE__, __LINE__, setting_name);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
|
||||
existing_secrets = nm_connection_to_hash (priv->secrets, NM_SETTING_HASH_FLAG_ONLY_SECRETS);
|
||||
call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
|
||||
NM_CONNECTION (self),
|
||||
filter_by_uid,
|
||||
uid,
|
||||
existing_secrets,
|
||||
setting_name,
|
||||
flags,
|
||||
hint,
|
||||
agent_secrets_done_cb,
|
||||
self,
|
||||
callback,
|
||||
callback_data);
|
||||
g_hash_table_unref (existing_secrets);
|
||||
|
||||
return call_id;
|
||||
}
|
||||
|
||||
void
|
||||
nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
|
||||
guint32 call_id)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id);
|
||||
}
|
||||
|
||||
/**** User authorization **************************************/
|
||||
|
@ -660,25 +738,10 @@ impl_settings_connection_delete (NMSettingsConnection *self,
|
|||
|
||||
/**************************************************************/
|
||||
|
||||
static gboolean
|
||||
get_secrets_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer data)
|
||||
{
|
||||
guint handler_call_id = g_value_get_uint (handler_return);
|
||||
|
||||
if (handler_call_id > 0)
|
||||
g_value_set_uint (return_accu, handler_call_id);
|
||||
|
||||
/* Abort signal emission if a valid call ID got returned */
|
||||
return handler_call_id ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
dbus_get_agent_secrets_cb (NMSettingsConnection *self,
|
||||
const char *setting_name,
|
||||
guint32 call_id,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
@ -712,36 +775,59 @@ dbus_secrets_auth_cb (NMSettingsConnection *self,
|
|||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
char *sender, *setting_name = user_data;
|
||||
DBusError dbus_error;
|
||||
gulong sender_uid;
|
||||
guint32 call_id = 0;
|
||||
GError *local = NULL;
|
||||
|
||||
if (error) {
|
||||
local = g_error_copy (error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
sender = dbus_g_method_get_sender (context);
|
||||
if (!sender) {
|
||||
local = g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
||||
"Unable to get request D-Bus sender");
|
||||
} else if (!error) {
|
||||
g_signal_emit (self, signals[GET_SECRETS], 0,
|
||||
sender,
|
||||
setting_name,
|
||||
dbus_get_agent_secrets_cb,
|
||||
context,
|
||||
&call_id);
|
||||
if (call_id > 0) {
|
||||
/* track the request and wait for the callback */
|
||||
priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id));
|
||||
} else {
|
||||
local = g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_SECRETS_UNAVAILABLE,
|
||||
"No secrets were available");
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (error || local)
|
||||
/* Get the unix user of the requestor */
|
||||
dbus_error_init (&dbus_error);
|
||||
sender_uid = dbus_bus_get_unix_user (nm_dbus_manager_get_dbus_connection (priv->dbus_mgr),
|
||||
sender,
|
||||
&dbus_error);
|
||||
g_free (sender);
|
||||
|
||||
if (dbus_error_is_set (&dbus_error)) {
|
||||
local = g_error_new (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_PERMISSION_DENIED,
|
||||
"Unable to get sender UID: %s",
|
||||
dbus_error.message);
|
||||
dbus_error_free (&dbus_error);
|
||||
goto done;
|
||||
}
|
||||
|
||||
call_id = nm_settings_connection_get_secrets (self,
|
||||
TRUE,
|
||||
sender_uid,
|
||||
setting_name,
|
||||
0, /* GET_SECRETS_FLAG_NONE */
|
||||
NULL,
|
||||
dbus_get_agent_secrets_cb,
|
||||
context,
|
||||
&local);
|
||||
if (call_id > 0) {
|
||||
/* track the request and wait for the callback */
|
||||
priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id));
|
||||
}
|
||||
|
||||
done:
|
||||
if (local)
|
||||
dbus_g_method_return_error (context, error ? error : local);
|
||||
|
||||
g_free (setting_name);
|
||||
g_free (sender);
|
||||
g_clear_error (&local);
|
||||
}
|
||||
|
||||
|
@ -763,6 +849,8 @@ nm_settings_connection_init (NMSettingsConnection *self)
|
|||
char *dbus_path;
|
||||
GError *error = NULL;
|
||||
|
||||
priv->dbus_mgr = nm_dbus_manager_get ();
|
||||
|
||||
priv->authority = polkit_authority_get_sync (NULL, NULL);
|
||||
if (!priv->authority) {
|
||||
nm_log_warn (LOGD_SETTINGS, "failed to create PolicyKit authority: (%d) %s",
|
||||
|
@ -781,6 +869,8 @@ nm_settings_connection_init (NMSettingsConnection *self)
|
|||
NM_SESSION_MONITOR_CHANGED,
|
||||
G_CALLBACK (session_changed_cb),
|
||||
self);
|
||||
|
||||
priv->agent_mgr = nm_agent_manager_get ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -805,12 +895,14 @@ dispose (GObject *object)
|
|||
|
||||
/* Cancel in-progress secrets requests */
|
||||
for (iter = priv->reqs; iter; iter = g_slist_next (iter))
|
||||
g_signal_emit (self, signals[CANCEL_SECRETS], 0, GPOINTER_TO_UINT (iter->data));
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data));
|
||||
g_slist_free (priv->reqs);
|
||||
|
||||
set_visible (self, FALSE);
|
||||
|
||||
g_object_unref (priv->session_monitor);
|
||||
g_object_unref (priv->agent_mgr);
|
||||
g_object_unref (priv->dbus_mgr);
|
||||
|
||||
out:
|
||||
G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object);
|
||||
|
@ -881,24 +973,6 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class)
|
|||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/* not exported over D-Bus */
|
||||
signals[GET_SECRETS] =
|
||||
g_signal_new (NM_SETTINGS_CONNECTION_GET_SECRETS,
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMSettingsConnectionClass, get_secrets),
|
||||
get_secrets_accumulator, NULL,
|
||||
_nm_marshal_UINT__STRING_STRING_POINTER_POINTER,
|
||||
G_TYPE_UINT, 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
|
||||
signals[CANCEL_SECRETS] =
|
||||
g_signal_new (NM_SETTINGS_CONNECTION_CANCEL_SECRETS,
|
||||
G_TYPE_FROM_CLASS (class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__UINT,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (class),
|
||||
&dbus_glib_nm_settings_connection_object_info);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#define NM_SETTINGS_CONNECTION_H
|
||||
|
||||
#include <nm-connection.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -53,12 +52,6 @@ typedef void (*NMSettingsConnectionDeleteFunc) (NMSettingsConnection *connection
|
|||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
typedef void (*NMSettingsConnectionSecretsUpdatedFunc) (NMSettingsConnection *connection,
|
||||
const char *setting_name,
|
||||
guint32 call_id,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
struct _NMSettingsConnection {
|
||||
NMConnection parent;
|
||||
};
|
||||
|
@ -77,15 +70,6 @@ struct _NMSettingsConnectionClass {
|
|||
|
||||
gboolean (*supports_secrets) (NMSettingsConnection *connection,
|
||||
const char *setting_name);
|
||||
|
||||
/* signals */
|
||||
guint32 (*get_secrets) (NMSettingsConnection *connection,
|
||||
const char *sender, /* dbus bus name of requestor */
|
||||
const char *setting_name,
|
||||
NMSettingsConnectionSecretsUpdatedFunc callback,
|
||||
gpointer callback_data);
|
||||
|
||||
void (*cancel_secrets) (NMSettingsConnection *connection, guint32 call_id);
|
||||
};
|
||||
|
||||
GType nm_settings_connection_get_type (void);
|
||||
|
@ -107,9 +91,24 @@ void nm_settings_connection_delete (NMSettingsConnection *connection,
|
|||
NMSettingsConnectionDeleteFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
GHashTable *nm_settings_connection_get_secrets (NMSettingsConnection *connection,
|
||||
const char *setting_name,
|
||||
GError **error);
|
||||
typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *connection,
|
||||
guint32 call_id,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
guint32 nm_settings_connection_get_secrets (NMSettingsConnection *connection,
|
||||
gboolean filter_by_uid,
|
||||
gulong uid,
|
||||
const char *setting_name,
|
||||
guint32 flags,
|
||||
const char *hint,
|
||||
NMSettingsConnectionSecretsFunc callback,
|
||||
gpointer callback_data,
|
||||
GError **error);
|
||||
|
||||
void nm_settings_connection_cancel_secrets (NMSettingsConnection *connection,
|
||||
guint32 call_id);
|
||||
|
||||
gboolean nm_settings_connection_is_visible (NMSettingsConnection *self);
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "nm-manager-auth.h"
|
||||
#include "nm-session-monitor.h"
|
||||
#include "system-settings/plugins/keyfile/plugin.h"
|
||||
#include "nm-agent-manager.h"
|
||||
|
||||
#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default"
|
||||
|
||||
|
@ -104,6 +105,8 @@ typedef struct {
|
|||
NMDBusManager *dbus_mgr;
|
||||
DBusGConnection *bus;
|
||||
|
||||
NMAgentManager *agent_mgr;
|
||||
|
||||
PolkitAuthority *authority;
|
||||
guint auth_changed_id;
|
||||
char *config_file;
|
||||
|
@ -1383,6 +1386,13 @@ nm_settings_init (NMSettings *self)
|
|||
}
|
||||
|
||||
priv->session_monitor = nm_session_monitor_get ();
|
||||
|
||||
/* Hold a reference to the agent manager so it stays alive; the only
|
||||
* other holders are NMSettingsConnection objects which are often
|
||||
* transient, and we don't want the agent manager to get destroyed and
|
||||
* recreated often.
|
||||
*/
|
||||
priv->agent_mgr = nm_agent_manager_get ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1404,6 +1414,7 @@ dispose (GObject *object)
|
|||
g_object_unref (priv->dbus_mgr);
|
||||
|
||||
g_object_unref (priv->session_monitor);
|
||||
g_object_unref (priv->agent_mgr);
|
||||
|
||||
G_OBJECT_CLASS (nm_settings_parent_class)->dispose (object);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "nm-dns-manager.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-glib-compat.h"
|
||||
#include "settings/nm-settings-connection.h"
|
||||
|
||||
#include "nm-vpn-connection-glue.h"
|
||||
|
||||
|
@ -768,22 +769,22 @@ cancel_get_secrets (NMVPNConnection *self)
|
|||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
if (priv->secrets_id) {
|
||||
nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->secrets_id);
|
||||
priv->secrets_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
vpn_secrets_cb (NMActRequest *req,
|
||||
vpn_secrets_cb (NMSettingsConnection *connection,
|
||||
guint32 call_id,
|
||||
NMConnection *connection,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
g_return_if_fail (req == priv->act_request);
|
||||
g_return_if_fail (NM_CONNECTION (connection) == priv->connection);
|
||||
g_return_if_fail (call_id == priv->secrets_id);
|
||||
|
||||
priv->secrets_id = 0;
|
||||
|
@ -802,6 +803,7 @@ connection_need_secrets_cb (DBusGProxy *proxy,
|
|||
{
|
||||
NMVPNConnection *self = NM_VPN_CONNECTION (user_data);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self);
|
||||
GError *local = NULL;
|
||||
|
||||
if (error) {
|
||||
nm_log_err (LOGD_VPN, "NeedSecrets failed: %s %s",
|
||||
|
@ -817,17 +819,21 @@ connection_need_secrets_cb (DBusGProxy *proxy,
|
|||
return;
|
||||
}
|
||||
|
||||
priv->secrets_id = nm_act_request_get_secrets_vpn (priv->act_request,
|
||||
priv->connection,
|
||||
priv->user_requested,
|
||||
priv->user_uid,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION,
|
||||
NULL,
|
||||
vpn_secrets_cb,
|
||||
self);
|
||||
if (!priv->secrets_id)
|
||||
priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection),
|
||||
priv->user_requested,
|
||||
priv->user_uid,
|
||||
setting_name,
|
||||
NM_ACT_REQUEST_GET_SECRETS_FLAG_ALLOW_INTERACTION,
|
||||
NULL,
|
||||
vpn_secrets_cb,
|
||||
self,
|
||||
&local);
|
||||
if (!priv->secrets_id) {
|
||||
if (local)
|
||||
nm_log_err (LOGD_VPN, "failed to get secrets: (%d) %s", local->code, local->message);
|
||||
nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS);
|
||||
g_clear_error (&local);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue