libnm-util: verify permissions property type

Connections are normally created from hashes using g_object_set()
which calls that object's set_property handler.  But GObject does
not allow errors to be returned from property handlers, so if the
type doesn't match what it should be, the property does not get
set, and error is printed to stdout, and life goes on.

But that's not what we want for the permissions property since the
client might expect that property to be set, but the connection now
is available to everyone.  So validate the permissions property
type (its really the only one we need to be so paranoid about)
and return an error when the incoming property type is wrong.
This commit is contained in:
Dan Williams 2010-10-29 22:31:23 -05:00
parent 85db10a13f
commit 947efa3080

View file

@ -29,6 +29,7 @@
#include "nm-connection.h"
#include "nm-utils.h"
#include "nm-utils-private.h"
#include "nm-dbus-glib-types.h"
#include "nm-setting-8021x.h"
#include "nm-setting-bluetooth.h"
@ -456,6 +457,32 @@ nm_connection_get_setting_by_name (NMConnection *connection, const char *name)
return type ? nm_connection_get_setting (connection, type) : NULL;
}
static gboolean
validate_permissions_type (GHashTable *hash, GError **error)
{
GHashTable *s_con;
GValue *permissions;
/* Ensure the connection::permissions item (if present) is the correct
* type, otherwise the g_object_set() will throw a warning and ignore the
* error, leaving us with no permissions.
*/
s_con = g_hash_table_lookup (hash, NM_SETTING_CONNECTION_SETTING_NAME);
if (s_con) {
permissions = g_hash_table_lookup (s_con, NM_SETTING_CONNECTION_PERMISSIONS);
if (permissions) {
if (!G_VALUE_HOLDS (permissions, DBUS_TYPE_G_LIST_OF_STRING)) {
g_set_error_literal (error,
NM_SETTING_ERROR,
NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH,
"Wrong permissions property type; should be a list of strings.");
return FALSE;
}
}
}
return TRUE;
}
/**
* nm_connection_replace_settings:
* @connection: a #NMConnection
@ -476,6 +503,9 @@ nm_connection_replace_settings (NMConnection *connection,
if (error)
g_return_val_if_fail (*error == NULL, FALSE);
if (!validate_permissions_type (new_settings, error))
return FALSE;
g_hash_table_remove_all (NM_CONNECTION_GET_PRIVATE (connection)->settings);
g_hash_table_foreach (new_settings, parse_one_setting, connection);
@ -974,6 +1004,9 @@ nm_connection_new_from_hash (GHashTable *hash, GError **error)
g_return_val_if_fail (hash != NULL, NULL);
if (!validate_permissions_type (hash, error))
return FALSE;
connection = nm_connection_new ();
g_hash_table_foreach (hash, parse_one_setting, connection);