|
Packit Service |
d328f3 |
// SPDX-License-Identifier: GPL-2.0+
|
|
Packit Service |
d328f3 |
/*
|
|
Packit Service |
d328f3 |
* Dan Williams <dcbw@redhat.com>
|
|
Packit Service |
d328f3 |
*
|
|
Packit Service |
d328f3 |
* Copyright 2011 - 2014 Red Hat, Inc.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
#include "nm-default.h"
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
#include <string.h>
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
#include <libsecret/secret.h>
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
#include "applet-agent.h"
|
|
Packit Service |
d328f3 |
#include "utils.h"
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
#define KEYRING_UUID_TAG "connection-uuid"
|
|
Packit Service |
d328f3 |
#define KEYRING_SN_TAG "setting-name"
|
|
Packit Service |
d328f3 |
#define KEYRING_SK_TAG "setting-key"
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static const SecretSchema network_manager_secret_schema = {
|
|
Packit Service |
d328f3 |
"org.freedesktop.NetworkManager.Connection",
|
|
Packit Service |
d328f3 |
SECRET_SCHEMA_DONT_MATCH_NAME,
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
{ KEYRING_UUID_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
Packit Service |
d328f3 |
{ KEYRING_SN_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
Packit Service |
d328f3 |
{ KEYRING_SK_TAG, SECRET_SCHEMA_ATTRIBUTE_STRING },
|
|
Packit Service |
d328f3 |
{ NULL, 0 },
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
};
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
G_DEFINE_TYPE (AppletAgent, applet_agent, NM_TYPE_SECRET_AGENT_OLD);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
#define APPLET_AGENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), APPLET_TYPE_AGENT, AppletAgentPrivate))
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
typedef struct {
|
|
Packit Service |
d328f3 |
GHashTable *requests;
|
|
Packit Service |
d328f3 |
gboolean vpn_only;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
gboolean disposed;
|
|
Packit Service |
d328f3 |
} AppletAgentPrivate;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
enum {
|
|
Packit Service |
d328f3 |
GET_SECRETS,
|
|
Packit Service |
d328f3 |
CANCEL_SECRETS,
|
|
Packit Service |
d328f3 |
LAST_SIGNAL
|
|
Packit Service |
d328f3 |
};
|
|
Packit Service |
d328f3 |
static guint signals[LAST_SIGNAL] = { 0 };
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/*******************************************************/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
typedef struct {
|
|
Packit Service |
d328f3 |
guint id;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
NMSecretAgentOld *agent;
|
|
Packit Service |
d328f3 |
NMConnection *connection;
|
|
Packit Service |
d328f3 |
char *path;
|
|
Packit Service |
d328f3 |
char *setting_name;
|
|
Packit Service |
d328f3 |
char **hints;
|
|
Packit Service |
d328f3 |
guint32 flags;
|
|
Packit Service |
d328f3 |
NMSecretAgentOldGetSecretsFunc get_callback;
|
|
Packit Service |
d328f3 |
NMSecretAgentOldSaveSecretsFunc save_callback;
|
|
Packit Service |
d328f3 |
NMSecretAgentOldDeleteSecretsFunc delete_callback;
|
|
Packit Service |
d328f3 |
gpointer callback_data;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
GCancellable *cancellable;
|
|
Packit Service |
d328f3 |
gint keyring_calls;
|
|
Packit Service |
d328f3 |
} Request;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static Request *
|
|
Packit Service |
d328f3 |
request_new (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
NMConnection *connection,
|
|
Packit Service |
d328f3 |
const char *connection_path,
|
|
Packit Service |
d328f3 |
const char *setting_name,
|
|
Packit Service |
d328f3 |
const char **hints,
|
|
Packit Service |
d328f3 |
guint32 flags,
|
|
Packit Service |
d328f3 |
NMSecretAgentOldGetSecretsFunc get_callback,
|
|
Packit Service |
d328f3 |
NMSecretAgentOldSaveSecretsFunc save_callback,
|
|
Packit Service |
d328f3 |
NMSecretAgentOldDeleteSecretsFunc delete_callback,
|
|
Packit Service |
d328f3 |
gpointer callback_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
static guint32 counter = 1;
|
|
Packit Service |
d328f3 |
Request *r;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r = g_slice_new0 (Request);
|
|
Packit Service |
d328f3 |
r->id = counter++;
|
|
Packit Service |
d328f3 |
r->agent = agent;
|
|
Packit Service |
d328f3 |
r->connection = g_object_ref (connection);
|
|
Packit Service |
d328f3 |
r->path = g_strdup (connection_path);
|
|
Packit Service |
d328f3 |
r->setting_name = g_strdup (setting_name);
|
|
Packit Service |
d328f3 |
if (hints)
|
|
Packit Service |
d328f3 |
r->hints = g_strdupv ((gchar **) hints);
|
|
Packit Service |
d328f3 |
r->flags = flags;
|
|
Packit Service |
d328f3 |
r->get_callback = get_callback;
|
|
Packit Service |
d328f3 |
r->save_callback = save_callback;
|
|
Packit Service |
d328f3 |
r->delete_callback = delete_callback;
|
|
Packit Service |
d328f3 |
r->callback_data = callback_data;
|
|
Packit Service |
d328f3 |
r->cancellable = g_cancellable_new ();
|
|
Packit Service |
d328f3 |
return r;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
request_free (Request *r)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
if (!g_cancellable_is_cancelled (r->cancellable))
|
|
Packit Service |
d328f3 |
g_hash_table_remove (APPLET_AGENT_GET_PRIVATE (r->agent)->requests, GUINT_TO_POINTER (r->id));
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* By the time the request is freed, all keyring calls should be completed */
|
|
Packit Service |
d328f3 |
g_warn_if_fail (r->keyring_calls == 0);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_object_unref (r->connection);
|
|
Packit Service |
d328f3 |
g_free (r->path);
|
|
Packit Service |
d328f3 |
g_free (r->setting_name);
|
|
Packit Service |
d328f3 |
g_strfreev (r->hints);
|
|
Packit Service |
d328f3 |
g_object_unref (r->cancellable);
|
|
Packit Service |
d328f3 |
memset (r, 0, sizeof (*r));
|
|
Packit Service |
d328f3 |
g_slice_free (Request, r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/*******************************************************/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
get_save_cb (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
NMConnection *connection,
|
|
Packit Service |
d328f3 |
GError *error,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
/* Ignored */
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
get_secrets_cb (AppletAgent *self,
|
|
Packit Service |
d328f3 |
GVariant *secrets,
|
|
Packit Service |
d328f3 |
GError *error,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
Request *r = user_data;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* 'secrets' shouldn't be valid if there was an error */
|
|
Packit Service |
d328f3 |
if (error) {
|
|
Packit Service |
d328f3 |
g_warn_if_fail (secrets == NULL);
|
|
Packit Service |
d328f3 |
secrets = NULL;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (!g_cancellable_is_cancelled (r->cancellable)) {
|
|
Packit Service |
d328f3 |
/* Save updated secrets as long as user-interaction was allowed; otherwise
|
|
Packit Service |
d328f3 |
* we'd be saving secrets we just pulled out of the keyring which is somewhat
|
|
Packit Service |
d328f3 |
* redundant.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
if (secrets && (r->flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)) {
|
|
Packit Service |
d328f3 |
NMConnection *dupl;
|
|
Packit Service |
d328f3 |
GVariantIter iter;
|
|
Packit Service |
d328f3 |
const char *setting_name;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Copy the existing connection and update its secrets */
|
|
Packit Service |
d328f3 |
dupl = nm_simple_connection_new_clone (r->connection);
|
|
Packit Service |
d328f3 |
g_variant_iter_init (&iter, secrets);
|
|
Packit Service |
d328f3 |
while (g_variant_iter_next (&iter, "{&s@a{sv}}", (gpointer) &setting_name, NULL))
|
|
Packit Service |
d328f3 |
nm_connection_update_secrets (dupl, setting_name, secrets, NULL);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* And save updated secrets to the keyring */
|
|
Packit Service |
d328f3 |
nm_secret_agent_old_save_secrets (NM_SECRET_AGENT_OLD (self), dupl, get_save_cb, NULL);
|
|
Packit Service |
d328f3 |
g_object_unref (dupl);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r->get_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, secrets, error, r->callback_data);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
request_free (r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
ask_for_secrets (Request *r)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
/* Ask the applet to get some secrets for us */
|
|
Packit Service |
d328f3 |
g_signal_emit (r->agent,
|
|
Packit Service |
d328f3 |
signals[GET_SECRETS],
|
|
Packit Service |
d328f3 |
0,
|
|
Packit Service |
d328f3 |
GUINT_TO_POINTER (r->id),
|
|
Packit Service |
d328f3 |
r->connection,
|
|
Packit Service |
d328f3 |
r->setting_name,
|
|
Packit Service |
d328f3 |
r->hints,
|
|
Packit Service |
d328f3 |
r->flags,
|
|
Packit Service |
d328f3 |
get_secrets_cb,
|
|
Packit Service |
d328f3 |
r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
check_always_ask_cb (NMSetting *setting,
|
|
Packit Service |
d328f3 |
const char *key,
|
|
Packit Service |
d328f3 |
const GValue *value,
|
|
Packit Service |
d328f3 |
GParamFlags flags,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
gboolean *always_ask = user_data;
|
|
Packit Service |
d328f3 |
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (flags & NM_SETTING_PARAM_SECRET) {
|
|
Packit Service |
d328f3 |
if (nm_setting_get_secret_flags (setting, key, &secret_flags, NULL)) {
|
|
Packit Service |
d328f3 |
if (secret_flags & NM_SETTING_SECRET_FLAG_NOT_SAVED)
|
|
Packit Service |
d328f3 |
*always_ask = TRUE;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static gboolean
|
|
Packit Service |
d328f3 |
has_always_ask (NMSetting *setting)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
gboolean always_ask = FALSE;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
nm_setting_enumerate_values (setting, check_always_ask_cb, &always_ask);
|
|
Packit Service |
d328f3 |
return always_ask;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static gboolean
|
|
Packit Service |
d328f3 |
is_connection_always_ask (NMConnection *connection)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
NMSettingConnection *s_con;
|
|
Packit Service |
d328f3 |
const char *ctype;
|
|
Packit Service |
d328f3 |
NMSetting *setting;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* For the given connection type, check if the secrets for that connection
|
|
Packit Service |
d328f3 |
* are always-ask or not.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
s_con = nm_connection_get_setting_connection (connection);
|
|
Packit Service |
d328f3 |
g_assert (s_con);
|
|
Packit Service |
d328f3 |
ctype = nm_setting_connection_get_connection_type (s_con);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting_by_name (connection, ctype);
|
|
Packit Service |
d328f3 |
g_return_val_if_fail (setting != NULL, FALSE);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (has_always_ask (setting))
|
|
Packit Service |
d328f3 |
return TRUE;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Try type-specific settings too; be a bit paranoid and only consider
|
|
Packit Service |
d328f3 |
* secrets from settings relevant to the connection type.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
if (NM_IS_SETTING_WIRELESS (setting)) {
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY);
|
|
Packit Service |
d328f3 |
if (setting && has_always_ask (setting))
|
|
Packit Service |
d328f3 |
return TRUE;
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
|
|
Packit Service |
d328f3 |
if (setting && has_always_ask (setting))
|
|
Packit Service |
d328f3 |
return TRUE;
|
|
Packit Service |
d328f3 |
} else if (NM_IS_SETTING_WIRED (setting)) {
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_PPPOE);
|
|
Packit Service |
d328f3 |
if (setting && has_always_ask (setting))
|
|
Packit Service |
d328f3 |
return TRUE;
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
|
|
Packit Service |
d328f3 |
if (setting && has_always_ask (setting))
|
|
Packit Service |
d328f3 |
return TRUE;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
return FALSE;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
keyring_find_secrets_cb (GObject *source,
|
|
Packit Service |
d328f3 |
GAsyncResult *result,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
Request *r = user_data;
|
|
Packit Service |
d328f3 |
GError *error = NULL;
|
|
Packit Service |
d328f3 |
GError *search_error = NULL;
|
|
Packit Service |
d328f3 |
const char *connection_id = NULL;
|
|
Packit Service |
d328f3 |
GVariantBuilder builder_setting, builder_connection;
|
|
Packit Service |
d328f3 |
GVariant *settings = NULL;
|
|
Packit Service |
d328f3 |
GList *list = NULL;
|
|
Packit Service |
d328f3 |
GList *iter;
|
|
Packit Service |
d328f3 |
gboolean hint_found = FALSE, ask = FALSE;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r->keyring_calls--;
|
|
Packit Service |
d328f3 |
if (g_cancellable_is_cancelled (r->cancellable)) {
|
|
Packit Service |
d328f3 |
/* Callback already called by NM or dispose */
|
|
Packit Service |
d328f3 |
request_free (r);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
list = secret_service_search_finish (NULL, result, &search_error);
|
|
Packit Service |
d328f3 |
connection_id = nm_connection_get_id (r->connection);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (g_error_matches (search_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
Packit Service |
d328f3 |
error = g_error_new_literal (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_USER_CANCELED,
|
|
Packit Service |
d328f3 |
"The secrets request was canceled by the user");
|
|
Packit Service |
d328f3 |
g_error_free (search_error);
|
|
Packit Service |
d328f3 |
goto done;
|
|
Packit Service |
d328f3 |
} else if ( (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION)
|
|
Packit Service |
d328f3 |
&& g_error_matches (search_error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN)) {
|
|
Packit Service |
d328f3 |
/* If the connection always asks for secrets, tolerate
|
|
Packit Service |
d328f3 |
* keyring service not being present. */
|
|
Packit Service |
d328f3 |
g_clear_error (&search_error);
|
|
Packit Service |
d328f3 |
} else if (search_error) {
|
|
Packit Service |
d328f3 |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit Service |
d328f3 |
"%s.%d - failed to read secrets from keyring (%s)",
|
|
Packit Service |
d328f3 |
__FILE__, __LINE__, search_error->message);
|
|
Packit Service |
d328f3 |
g_error_free (search_error);
|
|
Packit Service |
d328f3 |
goto done;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Only ask if we're allowed to, so that eg a connection editor which
|
|
Packit Service |
d328f3 |
* requests secrets for its UI, for a connection which doesn't have any
|
|
Packit Service |
d328f3 |
* secrets yet, doesn't trigger the applet secrets dialog.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
if ( (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION)
|
|
Packit Service |
d328f3 |
&& g_list_length (list) == 0) {
|
|
Packit Service |
d328f3 |
g_message ("No keyring secrets found for %s/%s; asking user.", connection_id, r->setting_name);
|
|
Packit Service |
d328f3 |
ask_for_secrets (r);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_variant_builder_init (&builder_setting, NM_VARIANT_TYPE_SETTING);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Extract the secrets from the list of matching keyring items */
|
|
Packit Service |
d328f3 |
for (iter = list; iter != NULL; iter = g_list_next (iter)) {
|
|
Packit Service |
d328f3 |
SecretItem *item = iter->data;
|
|
Packit Service |
d328f3 |
SecretValue *secret;
|
|
Packit Service |
d328f3 |
const char *key_name;
|
|
Packit Service |
d328f3 |
GHashTable *attributes;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
secret = secret_item_get_secret (item);
|
|
Packit Service |
d328f3 |
if (secret) {
|
|
Packit Service |
d328f3 |
attributes = secret_item_get_attributes (item);
|
|
Packit Service |
d328f3 |
key_name = g_hash_table_lookup (attributes, KEYRING_SK_TAG);
|
|
Packit Service |
d328f3 |
if (!key_name) {
|
|
Packit Service |
d328f3 |
g_hash_table_unref (attributes);
|
|
Packit Service |
d328f3 |
secret_value_unref (secret);
|
|
Packit Service |
d328f3 |
continue;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_variant_builder_add (&builder_setting, "{sv}", key_name,
|
|
Packit Service |
d328f3 |
g_variant_new_string (secret_value_get (secret, NULL)));
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* See if this property matches a given hint */
|
|
Packit Service |
d328f3 |
if (r->hints && r->hints[0]) {
|
|
Packit Service |
d328f3 |
if (!g_strcmp0 (r->hints[0], key_name) || !g_strcmp0 (r->hints[1], key_name))
|
|
Packit Service |
d328f3 |
hint_found = TRUE;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_hash_table_unref (attributes);
|
|
Packit Service |
d328f3 |
secret_value_unref (secret);
|
|
Packit Service |
d328f3 |
break;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* If there were hints, and none of the hints were returned by the keyring,
|
|
Packit Service |
d328f3 |
* get some new secrets.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
if (r->flags) {
|
|
Packit Service |
d328f3 |
if (r->hints && r->hints[0] && !hint_found)
|
|
Packit Service |
d328f3 |
ask = TRUE;
|
|
Packit Service |
d328f3 |
else if (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW) {
|
|
Packit Service |
d328f3 |
g_message ("New secrets for %s/%s requested; ask the user", connection_id, r->setting_name);
|
|
Packit Service |
d328f3 |
ask = TRUE;
|
|
Packit Service |
d328f3 |
} else if ( (r->flags & NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION)
|
|
Packit Service |
d328f3 |
&& is_connection_always_ask (r->connection))
|
|
Packit Service |
d328f3 |
ask = TRUE;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Returned secrets are a{sa{sv}}; this is the outer a{s...} hash that
|
|
Packit Service |
d328f3 |
* will contain all the individual settings hashes.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
g_variant_builder_init (&builder_connection, NM_VARIANT_TYPE_CONNECTION);
|
|
Packit Service |
d328f3 |
g_variant_builder_add (&builder_connection, "{sa{sv}}", r->setting_name, &builder_setting);
|
|
Packit Service |
d328f3 |
settings = g_variant_builder_end (&builder_connection);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
done:
|
|
Packit Service |
d328f3 |
g_list_free_full (list, g_object_unref);
|
|
Packit Service |
d328f3 |
if (ask) {
|
|
Packit Service |
d328f3 |
GVariantIter dict_iter;
|
|
Packit Service |
d328f3 |
const char *setting_name;
|
|
Packit Service |
d328f3 |
GVariant *setting_dict;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Stuff all the found secrets into the connection for the UI to use */
|
|
Packit Service |
d328f3 |
g_variant_iter_init (&dict_iter, settings);
|
|
Packit Service |
d328f3 |
while (g_variant_iter_next (&dict_iter, "{s@a{sv}}", &setting_name, &setting_dict)) {
|
|
Packit Service |
d328f3 |
nm_connection_update_secrets (r->connection,
|
|
Packit Service |
d328f3 |
setting_name,
|
|
Packit Service |
d328f3 |
setting_dict,
|
|
Packit Service |
d328f3 |
NULL);
|
|
Packit Service |
d328f3 |
g_variant_unref (setting_dict);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
ask_for_secrets (r);
|
|
Packit Service |
d328f3 |
} else {
|
|
Packit Service |
d328f3 |
/* Otherwise send the secrets back to NetworkManager */
|
|
Packit Service |
d328f3 |
r->get_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, error ? NULL : settings, error, r->callback_data);
|
|
Packit Service |
d328f3 |
request_free (r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (settings)
|
|
Packit Service |
d328f3 |
g_variant_unref (settings);
|
|
Packit Service |
d328f3 |
g_clear_error (&error);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
get_secrets (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
NMConnection *connection,
|
|
Packit Service |
d328f3 |
const char *connection_path,
|
|
Packit Service |
d328f3 |
const char *setting_name,
|
|
Packit Service |
d328f3 |
const char **hints,
|
|
Packit Service |
d328f3 |
guint32 flags,
|
|
Packit Service |
d328f3 |
NMSecretAgentOldGetSecretsFunc callback,
|
|
Packit Service |
d328f3 |
gpointer callback_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent);
|
|
Packit Service |
d328f3 |
Request *r;
|
|
Packit Service |
d328f3 |
GError *error = NULL;
|
|
Packit Service |
d328f3 |
NMSettingConnection *s_con;
|
|
Packit Service |
d328f3 |
NMSetting *setting;
|
|
Packit Service |
d328f3 |
const char *uuid, *ctype;
|
|
Packit Service |
d328f3 |
GHashTable *attrs;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting_by_name (connection, setting_name);
|
|
Packit Service |
d328f3 |
if (!setting) {
|
|
Packit Service |
d328f3 |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
|
|
Packit Service |
d328f3 |
"%s.%d - Connection didn't have requested setting '%s'.",
|
|
Packit Service |
d328f3 |
__FILE__, __LINE__, setting_name);
|
|
Packit Service |
d328f3 |
callback (agent, connection, NULL, error, callback_data);
|
|
Packit Service |
d328f3 |
g_error_free (error);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
uuid = nm_connection_get_uuid (connection);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
s_con = nm_connection_get_setting_connection (connection);
|
|
Packit Service |
d328f3 |
g_assert (s_con);
|
|
Packit Service |
d328f3 |
ctype = nm_setting_connection_get_connection_type (s_con);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (!uuid || !ctype) {
|
|
Packit Service |
d328f3 |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_INVALID_CONNECTION,
|
|
Packit Service |
d328f3 |
"%s.%d - Connection didn't have required UUID.",
|
|
Packit Service |
d328f3 |
__FILE__, __LINE__);
|
|
Packit Service |
d328f3 |
callback (agent, connection, NULL, error, callback_data);
|
|
Packit Service |
d328f3 |
g_error_free (error);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Track the secrets request */
|
|
Packit Service |
d328f3 |
r = request_new (agent, connection, connection_path, setting_name, hints, flags, callback, NULL, NULL, callback_data);
|
|
Packit Service |
d328f3 |
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* VPN passwords are handled by the VPN plugin's auth dialog */
|
|
Packit Service |
d328f3 |
if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) {
|
|
Packit Service |
d328f3 |
ask_for_secrets (r);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Only handle non-VPN secrets if we're supposed to */
|
|
Packit Service |
d328f3 |
if (priv->vpn_only == TRUE) {
|
|
Packit Service |
d328f3 |
error = g_error_new_literal (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_NO_SECRETS,
|
|
Packit Service |
d328f3 |
"Only handling VPN secrets at this time.");
|
|
Packit Service |
d328f3 |
callback (agent, connection, NULL, error, callback_data);
|
|
Packit Service |
d328f3 |
g_error_free (error);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* For everything else we scrape the keyring for secrets first, and ask
|
|
Packit Service |
d328f3 |
* later if required.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
attrs = secret_attributes_build (&network_manager_secret_schema,
|
|
Packit Service |
d328f3 |
KEYRING_UUID_TAG, uuid,
|
|
Packit Service |
d328f3 |
KEYRING_SN_TAG, setting_name,
|
|
Packit Service |
d328f3 |
NULL);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
secret_service_search (NULL, &network_manager_secret_schema, attrs,
|
|
Packit Service |
d328f3 |
SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS,
|
|
Packit Service |
d328f3 |
r->cancellable, keyring_find_secrets_cb, r);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r->keyring_calls++;
|
|
Packit Service |
d328f3 |
g_hash_table_unref (attrs);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/*******************************************************/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
cancel_get_secrets (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
const char *connection_path,
|
|
Packit Service |
d328f3 |
const char *setting_name)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent);
|
|
Packit Service |
d328f3 |
GHashTableIter iter;
|
|
Packit Service |
d328f3 |
Request *r;
|
|
Packit Service |
d328f3 |
GError *error;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
error = g_error_new_literal (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_AGENT_CANCELED,
|
|
Packit Service |
d328f3 |
"Canceled by NetworkManager");
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_hash_table_iter_init (&iter, priv->requests);
|
|
Packit Service |
d328f3 |
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r)) {
|
|
Packit Service |
d328f3 |
/* Only care about GetSecrets requests here */
|
|
Packit Service |
d328f3 |
if (r->get_callback == NULL)
|
|
Packit Service |
d328f3 |
continue;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Cancel any matching GetSecrets call */
|
|
Packit Service |
d328f3 |
if ( g_strcmp0 (r->path, connection_path) == 0
|
|
Packit Service |
d328f3 |
&& g_strcmp0 (r->setting_name, setting_name) == 0) {
|
|
Packit Service |
d328f3 |
/* cancel outstanding keyring operations */
|
|
Packit Service |
d328f3 |
g_cancellable_cancel (r->cancellable);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r->get_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, NULL, error, r->callback_data);
|
|
Packit Service |
d328f3 |
g_hash_table_iter_remove (&iter);
|
|
Packit Service |
d328f3 |
g_signal_emit (r->agent, signals[CANCEL_SECRETS], 0, GUINT_TO_POINTER (r->id));
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_error_free (error);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/*******************************************************/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
save_request_try_complete (Request *r)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
/* Only call the SaveSecrets callback and free the request when all the
|
|
Packit Service |
d328f3 |
* secrets have been saved to the keyring.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
if (r->keyring_calls == 0) {
|
|
Packit Service |
d328f3 |
if (!g_cancellable_is_cancelled (r->cancellable))
|
|
Packit Service |
d328f3 |
r->save_callback (NM_SECRET_AGENT_OLD (r->agent), r->connection, NULL, r->callback_data);
|
|
Packit Service |
d328f3 |
request_free (r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
save_secret_cb (GObject *source,
|
|
Packit Service |
d328f3 |
GAsyncResult *result,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
secret_password_store_finish (result, NULL);
|
|
Packit Service |
d328f3 |
save_request_try_complete (user_data);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static GHashTable *
|
|
Packit Service |
d328f3 |
_create_keyring_add_attr_list (NMConnection *connection,
|
|
Packit Service |
d328f3 |
const char *setting_name,
|
|
Packit Service |
d328f3 |
const char *setting_key,
|
|
Packit Service |
d328f3 |
char **out_display_name)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
const char *connection_id, *connection_uuid;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_return_val_if_fail (connection != NULL, NULL);
|
|
Packit Service |
d328f3 |
g_return_val_if_fail (setting_name != NULL, NULL);
|
|
Packit Service |
d328f3 |
g_return_val_if_fail (setting_key != NULL, NULL);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
connection_uuid = nm_connection_get_uuid (connection);
|
|
Packit Service |
d328f3 |
g_assert (connection_uuid);
|
|
Packit Service |
d328f3 |
connection_id = nm_connection_get_id (connection);
|
|
Packit Service |
d328f3 |
g_assert (connection_id);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (out_display_name) {
|
|
Packit Service |
d328f3 |
*out_display_name = g_strdup_printf ("Network secret for %s/%s/%s",
|
|
Packit Service |
d328f3 |
connection_id,
|
|
Packit Service |
d328f3 |
setting_name,
|
|
Packit Service |
d328f3 |
setting_key);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
return secret_attributes_build (&network_manager_secret_schema,
|
|
Packit Service |
d328f3 |
KEYRING_UUID_TAG, connection_uuid,
|
|
Packit Service |
d328f3 |
KEYRING_SN_TAG, setting_name,
|
|
Packit Service |
d328f3 |
KEYRING_SK_TAG, setting_key,
|
|
Packit Service |
d328f3 |
NULL);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
save_one_secret (Request *r,
|
|
Packit Service |
d328f3 |
NMSetting *setting,
|
|
Packit Service |
d328f3 |
const char *key,
|
|
Packit Service |
d328f3 |
const char *secret,
|
|
Packit Service |
d328f3 |
const char *display_name)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
GHashTable *attrs;
|
|
Packit Service |
d328f3 |
char *alt_display_name = NULL;
|
|
Packit Service |
d328f3 |
const char *setting_name;
|
|
Packit Service |
d328f3 |
NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Don't system-owned or always-ask secrets */
|
|
Packit Service |
d328f3 |
if (!nm_setting_get_secret_flags (setting, key, &secret_flags, NULL))
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
if (secret_flags != NM_SETTING_SECRET_FLAG_AGENT_OWNED)
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
setting_name = nm_setting_get_name (setting);
|
|
Packit Service |
d328f3 |
g_assert (setting_name);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
attrs = _create_keyring_add_attr_list (r->connection,
|
|
Packit Service |
d328f3 |
setting_name,
|
|
Packit Service |
d328f3 |
key,
|
|
Packit Service |
d328f3 |
display_name ? NULL : &alt_display_name);
|
|
Packit Service |
d328f3 |
g_assert (attrs);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
secret_password_storev (&network_manager_secret_schema, attrs, NULL,
|
|
Packit Service |
d328f3 |
display_name ? display_name : alt_display_name, secret,
|
|
Packit Service |
d328f3 |
r->cancellable, save_secret_cb, r);
|
|
Packit Service |
d328f3 |
r->keyring_calls++;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_hash_table_unref (attrs);
|
|
Packit Service |
d328f3 |
g_free (alt_display_name);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
vpn_secret_iter_cb (const char *key, const char *secret, gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
Request *r = user_data;
|
|
Packit Service |
d328f3 |
NMSetting *setting;
|
|
Packit Service |
d328f3 |
const char *service_name, *id;
|
|
Packit Service |
d328f3 |
char *display_name;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (secret && strlen (secret)) {
|
|
Packit Service |
d328f3 |
setting = nm_connection_get_setting (r->connection, NM_TYPE_SETTING_VPN);
|
|
Packit Service |
d328f3 |
g_assert (setting);
|
|
Packit Service |
d328f3 |
service_name = nm_setting_vpn_get_service_type (NM_SETTING_VPN (setting));
|
|
Packit Service |
d328f3 |
g_assert (service_name);
|
|
Packit Service |
d328f3 |
id = nm_connection_get_id (r->connection);
|
|
Packit Service |
d328f3 |
g_assert (id);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
display_name = g_strdup_printf ("VPN %s secret for %s/%s/" NM_SETTING_VPN_SETTING_NAME,
|
|
Packit Service |
d328f3 |
key,
|
|
Packit Service |
d328f3 |
id,
|
|
Packit Service |
d328f3 |
service_name);
|
|
Packit Service |
d328f3 |
save_one_secret (r, setting, key, secret, display_name);
|
|
Packit Service |
d328f3 |
g_free (display_name);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
write_one_secret_to_keyring (NMSetting *setting,
|
|
Packit Service |
d328f3 |
const char *key,
|
|
Packit Service |
d328f3 |
const GValue *value,
|
|
Packit Service |
d328f3 |
GParamFlags flags,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
Request *r = user_data;
|
|
Packit Service |
d328f3 |
GType type = G_VALUE_TYPE (value);
|
|
Packit Service |
d328f3 |
const char *secret;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Non-secrets obviously don't get saved in the keyring */
|
|
Packit Service |
d328f3 |
if (!(flags & NM_SETTING_PARAM_SECRET))
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (NM_IS_SETTING_VPN (setting) && (g_strcmp0 (key, NM_SETTING_VPN_SECRETS) == 0)) {
|
|
Packit Service |
d328f3 |
g_return_if_fail (type == G_TYPE_HASH_TABLE);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Process VPN secrets specially since it's a hash of secrets, not just one */
|
|
Packit Service |
d328f3 |
nm_setting_vpn_foreach_secret (NM_SETTING_VPN (setting), vpn_secret_iter_cb, r);
|
|
Packit Service |
d328f3 |
} else {
|
|
Packit Service |
d328f3 |
/* FIXME: password-raw is not string */
|
|
Packit Service |
d328f3 |
if (!g_strcmp0 (key, NM_SETTING_802_1X_PASSWORD_RAW))
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
g_return_if_fail (type == G_TYPE_STRING);
|
|
Packit Service |
d328f3 |
secret = g_value_get_string (value);
|
|
Packit Service |
d328f3 |
if (secret && strlen (secret))
|
|
Packit Service |
d328f3 |
save_one_secret (r, setting, key, secret, NULL);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
save_delete_cb (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
NMConnection *connection,
|
|
Packit Service |
d328f3 |
GError *error,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
Request *r = user_data;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Ignore errors; now save all new secrets */
|
|
Packit Service |
d328f3 |
nm_connection_for_each_setting_value (connection, write_one_secret_to_keyring, r);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* If no secrets actually got saved there may be nothing to do so
|
|
Packit Service |
d328f3 |
* try to complete the request here. If there were secrets to save the
|
|
Packit Service |
d328f3 |
* request will get completed when those keyring calls return.
|
|
Packit Service |
d328f3 |
*/
|
|
Packit Service |
d328f3 |
save_request_try_complete (r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
save_secrets (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
NMConnection *connection,
|
|
Packit Service |
d328f3 |
const char *connection_path,
|
|
Packit Service |
d328f3 |
NMSecretAgentOldSaveSecretsFunc callback,
|
|
Packit Service |
d328f3 |
gpointer callback_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent);
|
|
Packit Service |
d328f3 |
Request *r;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, callback, NULL, callback_data);
|
|
Packit Service |
d328f3 |
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* First delete any existing items in the keyring */
|
|
Packit Service |
d328f3 |
nm_secret_agent_old_delete_secrets (agent, connection, save_delete_cb, r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/*******************************************************/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
delete_find_items_cb (GObject *source,
|
|
Packit Service |
d328f3 |
GAsyncResult *result,
|
|
Packit Service |
d328f3 |
gpointer user_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
Request *r = user_data;
|
|
Packit Service |
d328f3 |
GError *secret_error = NULL;
|
|
Packit Service |
d328f3 |
GError *error = NULL;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r->keyring_calls--;
|
|
Packit Service |
d328f3 |
if (g_cancellable_is_cancelled (r->cancellable)) {
|
|
Packit Service |
d328f3 |
/* Callback already called by NM or dispose */
|
|
Packit Service |
d328f3 |
request_free (r);
|
|
Packit Service |
d328f3 |
return;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
secret_password_clear_finish (result, &secret_error);
|
|
Packit Service |
d328f3 |
if (secret_error != NULL) {
|
|
Packit Service |
d328f3 |
error = g_error_new (NM_SECRET_AGENT_ERROR,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_ERROR_FAILED,
|
|
Packit Service |
d328f3 |
"The request could not be completed (%s)",
|
|
Packit Service |
d328f3 |
secret_error->message);
|
|
Packit Service |
d328f3 |
g_error_free (secret_error);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r->delete_callback (r->agent, r->connection, error, r->callback_data);
|
|
Packit Service |
d328f3 |
request_free (r);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
delete_secrets (NMSecretAgentOld *agent,
|
|
Packit Service |
d328f3 |
NMConnection *connection,
|
|
Packit Service |
d328f3 |
const char *connection_path,
|
|
Packit Service |
d328f3 |
NMSecretAgentOldDeleteSecretsFunc callback,
|
|
Packit Service |
d328f3 |
gpointer callback_data)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent);
|
|
Packit Service |
d328f3 |
Request *r;
|
|
Packit Service |
d328f3 |
NMSettingConnection *s_con;
|
|
Packit Service |
d328f3 |
const char *uuid;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, NULL, callback, callback_data);
|
|
Packit Service |
d328f3 |
g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
s_con = nm_connection_get_setting_connection (connection);
|
|
Packit Service |
d328f3 |
g_assert (s_con);
|
|
Packit Service |
d328f3 |
uuid = nm_setting_connection_get_uuid (s_con);
|
|
Packit Service |
d328f3 |
g_assert (uuid);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
secret_password_clear (&network_manager_secret_schema, r->cancellable,
|
|
Packit Service |
d328f3 |
delete_find_items_cb, r,
|
|
Packit Service |
d328f3 |
KEYRING_UUID_TAG, uuid,
|
|
Packit Service |
d328f3 |
NULL);
|
|
Packit Service |
d328f3 |
r->keyring_calls++;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
void
|
|
Packit Service |
d328f3 |
applet_agent_handle_vpn_only (AppletAgent *agent, gboolean vpn_only)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
g_return_if_fail (agent != NULL);
|
|
Packit Service |
d328f3 |
g_return_if_fail (APPLET_IS_AGENT (agent));
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
APPLET_AGENT_GET_PRIVATE (agent)->vpn_only = vpn_only;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/*******************************************************/
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
AppletAgent *
|
|
Packit Service |
d328f3 |
applet_agent_new (GError **error)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgent *agent;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
agent = g_object_new (APPLET_TYPE_AGENT,
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_OLD_IDENTIFIER, "org.freedesktop.nm-applet",
|
|
Packit Service |
d328f3 |
NM_SECRET_AGENT_OLD_CAPABILITIES, NM_SECRET_AGENT_CAPABILITY_VPN_HINTS,
|
|
Packit Service |
d328f3 |
NULL);
|
|
Packit Service |
d328f3 |
if (!g_initable_init (G_INITABLE (agent), NULL, error)) {
|
|
Packit Service |
d328f3 |
g_object_unref (agent);
|
|
Packit Service |
d328f3 |
return NULL;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
return agent;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
applet_agent_init (AppletAgent *self)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
priv->requests = g_hash_table_new (g_direct_hash, g_direct_equal);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
dispose (GObject *object)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
AppletAgent *self = APPLET_AGENT (object);
|
|
Packit Service |
d328f3 |
AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
if (!priv->disposed) {
|
|
Packit Service |
d328f3 |
GHashTableIter iter;
|
|
Packit Service |
d328f3 |
Request *r;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Mark any outstanding requests as canceled */
|
|
Packit Service |
d328f3 |
g_hash_table_iter_init (&iter, priv->requests);
|
|
Packit Service |
d328f3 |
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r))
|
|
Packit Service |
d328f3 |
g_cancellable_cancel (r->cancellable);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_hash_table_destroy (priv->requests);
|
|
Packit Service |
d328f3 |
priv->disposed = TRUE;
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
G_OBJECT_CLASS (applet_agent_parent_class)->dispose (object);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
static void
|
|
Packit Service |
d328f3 |
applet_agent_class_init (AppletAgentClass *agent_class)
|
|
Packit Service |
d328f3 |
{
|
|
Packit Service |
d328f3 |
GObjectClass *object_class = G_OBJECT_CLASS (agent_class);
|
|
Packit Service |
d328f3 |
NMSecretAgentOldClass *parent_class = NM_SECRET_AGENT_OLD_CLASS (agent_class);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
g_type_class_add_private (agent_class, sizeof (AppletAgentPrivate));
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* virtual methods */
|
|
Packit Service |
d328f3 |
object_class->dispose = dispose;
|
|
Packit Service |
d328f3 |
parent_class->get_secrets = get_secrets;
|
|
Packit Service |
d328f3 |
parent_class->cancel_get_secrets = cancel_get_secrets;
|
|
Packit Service |
d328f3 |
parent_class->save_secrets = save_secrets;
|
|
Packit Service |
d328f3 |
parent_class->delete_secrets = delete_secrets;
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
/* Signals */
|
|
Packit Service |
d328f3 |
signals[GET_SECRETS] =
|
|
Packit Service |
d328f3 |
g_signal_new (APPLET_AGENT_GET_SECRETS,
|
|
Packit Service |
d328f3 |
G_OBJECT_CLASS_TYPE (object_class),
|
|
Packit Service |
d328f3 |
G_SIGNAL_RUN_FIRST,
|
|
Packit Service |
d328f3 |
G_STRUCT_OFFSET (AppletAgentClass, get_secrets),
|
|
Packit Service |
d328f3 |
NULL, NULL, NULL,
|
|
Packit Service |
d328f3 |
G_TYPE_NONE, 7,
|
|
Packit Service |
d328f3 |
G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
|
|
Packit Service |
d328f3 |
|
|
Packit Service |
d328f3 |
signals[CANCEL_SECRETS] =
|
|
Packit Service |
d328f3 |
g_signal_new (APPLET_AGENT_CANCEL_SECRETS,
|
|
Packit Service |
d328f3 |
G_OBJECT_CLASS_TYPE (object_class),
|
|
Packit Service |
d328f3 |
G_SIGNAL_RUN_FIRST,
|
|
Packit Service |
d328f3 |
G_STRUCT_OFFSET (AppletAgentClass, cancel_secrets),
|
|
Packit Service |
d328f3 |
NULL, NULL, NULL,
|
|
Packit Service |
d328f3 |
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
Packit Service |
d328f3 |
}
|
|
Packit Service |
d328f3 |
|