mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-20 00:21:29 +00:00
settings: refactor call_id type of async functions for NMAgentManager, NMSettingsConnection and NMActRequest
Instead of having the call_id of type guint32, make it an (opaque) pointer type. This has the advantage of strong typing and avoids the possiblity of reusing an invalid integer (or overflow of the call-id counter). OTOH, it has the disadvantage, that after a call_id is disposed, it might be reused for future invocations (because malloc might reuse the memory). In fact, it is always an error to use a call_id that is already completed. This commit also adds assertions to the cancel() calls that the provided call_id is a pending call. Hence, such a bug will be uncovered by assertions (that only might not tigger in certain unlikely cases where a call-id got reused). Note that for NMAgentManager, save_secrets() and delete_secrets() both returned a call_id. But they didn't also provide a callback when the operation completes. So the user trying to cancel such a call, cannot know whether the operation is still in process and he cannot avoid triggering an assertion. Fix that by not returning a call-id for these operations. No caller cared about it anyway. For NMSettingsConnection, also track the internally scheduled requests for so that we can cancel them on dispose.
This commit is contained in:
parent
40eda71dc6
commit
21fd5fa0ab
|
@ -480,7 +480,7 @@ supplicant_interface_release (NMDeviceEthernet *self)
|
|||
|
||||
static void
|
||||
wired_secrets_cb (NMActRequest *req,
|
||||
guint32 call_id,
|
||||
NMActRequestGetSecretsCallId call_id,
|
||||
NMConnection *connection,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
|
|
|
@ -1674,7 +1674,7 @@ cleanup_association_attempt (NMDeviceWifi *self, gboolean disconnect)
|
|||
|
||||
static void
|
||||
wifi_secrets_cb (NMActRequest *req,
|
||||
guint32 call_id,
|
||||
NMActRequestGetSecretsCallId call_id,
|
||||
NMConnection *connection,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
|
|
|
@ -73,7 +73,7 @@ typedef struct {
|
|||
|
||||
NMActRequest *act_request;
|
||||
guint32 secrets_tries;
|
||||
guint32 secrets_id;
|
||||
NMActRequestGetSecretsCallId secrets_id;
|
||||
|
||||
guint32 mm_ip_timeout;
|
||||
|
||||
|
@ -724,13 +724,13 @@ cancel_get_secrets (NMModem *self)
|
|||
|
||||
if (priv->secrets_id) {
|
||||
nm_act_request_cancel_secrets (priv->act_request, priv->secrets_id);
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
modem_secrets_cb (NMActRequest *req,
|
||||
guint32 call_id,
|
||||
NMActRequestGetSecretsCallId call_id,
|
||||
NMConnection *connection,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
|
@ -740,7 +740,7 @@ modem_secrets_cb (NMActRequest *req,
|
|||
|
||||
g_return_if_fail (call_id == priv->secrets_id);
|
||||
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
|
||||
if (error)
|
||||
nm_log_warn (LOGD_MB, "(%s): %s", nm_modem_get_uid (self), error->message);
|
||||
|
|
|
@ -75,16 +75,18 @@ nm_act_request_get_connection (NMActRequest *req)
|
|||
|
||||
/*******************************************************************/
|
||||
|
||||
typedef struct {
|
||||
struct _NMActRequestGetSecretsCallId {
|
||||
NMActRequest *self;
|
||||
guint32 call_id;
|
||||
NMSettingsConnectionCallId call_id_s;
|
||||
NMActRequestSecretsFunc callback;
|
||||
gpointer callback_data;
|
||||
} GetSecretsInfo;
|
||||
};
|
||||
|
||||
typedef struct _NMActRequestGetSecretsCallId GetSecretsInfo;
|
||||
|
||||
static void
|
||||
get_secrets_cb (NMSettingsConnection *connection,
|
||||
guint32 call_id,
|
||||
NMSettingsConnectionCallId call_id_s,
|
||||
const char *agent_username,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
|
@ -93,14 +95,14 @@ get_secrets_cb (NMSettingsConnection *connection,
|
|||
GetSecretsInfo *info = user_data;
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (info->self);
|
||||
|
||||
g_return_if_fail (info->call_id == call_id);
|
||||
g_return_if_fail (info->call_id_s == call_id_s);
|
||||
priv->secrets_calls = g_slist_remove (priv->secrets_calls, info);
|
||||
|
||||
info->callback (info->self, call_id, NM_CONNECTION (connection), error, info->callback_data);
|
||||
info->callback (info->self, info, NM_CONNECTION (connection), error, info->callback_data);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
guint32
|
||||
NMActRequestGetSecretsCallId
|
||||
nm_act_request_get_secrets (NMActRequest *self,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
|
@ -110,7 +112,7 @@ nm_act_request_get_secrets (NMActRequest *self,
|
|||
{
|
||||
NMActRequestPrivate *priv;
|
||||
GetSecretsInfo *info;
|
||||
guint32 call_id;
|
||||
NMSettingsConnectionCallId call_id_s;
|
||||
NMConnection *connection;
|
||||
const char *hints[2] = { hint, NULL };
|
||||
|
||||
|
@ -128,25 +130,25 @@ nm_act_request_get_secrets (NMActRequest *self,
|
|||
flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED;
|
||||
|
||||
connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
|
||||
call_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection),
|
||||
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
|
||||
setting_name,
|
||||
flags,
|
||||
hints,
|
||||
get_secrets_cb,
|
||||
info,
|
||||
NULL);
|
||||
if (call_id > 0) {
|
||||
info->call_id = call_id;
|
||||
call_id_s = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (connection),
|
||||
nm_active_connection_get_subject (NM_ACTIVE_CONNECTION (self)),
|
||||
setting_name,
|
||||
flags,
|
||||
hints,
|
||||
get_secrets_cb,
|
||||
info,
|
||||
NULL);
|
||||
if (call_id_s) {
|
||||
info->call_id_s = call_id_s;
|
||||
priv->secrets_calls = g_slist_append (priv->secrets_calls, info);
|
||||
} else
|
||||
g_free (info);
|
||||
|
||||
return call_id;
|
||||
return info;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
|
||||
nm_act_request_cancel_secrets (NMActRequest *self, NMActRequestGetSecretsCallId call_id)
|
||||
{
|
||||
NMActRequestPrivate *priv;
|
||||
NMConnection *connection;
|
||||
|
@ -154,24 +156,25 @@ nm_act_request_cancel_secrets (NMActRequest *self, guint32 call_id)
|
|||
|
||||
g_return_if_fail (self);
|
||||
g_return_if_fail (NM_IS_ACT_REQUEST (self));
|
||||
g_return_if_fail (call_id > 0);
|
||||
g_return_if_fail (call_id);
|
||||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
|
||||
connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
|
||||
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) {
|
||||
if (info == 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 (connection), call_id);
|
||||
connection = nm_active_connection_get_connection (NM_ACTIVE_CONNECTION (self));
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id_s);
|
||||
g_free (info);
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
@ -444,7 +447,7 @@ dispose (GObject *object)
|
|||
for (iter = priv->secrets_calls; connection && iter; iter = g_slist_next (iter)) {
|
||||
GetSecretsInfo *info = iter->data;
|
||||
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id);
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (connection), info->call_id_s);
|
||||
g_free (info);
|
||||
}
|
||||
g_slist_free (priv->secrets_calls);
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
#define NM_IS_ACT_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_ACT_REQUEST))
|
||||
#define NM_ACT_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACT_REQUEST, NMActRequestClass))
|
||||
|
||||
struct _NMActRequestGetSecretsCallId;
|
||||
typedef struct _NMActRequestGetSecretsCallId *NMActRequestGetSecretsCallId;
|
||||
|
||||
struct _NMActRequest {
|
||||
NMActiveConnection parent;
|
||||
};
|
||||
|
@ -62,19 +65,19 @@ void nm_act_request_add_share_rule (NMActRequest *req,
|
|||
/* Secrets handling */
|
||||
|
||||
typedef void (*NMActRequestSecretsFunc) (NMActRequest *req,
|
||||
guint32 call_id,
|
||||
NMActRequestGetSecretsCallId call_id,
|
||||
NMConnection *connection,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
guint32 nm_act_request_get_secrets (NMActRequest *req,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data);
|
||||
NMActRequestGetSecretsCallId nm_act_request_get_secrets (NMActRequest *req,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
const char *hint,
|
||||
NMActRequestSecretsFunc callback,
|
||||
gpointer callback_data);
|
||||
|
||||
void nm_act_request_cancel_secrets (NMActRequest *req, guint32 call_id);
|
||||
void nm_act_request_cancel_secrets (NMActRequest *req, NMActRequestGetSecretsCallId call_id);
|
||||
|
||||
#endif /* __NETWORKMANAGER_ACTIVATION_REQUEST_H__ */
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ typedef struct {
|
|||
|
||||
NMActRequest *act_req;
|
||||
GDBusMethodInvocation *pending_secrets_context;
|
||||
guint32 secrets_id;
|
||||
NMActRequestGetSecretsCallId secrets_id;
|
||||
const char *secrets_setting_name;
|
||||
|
||||
guint32 ppp_watch_id;
|
||||
|
@ -243,7 +243,7 @@ cancel_get_secrets (NMPPPManager *self)
|
|||
|
||||
if (priv->secrets_id) {
|
||||
nm_act_request_cancel_secrets (priv->act_req, priv->secrets_id);
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
}
|
||||
priv->secrets_setting_name = NULL;
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ extract_details_from_connection (NMConnection *connection,
|
|||
|
||||
static void
|
||||
ppp_secrets_cb (NMActRequest *req,
|
||||
guint32 call_id,
|
||||
NMActRequestGetSecretsCallId call_id,
|
||||
NMConnection *connection,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
|
@ -348,7 +348,7 @@ ppp_secrets_cb (NMActRequest *req,
|
|||
|
||||
out:
|
||||
priv->pending_secrets_context = NULL;
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
priv->secrets_setting_name = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ enum {
|
|||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
|
||||
typedef struct _Request Request;
|
||||
typedef struct _NMAgentManagerCallId Request;
|
||||
|
||||
static void request_add_agent (Request *req, NMSecretAgent *agent);
|
||||
|
||||
|
@ -160,7 +160,7 @@ remove_agent (NMAgentManager *self, const char *owner)
|
|||
|
||||
/* Remove this agent from any in-progress secrets requests */
|
||||
g_hash_table_iter_init (&iter, priv->requests);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &data))
|
||||
while (g_hash_table_iter_next (&iter, &data, NULL))
|
||||
request_remove_agent ((Request *) data, agent, &pending_reqs);
|
||||
|
||||
/* We cannot call request_next_agent() from from within hash iterating loop,
|
||||
|
@ -290,7 +290,7 @@ agent_register_permissions_done (NMAuthChain *chain,
|
|||
|
||||
/* Add this agent to any in-progress secrets requests */
|
||||
g_hash_table_iter_init (&iter, priv->requests);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &req))
|
||||
while (g_hash_table_iter_next (&iter, (gpointer) &req, NULL))
|
||||
request_add_agent (req, agent);
|
||||
}
|
||||
|
||||
|
@ -435,12 +435,11 @@ done:
|
|||
|
||||
/*************************************************************/
|
||||
|
||||
struct _Request {
|
||||
struct _NMAgentManagerCallId {
|
||||
NMAgentManager *self;
|
||||
|
||||
RequestType request_type;
|
||||
|
||||
guint32 reqid;
|
||||
char *detail;
|
||||
|
||||
NMAuthSubject *subject;
|
||||
|
@ -485,8 +484,6 @@ struct _Request {
|
|||
};
|
||||
};
|
||||
|
||||
static guint32 next_req_id = 1;
|
||||
|
||||
static Request *
|
||||
request_new (NMAgentManager *self,
|
||||
RequestType request_type,
|
||||
|
@ -498,7 +495,6 @@ request_new (NMAgentManager *self,
|
|||
req = g_slice_new0 (Request);
|
||||
req->self = g_object_ref (self);
|
||||
req->request_type = request_type;
|
||||
req->reqid = next_req_id++;
|
||||
req->detail = g_strdup (detail);
|
||||
req->subject = g_object_ref (subject);
|
||||
return req;
|
||||
|
@ -569,7 +565,7 @@ req_complete (Request *req,
|
|||
switch (req->request_type) {
|
||||
case REQUEST_TYPE_CON_GET:
|
||||
req->con.get.callback (self,
|
||||
req->reqid,
|
||||
req,
|
||||
agent_dbus_owner,
|
||||
agent_username,
|
||||
req->con.current_has_modify,
|
||||
|
@ -589,7 +585,7 @@ req_complete (Request *req,
|
|||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
g_hash_table_remove (priv->requests, GUINT_TO_POINTER (req->reqid));
|
||||
g_hash_table_remove (priv->requests, req);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1137,7 +1133,7 @@ _con_get_try_complete_early (Request *req)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
guint32
|
||||
NMAgentManagerCallId
|
||||
nm_agent_manager_get_secrets (NMAgentManager *self,
|
||||
NMConnection *connection,
|
||||
NMAuthSubject *subject,
|
||||
|
@ -1184,24 +1180,26 @@ nm_agent_manager_get_secrets (NMAgentManager *self,
|
|||
req->con.get.other_data2 = other_data2;
|
||||
req->con.get.other_data3 = other_data3;
|
||||
|
||||
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
|
||||
g_hash_table_add (priv->requests, req);
|
||||
|
||||
/* Kick off the request */
|
||||
if (!(req->con.get.flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ONLY_SYSTEM))
|
||||
request_add_agents (self, req);
|
||||
req->idle_id = g_idle_add (request_start, req);
|
||||
return req->reqid;
|
||||
return req;
|
||||
}
|
||||
|
||||
void
|
||||
nm_agent_manager_cancel_secrets (NMAgentManager *self,
|
||||
guint32 request_id)
|
||||
NMAgentManagerCallId request_id)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (request_id > 0);
|
||||
g_return_if_fail (request_id);
|
||||
g_return_if_fail (request_id->request_type == REQUEST_TYPE_CON_GET);
|
||||
|
||||
g_hash_table_remove (NM_AGENT_MANAGER_GET_PRIVATE (self)->requests,
|
||||
GUINT_TO_POINTER (request_id));
|
||||
if (!g_hash_table_remove (NM_AGENT_MANAGER_GET_PRIVATE (self)->requests,
|
||||
request_id))
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
@ -1260,7 +1258,7 @@ _con_save_request_start (Request *req)
|
|||
}
|
||||
}
|
||||
|
||||
guint32
|
||||
void
|
||||
nm_agent_manager_save_secrets (NMAgentManager *self,
|
||||
NMConnection *connection,
|
||||
NMAuthSubject *subject)
|
||||
|
@ -1268,8 +1266,8 @@ nm_agent_manager_save_secrets (NMAgentManager *self,
|
|||
NMAgentManagerPrivate *priv = NM_AGENT_MANAGER_GET_PRIVATE (self);
|
||||
Request *req;
|
||||
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), 0);
|
||||
g_return_if_fail (self);
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
|
||||
nm_log_dbg (LOGD_SETTINGS,
|
||||
"Saving secrets for connection %s (%s)",
|
||||
|
@ -1281,12 +1279,11 @@ nm_agent_manager_save_secrets (NMAgentManager *self,
|
|||
nm_connection_get_id (connection),
|
||||
subject);
|
||||
req->con.connection = g_object_ref (connection);
|
||||
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
|
||||
g_hash_table_add (priv->requests, req);
|
||||
|
||||
/* Kick off the request */
|
||||
request_add_agents (self, req);
|
||||
req->idle_id = g_idle_add (request_start, req);
|
||||
return req->reqid;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
@ -1342,7 +1339,7 @@ _con_del_request_start (Request *req)
|
|||
}
|
||||
}
|
||||
|
||||
guint32
|
||||
void
|
||||
nm_agent_manager_delete_secrets (NMAgentManager *self,
|
||||
NMConnection *connection)
|
||||
{
|
||||
|
@ -1350,8 +1347,8 @@ nm_agent_manager_delete_secrets (NMAgentManager *self,
|
|||
NMAuthSubject *subject;
|
||||
Request *req;
|
||||
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), 0);
|
||||
g_return_if_fail (self != NULL);
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
|
||||
nm_log_dbg (LOGD_SETTINGS,
|
||||
"Deleting secrets for connection %s (%s)",
|
||||
|
@ -1365,12 +1362,11 @@ nm_agent_manager_delete_secrets (NMAgentManager *self,
|
|||
subject);
|
||||
req->con.connection = g_object_ref (connection);
|
||||
g_object_unref (subject);
|
||||
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (req->reqid), req);
|
||||
g_hash_table_add (priv->requests, req);
|
||||
|
||||
/* Kick off the request */
|
||||
request_add_agents (self, req);
|
||||
req->idle_id = g_idle_add (request_start, req);
|
||||
return req->reqid;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
@ -1493,8 +1489,8 @@ nm_agent_manager_init (NMAgentManager *self)
|
|||
priv->agents = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
|
||||
priv->requests = g_hash_table_new_full (g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) request_free);
|
||||
(GDestroyNotify) request_free,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
#define NM_IS_AGENT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_AGENT_MANAGER))
|
||||
#define NM_AGENT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_AGENT_MANAGER, NMAgentManagerClass))
|
||||
|
||||
struct _NMAgentManagerCallId;
|
||||
typedef struct _NMAgentManagerCallId *NMAgentManagerCallId;
|
||||
|
||||
struct _NMAgentManager {
|
||||
NMExportedObject parent;
|
||||
};
|
||||
|
@ -50,7 +53,7 @@ NMAgentManager *nm_agent_manager_get (void);
|
|||
|
||||
/* If no agent fulfilled the secrets request, agent_dbus_owner will be NULL */
|
||||
typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
|
||||
guint32 call_id,
|
||||
NMAgentManagerCallId call_id,
|
||||
const char *agent_dbus_owner,
|
||||
const char *agent_uname,
|
||||
gboolean agent_has_modify,
|
||||
|
@ -62,27 +65,27 @@ typedef void (*NMAgentSecretsResultFunc) (NMAgentManager *manager,
|
|||
gpointer other_data2,
|
||||
gpointer other_data3);
|
||||
|
||||
guint32 nm_agent_manager_get_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection,
|
||||
NMAuthSubject *subject,
|
||||
GVariant *existing_secrets,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
const char **hints,
|
||||
NMAgentSecretsResultFunc callback,
|
||||
gpointer callback_data,
|
||||
gpointer other_data2,
|
||||
gpointer other_data3);
|
||||
NMAgentManagerCallId nm_agent_manager_get_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection,
|
||||
NMAuthSubject *subject,
|
||||
GVariant *existing_secrets,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
const char **hints,
|
||||
NMAgentSecretsResultFunc callback,
|
||||
gpointer callback_data,
|
||||
gpointer other_data2,
|
||||
gpointer other_data3);
|
||||
|
||||
void nm_agent_manager_cancel_secrets (NMAgentManager *manager,
|
||||
guint32 request_id);
|
||||
NMAgentManagerCallId request_id);
|
||||
|
||||
guint32 nm_agent_manager_save_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection,
|
||||
NMAuthSubject *subject);
|
||||
void nm_agent_manager_save_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection,
|
||||
NMAuthSubject *subject);
|
||||
|
||||
guint32 nm_agent_manager_delete_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection);
|
||||
void nm_agent_manager_delete_secrets (NMAgentManager *manager,
|
||||
NMConnection *connection);
|
||||
|
||||
NMSecretAgent *nm_agent_manager_get_agent_by_user (NMAgentManager *manager,
|
||||
const char *username);
|
||||
|
|
|
@ -72,6 +72,18 @@ G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_E
|
|||
NM_TYPE_SETTINGS_CONNECTION, \
|
||||
NMSettingsConnectionPrivate))
|
||||
|
||||
static inline NMAgentManagerCallId
|
||||
NM_AGENT_MANAGER_CALL_ID (NMSettingsConnectionCallId call_id)
|
||||
{
|
||||
return (NMAgentManagerCallId) call_id;
|
||||
}
|
||||
|
||||
static inline NMSettingsConnectionCallId
|
||||
NM_SETTINGS_CONNECTION_CALL_ID (NMAgentManagerCallId call_id_a)
|
||||
{
|
||||
return (NMSettingsConnectionCallId) call_id_a;
|
||||
}
|
||||
|
||||
enum {
|
||||
PROP_0 = 0,
|
||||
PROP_VISIBLE,
|
||||
|
@ -103,7 +115,9 @@ typedef struct {
|
|||
|
||||
GSList *pending_auths; /* List of pending authentication requests */
|
||||
gboolean visible; /* Is this connection is visible by some session? */
|
||||
GSList *reqs; /* in-progress secrets requests */
|
||||
|
||||
GSList *reqs_int; /* in-progress internal secrets requests */
|
||||
GSList *reqs_ext; /* in-progress external secrets requests (D-Bus) */
|
||||
|
||||
/* Caches secrets from on-disk connections; were they not cached any
|
||||
* call to nm_connection_clear_secrets() wipes them out and we'd have
|
||||
|
@ -794,7 +808,7 @@ new_secrets_commit_cb (NMSettingsConnection *self,
|
|||
|
||||
static void
|
||||
agent_secrets_done_cb (NMAgentManager *manager,
|
||||
guint32 call_id,
|
||||
NMAgentManagerCallId call_id_a,
|
||||
const char *agent_dbus_owner,
|
||||
const char *agent_username,
|
||||
gboolean agent_has_modify,
|
||||
|
@ -806,6 +820,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
gpointer other_data2,
|
||||
gpointer other_data3)
|
||||
{
|
||||
NMSettingsConnectionCallId call_id = NM_SETTINGS_CONNECTION_CALL_ID (call_id_a);
|
||||
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (user_data);
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
NMSettingsConnectionSecretsFunc callback = other_data2;
|
||||
|
@ -815,8 +830,10 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
gboolean agent_had_system = FALSE;
|
||||
ForEachSecretFlags cmp_flags = { NM_SETTING_SECRET_FLAG_NONE, NM_SETTING_SECRET_FLAG_NONE };
|
||||
|
||||
priv->reqs_int = g_slist_remove (priv->reqs_int, call_id_a);
|
||||
|
||||
if (error) {
|
||||
_LOGD ("(%s:%u) secrets request error: (%d) %s",
|
||||
_LOGD ("(%s:%p) secrets request error: (%d) %s",
|
||||
setting_name,
|
||||
call_id,
|
||||
error->code,
|
||||
|
@ -837,7 +854,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
|
||||
g_assert (secrets);
|
||||
if (agent_dbus_owner) {
|
||||
_LOGD ("(%s:%u) secrets returned from agent %s",
|
||||
_LOGD ("(%s:%p) secrets returned from agent %s",
|
||||
setting_name,
|
||||
call_id,
|
||||
agent_dbus_owner);
|
||||
|
@ -854,7 +871,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
/* No user interaction was allowed when requesting secrets; the
|
||||
* agent is being bad. Remove system-owned secrets.
|
||||
*/
|
||||
_LOGD ("(%s:%u) interaction forbidden but agent %s returned system secrets",
|
||||
_LOGD ("(%s:%p) interaction forbidden but agent %s returned system secrets",
|
||||
setting_name,
|
||||
call_id,
|
||||
agent_dbus_owner);
|
||||
|
@ -864,7 +881,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
/* Agent didn't successfully authenticate; clear system-owned secrets
|
||||
* from the secrets the agent returned.
|
||||
*/
|
||||
_LOGD ("(%s:%u) agent failed to authenticate but provided system secrets",
|
||||
_LOGD ("(%s:%p) agent failed to authenticate but provided system secrets",
|
||||
setting_name,
|
||||
call_id);
|
||||
|
||||
|
@ -872,12 +889,12 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_LOGD ("(%s:%u) existing secrets returned",
|
||||
_LOGD ("(%s:%p) existing secrets returned",
|
||||
setting_name,
|
||||
call_id);
|
||||
}
|
||||
|
||||
_LOGD ("(%s:%u) secrets request completed",
|
||||
_LOGD ("(%s:%p) secrets request completed",
|
||||
setting_name,
|
||||
call_id);
|
||||
|
||||
|
@ -914,19 +931,19 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
* nothing has changed, since agent-owned secrets don't get saved here.
|
||||
*/
|
||||
if (agent_had_system) {
|
||||
_LOGD ("(%s:%u) saving new secrets to backing storage",
|
||||
_LOGD ("(%s:%p) saving new secrets to backing storage",
|
||||
setting_name,
|
||||
call_id);
|
||||
|
||||
nm_settings_connection_commit_changes (self, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, new_secrets_commit_cb, NULL);
|
||||
} else {
|
||||
_LOGD ("(%s:%u) new agent secrets processed",
|
||||
_LOGD ("(%s:%p) new agent secrets processed",
|
||||
setting_name,
|
||||
call_id);
|
||||
}
|
||||
|
||||
} else {
|
||||
_LOGD ("(%s:%u) failed to update with agent secrets: (%d) %s",
|
||||
_LOGD ("(%s:%p) failed to update with agent secrets: (%d) %s",
|
||||
setting_name,
|
||||
call_id,
|
||||
local ? local->code : -1,
|
||||
|
@ -934,7 +951,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
}
|
||||
g_variant_unref (filtered_secrets);
|
||||
} else {
|
||||
_LOGD ("(%s:%u) failed to update with existing secrets: (%d) %s",
|
||||
_LOGD ("(%s:%p) failed to update with existing secrets: (%d) %s",
|
||||
setting_name,
|
||||
call_id,
|
||||
local ? local->code : -1,
|
||||
|
@ -963,7 +980,7 @@ agent_secrets_done_cb (NMAgentManager *manager,
|
|||
*
|
||||
* Returns: a call ID which may be used to cancel the ongoing secrets request
|
||||
**/
|
||||
guint32
|
||||
NMSettingsConnectionCallId
|
||||
nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
||||
NMAuthSubject *subject,
|
||||
const char *setting_name,
|
||||
|
@ -975,7 +992,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
|||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
GVariant *existing_secrets;
|
||||
guint32 call_id = 0;
|
||||
NMAgentManagerCallId call_id_a;
|
||||
gs_free char *joined_hints = NULL;
|
||||
|
||||
/* Use priv->secrets to work around the fact that nm_connection_clear_secrets()
|
||||
|
@ -985,7 +1002,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
|||
g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED,
|
||||
"%s.%d - Internal error; secrets cache invalid.",
|
||||
__FILE__, __LINE__);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Make sure the request actually requests something we can return */
|
||||
|
@ -993,46 +1010,50 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
|||
g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND,
|
||||
"%s.%d - Connection didn't have requested setting '%s'.",
|
||||
__FILE__, __LINE__, setting_name);
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
existing_secrets = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS);
|
||||
if (existing_secrets)
|
||||
g_variant_ref_sink (existing_secrets);
|
||||
call_id = nm_agent_manager_get_secrets (priv->agent_mgr,
|
||||
NM_CONNECTION (self),
|
||||
subject,
|
||||
existing_secrets,
|
||||
setting_name,
|
||||
flags,
|
||||
hints,
|
||||
agent_secrets_done_cb,
|
||||
self,
|
||||
callback,
|
||||
callback_data);
|
||||
call_id_a = nm_agent_manager_get_secrets (priv->agent_mgr,
|
||||
NM_CONNECTION (self),
|
||||
subject,
|
||||
existing_secrets,
|
||||
setting_name,
|
||||
flags,
|
||||
hints,
|
||||
agent_secrets_done_cb,
|
||||
self,
|
||||
callback,
|
||||
callback_data);
|
||||
if (existing_secrets)
|
||||
g_variant_unref (existing_secrets);
|
||||
|
||||
_LOGD ("(%s:%u) secrets requested flags 0x%X hints '%s'",
|
||||
_LOGD ("(%s:%p) secrets requested flags 0x%X hints '%s'",
|
||||
setting_name,
|
||||
call_id,
|
||||
call_id_a,
|
||||
flags,
|
||||
(hints && hints[0]) ? (joined_hints = g_strjoinv (",", (char **) hints)) : "(none)");
|
||||
|
||||
return call_id;
|
||||
priv->reqs_int = g_slist_append (priv->reqs_int, call_id_a);
|
||||
|
||||
return NM_SETTINGS_CONNECTION_CALL_ID (call_id_a);
|
||||
}
|
||||
|
||||
void
|
||||
nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
|
||||
guint32 call_id)
|
||||
NMSettingsConnectionCallId call_id)
|
||||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
_LOGD ("(%u) secrets canceled",
|
||||
call_id);
|
||||
if (!g_slist_find (priv->reqs_int, call_id))
|
||||
g_return_if_reached ();
|
||||
|
||||
priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr, call_id);
|
||||
_LOGD ("(%p) secrets canceled", call_id);
|
||||
|
||||
priv->reqs_int = g_slist_remove (priv->reqs_int, call_id);
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr, NM_AGENT_MANAGER_CALL_ID (call_id));
|
||||
}
|
||||
|
||||
/**** User authorization **************************************/
|
||||
|
@ -1606,7 +1627,7 @@ impl_settings_connection_delete (NMSettingsConnection *self,
|
|||
{
|
||||
NMAuthSubject *subject = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
|
||||
if (!check_writable (NM_CONNECTION (self), &error))
|
||||
goto out_err;
|
||||
|
||||
|
@ -1627,7 +1648,7 @@ out_err:
|
|||
|
||||
static void
|
||||
dbus_get_agent_secrets_cb (NMSettingsConnection *self,
|
||||
guint32 call_id,
|
||||
NMSettingsConnectionCallId call_id,
|
||||
const char *agent_username,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
|
@ -1637,7 +1658,7 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
|
|||
GDBusMethodInvocation *context = user_data;
|
||||
GVariant *dict;
|
||||
|
||||
priv->reqs = g_slist_remove (priv->reqs, GUINT_TO_POINTER (call_id));
|
||||
priv->reqs_ext = g_slist_remove (priv->reqs_ext, call_id);
|
||||
|
||||
if (error)
|
||||
g_dbus_method_invocation_return_gerror (context, error);
|
||||
|
@ -1655,7 +1676,7 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self,
|
|||
}
|
||||
|
||||
static void
|
||||
dbus_get_secrets_auth_cb (NMSettingsConnection *self,
|
||||
dbus_get_secrets_auth_cb (NMSettingsConnection *self,
|
||||
GDBusMethodInvocation *context,
|
||||
NMAuthSubject *subject,
|
||||
GError *error,
|
||||
|
@ -1663,22 +1684,22 @@ dbus_get_secrets_auth_cb (NMSettingsConnection *self,
|
|||
{
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
char *setting_name = user_data;
|
||||
guint32 call_id = 0;
|
||||
NMSettingsConnectionCallId call_id;
|
||||
GError *local = NULL;
|
||||
|
||||
if (!error) {
|
||||
call_id = nm_settings_connection_get_secrets (self,
|
||||
subject,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED
|
||||
| NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS,
|
||||
NULL,
|
||||
dbus_get_agent_secrets_cb,
|
||||
context,
|
||||
&local);
|
||||
if (call_id > 0) {
|
||||
subject,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_USER_REQUESTED
|
||||
| NM_SECRET_AGENT_GET_SECRETS_FLAG_NO_ERRORS,
|
||||
NULL,
|
||||
dbus_get_agent_secrets_cb,
|
||||
context,
|
||||
&local);
|
||||
if (call_id) {
|
||||
/* track the request and wait for the callback */
|
||||
priv->reqs = g_slist_append (priv->reqs, GUINT_TO_POINTER (call_id));
|
||||
priv->reqs_ext = g_slist_append (priv->reqs_ext, call_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2334,15 +2355,31 @@ constructed (GObject *object)
|
|||
G_OBJECT_CLASS (nm_settings_connection_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
_cancel_all (NMAgentManager *agent_mgr, GSList **preqs)
|
||||
{
|
||||
while (*preqs) {
|
||||
NMAgentManagerCallId call_id_a = (*preqs)->data;
|
||||
|
||||
*preqs = g_slist_delete_link (*preqs, *preqs);
|
||||
nm_agent_manager_cancel_secrets (agent_mgr, call_id_a);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dispose (GObject *object)
|
||||
{
|
||||
NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object);
|
||||
NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
|
||||
_LOGD ("disposing");
|
||||
|
||||
/* Cancel in-progress secrets requests */
|
||||
if (priv->agent_mgr) {
|
||||
_cancel_all (priv->agent_mgr, &priv->reqs_ext);
|
||||
_cancel_all (priv->agent_mgr, &priv->reqs_int);
|
||||
}
|
||||
|
||||
if (priv->updated_idle_id) {
|
||||
g_source_remove (priv->updated_idle_id);
|
||||
priv->updated_idle_id = 0;
|
||||
|
@ -2363,12 +2400,6 @@ dispose (GObject *object)
|
|||
g_slist_free_full (priv->pending_auths, (GDestroyNotify) nm_auth_chain_unref);
|
||||
priv->pending_auths = NULL;
|
||||
|
||||
/* Cancel in-progress secrets requests */
|
||||
for (iter = priv->reqs; iter; iter = g_slist_next (iter))
|
||||
nm_agent_manager_cancel_secrets (priv->agent_mgr, GPOINTER_TO_UINT (iter->data));
|
||||
g_slist_free (priv->reqs);
|
||||
priv->reqs = NULL;
|
||||
|
||||
g_clear_pointer (&priv->seen_bssids, (GDestroyNotify) g_hash_table_destroy);
|
||||
|
||||
set_visible (self, FALSE);
|
||||
|
|
|
@ -85,6 +85,9 @@ typedef enum { /*< skip >*/
|
|||
NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED = (1LL << 1),
|
||||
} NMSettingsConnectionCommitReason;
|
||||
|
||||
struct _NMSettingsConnectionCallId;
|
||||
typedef struct _NMSettingsConnectionCallId *NMSettingsConnectionCallId;
|
||||
|
||||
typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass;
|
||||
|
||||
typedef void (*NMSettingsConnectionCommitFunc) (NMSettingsConnection *self,
|
||||
|
@ -144,23 +147,23 @@ void nm_settings_connection_delete (NMSettingsConnection *self,
|
|||
gpointer user_data);
|
||||
|
||||
typedef void (*NMSettingsConnectionSecretsFunc) (NMSettingsConnection *self,
|
||||
guint32 call_id,
|
||||
NMSettingsConnectionCallId call_id,
|
||||
const char *agent_username,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
guint32 nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
||||
NMAuthSubject *subject,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
const char **hints,
|
||||
NMSettingsConnectionSecretsFunc callback,
|
||||
gpointer callback_data,
|
||||
GError **error);
|
||||
NMSettingsConnectionCallId nm_settings_connection_get_secrets (NMSettingsConnection *self,
|
||||
NMAuthSubject *subject,
|
||||
const char *setting_name,
|
||||
NMSecretAgentGetSecretsFlags flags,
|
||||
const char **hints,
|
||||
NMSettingsConnectionSecretsFunc callback,
|
||||
gpointer callback_data,
|
||||
GError **error);
|
||||
|
||||
void nm_settings_connection_cancel_secrets (NMSettingsConnection *self,
|
||||
guint32 call_id);
|
||||
NMSettingsConnectionCallId call_id);
|
||||
|
||||
gboolean nm_settings_connection_is_visible (NMSettingsConnection *self);
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ typedef struct {
|
|||
gboolean service_can_persist;
|
||||
gboolean connection_can_persist;
|
||||
|
||||
guint32 secrets_id;
|
||||
NMSettingsConnectionCallId secrets_id;
|
||||
SecretsReq secrets_idx;
|
||||
char *username;
|
||||
|
||||
|
@ -334,7 +334,7 @@ _set_vpn_state (NMVpnConnection *connection,
|
|||
/* Clear any in-progress secrets request */
|
||||
if (priv->secrets_id) {
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), priv->secrets_id);
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
}
|
||||
|
||||
dispatcher_cleanup (connection);
|
||||
|
@ -2009,7 +2009,7 @@ plugin_new_secrets_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_da
|
|||
|
||||
static void
|
||||
get_secrets_cb (NMSettingsConnection *connection,
|
||||
guint32 call_id,
|
||||
NMSettingsConnectionCallId call_id,
|
||||
const char *agent_username,
|
||||
const char *setting_name,
|
||||
GError *error,
|
||||
|
@ -2022,7 +2022,7 @@ get_secrets_cb (NMSettingsConnection *connection,
|
|||
g_return_if_fail (NM_CONNECTION (connection) == priv->connection);
|
||||
g_return_if_fail (call_id == priv->secrets_id);
|
||||
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
|
||||
if (error && priv->secrets_idx >= SECRETS_REQ_NEW) {
|
||||
nm_log_err (LOGD_VPN, "Failed to request VPN secrets #%d: (%d) %s",
|
||||
|
@ -2227,7 +2227,7 @@ dispose (GObject *object)
|
|||
if (priv->secrets_id) {
|
||||
nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection),
|
||||
priv->secrets_id);
|
||||
priv->secrets_id = 0;
|
||||
priv->secrets_id = NULL;
|
||||
}
|
||||
|
||||
if (priv->cancellable) {
|
||||
|
|
Loading…
Reference in a new issue