mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 01:47:58 +02:00
system-settings: cache secrets to protect against nm_connection_clear_secrets()
3rd patch in a series with:0bbdc6b0fcb135fa3265With NM 0.8 the system settings service was integrated into NM and thus nm_connection_clear_secrets() acts directly on the system settings plugins' NMConnection objects. So when NM cleared secrets (for example after determining that they might be bad in a device's stage2 handler), we completely lost the secrets forever. With this commit, the secrets are now cached and updated whenever the connection is updated, and thus are again available to send to NetworkManager when needed.
This commit is contained in:
parent
0bbdc6b0fc
commit
1151ac2478
1 changed files with 37 additions and 1 deletions
|
|
@ -43,6 +43,7 @@ G_DEFINE_TYPE_EXTENDED (NMSysconfigConnection, nm_sysconfig_connection, NM_TYPE_
|
|||
typedef struct {
|
||||
PolkitAuthority *authority;
|
||||
GSList *pk_calls;
|
||||
NMConnection *secrets;
|
||||
} NMSysconfigConnectionPrivate;
|
||||
|
||||
/**************************************************************/
|
||||
|
|
@ -60,9 +61,17 @@ nm_sysconfig_connection_update (NMSysconfigConnection *self,
|
|||
gboolean signal_update,
|
||||
GError **error)
|
||||
{
|
||||
NMSysconfigConnectionPrivate *priv;
|
||||
GHashTable *new_settings;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
g_return_val_if_fail (NM_IS_SYSCONFIG_CONNECTION (self), FALSE);
|
||||
g_return_val_if_fail (new != NULL, FALSE);
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (new), FALSE);
|
||||
|
||||
priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
/* Do nothing if there's nothing to update */
|
||||
if (nm_connection_compare (NM_CONNECTION (self),
|
||||
NM_CONNECTION (new),
|
||||
|
|
@ -72,6 +81,13 @@ nm_sysconfig_connection_update (NMSysconfigConnection *self,
|
|||
new_settings = nm_connection_to_hash (new);
|
||||
g_assert (new_settings);
|
||||
if (nm_connection_replace_settings (NM_CONNECTION (self), new_settings, error)) {
|
||||
/* Copy the connection to keep its secrets around even if NM
|
||||
* calls nm_connection_clear_secrets().
|
||||
*/
|
||||
if (priv->secrets)
|
||||
g_object_unref (priv->secrets);
|
||||
priv->secrets = nm_connection_duplicate (NM_CONNECTION (self));
|
||||
|
||||
if (signal_update) {
|
||||
nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (self),
|
||||
ignore_cb,
|
||||
|
|
@ -167,12 +183,29 @@ get_secrets (NMSettingsConnectionInterface *connection,
|
|||
NMSettingsConnectionInterfaceGetSecretsFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSysconfigConnection *self = NM_SYSCONFIG_CONNECTION (connection);
|
||||
NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
|
||||
GHashTable *settings = NULL;
|
||||
GHashTable *secrets = NULL;
|
||||
NMSetting *setting;
|
||||
GError *error = NULL;
|
||||
|
||||
setting = nm_connection_get_setting_by_name (NM_CONNECTION (connection), setting_name);
|
||||
/* Use priv->secrets to work around the fact that nm_connection_clear_secrets()
|
||||
* will clear secrets on this object's settings. priv->secrets should be
|
||||
* a complete copy of this object and kept in sync by
|
||||
* nm_sysconfig_connection_update().
|
||||
*/
|
||||
if (!priv->secrets) {
|
||||
error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
|
||||
NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
|
||||
"%s.%d - Internal error; secrets cache invalid.",
|
||||
__FILE__, __LINE__);
|
||||
(*callback) (connection, NULL, error, user_data);
|
||||
g_error_free (error);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
setting = nm_connection_get_setting_by_name (priv->secrets, setting_name);
|
||||
if (!setting) {
|
||||
error = g_error_new (NM_SETTINGS_INTERFACE_ERROR,
|
||||
NM_SETTINGS_INTERFACE_ERROR_INVALID_CONNECTION,
|
||||
|
|
@ -591,6 +624,9 @@ dispose (GObject *object)
|
|||
NMSysconfigConnectionPrivate *priv = NM_SYSCONFIG_CONNECTION_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
|
||||
if (priv->secrets)
|
||||
g_object_unref (priv->secrets);
|
||||
|
||||
/* Cancel PolicyKit requests */
|
||||
for (iter = priv->pk_calls; iter; iter = g_slist_next (iter)) {
|
||||
PolkitCall *call = iter->data;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue