diff options
Diffstat (limited to 'src/nm-active-connection.c')
-rw-r--r-- | src/nm-active-connection.c | 177 |
1 files changed, 136 insertions, 41 deletions
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index 4b147f750c..aa892cc711 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -25,9 +25,11 @@ #include "nm-dbus-interface.h" #include "nm-device.h" #include "nm-settings-connection.h" +#include "nm-simple-connection.h" #include "nm-auth-utils.h" #include "nm-auth-subject.h" #include "NetworkManagerUtils.h" +#include "nm-core-internal.h" #include "nmdbus-active-connection.h" @@ -39,7 +41,8 @@ G_DEFINE_ABSTRACT_TYPE (NMActiveConnection, nm_active_connection, NM_TYPE_EXPORT NMActiveConnectionPrivate)) typedef struct { - NMConnection *connection; + NMSettingsConnection *settings_connection; + NMConnection *applied_connection; char *specific_object; NMDevice *device; @@ -82,7 +85,7 @@ enum { PROP_VPN, PROP_MASTER, - PROP_INT_CONNECTION, + PROP_INT_SETTINGS_CONNECTION, PROP_INT_DEVICE, PROP_INT_SUBJECT, PROP_INT_MASTER, @@ -173,7 +176,7 @@ nm_active_connection_set_state (NMActiveConnection *self, if ( new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) { - nm_settings_connection_update_timestamp (NM_SETTINGS_CONNECTION (priv->connection), + nm_settings_connection_update_timestamp (priv->settings_connection, (guint64) time (NULL), TRUE); } @@ -206,53 +209,120 @@ nm_active_connection_set_state (NMActiveConnection *self, } const char * -nm_active_connection_get_id (NMActiveConnection *self) +nm_active_connection_get_settings_connection_id (NMActiveConnection *self) { + NMSettingsConnection *con; + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - return nm_connection_get_id (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection); + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection; + return con + ? nm_connection_get_id (NM_CONNECTION (con)) + : NULL; } -const char * -nm_active_connection_get_uuid (NMActiveConnection *self) +NMSettingsConnection * +_nm_active_connection_get_settings_connection (NMActiveConnection *self) { g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - return nm_connection_get_uuid (NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection; } -NMConnection * -nm_active_connection_get_connection (NMActiveConnection *self) +NMSettingsConnection * +nm_active_connection_get_settings_connection (NMActiveConnection *self) { - return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->connection; + NMSettingsConnection *con; + + con = _nm_active_connection_get_settings_connection (self); + + /* Only call this function on an active-connection that is already + * fully set-up (i.e. that has a settings-connection). Other uses + * indicate a bug. */ + g_return_val_if_fail (con, NULL); + return con; } -const char * -nm_active_connection_get_connection_type (NMActiveConnection *self) +NMConnection * +nm_active_connection_get_applied_connection (NMActiveConnection *self) { - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + NMConnection *con; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - if (priv->connection == NULL) - return NULL; + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection; - return nm_connection_get_connection_type (priv->connection); + /* Only call this function on an active-connection that is already + * fully set-up (i.e. that has a settings-connection). Other uses + * indicate a bug. */ + g_return_val_if_fail (con, NULL); + return con; } void -nm_active_connection_set_connection (NMActiveConnection *self, - NMConnection *connection) +nm_active_connection_set_settings_connection (NMActiveConnection *self, + NMSettingsConnection *connection) { - NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + NMActiveConnectionPrivate *priv; - /* Can't change connection after the ActiveConnection is exported over D-Bus */ + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (!priv->settings_connection); + g_return_if_fail (!priv->applied_connection); + + /* Can't change connection after the ActiveConnection is exported over D-Bus. + * + * Later, we want to change the settings-connection of an activated connection. + * When doing that, this changes the assumption that the settings-connection + * never changes (once it's set). That has effects for NMVpnConnection and + * NMActivationRequest. + * For example, we'd have to cancel all pending seret requests. */ g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self))); - g_return_if_fail (priv->connection == NULL || !NM_IS_SETTINGS_CONNECTION (priv->connection)); - if (priv->connection) - g_object_unref (priv->connection); - priv->connection = g_object_ref (connection); + priv->settings_connection = g_object_ref (connection); + priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection)); + nm_connection_clear_secrets (priv->applied_connection); } +gboolean +nm_active_connection_has_unmodified_applied_connection (NMActiveConnection *self, NMSettingCompareFlags compare_flags) +{ + NMActiveConnectionPrivate *priv; + + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), FALSE); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + g_return_val_if_fail (priv->settings_connection, FALSE); + + return nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection, + priv->applied_connection, + compare_flags); +} + +/*******************************************************************/ + +void +nm_active_connection_clear_secrets (NMActiveConnection *self) +{ + NMActiveConnectionPrivate *priv; + + g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self)); + + priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); + + if (nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection, + priv->applied_connection, + NM_SETTING_COMPARE_FLAG_NONE)) + nm_connection_clear_secrets ((NMConnection *) priv->settings_connection); + nm_connection_clear_secrets (priv->applied_connection); +} + +/*******************************************************************/ + const char * nm_active_connection_get_specific_object (NMActiveConnection *self) { @@ -572,7 +642,7 @@ nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *m } _LOGD ("master ActiveConnection is [%p] %s", - master, nm_active_connection_get_id (master)); + master, nm_active_connection_get_settings_connection_id (master)); priv->master = g_object_ref (master); g_signal_connect (priv->master, @@ -667,6 +737,9 @@ done: /** * nm_active_connection_authorize: * @self: the #NMActiveConnection + * @initial_connection: (allow-none): for add-and-activate, there + * is no @settings_connection available when creating the active connection. + * Instead pass an alternative connection. * @result_func: function to be called on success or error * @user_data1: pointer passed to @result_func * @user_data2: additional pointer passed to @result_func @@ -677,16 +750,29 @@ done: */ void nm_active_connection_authorize (NMActiveConnection *self, + NMConnection *initial_connection, NMActiveConnectionAuthResultFunc result_func, gpointer user_data1, gpointer user_data2) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); const char *wifi_permission = NULL; + NMConnection *con; g_return_if_fail (result_func != NULL); g_return_if_fail (priv->chain == NULL); + if (initial_connection) { + g_return_if_fail (NM_IS_CONNECTION (initial_connection)); + g_return_if_fail (!priv->settings_connection); + g_return_if_fail (!priv->applied_connection); + con = initial_connection; + } else { + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (priv->settings_connection)); + g_return_if_fail (NM_IS_CONNECTION (priv->applied_connection)); + con = priv->applied_connection; + } + priv->chain = nm_auth_chain_new_subject (priv->subject, NULL, auth_done, self); g_assert (priv->chain); @@ -694,7 +780,7 @@ nm_active_connection_authorize (NMActiveConnection *self, nm_auth_chain_add_call (priv->chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, TRUE); /* Shared wifi connections require special permissions too */ - wifi_permission = nm_utils_get_shared_wifi_permission (priv->connection); + wifi_permission = nm_utils_get_shared_wifi_permission (con); if (wifi_permission) { priv->wifi_shared_permission = wifi_permission; nm_auth_chain_add_call (priv->chain, wifi_permission, TRUE); @@ -717,24 +803,32 @@ static void constructed (GObject *object) { NMActiveConnection *self = (NMActiveConnection *) object; + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object); - g_assert (NM_ACTIVE_CONNECTION_GET_PRIVATE (object)->subject); _LOGD ("constructed (%s)", G_OBJECT_TYPE_NAME (self)); + + g_return_if_fail (priv->subject); } static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) + const GValue *value, GParamSpec *pspec) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); const char *tmp; + NMSettingsConnection *con; switch (prop_id) { - case PROP_INT_CONNECTION: - g_warn_if_fail (priv->connection == NULL); - priv->connection = g_value_dup_object (value); + case PROP_INT_SETTINGS_CONNECTION: + /* construct-only */ + con = g_value_get_object (value); + if (con) { + priv->settings_connection = g_object_ref (con); + priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (con)); + nm_connection_clear_secrets (priv->applied_connection); + } break; case PROP_INT_DEVICE: nm_active_connection_set_device (NM_ACTIVE_CONNECTION (object), g_value_get_object (value)); @@ -778,16 +872,16 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_CONNECTION: - g_value_set_string (value, nm_connection_get_path (priv->connection)); + g_value_set_string (value, nm_connection_get_path (NM_CONNECTION (priv->settings_connection))); break; case PROP_ID: - g_value_set_string (value, nm_connection_get_id (priv->connection)); + g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->settings_connection))); break; case PROP_UUID: - g_value_set_string (value, nm_connection_get_uuid (priv->connection)); + g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->settings_connection))); break; case PROP_TYPE: - g_value_set_string (value, nm_connection_get_connection_type (priv->connection)); + g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->settings_connection))); break; case PROP_SPECIFIC_OBJECT: g_value_set_string (value, priv->specific_object ? priv->specific_object : "/"); @@ -883,7 +977,8 @@ dispose (GObject *object) g_free (priv->specific_object); priv->specific_object = NULL; - g_clear_object (&priv->connection); + g_clear_object (&priv->settings_connection); + g_clear_object (&priv->applied_connection); _device_cleanup (self); @@ -1024,10 +1119,10 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class) /* Internal properties */ g_object_class_install_property - (object_class, PROP_INT_CONNECTION, - g_param_spec_object (NM_ACTIVE_CONNECTION_INT_CONNECTION, "", "", - NM_TYPE_CONNECTION, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + (object_class, PROP_INT_SETTINGS_CONNECTION, + g_param_spec_object (NM_ACTIVE_CONNECTION_INT_SETTINGS_CONNECTION, "", "", + NM_TYPE_SETTINGS_CONNECTION, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); g_object_class_install_property |