static void dispose (GObject *object) { AppletAgent *self = APPLET_AGENT (object); AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self); if (!priv->disposed) { GHashTableIter iter; Request *r; GSList *kiter; /* Mark any outstanding requests as canceled */ g_hash_table_iter_init (&iter, priv->requests); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r)) { r->canceled = TRUE; /* cancel the request's outstanding keyring operations */ for (kiter = r->keyring_calls; kiter; kiter = g_slist_next (kiter)) { KeyringCall *call = kiter->data; gnome_keyring_cancel_request (call->keyring_id); } } g_hash_table_destroy (priv->requests); priv->disposed = TRUE; } G_OBJECT_CLASS (applet_agent_parent_class)->dispose (object); }
static void delete_secrets (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, NMSecretAgentDeleteSecretsFunc callback, gpointer callback_data) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); Request *r; NMSettingConnection *s_con; const char *uuid; r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, NULL, callback, callback_data); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); uuid = nm_setting_connection_get_uuid (s_con); g_assert (uuid); secret_password_clear (&network_manager_secret_schema, r->cancellable, delete_find_items_cb, r, KEYRING_UUID_TAG, uuid, NULL); r->keyring_calls++; }
static void cancel_get_secrets (NMSecretAgent *agent, const char *connection_path, const char *setting_name) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); GHashTableIter iter; Request *r; GError *error; error = g_error_new_literal (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_AGENT_CANCELED, "Canceled by NetworkManager"); g_hash_table_iter_init (&iter, priv->requests); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r)) { /* Only care about GetSecrets requests here */ if (r->get_callback == NULL) continue; /* Cancel any matching GetSecrets call */ if ( g_strcmp0 (r->path, connection_path) == 0 && g_strcmp0 (r->setting_name, setting_name) == 0) { /* cancel outstanding keyring operations */ g_cancellable_cancel (r->cancellable); r->get_callback (NM_SECRET_AGENT (r->agent), r->connection, NULL, error, r->callback_data); g_hash_table_remove (priv->requests, GUINT_TO_POINTER (r->id)); g_signal_emit (r->agent, signals[CANCEL_SECRETS], 0, GUINT_TO_POINTER (r->id)); } } g_error_free (error); }
static void delete_secrets (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, NMSecretAgentDeleteSecretsFunc callback, gpointer callback_data) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); Request *r; NMSettingConnection *s_con; const char *uuid; KeyringCall *call; r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, NULL, callback, callback_data); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); uuid = nm_setting_connection_get_uuid (s_con); g_assert (uuid); call = keyring_call_new (r); call->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET, delete_find_items_cb, call, keyring_call_free, KEYRING_UUID_TAG, GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, uuid, NULL); r->keyring_calls = g_slist_append (r->keyring_calls, call); }
static void applet_agent_init (AppletAgent *self) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self); priv->requests = g_hash_table_new (g_direct_hash, g_direct_equal); }
void applet_agent_handle_vpn_only (AppletAgent *agent, gboolean vpn_only) { g_return_if_fail (agent != NULL); g_return_if_fail (APPLET_IS_AGENT (agent)); APPLET_AGENT_GET_PRIVATE (agent)->vpn_only = vpn_only; }
static void applet_agent_init (AppletAgent *self) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self); priv->requests = g_hash_table_new (g_direct_hash, g_direct_equal); g_signal_connect (self, NM_SECRET_AGENT_REGISTRATION_RESULT, G_CALLBACK (agent_registration_result_cb), NULL); }
static void save_secrets (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, NMSecretAgentSaveSecretsFunc callback, gpointer callback_data) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); Request *r; r = request_new (agent, connection, connection_path, NULL, NULL, FALSE, NULL, callback, NULL, callback_data); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); /* First delete any existing items in the keyring */ nm_secret_agent_delete_secrets (agent, connection, save_delete_cb, r); }
static void request_free (Request *r) { if (r->canceled == FALSE) g_hash_table_remove (APPLET_AGENT_GET_PRIVATE (r->agent)->requests, GUINT_TO_POINTER (r->id)); /* By the time the request is freed, all keyring calls should be completed */ g_warn_if_fail (r->keyring_calls == NULL); g_object_unref (r->connection); g_free (r->path); g_free (r->setting_name); g_strfreev (r->hints); memset (r, 0, sizeof (*r)); g_slice_free (Request, r); }
static void dispose (GObject *object) { AppletAgent *self = APPLET_AGENT (object); AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (self); if (!priv->disposed) { GHashTableIter iter; Request *r; /* Mark any outstanding requests as canceled */ g_hash_table_iter_init (&iter, priv->requests); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &r)) g_cancellable_cancel (r->cancellable); g_hash_table_destroy (priv->requests); priv->disposed = TRUE; } G_OBJECT_CLASS (applet_agent_parent_class)->dispose (object); }
static void get_secrets (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, const char *setting_name, const char **hints, guint32 flags, NMSecretAgentGetSecretsFunc callback, gpointer callback_data) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); Request *r; GError *error = NULL; NMSettingConnection *s_con; NMSetting *setting; const char *uuid, *ctype; GHashTable *attrs; setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); callback (agent, connection, NULL, error, callback_data); g_error_free (error); return; } uuid = nm_connection_get_uuid (connection); s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); ctype = nm_setting_connection_get_connection_type (s_con); if (!uuid || !ctype) { error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "%s.%d - Connection didn't have required UUID.", __FILE__, __LINE__); callback (agent, connection, NULL, error, callback_data); g_error_free (error); return; } /* Track the secrets request */ r = request_new (agent, connection, connection_path, setting_name, hints, flags, callback, NULL, NULL, callback_data); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); /* VPN passwords are handled by the VPN plugin's auth dialog */ if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) { ask_for_secrets (r); return; } /* Only handle non-VPN secrets if we're supposed to */ if (priv->vpn_only == TRUE) { error = g_error_new_literal (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_NO_SECRETS, "Only handling VPN secrets at this time."); callback (agent, connection, NULL, error, callback_data); g_error_free (error); return; } /* For everything else we scrape the keyring for secrets first, and ask * later if required. */ attrs = secret_attributes_build (&network_manager_secret_schema, KEYRING_UUID_TAG, uuid, KEYRING_SN_TAG, setting_name, NULL); secret_service_search (NULL, &network_manager_secret_schema, attrs, SECRET_SEARCH_ALL | SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS, r->cancellable, keyring_find_secrets_cb, r); r->keyring_calls++; g_hash_table_unref (attrs); }
static void get_secrets (NMSecretAgent *agent, NMConnection *connection, const char *connection_path, const char *setting_name, const char **hints, guint32 flags, NMSecretAgentGetSecretsFunc callback, gpointer callback_data) { AppletAgentPrivate *priv = APPLET_AGENT_GET_PRIVATE (agent); Request *r; GError *error = NULL; NMSettingConnection *s_con; NMSetting *setting; const char *uuid, *ctype; KeyringCall *call; setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "%s.%d - Connection didn't have requested setting '%s'.", __FILE__, __LINE__, setting_name); callback (agent, connection, NULL, error, callback_data); g_error_free (error); return; } uuid = nm_connection_get_uuid (connection); s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); ctype = nm_setting_connection_get_connection_type (s_con); if (!uuid || !ctype) { error = g_error_new (NM_SECRET_AGENT_ERROR, NM_SECRET_AGENT_ERROR_INVALID_CONNECTION, "%s.%d - Connection didn't have required UUID.", __FILE__, __LINE__); callback (agent, connection, NULL, error, callback_data); g_error_free (error); return; } /* Track the secrets request */ r = request_new (agent, connection, connection_path, setting_name, hints, flags, callback, NULL, NULL, callback_data); g_hash_table_insert (priv->requests, GUINT_TO_POINTER (r->id), r); /* VPN passwords are handled by the VPN plugin's auth dialog */ if (!strcmp (ctype, NM_SETTING_VPN_SETTING_NAME)) { ask_for_secrets (r); return; } /* For everything else we scrape the keyring for secrets first, and ask * later if required. */ call = keyring_call_new (r); call->keyring_id = gnome_keyring_find_itemsv (GNOME_KEYRING_ITEM_GENERIC_SECRET, keyring_find_secrets_cb, call, keyring_call_free, KEYRING_UUID_TAG, GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, uuid, KEYRING_SN_TAG, GNOME_KEYRING_ATTRIBUTE_TYPE_STRING, setting_name, NULL); r->keyring_calls = g_slist_append (r->keyring_calls, call); }