diff --git a/ChangeLog b/ChangeLog index e70f196c4e..062e1f6951 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2008-08-26 Dan Williams + + Add connection UUIDs, since connection names can be changed, and since + old-style connection IDs could change over the life of the connection. The + UUID should be assigned at connection creation time, be stable for a given + connection, and should be unique among all connections for a given settings + service. + + * configure.in + libnm-util/Makefile.am + - Require libuuid + + * introspection/nm-exported-connection.xml + - Remove "GetID" method + + * libnm-glib/nm-dbus-connection.c + libnm-glib/nm-settings.c + libnm-glib/nm-settings.h + - Remove id-related stuff + + * libnm-util/nm-utils.c + libnm-util/nm-utils.h + libnm-util/libnm-util.ver + - (nm_utils_uuid_generate, nm_utils_uuid_generate_from_string): Add + utility functions to generate UUIDs + + * libnm-util/nm-setting-connection.c + libnm-util/nm-setting-connection.h + - Add 'uuid' member to the connection setting + - (verify): require valid 'uuid' for a valid connection + + * system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c + system-settings/plugins/ifcfg-fedora/reader.c + system-settings/plugins/ifcfg-suse/nm-suse-connection.c + system-settings/plugins/ifcfg-suse/parser.c + system-settings/plugins/keyfile/nm-keyfile-connection.c + system-settings/src/main.c + - Remove id-related stuff + - Give connections UUIDs where needed + 2008-08-25 Dan Williams * libnm-util/crypto_gnutls.c diff --git a/configure.in b/configure.in index b7aa4371dd..9f7db7c91f 100644 --- a/configure.in +++ b/configure.in @@ -243,6 +243,10 @@ PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8) AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_LIBS) +PKG_CHECK_MODULES(UUID, uuid) +AC_SUBST(UUID_CFLAGS) +AC_SUBST(UUID_LIBS) + PKG_CHECK_MODULES(POLKIT, polkit-dbus) ##### Find out the version of PolicyKit we're using diff --git a/introspection/nm-exported-connection.xml b/introspection/nm-exported-connection.xml index d0a8a707fa..0f2feeadf2 100644 --- a/introspection/nm-exported-connection.xml +++ b/introspection/nm-exported-connection.xml @@ -6,38 +6,27 @@ Represents a single network connection configuration. - + + + + Update the connection. + + + + - Obtain the ID of this connection. + New connection properties. - - - - The ID of this connection. - - + - - - Update the connection. - - + + + Delete the connection. + + - - - New connection properties. - - - - - - - Delete the connection. - - - - + diff --git a/libnm-glib/nm-dbus-connection.c b/libnm-glib/nm-dbus-connection.c index b3442478eb..f5ee94a7eb 100644 --- a/libnm-glib/nm-dbus-connection.c +++ b/libnm-glib/nm-dbus-connection.c @@ -52,12 +52,6 @@ get_settings (NMExportedConnection *exported) return nm_connection_to_hash (nm_exported_connection_get_connection (exported)); } -static const char * -get_id (NMExportedConnection *exported) -{ - return NM_DBUS_CONNECTION_GET_PRIVATE (exported)->path; -} - static void get_secrets (NMExportedConnection *connection, const gchar *setting_name, @@ -279,7 +273,6 @@ nm_dbus_connection_class_init (NMDBusConnectionClass *dbus_connection_class) object_class->finalize = finalize; connection_class->get_settings = get_settings; - connection_class->get_id = get_id; connection_class->get_secrets = get_secrets; connection_class->update = update; connection_class->delete = delete; diff --git a/libnm-glib/nm-settings.c b/libnm-glib/nm-settings.c index 3ac5b63340..430314761a 100644 --- a/libnm-glib/nm-settings.c +++ b/libnm-glib/nm-settings.c @@ -145,9 +145,6 @@ nm_settings_signal_new_connection (NMSettings *settings, NMExportedConnection *c * NMExportedConnection implementation */ -static gboolean impl_exported_connection_get_id (NMExportedConnection *connection, - gchar **id, - GError **error); static gboolean impl_exported_connection_get_settings (NMExportedConnection *connection, GHashTable **settings, GError **error); @@ -205,43 +202,6 @@ nm_exported_connection_new (NMConnection *wrapped) NULL); } -const char * -nm_exported_connection_get_id (NMExportedConnection *connection) -{ - NMExportedConnectionPrivate *priv; - NMSettingConnection *s_con; - - g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), NULL); - - priv = NM_EXPORTED_CONNECTION_GET_PRIVATE (connection); - if (EXPORTED_CONNECTION_CLASS (connection)->get_id) - return EXPORTED_CONNECTION_CLASS (connection)->get_id (connection); - - s_con = (NMSettingConnection *) nm_connection_get_setting (priv->wrapped, NM_TYPE_SETTING_CONNECTION); - if (NM_IS_SETTING_CONNECTION (s_con)) - return s_con->id; - - return NULL; -} - -static gboolean -impl_exported_connection_get_id (NMExportedConnection *connection, - gchar **id, - GError **error) -{ - g_return_val_if_fail (NM_IS_EXPORTED_CONNECTION (connection), FALSE); - - *id = g_strdup (nm_exported_connection_get_id (connection)); - if (!*id) { - g_set_error (error, NM_SETTINGS_ERROR, 1, - "%s.%d - Could not get connection ID.", - __FILE__, __LINE__); - return FALSE; - } - - return TRUE; -} - static gboolean impl_exported_connection_get_settings (NMExportedConnection *connection, GHashTable **settings, @@ -406,7 +366,6 @@ nm_exported_connection_class_init (NMExportedConnectionClass *exported_connectio object_class->get_property = get_property; object_class->dispose = nm_exported_connection_dispose; - exported_connection_class->get_id = NULL; exported_connection_class->get_settings = NULL; exported_connection_class->get_secrets = NULL; diff --git a/libnm-glib/nm-settings.h b/libnm-glib/nm-settings.h index 35c5022848..13b63885f4 100644 --- a/libnm-glib/nm-settings.h +++ b/libnm-glib/nm-settings.h @@ -32,13 +32,12 @@ typedef struct { GObjectClass parent_class; /* virtual methods */ - const gchar *(* get_id) (NMExportedConnection *connection); - GHashTable * (* get_settings) (NMExportedConnection *connection); - void (* get_secrets) (NMExportedConnection *connection, - const gchar *setting_name, - const gchar **hints, - gboolean request_new, - DBusGMethodInvocation *context); + GHashTable * (*get_settings) (NMExportedConnection *connection); + void (*get_secrets) (NMExportedConnection *connection, + const gchar *setting_name, + const gchar **hints, + gboolean request_new, + DBusGMethodInvocation *context); gboolean (*update) (NMExportedConnection *connection, GHashTable *new_settings, @@ -62,8 +61,6 @@ void nm_exported_connection_register_object (NMExportedConnection *connection, NMConnection *nm_exported_connection_get_connection (NMExportedConnection *connection); -const char *nm_exported_connection_get_id (NMExportedConnection *connection); - gboolean nm_exported_connection_update (NMExportedConnection *connection, GHashTable *new_settings, GError **err); diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 42d2fcdca7..a68b396290 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -2,10 +2,11 @@ INCLUDES = -I${top_srcdir} -I${top_srcdir}/include lib_LTLIBRARIES=libnm-util.la -libnm_util_la_CPPFLAGS = \ - $(GLIB_CFLAGS) \ - $(DBUS_CFLAGS) \ - -DDBUS_API_SUBJECT_TO_CHANGE \ +libnm_util_la_CPPFLAGS = \ + $(GLIB_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(UUID_CFLAGS) \ + -DDBUS_API_SUBJECT_TO_CHANGE \ -DG_DISABLE_DEPRECATED libnm_util_include_HEADERS = \ @@ -49,7 +50,7 @@ libnm_util_la_SOURCES= \ nm-utils.c \ $(libnm_util_include_HEADERS) -libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) +libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 218668d91e..9f5fa87114 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -120,6 +120,8 @@ global: nm_utils_string_in_list; nm_utils_string_list_contains; nm_utils_string_slist_validate; + nm_utils_uuid_generate; + nm_utils_uuid_generate_from_string; local: *; }; diff --git a/libnm-util/nm-setting-connection.c b/libnm-util/nm-setting-connection.c index bfc5f7444d..6c409bd3af 100644 --- a/libnm-util/nm-setting-connection.c +++ b/libnm-util/nm-setting-connection.c @@ -67,6 +67,7 @@ G_DEFINE_TYPE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING) enum { PROP_0, PROP_ID, + PROP_UUID, PROP_TYPE, PROP_AUTOCONNECT, PROP_TIMESTAMP, @@ -107,6 +108,20 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } + if (!self->uuid) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_MISSING_PROPERTY, + NM_SETTING_CONNECTION_UUID); + return FALSE; + } else if (!strlen (self->uuid)) { + g_set_error (error, + NM_SETTING_CONNECTION_ERROR, + NM_SETTING_CONNECTION_ERROR_INVALID_PROPERTY, + NM_SETTING_CONNECTION_UUID); + return FALSE; + } + if (!self->type) { g_set_error (error, NM_SETTING_CONNECTION_ERROR, @@ -145,6 +160,7 @@ finalize (GObject *object) NMSettingConnection *self = NM_SETTING_CONNECTION (object); g_free (self->id); + g_free (self->uuid); g_free (self->type); G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object); @@ -161,6 +177,10 @@ set_property (GObject *object, guint prop_id, g_free (setting->id); setting->id = g_value_dup_string (value); break; + case PROP_UUID: + g_free (setting->uuid); + setting->uuid = g_value_dup_string (value); + break; case PROP_TYPE: g_free (setting->type); setting->type = g_value_dup_string (value); @@ -187,6 +207,9 @@ get_property (GObject *object, guint prop_id, case PROP_ID: g_value_set_string (value, setting->id); break; + case PROP_UUID: + g_value_set_string (value, setting->uuid); + break; case PROP_TYPE: g_value_set_string (value, setting->type); break; @@ -223,6 +246,14 @@ nm_setting_connection_class_init (NMSettingConnectionClass *setting_class) NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_object_class_install_property + (object_class, PROP_UUID, + g_param_spec_string (NM_SETTING_CONNECTION_UUID, + "UUID", + "Universally unique connection identifier", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_FUZZY_IGNORE)); + g_object_class_install_property (object_class, PROP_TYPE, g_param_spec_string (NM_SETTING_CONNECTION_TYPE, diff --git a/libnm-util/nm-setting-connection.h b/libnm-util/nm-setting-connection.h index 2aaeba1607..d5e032a8e7 100644 --- a/libnm-util/nm-setting-connection.h +++ b/libnm-util/nm-setting-connection.h @@ -54,6 +54,7 @@ GType nm_setting_connection_error_get_type (void); GQuark nm_setting_connection_error_quark (void); #define NM_SETTING_CONNECTION_ID "id" +#define NM_SETTING_CONNECTION_UUID "uuid" #define NM_SETTING_CONNECTION_TYPE "type" #define NM_SETTING_CONNECTION_AUTOCONNECT "autoconnect" #define NM_SETTING_CONNECTION_TIMESTAMP "timestamp" @@ -62,6 +63,7 @@ typedef struct { NMSetting parent; char *id; + char *uuid; char *type; gboolean autoconnect; guint64 timestamp; diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 010ba80a96..0bca14e1f6 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -35,11 +35,14 @@ #include #include #include +#include + #include "nm-utils.h" #include "NetworkManager.h" #include "nm-dbus-glib-types.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" +#include "crypto.h" struct EncodingTriplet { @@ -1105,3 +1108,51 @@ nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value) g_value_take_boxed (value, dns); } + +char * +nm_utils_uuid_generate (void) +{ + uuid_t uuid; + char *buf; + + buf = g_malloc0 (37); + uuid_generate_random (uuid); + uuid_unparse_lower (uuid, &buf[0]); + return buf; +} + +char * +nm_utils_uuid_generate_from_string (const char *s) +{ + GError *error = NULL; + uuid_t *uuid; + char *buf = NULL; + + if (!crypto_init (&error)) { + nm_warning ("error initializing crypto: (%d) %s", + error ? error->code : 0, + error ? error->message : "unknown"); + if (error) + g_error_free (error); + return NULL; + } + + uuid = g_malloc0 (sizeof (uuid)); + if (!crypto_md5_hash (NULL, 0, s, strlen (s), (char *) uuid, sizeof (uuid), &error)) { + nm_warning ("error generating UUID: (%d) %s", + error ? error->code : 0, + error ? error->message : "unknown"); + if (error) + g_error_free (error); + goto out; + } + + buf = g_malloc0 (37); + uuid_unparse_lower (*uuid, &buf[0]); + +out: + g_free (uuid); + crypto_deinit (); + return buf; +} + diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index 464c0c5b6e..ff123ab3cd 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -196,4 +196,7 @@ void nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value); GSList *nm_utils_ip6_dns_from_gvalue (const GValue *value); void nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value); +char *nm_utils_uuid_generate (void); +char *nm_utils_uuid_generate_from_string (const char *s); + #endif /* NM_UTILS_H */ diff --git a/system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c b/system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c index 6e4064ff78..c997dded5c 100644 --- a/system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c +++ b/system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c @@ -318,12 +318,6 @@ get_settings (NMExportedConnection *exported) return nm_connection_to_hash (nm_exported_connection_get_connection (exported)); } -static const char * -get_id (NMExportedConnection *exported) -{ - return NM_IFCFG_CONNECTION_GET_PRIVATE (exported)->filename; -} - static gboolean update (NMExportedConnection *exported, GHashTable *new_settings, GError **error) { @@ -448,7 +442,6 @@ nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class) object_class->finalize = finalize; connection_class->get_settings = get_settings; - connection_class->get_id = get_id; connection_class->update = update; connection_class->delete = delete; diff --git a/system-settings/plugins/ifcfg-fedora/reader.c b/system-settings/plugins/ifcfg-fedora/reader.c index 0f926cce14..61f363723b 100644 --- a/system-settings/plugins/ifcfg-fedora/reader.c +++ b/system-settings/plugins/ifcfg-fedora/reader.c @@ -111,6 +111,8 @@ make_connection_setting (const char *file, s_con->type = g_strdup (type); + s_con->uuid = nm_utils_uuid_generate_from_string (ifcfg->fileName); + /* Be somewhat conservative about autoconnect */ if (svTrueValue (ifcfg, "ONBOOT", FALSE)) s_con->autoconnect = TRUE; diff --git a/system-settings/plugins/ifcfg-suse/nm-suse-connection.c b/system-settings/plugins/ifcfg-suse/nm-suse-connection.c index 52d300059f..230da18ea7 100644 --- a/system-settings/plugins/ifcfg-suse/nm-suse-connection.c +++ b/system-settings/plugins/ifcfg-suse/nm-suse-connection.c @@ -100,12 +100,6 @@ get_settings (NMExportedConnection *exported) return nm_connection_to_hash (nm_exported_connection_get_connection (exported)); } -static const char * -get_id (NMExportedConnection *exported) -{ - return NM_SUSE_CONNECTION_GET_PRIVATE (exported)->filename; -} - static gboolean update (NMExportedConnection *exported, GHashTable *new_settings, @@ -165,7 +159,6 @@ nm_suse_connection_class_init (NMSuseConnectionClass *suse_connection_class) object_class->finalize = finalize; connection_class->get_settings = get_settings; - connection_class->get_id = get_id; connection_class->update = update; connection_class->delete = delete; } diff --git a/system-settings/plugins/ifcfg-suse/parser.c b/system-settings/plugins/ifcfg-suse/parser.c index 56f5eccff4..9683c860ff 100644 --- a/system-settings/plugins/ifcfg-suse/parser.c +++ b/system-settings/plugins/ifcfg-suse/parser.c @@ -64,7 +64,7 @@ get_int (const char *str, int *value) static NMSetting * make_connection_setting (shvarFile *file, - const char *iface, + const char *iface, const char *type, const char *suggested) { @@ -85,6 +85,8 @@ make_connection_setting (shvarFile *file, s_con->type = g_strdup (type); + s_con->uuid = nm_utils_uuid_generate_from_string (file->fileName); + str = svGetValue (file, "STARTMODE"); if (str && !g_ascii_strcasecmp (str, "manual")) s_con->autoconnect = FALSE; diff --git a/system-settings/plugins/keyfile/nm-keyfile-connection.c b/system-settings/plugins/keyfile/nm-keyfile-connection.c index 3cdfe27d11..1999050eb5 100644 --- a/system-settings/plugins/keyfile/nm-keyfile-connection.c +++ b/system-settings/plugins/keyfile/nm-keyfile-connection.c @@ -3,6 +3,9 @@ #include #include #include +#include +#include + #include "nm-keyfile-connection.h" #include "reader.h" #include "writer.h" @@ -46,12 +49,6 @@ get_settings (NMExportedConnection *exported) return nm_connection_to_hash (nm_exported_connection_get_connection (exported)); } -static const char * -get_id (NMExportedConnection *exported) -{ - return NM_KEYFILE_CONNECTION_GET_PRIVATE (exported)->filename; -} - static gboolean update (NMExportedConnection *exported, GHashTable *new_settings, @@ -95,6 +92,7 @@ constructor (GType type, GObject *object; NMKeyfileConnectionPrivate *priv; NMConnection *wrapped; + NMSettingConnection *s_con; object = G_OBJECT_CLASS (nm_keyfile_connection_parent_class)->constructor (type, n_construct_params, construct_params); @@ -112,6 +110,20 @@ constructor (GType type, if (!wrapped) goto err; + /* if for some reason the connection didn't have a UUID, add one */ + s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION); + if (s_con && !s_con->uuid) { + GError *error = NULL; + + s_con->uuid = nm_utils_uuid_generate (); + if (!write_connection (wrapped, &error)) { + g_warning ("Couldn't update connection %s with a UUID: (%d) %s", + s_con->id, error ? error->code : 0, + error ? error->message : "unknown"); + g_error_free (error); + } + } + g_object_set (object, NM_EXPORTED_CONNECTION_CONNECTION, wrapped, NULL); g_object_unref (wrapped); @@ -181,7 +193,6 @@ nm_keyfile_connection_class_init (NMKeyfileConnectionClass *keyfile_connection_c object_class->finalize = finalize; connection_class->get_settings = get_settings; - connection_class->get_id = get_id; connection_class->update = update; connection_class->delete = delete; diff --git a/system-settings/src/main.c b/system-settings/src/main.c index 8832d07b8d..7eb3b4ce58 100644 --- a/system-settings/src/main.c +++ b/system-settings/src/main.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "dbus-settings.h" @@ -365,6 +366,7 @@ add_default_dhcp_connection (gpointer user_data) s_con->id = g_strdup_printf (_("Auto %s"), info->iface); s_con->type = g_strdup (NM_SETTING_WIRED_SETTING_NAME); s_con->autoconnect = TRUE; + s_con->uuid = nm_utils_uuid_generate (); nm_connection_add_setting (wrapped, NM_SETTING (s_con)); g_message ("Adding default connection '%s' for %s", s_con->id, info->udi);