mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 15:20:11 +01:00
cli: Process secret agent request for a connection only if we know its path
If we're activating the device without knowing the connection in advance, defer servicing the requests for the secrets until we set the path. [lkundrak@fedora20-2 ~]$ nmcli --ask c ifname wlan0 (process:18405): libnm-CRITICAL **: nm_object_get_path: assertion 'NM_IS_OBJECT (object)' failed Error: Connection activation failed: The device has no connections available. [lkundrak@fedora20-2 ~]$
This commit is contained in:
parent
d4240ad04c
commit
991df80408
5 changed files with 103 additions and 21 deletions
|
|
@ -142,11 +142,12 @@ static NMCResultCode
|
|||
do_agent_secret (NmCli *nmc, int argc, char **argv)
|
||||
{
|
||||
/* Create secret agent */
|
||||
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-agent", NULL);
|
||||
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-agent");
|
||||
if (nmc->secret_agent) {
|
||||
/* We keep running */
|
||||
nmc->should_wait = TRUE;
|
||||
|
||||
nm_secret_agent_simple_enable (nmc->secret_agent);
|
||||
g_signal_connect (nmc->secret_agent, "request-secrets", G_CALLBACK (secrets_requested), nmc);
|
||||
g_print (_("nmcli successfully registered as a NetworkManager's secret agent.\n"));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1780,6 +1780,14 @@ active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpoin
|
|||
const GPtrArray *devices;
|
||||
NMDevice *device;
|
||||
|
||||
if (nmc->secret_agent) {
|
||||
NMRemoteConnection *connection = nm_active_connection_get_connection (active);
|
||||
const gchar *path = nm_connection_get_path (NM_CONNECTION (connection));
|
||||
|
||||
nm_secret_agent_simple_set_connection_path (nmc->secret_agent, path);
|
||||
nm_secret_agent_simple_enable (nmc->secret_agent);
|
||||
}
|
||||
|
||||
devices = nm_active_connection_get_devices (active);
|
||||
device = devices->len ? g_ptr_array_index (devices, 0) : NULL;
|
||||
if ( device
|
||||
|
|
@ -2164,9 +2172,16 @@ nmc_activate_connection (NmCli *nmc,
|
|||
nmc->pwds_hash = pwds_hash;
|
||||
|
||||
/* Create secret agent */
|
||||
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-connect", nm_object_get_path (NM_OBJECT (connection)));
|
||||
if (nmc->secret_agent)
|
||||
nmc->secret_agent = nm_secret_agent_simple_new ("nmcli-connect");
|
||||
if (nmc->secret_agent) {
|
||||
g_signal_connect (nmc->secret_agent, "request-secrets", G_CALLBACK (secrets_requested), nmc);
|
||||
if (connection) {
|
||||
const gchar *path = nm_object_get_path (NM_OBJECT (connection));
|
||||
|
||||
nm_secret_agent_simple_set_connection_path (nmc->secret_agent, path);
|
||||
nm_secret_agent_simple_enable (nmc->secret_agent);
|
||||
}
|
||||
}
|
||||
|
||||
info = g_malloc0 (sizeof (ActivateConnectionInfo));
|
||||
info->nmc = nmc;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ typedef struct {
|
|||
GHashTable *requests;
|
||||
|
||||
char *path;
|
||||
gboolean enabled;
|
||||
} NMSecretAgentSimplePrivate;
|
||||
|
||||
static void
|
||||
|
|
@ -451,14 +452,6 @@ nm_secret_agent_simple_get_secrets (NMSecretAgent *agent,
|
|||
return;
|
||||
}
|
||||
|
||||
if (priv->path && g_strcmp0 (priv->path, connection_path) != 0) {
|
||||
/* We only handle requests for connection with @path if set. */
|
||||
error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED,
|
||||
"Request for %s secrets doesn't match path %s",
|
||||
request_id, priv->path);
|
||||
goto nope;
|
||||
}
|
||||
|
||||
s_con = nm_connection_get_setting_connection (connection);
|
||||
connection_type = nm_setting_connection_get_connection_type (s_con);
|
||||
|
||||
|
|
@ -485,7 +478,8 @@ nm_secret_agent_simple_get_secrets (NMSecretAgent *agent,
|
|||
request->request_id = request_id;
|
||||
g_hash_table_replace (priv->requests, request->request_id, request);
|
||||
|
||||
request_secrets_from_ui (request);
|
||||
if (priv->enabled)
|
||||
request_secrets_from_ui (request);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -588,6 +582,59 @@ nm_secret_agent_simple_delete_secrets (NMSecretAgent *agent,
|
|||
callback (agent, connection, NULL, callback_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_secret_agent_simple_set_connection_path:
|
||||
* @agent: the #NMSecretAgentSimple
|
||||
* @path: the path of the connection the agent handle secrets for
|
||||
*
|
||||
* Sets the path for a new #NMSecretAgentSimple.
|
||||
*/
|
||||
void
|
||||
nm_secret_agent_simple_set_connection_path (NMSecretAgent *agent, const char *path)
|
||||
{
|
||||
NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent);
|
||||
|
||||
g_free (priv->path);
|
||||
priv->path = g_strdup (path);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_secret_agent_simple_enable:
|
||||
* @agent: the #NMSecretAgentSimple
|
||||
*
|
||||
* Enables servicing the requests including the already queued ones.
|
||||
*/
|
||||
void
|
||||
nm_secret_agent_simple_enable (NMSecretAgent *agent)
|
||||
{
|
||||
NMSecretAgentSimplePrivate *priv = NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent);
|
||||
GList *requests, *iter;
|
||||
GError *error;
|
||||
|
||||
if (priv->enabled)
|
||||
return;
|
||||
priv->enabled = TRUE;
|
||||
|
||||
/* Service pending secret requests. */
|
||||
requests = g_hash_table_get_values (priv->requests);
|
||||
for (iter = requests; iter; iter = g_list_next (iter)) {
|
||||
NMSecretAgentSimpleRequest *request = iter->data;
|
||||
|
||||
if (!g_str_has_prefix (request->request_id, priv->path)) {
|
||||
request_secrets_from_ui (request);
|
||||
} else {
|
||||
/* We only handle requests for connection with @path if set. */
|
||||
error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_FAILED,
|
||||
"Request for %s secrets doesn't match path %s",
|
||||
request->request_id, priv->path);
|
||||
request->callback (agent, request->connection, NULL, error, request->callback_data);
|
||||
g_hash_table_remove (priv->requests, request->request_id);
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
g_list_free (requests);
|
||||
}
|
||||
|
||||
void
|
||||
nm_secret_agent_simple_class_init (NMSecretAgentSimpleClass *klass)
|
||||
{
|
||||
|
|
@ -639,22 +686,21 @@ nm_secret_agent_simple_class_init (NMSecretAgentSimpleClass *klass)
|
|||
/**
|
||||
* nm_secret_agent_simple_new:
|
||||
* @name: the identifier of secret agent
|
||||
* @path: (allow-none): the path of the connection the agent handle secrets for,
|
||||
* or %NULL to handle requests for all connections
|
||||
*
|
||||
* Creates a new #NMSecretAgentSimple.
|
||||
* Creates a new #NMSecretAgentSimple. It does not serve any requests until
|
||||
* nm_secret_agent_simple_enable() is called.
|
||||
*
|
||||
* Returns: a new #NMSecretAgentSimple
|
||||
* Returns: a new #NMSecretAgentSimple if the agent creation is successful
|
||||
* or %NULL in case of a failure.
|
||||
*/
|
||||
NMSecretAgent *
|
||||
nm_secret_agent_simple_new (const char *name, const char *path)
|
||||
nm_secret_agent_simple_new (const char *name)
|
||||
{
|
||||
NMSecretAgent *agent;
|
||||
|
||||
agent = g_initable_new (NM_TYPE_SECRET_AGENT_SIMPLE, NULL, NULL,
|
||||
NM_SECRET_AGENT_IDENTIFIER, name,
|
||||
NULL);
|
||||
NM_SECRET_AGENT_SIMPLE_GET_PRIVATE (agent)->path = g_strdup (path);
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,10 +47,13 @@ typedef struct {
|
|||
|
||||
GType nm_secret_agent_simple_get_type (void);
|
||||
|
||||
NMSecretAgent *nm_secret_agent_simple_new (const char *name, const char *path);
|
||||
NMSecretAgent *nm_secret_agent_simple_new (const char *name);
|
||||
void nm_secret_agent_simple_response (NMSecretAgentSimple *self,
|
||||
const char *request_id,
|
||||
GPtrArray *secrets);
|
||||
void nm_secret_agent_simple_set_connection_path (NMSecretAgent *agent,
|
||||
const char *path);
|
||||
void nm_secret_agent_simple_enable (NMSecretAgent *agent);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -145,8 +145,15 @@ activate_connection (NMConnection *connection,
|
|||
label = nmt_newt_label_new (_("Connecting..."));
|
||||
nmt_newt_form_set_content (form, label);
|
||||
|
||||
agent = nm_secret_agent_simple_new ("nmtui", nm_object_get_path (NM_OBJECT (connection)));
|
||||
g_signal_connect (agent, "request-secrets", G_CALLBACK (secrets_requested), NULL);
|
||||
agent = nm_secret_agent_simple_new ("nmtui");
|
||||
if (agent) {
|
||||
if (connection) {
|
||||
nm_secret_agent_simple_set_connection_path (agent,
|
||||
nm_object_get_path (NM_OBJECT (connection)));
|
||||
nm_secret_agent_simple_enable (agent);
|
||||
}
|
||||
g_signal_connect (agent, "request-secrets", G_CALLBACK (secrets_requested), NULL);
|
||||
}
|
||||
|
||||
specific_object_path = specific_object ? nm_object_get_path (specific_object) : NULL;
|
||||
|
||||
|
|
@ -182,6 +189,16 @@ activate_connection (NMConnection *connection,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (!connection) {
|
||||
connection = NM_CONNECTION (nm_active_connection_get_connection (ac));
|
||||
if (connection) {
|
||||
const gchar *path = nm_object_get_path (NM_OBJECT (connection));
|
||||
|
||||
nm_secret_agent_simple_set_connection_path (agent, path);
|
||||
nm_secret_agent_simple_enable (agent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now wait for the connection to actually reach the ACTIVATED state,
|
||||
* allowing the user to cancel if it takes too long.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue