diff options
| author | Michael Biebl <biebl@debian.org> | 2011-04-21 10:42:53 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2011-04-21 10:42:53 +0200 |
| commit | 8baa1aca8dfd35e3190d7d5655eb83b5b901e263 (patch) | |
| tree | a9ac1e67d0c22a48330c76f08fc5291f85307055 /src/vpn-manager/nm-vpn-connection.c | |
| parent | f75dd6fd1975146623052b843b182dc32c3fbe46 (diff) | |
Imported Upstream version 0.8.4.0 upstream/0.8.4.0
Diffstat (limited to 'src/vpn-manager/nm-vpn-connection.c')
| -rw-r--r-- | src/vpn-manager/nm-vpn-connection.c | 263 |
1 files changed, 85 insertions, 178 deletions
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 601d29bc..823b6149 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -30,11 +30,11 @@ #include "NetworkManager.h" #include "NetworkManagerVPN.h" #include "nm-vpn-connection.h" -#include "nm-device-interface.h" #include "nm-setting-connection.h" #include "nm-setting-vpn.h" #include "nm-setting-ip4-config.h" #include "nm-dbus-manager.h" +#include "nm-manager.h" #include "nm-system.h" #include "nm-logging.h" #include "nm-utils.h" @@ -47,23 +47,20 @@ #include "nm-dns-manager.h" #include "nm-netlink-monitor.h" #include "nm-glib-compat.h" -#include "settings/nm-settings-connection.h" #include "nm-vpn-connection-glue.h" -G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_VPN_CONNECTION_BASE) +static void secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class); + +G_DEFINE_TYPE_EXTENDED (NMVPNConnection, nm_vpn_connection, NM_TYPE_VPN_CONNECTION_BASE, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SECRETS_PROVIDER_INTERFACE, + secrets_provider_interface_init)) typedef struct { gboolean disposed; NMConnection *connection; - gboolean user_requested; - gulong user_uid; - NMActRequest *act_request; - guint32 secrets_id; - char *username; - NMDevice *parent_dev; gulong device_monitor; gulong device_ip4; @@ -200,17 +197,12 @@ device_ip4_config_changed (NMDevice *device, } NMVPNConnection * -nm_vpn_connection_new (NMConnection *connection, - NMActRequest *act_request, - NMDevice *parent_device, - gboolean user_requested, - gulong user_uid) +nm_vpn_connection_new (NMConnection *connection, NMDevice *parent_device) { NMVPNConnection *self; NMVPNConnectionPrivate *priv; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); self = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL); @@ -219,11 +211,8 @@ nm_vpn_connection_new (NMConnection *connection, priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - priv->user_requested = user_requested; - priv->user_uid = user_uid; priv->connection = g_object_ref (connection); priv->parent_dev = g_object_ref (parent_device); - priv->act_request = g_object_ref (act_request); priv->device_monitor = g_signal_connect (parent_device, "state-changed", G_CALLBACK (device_state_changed), @@ -475,7 +464,8 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_BANNER); if (val) { - g_free (priv->banner); + if (priv->banner) + g_free (priv->banner); priv->banner = g_strdup (g_value_get_string (val)); } @@ -594,36 +584,8 @@ nm_vpn_connection_connect_cb (DBusGProxy *proxy, GError *err, gpointer user_data } } -/* Add a username to a hashed connection */ -static GHashTable * -_hash_with_username (NMConnection *connection, const char *username) -{ - NMConnection *dup; - NMSetting *s_vpn; - GHashTable *hash; - const char *existing; - - /* Shortcut if we weren't given a username or if there already was one in - * the VPN setting; don't bother duplicating the connection and everything. - */ - s_vpn = nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); - g_assert (s_vpn); - existing = nm_setting_vpn_get_user_name (NM_SETTING_VPN (s_vpn)); - if (username == NULL || existing) - return nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); - - dup = nm_connection_duplicate (connection); - g_assert (dup); - s_vpn = nm_connection_get_setting (dup, NM_TYPE_SETTING_VPN); - g_assert (s_vpn); - g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, username, NULL); - hash = nm_connection_to_hash (dup, NM_SETTING_HASH_FLAG_ALL); - g_object_unref (dup); - return hash; -} - static void -really_activate (NMVPNConnection *connection, const char *username) +really_activate (NMVPNConnection *connection) { NMVPNConnectionPrivate *priv; GHashTable *hash; @@ -643,7 +605,7 @@ really_activate (NMVPNConnection *connection, const char *username) G_CALLBACK (nm_vpn_connection_ip4_config_get), connection, NULL); - hash = _hash_with_username (priv->connection, username); + hash = nm_connection_to_hash (priv->connection); org_freedesktop_NetworkManager_VPN_Plugin_connect_async (priv->proxy, hash, nm_vpn_connection_connect_cb, @@ -791,26 +753,55 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, /******************************************************************************/ -static void -vpn_secrets_cb (NMSettingsConnection *connection, - guint32 call_id, - const char *agent_username, - const char *setting_name, - GError *error, - gpointer user_data) +static gboolean +secrets_update_setting (NMSecretsProviderInterface *interface, + const char *setting_name, + GHashTable *new) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); + NMVPNConnection *self = NM_VPN_CONNECTION (interface); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + GError *error = NULL; + + g_return_val_if_fail (priv->connection != NULL, FALSE); + + if (strcmp (setting_name, NM_SETTING_VPN_SETTING_NAME)) + return FALSE; + + if (!nm_connection_update_secrets (priv->connection, NM_SETTING_VPN_SETTING_NAME, new, &error)) { + nm_log_warn (LOGD_VPN, "Failed to update VPN secrets: %d %s", + error ? error->code : -1, + error && error->message ? error->message : "(none)"); + g_clear_error (&error); + return FALSE; + } + return TRUE; +} - g_return_if_fail (NM_CONNECTION (connection) == priv->connection); - g_return_if_fail (call_id == priv->secrets_id); +static void +secrets_result (NMSecretsProviderInterface *interface, + const char *setting_name, + RequestSecretsCaller caller, + const GSList *updated, + GError *error) +{ + NMVPNConnection *self = NM_VPN_CONNECTION (interface); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - priv->secrets_id = 0; + g_return_if_fail (priv->connection != NULL); + g_return_if_fail (caller == SECRETS_CALLER_VPN); if (error) nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); else - really_activate (self, agent_username); + really_activate (self); +} + +static void +secrets_provider_interface_init (NMSecretsProviderInterface *sp_interface_class) +{ + /* interface implementation */ + sp_interface_class->update_setting = secrets_update_setting; + sp_interface_class->result = secrets_result; } static void @@ -821,7 +812,6 @@ connection_need_secrets_cb (DBusGProxy *proxy, { NMVPNConnection *self = NM_VPN_CONNECTION (user_data); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - GError *local = NULL; if (error) { nm_log_err (LOGD_VPN, "NeedSecrets failed: %s %s", @@ -832,107 +822,35 @@ connection_need_secrets_cb (DBusGProxy *proxy, } if (!setting_name || !strlen (setting_name)) { - nm_log_dbg (LOGD_VPN, "(%s/%s) service indicated no additional secrets required", - nm_connection_get_uuid (priv->connection), - nm_connection_get_id (priv->connection)); - /* No secrets required */ - really_activate (self, priv->username); + really_activate (self); return; } - nm_log_dbg (LOGD_VPN, "(%s/%s) service indicated additional '%s' secrets required", - nm_connection_get_uuid (priv->connection), - nm_connection_get_id (priv->connection), - setting_name); - - priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), - priv->user_requested, - priv->user_uid, - setting_name, - NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION, - NULL, - vpn_secrets_cb, - self, - &local); - if (!priv->secrets_id) { - if (local) - nm_log_err (LOGD_VPN, "failed to get secrets: (%d) %s", local->code, local->message); + /* Get the secrets the VPN plugin wants */ + if (!nm_secrets_provider_interface_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (self), + priv->connection, + setting_name, + FALSE, + SECRETS_CALLER_VPN, + NULL, + NULL)) nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); - g_clear_error (&local); - } } static void -existing_secrets_cb (NMSettingsConnection *connection, - guint32 call_id, - const char *agent_username, - const char *setting_name, - GError *error, - gpointer user_data) +call_need_secrets (NMVPNConnection *vpn_connection) { - NMVPNConnection *self = NM_VPN_CONNECTION (user_data); - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - GHashTable *hash; - - g_return_if_fail (NM_CONNECTION (connection) == priv->connection); - g_return_if_fail (call_id == priv->secrets_id); - - priv->secrets_id = 0; - - if (error) { - nm_log_err (LOGD_VPN, "Failed to request existing VPN secrets #2: (%s) %s", - g_quark_to_string (error->domain), - error->message); - nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); - } else { - nm_log_dbg (LOGD_VPN, "(%s/%s) asking service if additional secrets are required", - nm_connection_get_uuid (priv->connection), - nm_connection_get_id (priv->connection)); - - /* Cache the username for later */ - g_free (priv->username); - priv->username = g_strdup (agent_username); - - /* Ask the VPN service if more secrets are required */ - hash = _hash_with_username (priv->connection, priv->username); - org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy, - hash, - connection_need_secrets_cb, - self); - g_hash_table_destroy (hash); - } -} - -static void -get_existing_secrets (NMVPNConnection *self) -{ - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - GError *error = NULL; - - nm_log_dbg (LOGD_VPN, "(%s/%s) requesting existing VPN secrets", - nm_connection_get_uuid (priv->connection), - nm_connection_get_id (priv->connection)); - - /* Just get existing secrets if any so we can ask the VPN service if - * any more are required. - */ - priv->secrets_id = nm_settings_connection_get_secrets (NM_SETTINGS_CONNECTION (priv->connection), - priv->user_requested, - priv->user_uid, - NM_SETTING_VPN_SETTING_NAME, - NM_SETTINGS_GET_SECRETS_FLAG_NONE, - NULL, - existing_secrets_cb, - self, - &error); - if (priv->secrets_id == 0) { - nm_log_err (LOGD_VPN, "Failed to request existing VPN secrets #1: (%s) %s", - g_quark_to_string (error->domain), - error->message); - g_error_free (error); - nm_vpn_connection_fail (self, NM_VPN_CONNECTION_STATE_REASON_NO_SECRETS); - } + NMVPNConnectionPrivate *priv; + GHashTable *settings; + + priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); + settings = nm_connection_to_hash (priv->connection); + org_freedesktop_NetworkManager_VPN_Plugin_need_secrets_async (priv->proxy, + settings, + connection_need_secrets_cb, + vpn_connection); + g_hash_table_destroy (settings); } static void @@ -977,11 +895,15 @@ vpn_cleanup (NMVPNConnection *connection) priv->gw_route = NULL; } - g_free (priv->banner); - priv->banner = NULL; + if (priv->banner) { + g_free (priv->banner); + priv->banner = NULL; + } - g_free (priv->ip_iface); - priv->ip_iface = NULL; + if (priv->ip_iface) { + g_free (priv->ip_iface); + priv->ip_iface = NULL; + } /* Clear out connection secrets to ensure that the settings service * gets asked for them next time the connection is activated. @@ -991,25 +913,17 @@ vpn_cleanup (NMVPNConnection *connection) } static void -connection_state_changed (NMVPNConnection *self, +connection_state_changed (NMVPNConnection *connection, NMVPNConnectionState state, NMVPNConnectionStateReason reason) { - NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (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; - } + nm_secrets_provider_interface_cancel_get_secrets (NM_SECRETS_PROVIDER_INTERFACE (connection)); switch (state) { case NM_VPN_CONNECTION_STATE_NEED_AUTH: - get_existing_secrets (self); - break; - case NM_VPN_CONNECTION_STATE_ACTIVATED: - /* Secrets no longer needed now that we're connected */ - nm_connection_clear_secrets (priv->connection); + call_need_secrets (connection); break; case NM_VPN_CONNECTION_STATE_DISCONNECTED: case NM_VPN_CONNECTION_STATE_FAILED: @@ -1025,7 +939,7 @@ connection_state_changed (NMVPNConnection *self, g_object_unref (priv->proxy); priv->proxy = NULL; } - vpn_cleanup (self); + vpn_cleanup (connection); break; default: break; @@ -1069,14 +983,7 @@ dispose (GObject *object) if (priv->proxy) g_object_unref (priv->proxy); - if (priv->secrets_id) { - nm_settings_connection_cancel_secrets (NM_SETTINGS_CONNECTION (priv->connection), - priv->secrets_id); - } - - g_object_unref (priv->act_request); g_object_unref (priv->connection); - g_free (priv->username); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object); } |