diff options
| author | Michael Biebl <biebl@debian.org> | 2014-07-06 02:16:10 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2014-07-06 02:16:10 +0200 |
| commit | 33491bc4279481db8ae47213e34a6d695a0e8830 (patch) | |
| tree | 097d2b0fdff3fae6885381ae5e57a182cd8cbbba /src/settings/plugins/keyfile | |
| parent | 59c3714a494c3b3765657c0551ad82842d98a7d2 (diff) | |
Imported Upstream version 0.9.10.0 upstream/0.9.10.0
Diffstat (limited to 'src/settings/plugins/keyfile')
21 files changed, 1842 insertions, 728 deletions
diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am index b0cd688a..cac97e7f 100644 --- a/src/settings/plugins/keyfile/Makefile.am +++ b/src/settings/plugins/keyfile/Makefile.am @@ -1,13 +1,21 @@ SUBDIRS = . tests +@GNOME_CODE_COVERAGE_RULES@ + AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/config \ + -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ + -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ -DNMCONFDIR=\"$(nmconfdir)\" noinst_LTLIBRARIES = \ diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in index 79dfcb42..8c4d6101 100644 --- a/src/settings/plugins/keyfile/Makefile.in +++ b/src/settings/plugins/keyfile/Makefile.in @@ -82,7 +82,8 @@ subdir = src/settings/plugins/keyfile DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -250,12 +251,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -280,7 +284,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -325,12 +328,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -347,6 +354,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -374,11 +383,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -393,6 +407,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -455,6 +470,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -465,15 +481,22 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ SUBDIRS = . tests AM_CPPFLAGS = \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/config \ + -I$(top_srcdir)/src/logging \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/include \ -I$(top_builddir)/include \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ + -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ -DNMCONFDIR=\"$(nmconfdir)\" noinst_LTLIBRARIES = \ @@ -881,6 +904,8 @@ uninstall-am: tags tags-am uninstall uninstall-am +@GNOME_CODE_COVERAGE_RULES@ + install-data-hook: $(mkinstalldirs) -m 0755 $(DESTDIR)$(keyfiledir) diff --git a/src/settings/plugins/keyfile/common.h b/src/settings/plugins/keyfile/common.h index d48c32f2..4faa5a84 100644 --- a/src/settings/plugins/keyfile/common.h +++ b/src/settings/plugins/keyfile/common.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2008 - 2010 Red Hat, Inc. + * (C) Copyright 2008 - 2013 Red Hat, Inc. */ #ifndef __COMMON_H__ @@ -24,7 +24,7 @@ #include <glib.h> #define KEYFILE_PLUGIN_NAME "keyfile" -#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2010 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." +#define KEYFILE_PLUGIN_INFO "(c) 2007 - 2013 Red Hat, Inc. To report bugs please use the NetworkManager mailing list." #define KEYFILE_DIR NMCONFDIR "/system-connections" diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.c b/src/settings/plugins/keyfile/nm-keyfile-connection.c index 6d72bbfe..4ef761c6 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.c +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.c @@ -41,16 +41,17 @@ typedef struct { } NMKeyfileConnectionPrivate; NMKeyfileConnection * -nm_keyfile_connection_new (const char *full_path, - NMConnection *source, +nm_keyfile_connection_new (NMConnection *source, + const char *full_path, GError **error) { GObject *object; NMKeyfileConnectionPrivate *priv; NMConnection *tmp; const char *uuid; + gboolean update_unsaved = TRUE; - g_return_val_if_fail (full_path != NULL, NULL); + g_assert (source || full_path); /* If we're given a connection already, prefer that instead of re-reading */ if (source) @@ -59,31 +60,33 @@ nm_keyfile_connection_new (const char *full_path, tmp = nm_keyfile_plugin_connection_from_file (full_path, error); if (!tmp) return NULL; + + uuid = nm_connection_get_uuid (NM_CONNECTION (tmp)); + if (!uuid) { + g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, + "Connection in file %s had no UUID", full_path); + g_object_unref (tmp); + return NULL; + } + + /* If we just read the connection from disk, it's clearly not Unsaved */ + update_unsaved = FALSE; } object = (GObject *) g_object_new (NM_TYPE_KEYFILE_CONNECTION, NULL); - if (!object) - goto out; priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (object); priv->path = g_strdup (full_path); /* Update our settings with what was read from the file */ - if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), tmp, error)) { - g_object_unref (object); - object = NULL; - goto out; - } - - uuid = nm_connection_get_uuid (NM_CONNECTION (object)); - if (!uuid) { - g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, - "Connection in file %s had no UUID", full_path); + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (object), + tmp, + update_unsaved, + error)) { g_object_unref (object); object = NULL; } -out: g_object_unref (tmp); return (NMKeyfileConnection *) object; } @@ -145,7 +148,8 @@ do_delete (NMSettingsConnection *connection, { NMKeyfileConnectionPrivate *priv = NM_KEYFILE_CONNECTION_GET_PRIVATE (connection); - g_unlink (priv->path); + if (priv->path) + g_unlink (priv->path); NM_SETTINGS_CONNECTION_CLASS (nm_keyfile_connection_parent_class)->delete (connection, callback, diff --git a/src/settings/plugins/keyfile/nm-keyfile-connection.h b/src/settings/plugins/keyfile/nm-keyfile-connection.h index e3bce11b..07dcafcb 100644 --- a/src/settings/plugins/keyfile/nm-keyfile-connection.h +++ b/src/settings/plugins/keyfile/nm-keyfile-connection.h @@ -43,8 +43,8 @@ typedef struct { GType nm_keyfile_connection_get_type (void); -NMKeyfileConnection *nm_keyfile_connection_new (const char *filename, - NMConnection *source, +NMKeyfileConnection *nm_keyfile_connection_new (NMConnection *source, + const char *filename, GError **error); const char *nm_keyfile_connection_get_path (NMKeyfileConnection *self); diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c index ef6613e6..10c83971 100644 --- a/src/settings/plugins/keyfile/plugin.c +++ b/src/settings/plugins/keyfile/plugin.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2012 Red Hat, Inc. + * Copyright (C) 2008 - 2013 Red Hat, Inc. */ #include <config.h> @@ -34,6 +34,9 @@ #include <nm-connection.h> #include <nm-setting.h> #include <nm-setting-connection.h> +#include <nm-utils.h> +#include <nm-config.h> +#include <nm-logging.h> #include "plugin.h" #include "nm-system-config-interface.h" @@ -52,12 +55,13 @@ G_DEFINE_TYPE_EXTENDED (SCPluginKeyfile, sc_plugin_keyfile, G_TYPE_OBJECT, 0, #define SC_PLUGIN_KEYFILE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SC_TYPE_PLUGIN_KEYFILE, SCPluginKeyfilePrivate)) typedef struct { - GHashTable *hash; + GHashTable *connections; /* uuid::connection */ + gboolean initialized; GFileMonitor *monitor; guint monitor_id; - char *conf_file; + const char *conf_file; GFileMonitor *conf_file_monitor; guint conf_file_monitor_id; @@ -66,127 +70,132 @@ typedef struct { gboolean disposed; } SCPluginKeyfilePrivate; -static NMSettingsConnection * -_internal_new_connection (SCPluginKeyfile *self, - const char *full_path, - NMConnection *source, - GError **error) +static void +connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) { - SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - NMKeyfileConnection *connection; + g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (user_data)->connections, + nm_connection_get_uuid (NM_CONNECTION (obj))); +} - g_return_val_if_fail (full_path != NULL, NULL); +/* Monitoring */ - connection = nm_keyfile_connection_new (full_path, source, error); - if (connection) { - g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_path (connection), - connection); - } +static void +remove_connection (SCPluginKeyfile *self, NMKeyfileConnection *connection) +{ + gboolean removed; + + g_return_if_fail (connection != NULL); + + nm_log_info (LOGD_SETTINGS, "removed %s.", nm_keyfile_connection_get_path (connection)); - return (NMSettingsConnection *) connection; + /* Removing from the hash table should drop the last reference */ + g_object_ref (connection); + g_signal_handlers_disconnect_by_func (connection, connection_removed_cb, self); + removed = g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->connections, + nm_connection_get_uuid (NM_CONNECTION (connection))); + nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); + g_object_unref (connection); + + g_return_if_fail (removed); } static void -read_connections (NMSystemConfigInterface *config) +update_connection (SCPluginKeyfile *self, + NMKeyfileConnection *connection, + const char *name) { - SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); - GDir *dir; + NMKeyfileConnection *tmp; GError *error = NULL; - const char *item; - dir = g_dir_open (KEYFILE_DIR, 0, &error); - if (!dir) { - PLUGIN_WARN (KEYFILE_PLUGIN_NAME, "Cannot read directory '%s': (%d) %s", - KEYFILE_DIR, - error ? error->code : -1, - error && error->message ? error->message : "(unknown)"); + tmp = nm_keyfile_connection_new (NULL, name, &error); + if (!tmp) { + /* Error; remove the connection */ + nm_log_warn (LOGD_SETTINGS, " error in connection %s: %s", name, + (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); + remove_connection (self, connection); return; } - while ((item = g_dir_read_name (dir))) { - NMSettingsConnection *connection; - char *full_path; - - if (nm_keyfile_plugin_utils_should_ignore_file (item)) - continue; - - full_path = g_build_filename (KEYFILE_DIR, item, NULL); - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "parsing %s ... ", item); - - connection = _internal_new_connection (self, full_path, NULL, &error); - if (connection) { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " read connection '%s'", - nm_connection_get_id (NM_CONNECTION (connection))); - } else { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", - (error && error->message) ? error->message : "(unknown)"); + if (!nm_connection_compare (NM_CONNECTION (connection), + NM_CONNECTION (tmp), + NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | + NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { + nm_log_info (LOGD_SETTINGS, "updating %s", name); + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection), + NM_CONNECTION (tmp), + FALSE, /* don't set Unsaved */ + &error)) { + /* Shouldn't ever get here as 'new' was verified by the reader already */ + g_assert_no_error (error); } - g_clear_error (&error); - g_free (full_path); } - g_dir_close (dir); + g_object_unref (tmp); } -static void -update_connection_settings_commit_cb (NMSettingsConnection *orig, GError *error, gpointer user_data) +static NMKeyfileConnection * +find_by_path (SCPluginKeyfile *self, const char *path) { - if (error) { - g_warning ("%s: '%s' / '%s' invalid: %d", - __func__, - error ? g_type_name (nm_connection_lookup_setting_type_by_quark (error->domain)) : "(none)", - (error && error->message) ? error->message : "(none)", - error ? error->code : -1); - g_clear_error (&error); + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + GHashTableIter iter; + NMKeyfileConnection *candidate = NULL; - nm_settings_connection_signal_remove (orig); - } -} + g_return_val_if_fail (path != NULL, NULL); -static void -update_connection_settings (NMKeyfileConnection *orig, - NMKeyfileConnection *new) -{ - nm_settings_connection_replace_and_commit (NM_SETTINGS_CONNECTION (orig), - NM_CONNECTION (new), - update_connection_settings_commit_cb, NULL); + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) &candidate)) { + if (g_strcmp0 (path, nm_keyfile_connection_get_path (candidate)) == 0) + return candidate; + } + return NULL; } -/* Monitoring */ - static void -remove_connection (SCPluginKeyfile *self, - NMKeyfileConnection *connection, - const char *name) -{ - g_return_if_fail (connection != NULL); - g_return_if_fail (name != NULL); - - /* Removing from the hash table should drop the last reference */ - g_object_ref (connection); - g_hash_table_remove (SC_PLUGIN_KEYFILE_GET_PRIVATE (self)->hash, name); - nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); - g_object_unref (connection); -} - -static NMKeyfileConnection * -find_by_uuid (SCPluginKeyfile *self, const char *uuid) +new_connection (SCPluginKeyfile *self, + const char *name, + char **out_old_path) { SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - GHashTableIter iter; - gpointer data = NULL; + NMKeyfileConnection *tmp, *connection; + GError *error = NULL; + const char *uuid; - g_return_val_if_fail (uuid != NULL, NULL); + if (out_old_path) + *out_old_path = NULL; - g_hash_table_iter_init (&iter, priv->hash); - while (g_hash_table_iter_next (&iter, NULL, &data)) { - NMConnection *candidate = NM_CONNECTION (data); + tmp = nm_keyfile_connection_new (NULL, name, &error); + if (!tmp) { + nm_log_warn (LOGD_SETTINGS, " error in connection %s: %s", name, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + return; + } - if (strcmp (uuid, nm_connection_get_uuid (candidate)) == 0) - return NM_KEYFILE_CONNECTION (candidate); + /* Connection renames will show as different paths but same UUID */ + uuid = nm_connection_get_uuid (NM_CONNECTION (tmp)); + connection = g_hash_table_lookup (priv->connections, uuid); + if (connection) { + nm_log_info (LOGD_SETTINGS, "rename %s -> %s", nm_keyfile_connection_get_path (connection), name); + if (!nm_settings_connection_replace_settings (NM_SETTINGS_CONNECTION (connection), + NM_CONNECTION (tmp), + FALSE, /* don't set Unsaved */ + &error)) { + /* Shouldn't ever get here as 'tmp' was verified by the reader already */ + g_assert_no_error (error); + } + g_object_unref (tmp); + if (out_old_path) + *out_old_path = g_strdup (nm_keyfile_connection_get_path (connection)); + nm_keyfile_connection_set_path (connection, name); + } else { + nm_log_info (LOGD_SETTINGS, "new connection %s", name); + g_hash_table_insert (priv->connections, g_strdup (uuid), tmp); + g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, tmp); + + g_signal_connect (tmp, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); } - return NULL; } static void @@ -198,10 +207,8 @@ dir_changed (GFileMonitor *monitor, { NMSystemConfigInterface *config = NM_SYSTEM_CONFIG_INTERFACE (user_data); SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); - SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); - char *full_path; NMKeyfileConnection *connection; - GError *error = NULL; + char *full_path; full_path = g_file_get_path (file); if (nm_keyfile_plugin_utils_should_ignore_file (full_path)) { @@ -209,89 +216,19 @@ dir_changed (GFileMonitor *monitor, return; } - connection = g_hash_table_lookup (priv->hash, full_path); + connection = find_by_path (self, full_path); switch (event_type) { case G_FILE_MONITOR_EVENT_DELETED: - if (connection) { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "removed %s.", full_path); - remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); - } + if (connection) + remove_connection (SC_PLUGIN_KEYFILE (config), connection); break; case G_FILE_MONITOR_EVENT_CREATED: case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT: - if (connection) { - /* Update */ - NMKeyfileConnection *tmp; - - tmp = nm_keyfile_connection_new (full_path, NULL, &error); - if (tmp) { - if (!nm_connection_compare (NM_CONNECTION (connection), - NM_CONNECTION (tmp), - NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | - NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); - update_connection_settings (connection, tmp); - } - g_object_unref (tmp); - } else { - /* Error; remove the connection */ - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", - (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); - remove_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); - } - } else { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, "updating %s", full_path); - - /* New */ - connection = nm_keyfile_connection_new (full_path, NULL, &error); - if (connection) { - NMKeyfileConnection *found = NULL; - - /* Connection renames will show up as different files but with - * the same UUID. Try to find the original connection. - * A connection rename is treated just like an update except - * there's a bit more housekeeping with the hash table. - */ - found = find_by_uuid (self, nm_connection_get_uuid (NM_CONNECTION (connection))); - if (found) { - const char *old_path = nm_keyfile_connection_get_path (connection); - - /* Removing from the hash table should drop the last reference, - * but of course we want to keep the connection around. - */ - g_object_ref (found); - g_hash_table_remove (priv->hash, old_path); - - /* Updating settings should update the NMKeyfileConnection's - * filename property too. - */ - update_connection_settings (found, connection); - /* However, when connections are the same and only the filename changed - * we need to update the path manually (commit_changes() is not called. - */ - nm_keyfile_connection_set_path (found, full_path); - - /* Re-insert the connection back into the hash with the new filename */ - g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_path (found), - found); - - /* Get rid of the temporary connection */ - g_object_unref (connection); - } else { - g_hash_table_insert (priv->hash, - (gpointer) nm_keyfile_connection_get_path (connection), - connection); - g_signal_emit_by_name (config, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); - } - } else { - PLUGIN_PRINT (KEYFILE_PLUGIN_NAME, " error: %s", - (error && error->message) ? error->message : "(unknown)"); - g_clear_error (&error); - } - } + if (connection) + update_connection (SC_PLUGIN_KEYFILE (config), connection, full_path); + else + new_connection (SC_PLUGIN_KEYFILE (config), full_path, NULL); break; default: break; @@ -344,15 +281,15 @@ setup_monitoring (NMSystemConfigInterface *config) GFile *file; GFileMonitor *monitor; - priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - - file = g_file_new_for_path (KEYFILE_DIR); - monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); - g_object_unref (file); + if (nm_config_get_monitor_connection_files (nm_config_get ())) { + file = g_file_new_for_path (KEYFILE_DIR); + monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL); + g_object_unref (file); - if (monitor) { - priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), config); - priv->monitor = monitor; + if (monitor) { + priv->monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (dir_changed), config); + priv->monitor = monitor; + } } if (priv->conf_file) { @@ -367,6 +304,69 @@ setup_monitoring (NMSystemConfigInterface *config) } } +static void +read_connections (NMSystemConfigInterface *config) +{ + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); + GDir *dir; + GError *error = NULL; + const char *item; + GHashTable *oldconns; + GHashTableIter iter; + gpointer data; + + dir = g_dir_open (KEYFILE_DIR, 0, &error); + if (!dir) { + nm_log_warn (LOGD_SETTINGS, "Cannot read directory '%s': (%d) %s", + KEYFILE_DIR, + error ? error->code : -1, + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + return; + } + + oldconns = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_iter_init (&iter, priv->connections); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + const char *con_path = nm_keyfile_connection_get_path (data); + if (con_path) + g_hash_table_insert (oldconns, g_strdup (con_path), data); + } + + while ((item = g_dir_read_name (dir))) { + NMKeyfileConnection *connection; + char *full_path, *old_path; + + if (nm_keyfile_plugin_utils_should_ignore_file (item)) + continue; + + full_path = g_build_filename (KEYFILE_DIR, item, NULL); + + connection = g_hash_table_lookup (oldconns, full_path); + if (connection) { + g_hash_table_remove (oldconns, full_path); + update_connection (self, connection, full_path); + } else { + new_connection (self, full_path, &old_path); + if (old_path) { + g_hash_table_remove (oldconns, old_path); + g_free (old_path); + } + } + + g_free (full_path); + } + g_dir_close (dir); + + g_hash_table_iter_init (&iter, oldconns); + while (g_hash_table_iter_next (&iter, NULL, &data)) { + g_hash_table_iter_remove (&iter); + remove_connection (self, data); + } + g_hash_table_destroy (oldconns); +} + /* Plugin */ static GSList * @@ -377,34 +377,104 @@ get_connections (NMSystemConfigInterface *config) gpointer data = NULL; GSList *list = NULL; - if (!priv->hash) { + if (!priv->initialized) { setup_monitoring (config); read_connections (config); + priv->initialized = TRUE; } - g_hash_table_iter_init (&iter, priv->hash); + g_hash_table_iter_init (&iter, priv->connections); while (g_hash_table_iter_next (&iter, NULL, &data)) list = g_slist_prepend (list, data); return list; } +static gboolean +load_connection (NMSystemConfigInterface *config, + const char *filename) +{ + SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + NMKeyfileConnection *connection; + int dir_len = strlen (KEYFILE_DIR); + + if ( strncmp (filename, KEYFILE_DIR, dir_len) != 0 + || filename[dir_len] != '/' + || strchr (filename + dir_len + 1, '/') != NULL) + return FALSE; + + if (nm_keyfile_plugin_utils_should_ignore_file (filename + dir_len + 1)) + return FALSE; + + connection = find_by_path (self, filename); + if (connection) + update_connection (self, connection, filename); + else { + new_connection (self, filename, NULL); + connection = find_by_path (self, filename); + } + + return (connection != NULL); +} + +static void +reload_connections (NMSystemConfigInterface *config) +{ + read_connections (config); +} + static NMSettingsConnection * add_connection (NMSystemConfigInterface *config, NMConnection *connection, + gboolean save_to_disk, GError **error) { SCPluginKeyfile *self = SC_PLUGIN_KEYFILE (config); + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (self); NMSettingsConnection *added = NULL; char *path = NULL; - /* Write it out first, then add the connection to our internal list */ - if (nm_keyfile_plugin_write_connection (connection, NULL, &path, error)) { - added = _internal_new_connection (self, path, connection, error); - g_free (path); + if (save_to_disk) { + if (!nm_keyfile_plugin_write_connection (connection, NULL, &path, error)) + return NULL; } + + added = (NMSettingsConnection *) nm_keyfile_connection_new (connection, path, error); + if (added) { + g_hash_table_insert (priv->connections, + g_strdup (nm_connection_get_uuid (NM_CONNECTION (added))), + added); + g_signal_connect (added, NM_SETTINGS_CONNECTION_REMOVED, + G_CALLBACK (connection_removed_cb), + self); + } + g_free (path); return added; } +static gboolean +parse_key_file_allow_none (SCPluginKeyfilePrivate *priv, + GKeyFile *key_file, + GError **error) +{ + gboolean ret = FALSE; + GError *local_error = NULL; + + if (!g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &local_error)) { + if (g_error_matches (local_error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) + g_clear_error (&local_error); + else { + g_propagate_prefixed_error (error, local_error, + "Error parsing file '%s': ", + priv->conf_file); + goto out; + } + } + ret = TRUE; + + out: + return ret; +} + static GSList * get_unmanaged_specs (NMSystemConfigInterface *config) { @@ -412,48 +482,45 @@ get_unmanaged_specs (NMSystemConfigInterface *config) GKeyFile *key_file; GSList *specs = NULL; GError *error = NULL; + char *str; if (!priv->conf_file) return NULL; key_file = g_key_file_new (); - if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) { - char *str; - - str = g_key_file_get_value (key_file, "keyfile", "unmanaged-devices", NULL); - if (str) { - char **udis; - int i; - - udis = g_strsplit (str, ";", -1); - g_free (str); - - for (i = 0; udis[i] != NULL; i++) { - /* Verify unmanaged specification and add it to the list */ - if (strlen (udis[i]) > 4 && !strncmp (udis[i], "mac:", 4) && ether_aton (udis[i] + 4)) { - char *p = udis[i]; - - /* To accept uppercase MACs in configuration file, we have to convert values to lowercase here. - * Unmanaged MACs in specs are always in lowercase. */ - while (*p) { - *p = g_ascii_tolower (*p); - p++; - } - specs = g_slist_append (specs, udis[i]); - } else { - g_warning ("Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]); - g_free (udis[i]); - } - } + if (!parse_key_file_allow_none (priv, key_file, &error)) + goto out; + + str = g_key_file_get_value (key_file, "keyfile", "unmanaged-devices", NULL); + if (str) { + char **udis; + int i; + + udis = g_strsplit (str, ";", -1); + g_free (str); - g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */ + for (i = 0; udis[i] != NULL; i++) { + /* Verify unmanaged specification and add it to the list */ + if (!strncmp (udis[i], "mac:", 4) && nm_utils_hwaddr_valid (udis[i] + 4)) { + specs = g_slist_append (specs, udis[i]); + } else if (!strncmp (udis[i], "interface-name:", 15) && nm_utils_iface_valid_name (udis[i] + 15)) { + specs = g_slist_append (specs, udis[i]); + } else { + nm_log_warn (LOGD_SETTINGS, "Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]); + g_free (udis[i]); + } } - } else { - g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message); - g_error_free (error); + + g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */ } - g_key_file_free (key_file); + out: + if (error) { + nm_log_warn (LOGD_SETTINGS, "%s", error->message); + g_error_free (error); + } + if (key_file) + g_key_file_free (key_file); return specs; } @@ -470,14 +537,18 @@ plugin_get_hostname (SCPluginKeyfile *plugin) return NULL; key_file = g_key_file_new (); - if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) - hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL); - else { - g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message); + if (!parse_key_file_allow_none (priv, key_file, &error)) + goto out; + + hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL); + + out: + if (error) { + nm_log_warn (LOGD_SETTINGS, "%s", error->message); g_error_free (error); } - - g_key_file_free (key_file); + if (key_file) + g_key_file_free (key_file); return hostname; } @@ -485,45 +556,49 @@ plugin_get_hostname (SCPluginKeyfile *plugin) static gboolean plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname) { + gboolean ret = FALSE; SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin); - GKeyFile *key_file; + GKeyFile *key_file = NULL; GError *error = NULL; - gboolean result = FALSE; + char *data = NULL; + gsize len; if (!priv->conf_file) { - g_warning ("Error saving hostname: no config file"); - return FALSE; + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Error saving hostname: no config file"); + goto out; } + g_free (priv->hostname); + priv->hostname = g_strdup (hostname); + key_file = g_key_file_new (); - if (g_key_file_load_from_file (key_file, priv->conf_file, G_KEY_FILE_NONE, &error)) { - char *data; - gsize len; + if (!parse_key_file_allow_none (priv, key_file, &error)) + goto out; - g_key_file_set_string (key_file, "keyfile", "hostname", hostname); + g_key_file_set_string (key_file, "keyfile", "hostname", hostname); - data = g_key_file_to_data (key_file, &len, &error); - if (data) { - g_file_set_contents (priv->conf_file, data, len, &error); - g_free (data); + data = g_key_file_to_data (key_file, &len, &error); + if (!data) + goto out; - g_free (priv->hostname); - priv->hostname = g_strdup (hostname); - result = TRUE; - } + if (!g_file_set_contents (priv->conf_file, data, len, &error)) { + g_prefix_error (&error, "Error saving hostname: "); + goto out; + } - if (error) { - g_warning ("Error saving hostname: %s", error->message); - g_error_free (error); - } - } else { - g_warning ("Error parsing file '%s': %s", priv->conf_file, error->message); + ret = TRUE; + + out: + if (error) { + nm_log_warn (LOGD_SETTINGS, "%s", error->message); g_error_free (error); } + g_free (data); + if (key_file) + g_key_file_free (key_file); - g_key_file_free (key_file); - - return result; + return ret; } /* GObject */ @@ -531,6 +606,9 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname) static void sc_plugin_keyfile_init (SCPluginKeyfile *plugin) { + SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin); + + priv->connections = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } static void @@ -603,10 +681,11 @@ dispose (GObject *object) } g_free (priv->hostname); - g_free (priv->conf_file); - if (priv->hash) - g_hash_table_destroy (priv->hash); + if (priv->connections) { + g_hash_table_destroy (priv->connections); + priv->connections = NULL; + } out: G_OBJECT_CLASS (sc_plugin_keyfile_parent_class)->dispose (object); @@ -645,26 +724,26 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c { /* interface implementation */ system_config_interface_class->get_connections = get_connections; + system_config_interface_class->load_connection = load_connection; + system_config_interface_class->reload_connections = reload_connections; system_config_interface_class->add_connection = add_connection; system_config_interface_class->get_unmanaged_specs = get_unmanaged_specs; } GObject * -nm_settings_keyfile_plugin_new (const char *config_file) +nm_settings_keyfile_plugin_new (void) { static SCPluginKeyfile *singleton = NULL; SCPluginKeyfilePrivate *priv; if (!singleton) { singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL)); - if (singleton) { - priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton); + priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton); - priv->conf_file = g_strdup (config_file); + priv->conf_file = nm_config_get_path (nm_config_get ()); - /* plugin_set_hostname() has to be called *after* priv->conf_file is set */ - priv->hostname = plugin_get_hostname (singleton); - } + /* plugin_set_hostname() has to be called *after* priv->conf_file is set */ + priv->hostname = plugin_get_hostname (singleton); } else g_object_ref (singleton); diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h index 9b317333..5f437390 100644 --- a/src/settings/plugins/keyfile/plugin.h +++ b/src/settings/plugins/keyfile/plugin.h @@ -43,6 +43,6 @@ GType sc_plugin_keyfile_get_type (void); GQuark keyfile_plugin_error_quark (void); -GObject *nm_settings_keyfile_plugin_new (const char *config_file); +GObject *nm_settings_keyfile_plugin_new (void); #endif /* _PLUGIN_H_ */ diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index ec4661eb..735f8c28 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -41,9 +41,35 @@ #include <string.h> #include "nm-dbus-glib-types.h" +#include "nm-glib-compat.h" #include "nm-system-config-interface.h" +#include "nm-logging.h" #include "reader.h" #include "common.h" +#include "utils.h" + +/* Some setting properties also contain setting names, such as + * NMSettingConnection's 'type' property (which specifies the base type of the + * connection, e.g. ethernet or wifi) or 'slave-type' (specifies type of slave + * connection, e.g. bond or bridge). This function handles translating those + * properties' values to the real setting name if they are an alias. + */ +static void +setting_alias_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + const char *setting_name = nm_setting_get_name (setting); + char *s; + const char *key_setting_name; + + s = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); + if (s) { + key_setting_name = nm_keyfile_plugin_get_setting_name_for_alias (s); + g_object_set (G_OBJECT (setting), + key, key_setting_name ? key_setting_name : s, + NULL); + g_free (s); + } +} static gboolean read_array_of_uint (GKeyFile *file, @@ -55,7 +81,7 @@ read_array_of_uint (GKeyFile *file, int i; gint *tmp; - tmp = g_key_file_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL); + tmp = nm_keyfile_plugin_kf_get_integer_list (file, nm_setting_get_name (setting), key, &length, NULL); array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); g_return_val_if_fail (array != NULL, FALSE); @@ -72,11 +98,19 @@ static gboolean get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *out) { long tmp; + char *endptr; + + if (!str || !str[0]) { + if (key_name) + nm_log_warn (LOGD_SETTINGS, "%s: ignoring missing number %s", __func__, key_name); + return FALSE; + } errno = 0; - tmp = strtol (str, NULL, 10); - if (errno || (tmp < 0) || (tmp > max_val)) { - g_warning ("%s: ignoring invalid IP %s item '%s'", __func__, key_name, str); + tmp = strtol (str, &endptr, 10); + if (errno || (tmp < 0) || (tmp > max_val) || *endptr != 0) { + if (key_name) + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid number %s '%s'", __func__, key_name, str); return FALSE; } @@ -85,12 +119,13 @@ get_one_int (const char *str, guint32 max_val, const char *key_name, guint32 *ou } static gpointer -build_ip4_address_or_route (const char *address_str, guint32 plen, const char *gateway_str, guint32 metric, gboolean route) +build_ip4_address_or_route (const char *key_name, const char *address_str, guint32 plen, const char *gateway_str, const char *metric_str, gboolean route) { GArray *result; - struct in_addr addr; + guint32 addr; guint32 address = 0; guint32 gateway = 0; + guint32 metric = 0; int err; g_return_val_if_fail (address_str, NULL); @@ -98,23 +133,30 @@ build_ip4_address_or_route (const char *address_str, guint32 plen, const char *g /* Address */ err = inet_pton (AF_INET, address_str, &addr); if (err <= 0) { - g_warning ("%s: ignoring invalid IPv4 address '%s'", __func__, address_str); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv4 address '%s'", __func__, address_str); return NULL; } - address = addr.s_addr; + address = addr; + /* Gateway */ - if (gateway_str) { + if (gateway_str && gateway_str[0]) { err = inet_pton (AF_INET, gateway_str, &addr); if (err <= 0) { - g_warning ("%s: ignoring invalid IPv4 gateway '%s'", __func__, gateway_str); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv4 gateway '%s'", __func__, gateway_str); return NULL; } - gateway = addr.s_addr; + gateway = addr; } else gateway = 0; - result = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3); + /* parse metric, default to 0 */ + if (metric_str) { + if (!get_one_int (metric_str, G_MAXUINT32, key_name, &metric)) + return NULL; + } + + result = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3 + !!route); g_array_append_val (result, address); g_array_append_val (result, plen); g_array_append_val (result, gateway); @@ -125,13 +167,14 @@ build_ip4_address_or_route (const char *address_str, guint32 plen, const char *g } static gpointer -build_ip6_address_or_route (const char *address_str, guint32 plen, const char *gateway_str, guint32 metric, gboolean route) +build_ip6_address_or_route (const char *key_name, const char *address_str, guint32 plen, const char *gateway_str, const char *metric_str, gboolean route) { GValueArray *result; struct in6_addr addr; GByteArray *address; GByteArray *gateway; - GValue value = { 0, }; + guint32 metric = 0; + GValue value = G_VALUE_INIT; int err; g_return_val_if_fail (address_str, NULL); @@ -141,9 +184,8 @@ build_ip6_address_or_route (const char *address_str, guint32 plen, const char *g /* add address */ err = inet_pton (AF_INET6, address_str, &addr); if (err <= 0) { - g_warning ("%s: ignoring invalid IPv6 address '%s'", __func__, address_str); - g_value_array_free (result); - return NULL; + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv6 address '%s'", __func__, address_str); + goto error_out; } address = g_byte_array_new (); g_byte_array_append (address, (guint8 *) addr.s6_addr, 16); @@ -159,15 +201,33 @@ build_ip6_address_or_route (const char *address_str, guint32 plen, const char *g g_value_unset (&value); /* add gateway */ - if (gateway_str) { + if (gateway_str && gateway_str[0]) { err = inet_pton (AF_INET6, gateway_str, &addr); if (err <= 0) { - g_warning ("%s: ignoring invalid IPv6 gateway '%s'", __func__, gateway_str); - g_value_array_free (result); - return NULL; + /* Try workaround for routes written by broken keyfile writer. + * Due to bug bgo#719851, an older version of writer would have + * written "a:b:c:d::/plen,metric" if the gateway was ::, instead + * of "a:b:c:d::/plen,,metric" or "a:b:c:d::/plen,::,metric" + * Try workaround by interepeting gateway_str as metric to accept such + * invalid routes. This broken syntax should not be not officially + * supported. + **/ + if (route && !metric_str && get_one_int (gateway_str, G_MAXUINT32, NULL, &metric)) + addr = in6addr_any; + else { + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid IPv6 gateway '%s'", __func__, gateway_str); + goto error_out; + } } } else - memset (&addr, 0, 16); + addr = in6addr_any; + + /* parse metric, default to 0 */ + if (metric_str) { + if (!get_one_int (metric_str, G_MAXUINT32, key_name, &metric)) + goto error_out; + } + gateway = g_byte_array_new (); g_byte_array_append (gateway, (guint8 *) addr.s6_addr, 16); g_value_init (&value, DBUS_TYPE_G_UCHAR_ARRAY); @@ -184,6 +244,10 @@ build_ip6_address_or_route (const char *address_str, guint32 plen, const char *g } return result; + +error_out: + g_value_array_free (result); + return NULL; } /* On success, returns pointer to the zero-terminated field (original @current). @@ -214,7 +278,8 @@ read_field (char **current, char **error, const char *characters, const char *de } /* fail on empty input */ - g_return_val_if_fail (**current, NULL); + if (!**current) + return NULL; /* remember beginning of input */ start = *current; @@ -251,18 +316,18 @@ read_field (char **current, char **error, const char *characters, const char *de * address (DEPRECATED) * address/plen * address/gateway (DEPRECATED) - * address/plen/gateway + * address/plen,gateway * * The following IPv4 and IPv6 route formats are supported: * * address/plen (NETWORK dev DEVICE) - * address/plen/gateway (NETWORK via GATEWAY dev DEVICE) - * address/plen//gateway (NETWORK dev DEVICE metric METRIC) - * address/plen/gateway/metric (NETWORK via GATEWAY dev DEVICE metric METRIC) + * address/plen,gateway (NETWORK via GATEWAY dev DEVICE) + * address/plen,,metric (NETWORK dev DEVICE metric METRIC) + * address/plen,gateway,metric (NETWORK via GATEWAY dev DEVICE metric METRIC) * * For backward, forward and sideward compatibility, slash (/), - * semicolon (;) and comma (,) are interchangable. The use of - * slash in the above examples is therefore not significant. + * semicolon (;) and comma (,) are interchangable. The choice of + * separator in the above examples is therefore not significant. * * Leaving out the prefix length is discouraged and DEPRECATED. The * default value of IPv6 prefix length was 64 and has not been @@ -279,19 +344,19 @@ read_one_ip_address_or_route (GKeyFile *file, gboolean ipv6, gboolean route) { - guint32 plen, metric; + guint32 plen; gpointer result; char *address_str, *plen_str, *gateway_str, *metric_str, *value, *current, *error; - current = value = g_key_file_get_string (file, setting_name, key_name, NULL); + current = value = nm_keyfile_plugin_kf_get_string (file, setting_name, key_name, NULL); if (!value) return NULL; /* get address field */ address_str = read_field (¤t, &error, IP_ADDRESS_CHARS, DELIMITERS); if (error) { - g_warning ("keyfile: Unexpected character '%c' in '%s.%s' address (position %td of '%s').", - *error, setting_name, key_name, error - current, current); + nm_log_warn (LOGD_SETTINGS, "keyfile: Unexpected character '%c' in '%s.%s' address (position %td of '%s').", + *error, setting_name, key_name, error - current, current); goto error; } /* get prefix length field (skippable) */ @@ -299,18 +364,18 @@ read_one_ip_address_or_route (GKeyFile *file, /* get gateway field */ gateway_str = read_field (¤t, &error, IP_ADDRESS_CHARS, DELIMITERS); if (error) { - g_warning ("keyfile: Unexpected character '%c' in '%s.%s' %s (position %td of '%s').", - *error, setting_name, key_name, - plen_str ? "gateway" : "gateway or prefix length", - error - current, current); + nm_log_warn (LOGD_SETTINGS, "keyfile: Unexpected character '%c' in '%s.%s' %s (position %td of '%s').", + *error, setting_name, key_name, + plen_str ? "gateway" : "gateway or prefix length", + error - current, current); goto error; } /* for routes, get metric */ if (route) { metric_str = read_field (¤t, &error, DIGITS, DELIMITERS); if (error) { - g_warning ("keyfile: Unexpected character '%c' in '%s.%s' prefix length (position %td of '%s').", - *error, setting_name, key_name, error - current, current); + nm_log_warn (LOGD_SETTINGS, "keyfile: Unexpected character '%c' in '%s.%s' prefix length (position %td of '%s').", + *error, setting_name, key_name, error - current, current); goto error; } } else @@ -319,13 +384,13 @@ read_one_ip_address_or_route (GKeyFile *file, /* there is still some data */ if (*current) { /* another field follows */ - g_warning ("keyfile: %s.%s: Garbage at the and of the line: %s", - setting_name, key_name, current); + nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: Garbage at the and of the line: %s", + setting_name, key_name, current); goto error; } else { /* semicolon at the end of input */ - g_message ("keyfile: %s.%s: Deprecated semicolon at the end of value.", - setting_name, key_name); + nm_log_info (LOGD_SETTINGS, "keyfile: %s.%s: Deprecated semicolon at the end of value.", + setting_name, key_name); } } @@ -338,23 +403,13 @@ read_one_ip_address_or_route (GKeyFile *file, plen = ipv6 ? 128 : 24; else plen = ipv6 ? 64 : 24; - g_warning ("keyfile: Missing prefix length in '%s.%s', defaulting to %d", - setting_name, key_name, plen); + nm_log_warn (LOGD_SETTINGS, "keyfile: Missing prefix length in '%s.%s', defaulting to %d", + setting_name, key_name, plen); } - /* parse metric, default to 0 */ - metric = 0; - if (metric_str) - g_return_val_if_fail (get_one_int (metric_str, G_MAXUINT32, - key_name, &metric), NULL); - /* build the appropriate data structure for NetworkManager settings */ - if (route) - g_debug ("keyfile: %s.%s: route %s/%d gateway %s metric %d", setting_name, key_name, address_str, plen, gateway_str, metric); - else - g_debug ("keyfile: %s.%s: address %s/%d gateway %s", setting_name, key_name, address_str, plen, gateway_str); result = (ipv6 ? build_ip6_address_or_route : build_ip4_address_or_route) ( - address_str, plen, gateway_str, metric, route); + key_name, address_str, plen, gateway_str, metric_str, route); g_free (value); return result; @@ -375,8 +430,10 @@ ip_address_or_route_parser (NMSetting *setting, const char *key, GKeyFile *keyfi GPtrArray *list; int i; + G_GNUC_BEGIN_IGNORE_DEPRECATIONS; list = g_ptr_array_new_with_free_func ( ipv6 ? (GDestroyNotify) g_value_array_free : (GDestroyNotify) g_array_unref); + G_GNUC_END_IGNORE_DEPRECATIONS; for (i = -1; i < 1000; i++) { const char **key_basename; @@ -415,21 +472,21 @@ ip4_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch char **list, **iter; int ret; - list = g_key_file_get_string_list (keyfile, setting_name, key, &length, NULL); + list = nm_keyfile_plugin_kf_get_string_list (keyfile, setting_name, key, &length, NULL); if (!list || !g_strv_length (list)) return; array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length); for (iter = list; *iter; iter++) { - struct in_addr addr; + guint32 addr; ret = inet_pton (AF_INET, *iter, &addr); if (ret <= 0) { - g_warning ("%s: ignoring invalid DNS server address '%s'", __func__, *iter); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid DNS server address '%s'", __func__, *iter); continue; } - g_array_append_val (array, addr.s_addr); + g_array_append_val (array, addr); } g_strfreev (list); @@ -448,7 +505,7 @@ ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch char **list, **iter; int ret; - list = g_key_file_get_string_list (keyfile, setting_name, key, &length, NULL); + list = nm_keyfile_plugin_kf_get_string_list (keyfile, setting_name, key, &length, NULL); if (!list || !g_strv_length (list)) return; @@ -460,7 +517,7 @@ ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch ret = inet_pton (AF_INET6, *iter, &addr); if (ret <= 0) { - g_warning ("%s: ignoring invalid DNS server IPv6 address '%s'", __func__, *iter); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid DNS server IPv6 address '%s'", __func__, *iter); continue; } byte_array = g_byte_array_new (); @@ -477,46 +534,52 @@ ip6_dns_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const ch } static void -mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path, gsize enforce_length) { const char *setting_name = nm_setting_get_name (setting); char *tmp_string = NULL, *p; gint *tmp_list; GByteArray *array = NULL; gsize length; - int i, type; - p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL); - if (tmp_string) { + p = tmp_string = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); + if (tmp_string && tmp_string[0]) { /* Look for enough ':' characters to signify a MAC address */ - i = 0; + guint i = 0; + while (*p) { if (*p == ':') i++; p++; } - /* If we found enough it's probably a string-format MAC address */ - type = nm_utils_hwaddr_type (i + 1); - if (type > 0) - array = nm_utils_hwaddr_atoba (tmp_string, type); + if (enforce_length == 0 || enforce_length == i+1) { + /* If we found enough it's probably a string-format MAC address */ + array = g_byte_array_sized_new (i+1); + g_byte_array_set_size (array, i+1); + if (!nm_utils_hwaddr_aton_len (tmp_string, array->data, array->len)) { + g_byte_array_unref (array); + array = NULL; + } + } } g_free (tmp_string); if (array == NULL) { /* Old format; list of ints */ - tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL); - type = nm_utils_hwaddr_type (length); - if (type < 0) { + tmp_list = nm_keyfile_plugin_kf_get_integer_list (keyfile, setting_name, key, &length, NULL); + if (length > 0 && (enforce_length == 0 || enforce_length == length)) { + gsize i; + array = g_byte_array_sized_new (length); for (i = 0; i < length; i++) { int val = tmp_list[i]; const guint8 v = (guint8) (val & 0xFF); if (val < 0 || val > 255) { - g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); + nm_log_warn (LOGD_SETTINGS, "%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); g_byte_array_free (array, TRUE); array = NULL; break; @@ -531,29 +594,41 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons g_object_set (setting, key, array, NULL); g_byte_array_free (array, TRUE); } else { - g_warning ("%s: ignoring invalid MAC address for %s / %s", - __func__, setting_name, key); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid MAC address for %s / %s", + __func__, setting_name, key); } } static void +mac_address_parser_ETHER (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + mac_address_parser (setting, key, keyfile, keyfile_path, ETH_ALEN); +} + +static void +mac_address_parser_INFINIBAND (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) +{ + mac_address_parser (setting, key, keyfile, keyfile_path, INFINIBAND_ALEN); +} + +static void read_hash_of_string (GKeyFile *file, NMSetting *setting, const char *key) { char **keys, **iter; char *value; const char *setting_name = nm_setting_get_name (setting); - keys = g_key_file_get_keys (file, setting_name, NULL, NULL); + keys = nm_keyfile_plugin_kf_get_keys (file, setting_name, NULL, NULL); if (!keys || !*keys) return; for (iter = keys; *iter; iter++) { - value = g_key_file_get_string (file, setting_name, *iter, NULL); + value = nm_keyfile_plugin_kf_get_string (file, setting_name, *iter, NULL); if (!value) continue; if (NM_IS_SETTING_VPN (setting)) { - if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE)) + if (strcmp (*iter, NM_SETTING_VPN_SERVICE_TYPE) && strcmp (*iter, NM_SETTING_VPN_USER_NAME)) nm_setting_vpn_add_data_item (NM_SETTING_VPN (setting), *iter, value); } if (NM_IS_SETTING_BOND (setting)) { @@ -596,7 +671,7 @@ get_uchar_array (GKeyFile *keyfile, /* New format: just a string * Old format: integer list; e.g. 11;25;38; */ - tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL); + tmp_string = nm_keyfile_plugin_kf_get_string (keyfile, setting_name, key, NULL); if (tmp_string) { GRegex *regex; GMatchInfo *match_info; @@ -621,16 +696,16 @@ get_uchar_array (GKeyFile *keyfile, if (!array) { /* Old format; list of ints */ - tmp_list = g_key_file_get_integer_list (keyfile, setting_name, key, &length, NULL); + tmp_list = nm_keyfile_plugin_kf_get_integer_list (keyfile, setting_name, key, &length, NULL); array = g_byte_array_sized_new (length); for (i = 0; i < length; i++) { int val = tmp_list[i]; unsigned char v = (unsigned char) (val & 0xFF); if (val < 0 || val > 255) { - g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); + nm_log_warn (LOGD_SETTINGS, "%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); } else g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); } @@ -655,8 +730,8 @@ ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char g_object_set (setting, key, array, NULL); g_byte_array_free (array, TRUE); } else { - g_warning ("%s: ignoring invalid SSID for %s / %s", - __func__, setting_name, key); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid SSID for %s / %s", + __func__, setting_name, key); } } @@ -671,8 +746,8 @@ password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, con g_object_set (setting, key, array, NULL); g_byte_array_free (array, TRUE); } else { - g_warning ("%s: ignoring invalid raw password for %s / %s", - __func__, setting_name, key); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid raw password for %s / %s", + __func__, setting_name, key); } } @@ -773,7 +848,7 @@ handle_as_path (GByteArray *array, /* Warn if the certificate didn't exist */ if (exists == FALSE) - PLUGIN_WARN (KEYFILE_PLUGIN_NAME, " certificate or key %s does not exist", path); + nm_log_warn (LOGD_SETTINGS, "certificate or key %s does not exist", path); } g_free (path); @@ -800,8 +875,8 @@ cert_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char if (success == FALSE) g_object_set (setting, key, array, NULL); } else { - g_warning ("%s: ignoring invalid key/cert value for %s / %s", - __func__, setting_name, key); + nm_log_warn (LOGD_SETTINGS, "%s: ignoring invalid key/cert value for %s / %s", + __func__, setting_name, key); } if (array) @@ -822,6 +897,14 @@ typedef struct { * in struct in6_addr internally, but as string in keyfiles. */ static KeyParser key_parsers[] = { + { NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE, + TRUE, + setting_alias_parser }, + { NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_MAC_ADDRESS, + TRUE, + mac_address_parser_ETHER }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_ADDRESSES, FALSE, @@ -849,35 +932,35 @@ static KeyParser key_parsers[] = { { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_CLONED_MAC_ADDRESS, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_MAC_ADDRESS, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_BSSID, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_BLUETOOTH_SETTING_NAME, NM_SETTING_BLUETOOTH_BDADDR, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_INFINIBAND_SETTING_NAME, NM_SETTING_INFINIBAND_MAC_ADDRESS, TRUE, - mac_address_parser }, + mac_address_parser_INFINIBAND }, { NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS, TRUE, - mac_address_parser }, + mac_address_parser_ETHER }, { NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, TRUE, @@ -969,10 +1052,10 @@ read_one_setting_value (NMSetting *setting, * like IP addresses and routes where more than one value is actually * encoded by the setting property, this won't be true. */ - if (check_for_key && !g_key_file_has_key (info->keyfile, setting_name, key, &err)) { + if (check_for_key && !nm_keyfile_plugin_kf_has_key (info->keyfile, setting_name, key, &err)) { /* Key doesn't exist or an error ocurred, thus nothing to do. */ if (err) { - g_warning ("Error loading setting '%s' value: %s", setting_name, err->message); + nm_log_warn (LOGD_SETTINGS, "Error loading setting '%s' value: %s", setting_name, err->message); g_error_free (err); } return; @@ -981,7 +1064,7 @@ read_one_setting_value (NMSetting *setting, /* If there's a custom parser for this key, handle that before the generic * parsers below. */ - if (parser && parser->setting_name) { + if (parser->setting_name) { (*parser->parser) (setting, key, info->keyfile, info->keyfile_path); return; } @@ -991,39 +1074,39 @@ read_one_setting_value (NMSetting *setting, if (type == G_TYPE_STRING) { char *str_val; - str_val = g_key_file_get_string (info->keyfile, setting_name, key, NULL); + str_val = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL); g_object_set (setting, key, str_val, NULL); g_free (str_val); } else if (type == G_TYPE_UINT) { int int_val; - int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL); + int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); if (int_val < 0) - g_warning ("Casting negative value (%i) to uint", int_val); + nm_log_warn (LOGD_SETTINGS, "Casting negative value (%i) to uint", int_val); g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_INT) { int int_val; - int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL); + int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_BOOLEAN) { gboolean bool_val; - bool_val = g_key_file_get_boolean (info->keyfile, setting_name, key, NULL); + bool_val = nm_keyfile_plugin_kf_get_boolean (info->keyfile, setting_name, key, NULL); g_object_set (setting, key, bool_val, NULL); } else if (type == G_TYPE_CHAR) { int int_val; - int_val = g_key_file_get_integer (info->keyfile, setting_name, key, NULL); + int_val = nm_keyfile_plugin_kf_get_integer (info->keyfile, setting_name, key, NULL); if (int_val < G_MININT8 || int_val > G_MAXINT8) - g_warning ("Casting value (%i) to char", int_val); + nm_log_warn (LOGD_SETTINGS, "Casting value (%i) to char", int_val); g_object_set (setting, key, int_val, NULL); } else if (type == G_TYPE_UINT64) { char *tmp_str; guint64 uint_val; - tmp_str = g_key_file_get_value (info->keyfile, setting_name, key, NULL); + tmp_str = nm_keyfile_plugin_kf_get_value (info->keyfile, setting_name, key, NULL); uint_val = g_ascii_strtoull (tmp_str, NULL, 10); g_free (tmp_str); g_object_set (setting, key, uint_val, NULL); @@ -1033,7 +1116,7 @@ read_one_setting_value (NMSetting *setting, gsize length; int i; - tmp = g_key_file_get_integer_list (info->keyfile, setting_name, key, &length, NULL); + tmp = nm_keyfile_plugin_kf_get_integer_list (info->keyfile, setting_name, key, &length, NULL); array = g_byte_array_sized_new (length); for (i = 0; i < length; i++) { @@ -1041,9 +1124,9 @@ read_one_setting_value (NMSetting *setting, unsigned char v = (unsigned char) (val & 0xFF); if (val < 0 || val > 255) { - g_warning ("%s: %s / %s ignoring invalid byte element '%d' (not " - " between 0 and 255 inclusive)", __func__, setting_name, - key, val); + nm_log_warn (LOGD_SETTINGS, "%s: %s / %s ignoring invalid byte element '%d' (not " + " between 0 and 255 inclusive)", __func__, setting_name, + key, val); } else g_byte_array_append (array, (const unsigned char *) &v, sizeof (v)); } @@ -1057,7 +1140,7 @@ read_one_setting_value (NMSetting *setting, int i; GSList *list = NULL; - sa = g_key_file_get_string_list (info->keyfile, setting_name, key, &length, NULL); + sa = nm_keyfile_plugin_kf_get_string_list (info->keyfile, setting_name, key, &length, NULL); for (i = 0; i < length; i++) list = g_slist_prepend (list, sa[i]); @@ -1070,26 +1153,28 @@ read_one_setting_value (NMSetting *setting, read_hash_of_string (info->keyfile, setting, key); } else if (type == DBUS_TYPE_G_UINT_ARRAY) { if (!read_array_of_uint (info->keyfile, setting, key)) { - g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'", - setting_name, key, G_VALUE_TYPE_NAME (value)); + nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (read): '%s/%s' : '%s'", + setting_name, key, G_VALUE_TYPE_NAME (value)); } } else { - g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'", - setting_name, key, G_VALUE_TYPE_NAME (value)); + nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (read): '%s/%s' : '%s'", + setting_name, key, G_VALUE_TYPE_NAME (value)); } } static NMSetting * -read_setting (GKeyFile *file, const char *keyfile_path, const char *setting_name) +read_setting (GKeyFile *file, const char *keyfile_path, const char *group) { NMSetting *setting; ReadInfo info = { file, keyfile_path }; + const char *alias; - setting = nm_connection_create_setting (setting_name); + alias = nm_keyfile_plugin_get_setting_name_for_alias (group); + setting = nm_connection_create_setting (alias ? alias : group); if (setting) nm_setting_enumerate_values (setting, read_one_setting_value, &info); else - g_warning ("Invalid setting name '%s'", setting_name); + nm_log_warn (LOGD_SETTINGS, "Invalid setting name '%s'", group); return setting; } @@ -1099,11 +1184,11 @@ read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn) { char **keys, **iter; - keys = g_key_file_get_keys (file, VPN_SECRETS_GROUP, NULL, NULL); + keys = nm_keyfile_plugin_kf_get_keys (file, VPN_SECRETS_GROUP, NULL, NULL); for (iter = keys; *iter; iter++) { char *secret; - secret = g_key_file_get_string (file, VPN_SECRETS_GROUP, *iter, NULL); + secret = nm_keyfile_plugin_kf_get_string (file, VPN_SECRETS_GROUP, *iter, NULL); if (secret) { nm_setting_vpn_add_secret (s_vpn, *iter, secret); g_free (secret); @@ -1112,12 +1197,36 @@ read_vpn_secrets (GKeyFile *file, NMSettingVPN *s_vpn) g_strfreev (keys); } +static void +ensure_slave_setting (NMConnection *connection) +{ + NMSettingConnection *s_con = nm_connection_get_setting_connection (connection); + const char *slave_type; + GType slave_gtype = G_TYPE_INVALID; + NMSetting *setting; + + slave_type = nm_setting_connection_get_slave_type (s_con); + if (!slave_type) + return; + + if (g_strcmp0 (slave_type, NM_SETTING_BRIDGE_SETTING_NAME) == 0) + slave_gtype = NM_TYPE_SETTING_BRIDGE_PORT; + else if (g_strcmp0 (slave_type, NM_SETTING_TEAM_SETTING_NAME) == 0) + slave_gtype = NM_TYPE_SETTING_TEAM_PORT; + + if (slave_gtype != G_TYPE_INVALID && !nm_connection_get_setting (connection, slave_gtype)) { + setting = (NMSetting *) g_object_new (slave_gtype, NULL); + g_assert (setting); + nm_connection_add_setting (connection, setting); + } +} + NMConnection * nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) { GKeyFile *key_file; struct stat statbuf; - gboolean bad_owner, bad_permissions; + gboolean bad_permissions; NMConnection *connection = NULL; NMSettingConnection *s_con; NMSetting *setting; @@ -1134,13 +1243,12 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) return NULL; } - bad_owner = getuid () != statbuf.st_uid; bad_permissions = statbuf.st_mode & 0077; - if (bad_owner || bad_permissions) { + if (bad_permissions) { g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, - "File permissions (%o) or owner (%d) were insecure", - statbuf.st_mode, statbuf.st_uid); + "File permissions (%o) were insecure", + statbuf.st_mode); return NULL; } @@ -1163,26 +1271,31 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) nm_connection_add_setting (connection, setting); } - /* Make sure that we have the base device type setting even if - * the keyfile didn't include it, which can happen when the base - * device type setting is all default values (like ethernet where - * the MAC address isn't given, or VLAN when the VLAN ID is zero). + /* Make sure that we have the base device type and slave type settings + * even if the keyfile didn't include it, which can happen when the + * setting in question is all default values (like ethernet where + * the MAC address isn't given, or VLAN when the VLAN ID is zero, or + * bridge port with all default settings). */ s_con = nm_connection_get_setting_connection (connection); if (s_con) { ctype = nm_setting_connection_get_connection_type (s_con); - setting = nm_connection_get_setting_by_name (connection, ctype); - if (ctype && !setting) { - NMSetting *base_setting; - GType base_setting_type; - - base_setting_type = nm_connection_lookup_setting_type (ctype); - if (base_setting_type != G_TYPE_INVALID) { - base_setting = (NMSetting *) g_object_new (base_setting_type, NULL); - g_assert (base_setting); - nm_connection_add_setting (connection, base_setting); + if (ctype) { + setting = nm_connection_get_setting_by_name (connection, ctype); + if (!setting) { + NMSetting *base_setting; + GType base_setting_type; + + base_setting_type = nm_connection_lookup_setting_type (ctype); + if (base_setting_type != G_TYPE_INVALID) { + base_setting = (NMSetting *) g_object_new (base_setting_type, NULL); + g_assert (base_setting); + nm_connection_add_setting (connection, base_setting); + } } } + + ensure_slave_setting (connection); } /* Handle vpn secrets after the 'vpn' setting was read */ @@ -1205,8 +1318,6 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error) g_clear_error (&verify_error); g_object_unref (connection); connection = NULL; - g_warning ("Connection failed to verify: %s", - verify_error ? g_type_name (nm_connection_lookup_setting_type_by_quark (verify_error->domain)) : "(unknown)"); } out: diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am index c2f5fe3d..fae6e4ea 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.am +++ b/src/settings/plugins/keyfile/tests/Makefile.am @@ -2,7 +2,7 @@ if ENABLE_TESTS SUBDIRS=keyfiles -noinst_PROGRAMS = test-keyfile +@GNOME_CODE_COVERAGE_RULES@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ @@ -10,22 +10,36 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/libnm-util \ -I$(top_builddir)/libnm-util \ -I$(top_srcdir)/libnm-glib \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/logging \ + -I$(top_srcdir)/src/settings \ -I$(srcdir)/../ \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ + $(POLKIT_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) \ + -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ + -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \ - -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" + -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" \ + -DNMCONFDIR=\"nonexistent\" + +noinst_PROGRAMS = test-keyfile test_keyfile_SOURCES = \ - test-keyfile.c + test-keyfile.c \ + ../reader.c \ + ../writer.c \ + ../errors.c \ + ../utils.c test_keyfile_LDADD = \ - $(builddir)/../libkeyfile-io.la \ + $(top_builddir)/src/libNetworkManager.la \ $(top_builddir)/libnm-glib/libnm-glib.la \ $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) + $(DBUS_LIBS) \ + $(CODE_COVERAGE_LDFLAGS) -check-local: test-keyfile - $(abs_builddir)/test-keyfile +TESTS = test-keyfile endif diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in index 675a9fcf..f7b4b62a 100644 --- a/src/settings/plugins/keyfile/tests/Makefile.in +++ b/src/settings/plugins/keyfile/tests/Makefile.in @@ -79,11 +79,13 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_TESTS_TRUE@noinst_PROGRAMS = test-keyfile$(EXEEXT) +@ENABLE_TESTS_TRUE@TESTS = test-keyfile$(EXEEXT) subdir = src/settings/plugins/keyfile/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/build-aux/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -102,15 +104,18 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) -am__test_keyfile_SOURCES_DIST = test-keyfile.c -@ENABLE_TESTS_TRUE@am_test_keyfile_OBJECTS = test-keyfile.$(OBJEXT) +am__test_keyfile_SOURCES_DIST = test-keyfile.c ../reader.c ../writer.c \ + ../errors.c ../utils.c +@ENABLE_TESTS_TRUE@am_test_keyfile_OBJECTS = test-keyfile.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ reader.$(OBJEXT) writer.$(OBJEXT) \ +@ENABLE_TESTS_TRUE@ errors.$(OBJEXT) utils.$(OBJEXT) test_keyfile_OBJECTS = $(am_test_keyfile_OBJECTS) am__DEPENDENCIES_1 = @ENABLE_TESTS_TRUE@test_keyfile_DEPENDENCIES = \ -@ENABLE_TESTS_TRUE@ $(builddir)/../libkeyfile-io.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) +@ENABLE_TESTS_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -191,6 +196,28 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} DIST_SUBDIRS = keyfiles DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ @@ -243,12 +270,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -273,7 +303,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -318,12 +347,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -340,6 +373,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -367,11 +402,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -386,6 +426,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -448,6 +489,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -458,6 +500,7 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ @ENABLE_TESTS_TRUE@SUBDIRS = keyfiles @ENABLE_TESTS_TRUE@AM_CPPFLAGS = \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/include \ @@ -465,20 +508,33 @@ with_resolvconf = @with_resolvconf@ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_builddir)/libnm-util \ @ENABLE_TESTS_TRUE@ -I$(top_srcdir)/libnm-glib \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/logging \ +@ENABLE_TESTS_TRUE@ -I$(top_srcdir)/src/settings \ @ENABLE_TESTS_TRUE@ -I$(srcdir)/../ \ @ENABLE_TESTS_TRUE@ $(GLIB_CFLAGS) \ @ENABLE_TESTS_TRUE@ $(DBUS_CFLAGS) \ +@ENABLE_TESTS_TRUE@ $(POLKIT_CFLAGS) \ +@ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_CFLAGS) \ +@ENABLE_TESTS_TRUE@ -DG_LOG_DOMAIN=\""NetworkManager-keyfile"\" \ +@ENABLE_TESTS_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ @ENABLE_TESTS_TRUE@ -DTEST_KEYFILES_DIR=\"$(abs_srcdir)/keyfiles\" \ -@ENABLE_TESTS_TRUE@ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" +@ENABLE_TESTS_TRUE@ -DTEST_SCRATCH_DIR=\"$(abs_builddir)/keyfiles\" \ +@ENABLE_TESTS_TRUE@ -DNMCONFDIR=\"nonexistent\" @ENABLE_TESTS_TRUE@test_keyfile_SOURCES = \ -@ENABLE_TESTS_TRUE@ test-keyfile.c +@ENABLE_TESTS_TRUE@ test-keyfile.c \ +@ENABLE_TESTS_TRUE@ ../reader.c \ +@ENABLE_TESTS_TRUE@ ../writer.c \ +@ENABLE_TESTS_TRUE@ ../errors.c \ +@ENABLE_TESTS_TRUE@ ../utils.c @ENABLE_TESTS_TRUE@test_keyfile_LDADD = \ -@ENABLE_TESTS_TRUE@ $(builddir)/../libkeyfile-io.la \ +@ENABLE_TESTS_TRUE@ $(top_builddir)/src/libNetworkManager.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-glib/libnm-glib.la \ @ENABLE_TESTS_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) +@ENABLE_TESTS_TRUE@ $(DBUS_LIBS) \ +@ENABLE_TESTS_TRUE@ $(CODE_COVERAGE_LDFLAGS) all: all-recursive @@ -534,7 +590,11 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errors.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test-keyfile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/writer.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -557,6 +617,62 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +reader.o: ../reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reader.o -MD -MP -MF $(DEPDIR)/reader.Tpo -c -o reader.o `test -f '../reader.c' || echo '$(srcdir)/'`../reader.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/reader.Tpo $(DEPDIR)/reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../reader.c' object='reader.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reader.o `test -f '../reader.c' || echo '$(srcdir)/'`../reader.c + +reader.obj: ../reader.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT reader.obj -MD -MP -MF $(DEPDIR)/reader.Tpo -c -o reader.obj `if test -f '../reader.c'; then $(CYGPATH_W) '../reader.c'; else $(CYGPATH_W) '$(srcdir)/../reader.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/reader.Tpo $(DEPDIR)/reader.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../reader.c' object='reader.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o reader.obj `if test -f '../reader.c'; then $(CYGPATH_W) '../reader.c'; else $(CYGPATH_W) '$(srcdir)/../reader.c'; fi` + +writer.o: ../writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT writer.o -MD -MP -MF $(DEPDIR)/writer.Tpo -c -o writer.o `test -f '../writer.c' || echo '$(srcdir)/'`../writer.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/writer.Tpo $(DEPDIR)/writer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../writer.c' object='writer.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o writer.o `test -f '../writer.c' || echo '$(srcdir)/'`../writer.c + +writer.obj: ../writer.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT writer.obj -MD -MP -MF $(DEPDIR)/writer.Tpo -c -o writer.obj `if test -f '../writer.c'; then $(CYGPATH_W) '../writer.c'; else $(CYGPATH_W) '$(srcdir)/../writer.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/writer.Tpo $(DEPDIR)/writer.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../writer.c' object='writer.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o writer.obj `if test -f '../writer.c'; then $(CYGPATH_W) '../writer.c'; else $(CYGPATH_W) '$(srcdir)/../writer.c'; fi` + +errors.o: ../errors.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.o -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.o `test -f '../errors.c' || echo '$(srcdir)/'`../errors.c + +errors.obj: ../errors.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errors.obj -MD -MP -MF $(DEPDIR)/errors.Tpo -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/errors.Tpo $(DEPDIR)/errors.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../errors.c' object='errors.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errors.obj `if test -f '../errors.c'; then $(CYGPATH_W) '../errors.c'; else $(CYGPATH_W) '$(srcdir)/../errors.c'; fi` + +utils.o: ../utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils.o -MD -MP -MF $(DEPDIR)/utils.Tpo -c -o utils.o `test -f '../utils.c' || echo '$(srcdir)/'`../utils.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utils.Tpo $(DEPDIR)/utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../utils.c' object='utils.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils.o `test -f '../utils.c' || echo '$(srcdir)/'`../utils.c + +utils.obj: ../utils.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utils.obj -MD -MP -MF $(DEPDIR)/utils.Tpo -c -o utils.obj `if test -f '../utils.c'; then $(CYGPATH_W) '../utils.c'; else $(CYGPATH_W) '$(srcdir)/../utils.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/utils.Tpo $(DEPDIR)/utils.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../utils.c' object='utils.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utils.obj `if test -f '../utils.c'; then $(CYGPATH_W) '../utils.c'; else $(CYGPATH_W) '$(srcdir)/../utils.c'; fi` + mostlyclean-libtool: -rm -f *.lo @@ -662,6 +778,99 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -717,9 +926,8 @@ distdir: $(DISTFILES) || exit 1; \ fi; \ done -@ENABLE_TESTS_FALSE@check-local: check-am: all-am - $(MAKE) $(AM_MAKEFLAGS) check-local + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile $(PROGRAMS) installdirs: installdirs-recursive @@ -828,7 +1036,7 @@ uninstall-am: .MAKE: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am check-local clean clean-generic clean-libtool \ + check-TESTS check-am clean clean-generic clean-libtool \ clean-noinstPROGRAMS cscopelist-am ctags ctags-am distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ @@ -843,8 +1051,7 @@ uninstall-am: uninstall-am -@ENABLE_TESTS_TRUE@check-local: test-keyfile -@ENABLE_TESTS_TRUE@ $(abs_builddir)/test-keyfile +@ENABLE_TESTS_TRUE@@GNOME_CODE_COVERAGE_RULES@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am index bbad8e30..576164d2 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am @@ -3,6 +3,8 @@ KEYFILES = \ Test_GSM_Connection \ Test_Wireless_Connection \ Test_Wired_Connection_MAC_Case \ + Test_MAC_Old_Format \ + Test_MAC_IB_Old_Format \ Test_Wired_Connection_IP6 \ ATT_Data_Connect_BT \ ATT_Data_Connect_Plain \ @@ -17,6 +19,8 @@ KEYFILES = \ Test_InfiniBand_Connection \ Test_Bridge_Main \ Test_Bridge_Component \ + Test_New_Wired_Group_Name \ + Test_New_Wireless_Group_Names \ Test_Missing_Vlan_Setting CERTS = \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in index 450269b4..05660e3e 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in +++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in @@ -80,7 +80,8 @@ host_triplet = @host@ subdir = src/settings/plugins/keyfile/tests/keyfiles DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/compiler_warnings.m4 \ +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_lib_readline.m4 \ + $(top_srcdir)/m4/compiler_warnings.m4 \ $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/gnome-code-coverage.m4 \ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/iconv.m4 \ @@ -144,12 +145,15 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATADIRNAME = @DATADIRNAME@ DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_GLIB_100_CFLAGS = @DBUS_GLIB_100_CFLAGS@ +DBUS_GLIB_100_LIBS = @DBUS_GLIB_100_LIBS@ DBUS_LIBS = @DBUS_LIBS@ DBUS_SYS_DIR = @DBUS_SYS_DIR@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHCLIENT_PATH = @DHCLIENT_PATH@ DHCPCD_PATH = @DHCPCD_PATH@ +DISTRO_NETWORK_SERVICE = @DISTRO_NETWORK_SERVICE@ DLLTOOL = @DLLTOOL@ DNSMASQ_PATH = @DNSMASQ_PATH@ DSYMUTIL = @DSYMUTIL@ @@ -174,7 +178,6 @@ GNUTLS_CFLAGS = @GNUTLS_CFLAGS@ GNUTLS_LIBS = @GNUTLS_LIBS@ GREP = @GREP@ GTKDOC_CHECK = @GTKDOC_CHECK@ -GTKDOC_CHECK_PATH = @GTKDOC_CHECK_PATH@ GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ @@ -219,12 +222,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBM = @LIBM@ +LIBNDP_CFLAGS = @LIBNDP_CFLAGS@ +LIBNDP_LIBS = @LIBNDP_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@ LIBSOUP_LIBS = @LIBSOUP_LIBS@ +LIBTEAMDCTL_CFLAGS = @LIBTEAMDCTL_CFLAGS@ +LIBTEAMDCTL_LIBS = @LIBTEAMDCTL_LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -241,6 +248,8 @@ MOC = @MOC@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NEWT_CFLAGS = @NEWT_CFLAGS@ +NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ @@ -268,11 +277,16 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ POLKIT_CFLAGS = @POLKIT_CFLAGS@ POLKIT_LIBS = @POLKIT_LIBS@ POSUB = @POSUB@ +PPPD_PATH = @PPPD_PATH@ PPPD_PLUGIN_DIR = @PPPD_PLUGIN_DIR@ +PPPOE_PATH = @PPPOE_PATH@ QT_CFLAGS = @QT_CFLAGS@ QT_LIBS = @QT_LIBS@ RANLIB = @RANLIB@ +READLINE_LIBS = @READLINE_LIBS@ SED = @SED@ +SELINUX_CFLAGS = @SELINUX_CFLAGS@ +SELINUX_LIBS = @SELINUX_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -287,6 +301,7 @@ UDEV_BASE_DIR = @UDEV_BASE_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ +VALGRIND_RULES = @VALGRIND_RULES@ VAPIGEN = @VAPIGEN@ VAPIGEN_MAKEFILE = @VAPIGEN_MAKEFILE@ VAPIGEN_VAPIDIR = @VAPIGEN_VAPIDIR@ @@ -349,6 +364,7 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ systemdsystemunitdir = @systemdsystemunitdir@ target_alias = @target_alias@ @@ -359,11 +375,14 @@ with_dhclient = @with_dhclient@ with_dhcpcd = @with_dhcpcd@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ +with_valgrind = @with_valgrind@ KEYFILES = \ Test_Wired_Connection \ Test_GSM_Connection \ Test_Wireless_Connection \ Test_Wired_Connection_MAC_Case \ + Test_MAC_Old_Format \ + Test_MAC_IB_Old_Format \ Test_Wired_Connection_IP6 \ ATT_Data_Connect_BT \ ATT_Data_Connect_Plain \ @@ -378,6 +397,8 @@ KEYFILES = \ Test_InfiniBand_Connection \ Test_Bridge_Main \ Test_Bridge_Component \ + Test_New_Wired_Group_Name \ + Test_New_Wireless_Group_Names \ Test_Missing_Vlan_Setting CERTS = \ diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format b/src/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format new file mode 100644 index 00000000..b2bf9155 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format @@ -0,0 +1,13 @@ +[connection] +id=Test InfiniBand Connection +uuid=5680a56d-c99f-45ad-a6dd-b44d5c398c12 +type=infiniband + +[infiniband] +mac-address=0;17;34;51;68;85;102;119;136;153;1;18;35;52;69;86;103;120;137;144; +transport-mode=datagram +mtu=1400 + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format b/src/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format new file mode 100644 index 00000000..9427b16c --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format @@ -0,0 +1,10 @@ +[connection] +id=Test MAC Old Format +uuid=8980a26d-c99f-4aad-a6bd-b439bc348ca4 +type=802-3-ethernet + +[802-3-ethernet] +mac-address=00:11:aa:BB:CC:55 +cloned-mac-address=00;22;170;187;204;254; +mtu=1400 + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name b/src/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name new file mode 100644 index 00000000..f27cd4a3 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name @@ -0,0 +1,13 @@ + +[connection] +id=Test Wired Connection +uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57 +type=ethernet + +[ethernet] +mac-address=00:11:22:33:44:55 +mtu=1400 + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names b/src/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names new file mode 100644 index 00000000..d9ac5864 --- /dev/null +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names @@ -0,0 +1,16 @@ +[connection] +id=Test New Wireless Group Names +uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa +type=wifi + +[wifi] +ssid=foobar +mode=infrastructure + +[wifi-security] +key-mgmt=wpa-psk +psk=s3cu4e passphrase + +[ipv4] +method=auto + diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection index 203441ef..de8373be 100644 --- a/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection +++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection @@ -20,8 +20,20 @@ addresses1=192.168.0.5;24;192.168.0.1; addresses2=1.2.3.4;16;1.2.1.1; address=2.3.4.5/24,2.3.4.6 address3=3.4.5.6/16 +address4=4.5.6.7/1.2.3.4 +address5=5.6.7.8 routes1=1.2.3.0/24,2.3.4.8,99 route=5.6.7.8/32 +routes2=1.1.1.2/12, +routes3=1.1.1.3/13,, +routes4=1.1.1.4/14,2.2.2.4 +routes5=1.1.1.5/15,2.2.2.5, +routes6=1.1.1.6/16,2.2.2.6,0 +routes7=1.1.1.7/17,0.0.0.0 +routes8=1.1.1.8/18,0.0.0.0, +routes9=1.1.1.9/19,0.0.0.0,0 +routes10=1.1.1.10/20,,0 +routes11=1.1.1.11/21,,21 ignore-auto-routes=false ignore-auto-dns=false @@ -33,8 +45,18 @@ addresses1=abcd:1234:ffff::cdde/64 addresses2=1:2:3:4:5:6:7:8/96 address=2:3:4:5:6:7:8:9/64,2:3:4:5:1:2:3:4 address3=3:4:5:6:7:8:9:0/128 +address4=3:4:5:6:7:8:9:14 +address5=3:4:5:6:7:8:9:15, +address6=3:4:5:6:7:8:9:16,66 +address7=3:4:5:6:7:8:9:17,67, +address8=3:4:5:6:7:8:9:18,68,:: +address9=3:4:5:6:7:8:9:19,69,1::09 routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99; route=d:e:f:0:1:2:3:4/64,f:e:d:c:1:2:3:4 route2=8:7:6:5:4:3:2:1/128 +route3=6:7:8:9:0:1:2:3/126,,1 +route4=7:8:9:0:1:2:3:4/125/::,5 +route5=8:9:0:1:2:3:4:5/124,6 +route6=8:9:0:1:2:3:4:6/123,, ignore-auto-routes=false ignore-auto-dns=false diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index 2f89c5f1..cc57c1c3 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2008 - 2011 Red Hat, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. */ #include <stdio.h> @@ -40,12 +40,13 @@ #include <nm-setting-gsm.h> #include <nm-setting-8021x.h> #include <nm-setting-infiniband.h> - -#include "nm-test-helpers.h" +#include <nm-logging.h> #include "reader.h" #include "writer.h" +#include "nm-test-utils.h" + #define TEST_WIRED_FILE TEST_KEYFILES_DIR"/Test_Wired_Connection" #define TEST_WIRELESS_FILE TEST_KEYFILES_DIR"/Test_Wireless_Connection" @@ -53,16 +54,15 @@ static void check_ip4_address (NMSettingIP4Config *config, int idx, const char *address_str, int plen, const char *gateway_str) { NMIP4Address *ip4 = nm_setting_ip4_config_get_address (config, idx); - struct in_addr address; - struct in_addr gateway; + guint32 address, gateway; g_assert (inet_pton (AF_INET, address_str, &address) == 1); g_assert (inet_pton (AF_INET, gateway_str, &gateway) == 1); g_assert (ip4); - g_assert (nm_ip4_address_get_address (ip4) == address.s_addr); + g_assert (nm_ip4_address_get_address (ip4) == address); g_assert (nm_ip4_address_get_prefix (ip4) == plen); - g_assert (nm_ip4_address_get_gateway (ip4) == gateway.s_addr); + g_assert (nm_ip4_address_get_gateway (ip4) == gateway); } static void @@ -86,16 +86,15 @@ check_ip4_route (NMSettingIP4Config *config, int idx, const char *destination_st const char *nexthop_str, int metric) { NMIP4Route *route = nm_setting_ip4_config_get_route (config, idx); - struct in_addr destination; - struct in_addr nexthop; + guint32 destination, nexthop; g_assert (inet_pton (AF_INET, destination_str, &destination) == 1); g_assert (inet_pton (AF_INET, nexthop_str, &nexthop) == 1); g_assert (route); - g_assert (nm_ip4_route_get_dest (route) == destination.s_addr); + g_assert (nm_ip4_route_get_dest (route) == destination); g_assert (nm_ip4_route_get_prefix (route) == plen); - g_assert (nm_ip4_route_get_next_hop (route) == nexthop.s_addr); + g_assert (nm_ip4_route_get_next_hop (route) == nexthop); g_assert (nm_ip4_route_get_metric (route) == metric); } @@ -135,7 +134,7 @@ test_read_valid_wired_connection (void) guint64 timestamp; const char *expected_dns1 = "4.2.2.1"; const char *expected_dns2 = "4.2.2.2"; - struct in_addr addr; + guint32 addr; struct in6_addr addr6; const char *expected6_dns1 = "1111:dddd::aaaa"; const char *expected6_dns2 = "1::cafe"; @@ -143,7 +142,36 @@ test_read_valid_wired_connection (void) const char *expected6_dnssearch2 = "redhat.com"; const char *expected6_dnssearch3 = "gnu.org"; + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.addresses1*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.addresses2*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*Missing prefix length*ipv4.address4*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*Missing prefix length*ipv4.address5*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.routes2*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.routes3*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.routes5*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.routes8*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*Missing prefix length*ipv6.address4*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv6.address5*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*Missing prefix length*ipv6.address5*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv6.address7*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv6.routes1*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv6.route6*semicolon at the end*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_FILE, NULL); + g_test_assert_expected_messages (); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_WIRED_FILE); @@ -259,7 +287,7 @@ test_read_valid_wired_connection (void) TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr.s_addr, + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 0) == addr, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #1", TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, @@ -270,23 +298,35 @@ test_read_valid_wired_connection (void) TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DNS); - ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr.s_addr, + ASSERT (nm_setting_ip4_config_get_dns (s_ip4, 1) == addr, "connection-verify-wired", "failed to verify %s: unexpected %s / %s key value #2", TEST_WIRED_FILE, NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_DNS); /* IPv4 addresses */ - g_assert (nm_setting_ip4_config_get_num_addresses (s_ip4) == 4); + g_assert (nm_setting_ip4_config_get_num_addresses (s_ip4) == 6); check_ip4_address (s_ip4, 0, "2.3.4.5", 24, "2.3.4.6"); check_ip4_address (s_ip4, 1, "192.168.0.5", 24, "192.168.0.1"); check_ip4_address (s_ip4, 2, "1.2.3.4", 16, "1.2.1.1"); check_ip4_address (s_ip4, 3, "3.4.5.6", 16, "0.0.0.0"); + check_ip4_address (s_ip4, 4, "4.5.6.7", 24, "1.2.3.4"); + check_ip4_address (s_ip4, 5, "5.6.7.8", 24, "0.0.0.0"); /* IPv4 routes */ - g_assert (nm_setting_ip4_config_get_num_routes (s_ip4) == 2); + g_assert (nm_setting_ip4_config_get_num_routes (s_ip4) == 12); check_ip4_route (s_ip4, 0, "5.6.7.8", 32, "0.0.0.0", 0); check_ip4_route (s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99); + check_ip4_route (s_ip4, 2, "1.1.1.2", 12, "0.0.0.0", 0); + check_ip4_route (s_ip4, 3, "1.1.1.3", 13, "0.0.0.0", 0); + check_ip4_route (s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", 0); + check_ip4_route (s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", 0); + check_ip4_route (s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", 0); + check_ip4_route (s_ip4, 7, "1.1.1.7", 17, "0.0.0.0", 0); + check_ip4_route (s_ip4, 8, "1.1.1.8", 18, "0.0.0.0", 0); + check_ip4_route (s_ip4, 9, "1.1.1.9", 19, "0.0.0.0", 0); + check_ip4_route (s_ip4, 10, "1.1.1.10", 20, "0.0.0.0", 0); + check_ip4_route (s_ip4, 11, "1.1.1.11", 21, "0.0.0.0", 21); /* ===== IPv6 SETTING ===== */ @@ -357,17 +397,27 @@ test_read_valid_wired_connection (void) NM_SETTING_IP6_CONFIG_DNS_SEARCH); /* IPv6 addresses */ - g_assert (nm_setting_ip6_config_get_num_addresses (s_ip6) == 4); + g_assert (nm_setting_ip6_config_get_num_addresses (s_ip6) == 10); check_ip6_address (s_ip6, 0, "2:3:4:5:6:7:8:9", 64, "2:3:4:5:1:2:3:4"); check_ip6_address (s_ip6, 1, "abcd:1234:ffff::cdde", 64, "::"); check_ip6_address (s_ip6, 2, "1:2:3:4:5:6:7:8", 96, "::"); check_ip6_address (s_ip6, 3, "3:4:5:6:7:8:9:0", 128, "::"); + check_ip6_address (s_ip6, 4, "3:4:5:6:7:8:9:14", 64, "::"); + check_ip6_address (s_ip6, 5, "3:4:5:6:7:8:9:15", 64, "::"); + check_ip6_address (s_ip6, 6, "3:4:5:6:7:8:9:16", 66, "::"); + check_ip6_address (s_ip6, 7, "3:4:5:6:7:8:9:17", 67, "::"); + check_ip6_address (s_ip6, 8, "3:4:5:6:7:8:9:18", 68, "::"); + check_ip6_address (s_ip6, 9, "3:4:5:6:7:8:9:19", 69, "1::09"); /* Route #1 */ - g_assert (nm_setting_ip6_config_get_num_routes (s_ip6) == 3); + g_assert (nm_setting_ip6_config_get_num_routes (s_ip6) == 7); check_ip6_route (s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", 0); check_ip6_route (s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99); check_ip6_route (s_ip6, 2, "8:7:6:5:4:3:2:1", 128, "::", 0); + check_ip6_route (s_ip6, 3, "6:7:8:9:0:1:2:3", 126, "::", 1); + check_ip6_route (s_ip6, 4, "7:8:9:0:1:2:3:4", 125, "::", 5); + check_ip6_route (s_ip6, 5, "8:9:0:1:2:3:4:5", 124, "::", 6); + check_ip6_route (s_ip6, 6, "8:9:0:1:2:3:4:6", 123, "::", 0); g_object_unref (connection); } @@ -377,17 +427,17 @@ add_one_ip4_address (NMSettingIP4Config *s_ip4, const char *gw, guint32 prefix) { - struct in_addr tmp; + guint32 tmp; NMIP4Address *ip4_addr; ip4_addr = nm_ip4_address_new (); nm_ip4_address_set_prefix (ip4_addr, prefix); inet_pton (AF_INET, addr, &tmp); - nm_ip4_address_set_address (ip4_addr, tmp.s_addr); + nm_ip4_address_set_address (ip4_addr, tmp); inet_pton (AF_INET, gw, &tmp); - nm_ip4_address_set_gateway (ip4_addr, tmp.s_addr); + nm_ip4_address_set_gateway (ip4_addr, tmp); nm_setting_ip4_config_add_address (s_ip4, ip4_addr); nm_ip4_address_unref (ip4_addr); @@ -400,7 +450,7 @@ add_one_ip4_route (NMSettingIP4Config *s_ip4, guint32 prefix, guint32 metric) { - struct in_addr addr; + guint32 addr; NMIP4Route *route; route = nm_ip4_route_new (); @@ -408,10 +458,10 @@ add_one_ip4_route (NMSettingIP4Config *s_ip4, nm_ip4_route_set_metric (route, metric); inet_pton (AF_INET, dest, &addr); - nm_ip4_route_set_dest (route, addr.s_addr); + nm_ip4_route_set_dest (route, addr); inet_pton (AF_INET, nh, &addr); - nm_ip4_route_set_next_hop (route, addr.s_addr); + nm_ip4_route_set_next_hop (route, addr); nm_setting_ip4_config_add_route (s_ip4, route); nm_ip4_route_unref (route); @@ -483,7 +533,7 @@ test_write_wired_connection (void) GError *error = NULL; pid_t owner_grp; uid_t owner_uid; - struct in_addr addr; + guint32 addr; struct in6_addr addr6; const char *dns1 = "4.2.2.1"; const char *dns2 = "4.2.2.2"; @@ -495,6 +545,10 @@ test_write_wired_connection (void) const char *route1_nh = "10.10.10.1"; const char *route2 = "1.1.1.1"; const char *route2_nh = "1.2.1.1"; + const char *route3 = "2.2.2.2"; + const char *route3_nh = "0.0.0.0"; + const char *route4 = "3.3.3.3"; + const char *route4_nh = "0.0.0.0"; const char *dns6_1 = "1::cafe"; const char *dns6_2 = "2::cafe"; const char *address6_1 = "abcd::beef"; @@ -503,18 +557,17 @@ test_write_wired_connection (void) const char *route6_1_nh = "8:7:6:5:4:3:2:1"; const char *route6_2 = "2001::1000"; const char *route6_2_nh = "2001::1111"; + const char *route6_3 = "4:5:6:7:8:9:0:1"; + const char *route6_3_nh = "::"; + const char *route6_4 = "5:6:7:8:9:0:1:2"; + const char *route6_4_nh = "::"; guint64 timestamp = 0x12345678L; connection = nm_connection_new (); - ASSERT (connection != NULL, - "connection-write", "failed to allocate new connection"); /* Connection setting */ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - ASSERT (s_con != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_CONNECTION_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); @@ -530,9 +583,6 @@ test_write_wired_connection (void) /* Wired setting */ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - ASSERT (s_wired != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_WIRED_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_wired)); mac = g_byte_array_sized_new (ETH_ALEN); @@ -546,9 +596,6 @@ test_write_wired_connection (void) /* IP4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - ASSERT (s_ip4 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, @@ -562,19 +609,18 @@ test_write_wired_connection (void) /* Routes */ add_one_ip4_route (s_ip4, route1, route1_nh, 24, 3); add_one_ip4_route (s_ip4, route2, route2_nh, 8, 1); + add_one_ip4_route (s_ip4, route3, route3_nh, 7, 0); + add_one_ip4_route (s_ip4, route4, route4_nh, 6, 4); /* DNS servers */ inet_pton (AF_INET, dns1, &addr); - nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr); + nm_setting_ip4_config_add_dns (s_ip4, addr); inet_pton (AF_INET, dns2, &addr); - nm_setting_ip4_config_add_dns (s_ip4, addr.s_addr); + nm_setting_ip4_config_add_dns (s_ip4, addr); /* IP6 setting */ s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); - ASSERT (s_ip6 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP6_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, @@ -588,6 +634,8 @@ test_write_wired_connection (void) /* Routes */ add_one_ip6_route (s_ip6, route6_1, route6_1_nh, 64, 3); add_one_ip6_route (s_ip6, route6_2, route6_2_nh, 56, 1); + add_one_ip6_route (s_ip6, route6_3, route6_3_nh, 63, 5); + add_one_ip6_route (s_ip6, route6_4, route6_4_nh, 62, 0); /* DNS servers */ inet_pton (AF_INET6, dns6_1, &addr6); @@ -754,15 +802,10 @@ test_write_ip6_wired_connection (void) const char *gw = "dcba::beef"; connection = nm_connection_new (); - ASSERT (connection != NULL, - "connection-write", "failed to allocate new connection"); /* Connection setting */ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - ASSERT (s_con != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_CONNECTION_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); @@ -777,17 +820,11 @@ test_write_ip6_wired_connection (void) /* Wired setting */ s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - ASSERT (s_wired != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_WIRED_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_wired)); /* IP4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - ASSERT (s_ip4 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, @@ -797,9 +834,6 @@ test_write_ip6_wired_connection (void) /* IP6 setting */ s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); - ASSERT (s_ip6 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP6_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, @@ -857,7 +891,14 @@ test_read_wired_mac_case (void) const char *expected_id = "Test Wired Connection MAC Case"; const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57"; + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.addresses1*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv4.addresses2*semicolon at the end*"); + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, + "*ipv6.routes1*semicolon at the end*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_MAC_CASE_FILE, NULL); + g_test_assert_expected_messages (); ASSERT (connection != NULL, "connection-read", "failed to read %s", TEST_WIRED_MAC_CASE_FILE); @@ -927,6 +968,79 @@ test_read_wired_mac_case (void) g_object_unref (connection); } +#define TEST_MAC_OLD_FORMAT_FILE TEST_KEYFILES_DIR"/Test_MAC_Old_Format" + +static void +test_read_mac_old_format (void) +{ + NMConnection *connection; + NMSettingWired *s_wired; + GError *error = NULL; + gboolean success; + const GByteArray *array; + char expected_mac[ETH_ALEN] = { 0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55 }; + char expected_cloned_mac[ETH_ALEN] = { 0x00, 0x16, 0xaa, 0xbb, 0xcc, 0xfe }; + + connection = nm_keyfile_plugin_connection_from_file (TEST_MAC_OLD_FORMAT_FILE, &error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + + /* MAC address */ + array = nm_setting_wired_get_mac_address (s_wired); + g_assert (array); + g_assert_cmpint (array->len, ==, ETH_ALEN); + g_assert (memcmp (array->data, expected_mac, ETH_ALEN) == 0); + + /* Cloned MAC address */ + array = nm_setting_wired_get_cloned_mac_address (s_wired); + g_assert (array); + g_assert_cmpint (array->len, ==, ETH_ALEN); + g_assert (memcmp (array->data, expected_cloned_mac, ETH_ALEN) == 0); + + g_object_unref (connection); +} + +#define TEST_MAC_IB_OLD_FORMAT_FILE TEST_KEYFILES_DIR"/Test_MAC_IB_Old_Format" + +static void +test_read_mac_ib_old_format (void) +{ + NMConnection *connection; + NMSettingInfiniband *s_ib; + GError *error = NULL; + gboolean success; + const GByteArray *array; + guint8 expected_mac[INFINIBAND_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, + 0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, + 0x90 }; + + connection = nm_keyfile_plugin_connection_from_file (TEST_MAC_IB_OLD_FORMAT_FILE, &error); + g_assert_no_error (error); + g_assert (connection); + + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + s_ib = nm_connection_get_setting_infiniband (connection); + g_assert (s_ib); + + /* MAC address */ + array = nm_setting_infiniband_get_mac_address (s_ib); + g_assert (array); + g_assert_cmpint (array->len, ==, INFINIBAND_ALEN); + g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + + g_object_unref (connection); +} + static void test_read_valid_wireless_connection (void) { @@ -1066,15 +1180,10 @@ test_write_wireless_connection (void) guint64 timestamp = 0x12344433L; connection = nm_connection_new (); - ASSERT (connection != NULL, - "connection-write", "failed to allocate new connection"); /* Connection setting */ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - ASSERT (s_con != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_CONNECTION_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); @@ -1090,9 +1199,6 @@ test_write_wireless_connection (void) /* Wireless setting */ s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - ASSERT (s_wireless != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_WIRELESS_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_wireless)); bssid = g_byte_array_sized_new (ETH_ALEN); @@ -1113,9 +1219,6 @@ test_write_wireless_connection (void) /* IP4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - ASSERT (s_ip4 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, @@ -1125,9 +1228,6 @@ test_write_wireless_connection (void) /* IP6 setting */ s_ip6 = NM_SETTING_IP6_CONFIG (nm_setting_ip6_config_new ()); - ASSERT (s_ip6 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP6_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip6)); g_object_set (s_ip6, @@ -1217,15 +1317,10 @@ test_write_string_ssid (void) GKeyFile *keyfile; connection = nm_connection_new (); - ASSERT (connection != NULL, - "connection-write", "failed to allocate new connection"); /* Connection setting */ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - ASSERT (s_con != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_CONNECTION_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); @@ -1239,9 +1334,6 @@ test_write_string_ssid (void) /* Wireless setting */ s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - ASSERT (s_wireless != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_WIRELESS_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_wireless)); ssid = g_byte_array_sized_new (sizeof (tmpssid)); @@ -1252,9 +1344,6 @@ test_write_string_ssid (void) /* IP4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - ASSERT (s_ip4 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, @@ -1276,7 +1365,7 @@ test_write_string_ssid (void) keyfile = g_key_file_new (); ASSERT (g_key_file_load_from_file (keyfile, testfile, 0, NULL) == TRUE, "string-ssid-verify", "failed to load keyfile to verify"); - tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, NULL); + tmp = g_key_file_get_string (keyfile, "wifi", NM_SETTING_WIRELESS_SSID, NULL); ASSERT (tmp, "string-ssid-verify", "failed to load 'ssid' key from file"); ASSERT (strlen (tmp) == sizeof (tmpssid), "string-ssid-verify", "reread SSID and expected were different sizes"); @@ -1398,7 +1487,7 @@ test_write_intlist_ssid (void) g_assert_no_error (error); g_assert (success); - intlist = g_key_file_get_integer_list (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, &len, &error); + intlist = g_key_file_get_integer_list (keyfile, "wifi", NM_SETTING_WIRELESS_SSID, &len, &error); g_assert_no_error (error); g_assert (intlist); g_assert_cmpint (len, ==, sizeof (tmpssid)); @@ -1554,7 +1643,7 @@ test_write_intlike_ssid (void) g_assert_no_error (error); g_assert (success); - tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, &error); + tmp = g_key_file_get_string (keyfile, "wifi", NM_SETTING_WIRELESS_SSID, &error); g_assert_no_error (error); g_assert (tmp); g_assert_cmpstr (tmp, ==, "101"); @@ -1642,7 +1731,7 @@ test_write_intlike_ssid_2 (void) g_assert_no_error (error); g_assert (success); - tmp = g_key_file_get_string (keyfile, NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID, &error); + tmp = g_key_file_get_string (keyfile, "wifi", NM_SETTING_WIRELESS_SSID, &error); g_assert_no_error (error); g_assert (tmp); g_assert_cmpstr (tmp, ==, "11\\;12\\;13\\;"); @@ -1843,15 +1932,10 @@ test_write_bt_dun_connection (void) guint64 timestamp = 0x12344433L; connection = nm_connection_new (); - ASSERT (connection != NULL, - "connection-write", "failed to allocate new connection"); /* Connection setting */ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - ASSERT (s_con != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_CONNECTION_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); @@ -1867,9 +1951,6 @@ test_write_bt_dun_connection (void) /* Bluetooth setting */ s_bt = NM_SETTING_BLUETOOTH (nm_setting_bluetooth_new ()); - ASSERT (s_bt != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_BLUETOOTH_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_bt)); bdaddr = g_byte_array_sized_new (ETH_ALEN); @@ -1885,9 +1966,6 @@ test_write_bt_dun_connection (void) /* IP4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - ASSERT (s_ip4 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, @@ -1896,9 +1974,6 @@ test_write_bt_dun_connection (void) /* GSM setting */ s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); - ASSERT (s_gsm != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_GSM_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_gsm)); g_object_set (s_gsm, @@ -2103,15 +2178,10 @@ test_write_gsm_connection (void) guint64 timestamp = 0x12344433L; connection = nm_connection_new (); - ASSERT (connection != NULL, - "connection-write", "failed to allocate new connection"); /* Connection setting */ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - ASSERT (s_con != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_CONNECTION_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_con)); uuid = nm_utils_uuid_generate (); @@ -2127,9 +2197,6 @@ test_write_gsm_connection (void) /* IP4 setting */ s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_ip4_config_new ()); - ASSERT (s_ip4 != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_IP4_CONFIG_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_ip4)); g_object_set (s_ip4, @@ -2138,9 +2205,6 @@ test_write_gsm_connection (void) /* GSM setting */ s_gsm = NM_SETTING_GSM (nm_setting_gsm_new ()); - ASSERT (s_gsm != NULL, - "connection-write", "failed to allocate new %s setting", - NM_SETTING_GSM_SETTING_NAME); nm_connection_add_setting (connection, NM_SETTING (s_gsm)); g_object_set (s_gsm, @@ -2228,7 +2292,10 @@ test_read_wired_8021x_tls_blob_connection (void) g_assert_cmpint (nm_setting_802_1x_get_ca_cert_scheme (s_8021x), ==, NM_SETTING_802_1X_CK_SCHEME_BLOB); /* Make sure it's not a path, since it's a blob */ + g_test_expect_message ("libnm-util", G_LOG_LEVEL_CRITICAL, + "*assertion*scheme == NM_SETTING_802_1X_CK_SCHEME_PATH*"); tmp = nm_setting_802_1x_get_ca_cert_path (s_8021x); + g_test_assert_expected_messages (); g_assert (tmp == NULL); /* Validate the path */ @@ -2258,7 +2325,10 @@ test_read_wired_8021x_tls_bad_path_connection (void) char *tmp2; gboolean success; + g_test_expect_message ("NetworkManager", G_LOG_LEVEL_WARNING, + "*does not exist*"); connection = nm_keyfile_plugin_connection_from_file (TEST_WIRED_TLS_PATH_MISSING_FILE, &error); + g_test_assert_expected_messages (); if (connection == NULL) { g_assert (error); g_warning ("Failed to read %s: %s", TEST_WIRED_TLS_PATH_MISSING_FILE, error->message); @@ -2894,6 +2964,7 @@ test_write_bridge_main (void) NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_TYPE, NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_CONNECTION_INTERFACE_NAME, "br0", NULL); g_free (uuid); @@ -3076,6 +3147,247 @@ test_write_bridge_component (void) } static void +test_read_new_wired_group_name (void) +{ + NMConnection *connection; + NMSettingWired *s_wired; + const GByteArray *array; + guint8 expected_mac[ETH_ALEN] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + GError *error = NULL; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_KEYFILES_DIR"/Test_New_Wired_Group_Name", &error); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Wired setting */ + s_wired = nm_connection_get_setting_wired (connection); + g_assert (s_wired); + g_assert_cmpint (nm_setting_wired_get_mtu (s_wired), ==, 1400); + + array = nm_setting_wired_get_mac_address (s_wired); + g_assert (array); + g_assert_cmpint (array->len, ==, ETH_ALEN); + g_assert_cmpint (memcmp (array->data, expected_mac, sizeof (expected_mac)), ==, 0); + + g_object_unref (connection); +} + +static void +test_write_new_wired_group_name (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + char *uuid; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + GKeyFile *kf; + char *s; + gint mtu; + + connection = nm_connection_new (); + g_assert (connection); + + /* Connection setting */ + s_con = (NMSettingConnection *) nm_setting_connection_new (); + g_assert (s_con); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write Wired New Group Name", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, + NULL); + g_free (uuid); + + /* Wired setting */ + s_wired = (NMSettingWired *) nm_setting_wired_new (); + g_assert (s_wired); + g_object_set (s_wired, NM_SETTING_WIRED_MTU, 1400, NULL); + nm_connection_add_setting (connection, NM_SETTING (s_wired)); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + g_assert (testfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + + /* Look at the keyfile itself to ensure we wrote out the new group names and type */ + kf = g_key_file_new (); + success = g_key_file_load_from_file (kf, testfile, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + g_assert (success); + + s = g_key_file_get_string (kf, NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, &error); + g_assert_no_error (error); + g_assert_cmpstr (s, ==, "ethernet"); + g_free (s); + + mtu = g_key_file_get_integer (kf, "ethernet", NM_SETTING_WIRED_MTU, &error); + g_assert_no_error (error); + g_assert_cmpint (mtu, ==, 1400); + + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +static void +test_read_new_wireless_group_names (void) +{ + NMConnection *connection; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + const GByteArray *array; + const char *expected_ssid = "foobar"; + GError *error = NULL; + gboolean success; + + connection = nm_keyfile_plugin_connection_from_file (TEST_KEYFILES_DIR"/Test_New_Wireless_Group_Names", &error); + g_assert_no_error (error); + g_assert (connection); + success = nm_connection_verify (connection, &error); + g_assert_no_error (error); + g_assert (success); + + /* Wifi setting */ + s_wifi = nm_connection_get_setting_wireless (connection); + g_assert (s_wifi); + + array = nm_setting_wireless_get_ssid (s_wifi); + g_assert (array); + g_assert_cmpint (array->len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (array->data, expected_ssid, array->len), ==, 0); + + g_assert_cmpstr (nm_setting_wireless_get_mode (s_wifi), ==, NM_SETTING_WIRELESS_MODE_INFRA); + + /* Wifi security setting */ + s_wsec = nm_connection_get_setting_wireless_security (connection); + g_assert (s_wsec); + g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); + g_assert_cmpstr (nm_setting_wireless_security_get_psk (s_wsec), ==, "s3cu4e passphrase"); + + g_object_unref (connection); +} + +static void +test_write_new_wireless_group_names (void) +{ + NMConnection *connection; + NMSettingConnection *s_con; + NMSettingWireless *s_wifi; + NMSettingWirelessSecurity *s_wsec; + char *uuid; + GByteArray *ssid; + unsigned char tmpssid[] = { 0x31, 0x33, 0x33, 0x37 }; + const char *expected_psk = "asdfasdfasdfa12315"; + gboolean success; + NMConnection *reread; + char *testfile = NULL; + GError *error = NULL; + pid_t owner_grp; + uid_t owner_uid; + GKeyFile *kf; + char *s; + + connection = nm_connection_new (); + + /* Connection setting */ + + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (connection, NM_SETTING (s_con)); + + uuid = nm_utils_uuid_generate (); + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, "Test Write New Wireless Group Names", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, + NULL); + g_free (uuid); + + /* WiFi setting */ + s_wifi = (NMSettingWireless *) nm_setting_wireless_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wifi)); + + ssid = g_byte_array_sized_new (sizeof (tmpssid)); + g_byte_array_append (ssid, &tmpssid[0], sizeof (tmpssid)); + g_object_set (s_wifi, + NM_SETTING_WIRELESS_SSID, ssid, + NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, + NULL); + g_byte_array_free (ssid, TRUE); + + /* WiFi security setting */ + s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new (); + nm_connection_add_setting (connection, NM_SETTING (s_wsec)); + g_object_set (s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_PSK, expected_psk, + NULL); + + /* Write out the connection */ + owner_uid = geteuid (); + owner_grp = getegid (); + success = nm_keyfile_plugin_write_test_connection (connection, TEST_SCRATCH_DIR, owner_uid, owner_grp, &testfile, &error); + g_assert_no_error (error); + g_assert (success); + + g_assert (testfile); + + /* Read the connection back in and compare it to the one we just wrote out */ + reread = nm_keyfile_plugin_connection_from_file (testfile, &error); + g_assert_no_error (error); + g_assert (reread); + g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT)); + + /* Look at the keyfile itself to ensure we wrote out the new group names and type */ + kf = g_key_file_new (); + success = g_key_file_load_from_file (kf, testfile, G_KEY_FILE_NONE, &error); + g_assert_no_error (error); + g_assert (success); + + s = g_key_file_get_string (kf, NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE, &error); + g_assert_no_error (error); + g_assert_cmpstr (s, ==, "wifi"); + g_free (s); + + s = g_key_file_get_string (kf, "wifi", NM_SETTING_WIRELESS_MODE, &error); + g_assert_no_error (error); + g_assert_cmpstr (s, ==, NM_SETTING_WIRELESS_MODE_INFRA); + g_free (s); + + s = g_key_file_get_string (kf, "wifi-security", NM_SETTING_WIRELESS_SECURITY_PSK, &error); + g_assert_no_error (error); + g_assert_cmpstr (s, ==, expected_psk); + g_free (s); + + unlink (testfile); + g_free (testfile); + + g_object_unref (reread); + g_object_unref (connection); +} + +static void test_read_missing_vlan_setting (void) { NMConnection *connection; @@ -3098,15 +3410,13 @@ test_read_missing_vlan_setting (void) g_object_unref (connection); } +NMTST_DEFINE (); + int main (int argc, char **argv) { - GError *error = NULL; char *base; - g_type_init (); - - if (!nm_utils_init (&error)) - FAIL ("nm-utils-init", "failed to initialize libnm-util: %s", error->message); + nmtst_init_assert_logging (&argc, &argv); /* The tests */ test_read_valid_wired_connection (); @@ -3116,6 +3426,8 @@ int main (int argc, char **argv) test_write_ip6_wired_connection (); test_read_wired_mac_case (); + test_read_mac_old_format (); + test_read_mac_ib_old_format (); test_read_valid_wireless_connection (); test_write_wireless_connection (); @@ -3154,6 +3466,11 @@ int main (int argc, char **argv) test_read_bridge_component (); test_write_bridge_component (); + test_read_new_wired_group_name (); + test_write_new_wired_group_name (); + test_read_new_wireless_group_names (); + test_write_new_wireless_group_names (); + test_read_missing_vlan_setting (); base = g_path_get_basename (argv[0]); diff --git a/src/settings/plugins/keyfile/utils.c b/src/settings/plugins/keyfile/utils.c index 8db5d524..e2bfc38c 100644 --- a/src/settings/plugins/keyfile/utils.c +++ b/src/settings/plugins/keyfile/utils.c @@ -22,6 +22,9 @@ #include <stdlib.h> #include <string.h> #include "utils.h" +#include <nm-setting-wired.h> +#include <nm-setting-wireless.h> +#include <nm-setting-wireless-security.h> static const char temp_letters[] = @@ -104,3 +107,176 @@ nm_keyfile_plugin_utils_should_ignore_file (const char *filename) return ignore; } +typedef struct { + const char *setting; + const char *alias; +} SettingAlias; + +static const SettingAlias alias_list[] = { + { NM_SETTING_WIRED_SETTING_NAME, "ethernet" }, + { NM_SETTING_WIRELESS_SETTING_NAME, "wifi" }, + { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-security" }, +}; + +const char * +nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name) +{ + guint i; + + g_return_val_if_fail (setting_name != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS (alias_list); i++) { + if (strcmp (setting_name, alias_list[i].setting) == 0) + return alias_list[i].alias; + } + return NULL; +} + +const char * +nm_keyfile_plugin_get_setting_name_for_alias (const char *alias) +{ + guint i; + + g_return_val_if_fail (alias != NULL, NULL); + + for (i = 0; i < G_N_ELEMENTS (alias_list); i++) { + if (strcmp (alias, alias_list[i].alias) == 0) + return alias_list[i].setting; + } + return NULL; +} + +/**********************************************************************/ + +/* List helpers */ +#define DEFINE_KF_LIST_WRAPPER(stype, get_ctype, set_ctype) \ +get_ctype \ +nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + gsize *out_length, \ + GError **error) \ +{ \ + get_ctype list; \ + const char *alias; \ + GError *local = NULL; \ + \ + list = g_key_file_get_##stype##_list (kf, group, key, out_length, &local); \ + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ + if (alias) { \ + g_clear_error (&local); \ + list = g_key_file_get_##stype##_list (kf, alias, key, out_length, &local); \ + } \ + } \ + if (local) \ + g_propagate_error (error, local); \ + return list; \ +} \ + \ +void \ +nm_keyfile_plugin_kf_set_##stype##_list (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + set_ctype list[], \ + gsize length) \ +{ \ + const char *alias; \ + \ + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ + g_key_file_set_##stype##_list (kf, alias ? alias : group, key, list, length); \ +} + +DEFINE_KF_LIST_WRAPPER(integer, gint*, gint); +DEFINE_KF_LIST_WRAPPER(string, gchar **, const gchar* const); + +/* Single value helpers */ +#define DEFINE_KF_WRAPPER(stype, get_ctype, set_ctype) \ +get_ctype \ +nm_keyfile_plugin_kf_get_##stype (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + GError **error) \ +{ \ + get_ctype val; \ + const char *alias; \ + GError *local = NULL; \ + \ + val = g_key_file_get_##stype (kf, group, key, &local); \ + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \ + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ + if (alias) { \ + g_clear_error (&local); \ + val = g_key_file_get_##stype (kf, alias, key, &local); \ + } \ + } \ + if (local) \ + g_propagate_error (error, local); \ + return val; \ +} \ + \ +void \ +nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + set_ctype value) \ +{ \ + const char *alias; \ + \ + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \ + g_key_file_set_##stype (kf, alias ? alias : group, key, value); \ +} + +DEFINE_KF_WRAPPER(string, gchar*, const gchar*); +DEFINE_KF_WRAPPER(integer, gint, gint); +DEFINE_KF_WRAPPER(boolean, gboolean, gboolean); +DEFINE_KF_WRAPPER(value, gchar*, const gchar*); + + +gchar ** +nm_keyfile_plugin_kf_get_keys (GKeyFile *kf, + const char *group, + gsize *out_length, + GError **error) +{ + gchar **keys; + const char *alias; + GError *local = NULL; + + keys = g_key_file_get_keys (kf, group, out_length, &local); + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); + if (alias) { + g_clear_error (&local); + keys = g_key_file_get_keys (kf, alias, out_length, &local); + } + } + if (local) + g_propagate_error (error, local); + return keys; +} + +gboolean +nm_keyfile_plugin_kf_has_key (GKeyFile *kf, + const char *group, + const char *key, + GError **error) +{ + gboolean has; + const char *alias; + GError *local = NULL; + + has = g_key_file_has_key (kf, group, key, &local); + if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { + alias = nm_keyfile_plugin_get_alias_for_setting_name (group); + if (alias) { + g_clear_error (&local); + has = g_key_file_has_key (kf, alias, key, &local); + } + } + if (local) + g_propagate_error (error, local); + return has; +} + + diff --git a/src/settings/plugins/keyfile/utils.h b/src/settings/plugins/keyfile/utils.h index 68e6e56f..9a2e485b 100644 --- a/src/settings/plugins/keyfile/utils.h +++ b/src/settings/plugins/keyfile/utils.h @@ -26,5 +26,54 @@ gboolean nm_keyfile_plugin_utils_should_ignore_file (const char *filename); +const char *nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name); + +const char *nm_keyfile_plugin_get_setting_name_for_alias (const char *alias); + +/*********************************************************/ + +/* List helpers */ +#define DEFINE_KF_LIST_WRAPPER_PROTO(stype, get_ctype, set_ctype) \ +get_ctype nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + gsize *out_length, \ + GError **error); \ +\ +void nm_keyfile_plugin_kf_set_##stype##_list (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + set_ctype list[], \ + gsize length); +DEFINE_KF_LIST_WRAPPER_PROTO(integer, gint*, gint) +DEFINE_KF_LIST_WRAPPER_PROTO(string, gchar**, const gchar* const) + +/* Single-value helpers */ +#define DEFINE_KF_WRAPPER_PROTO(stype, get_ctype, set_ctype) \ +get_ctype nm_keyfile_plugin_kf_get_##stype (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + GError **error); \ +\ +void nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \ + const char *group, \ + const char *key, \ + set_ctype value); +DEFINE_KF_WRAPPER_PROTO(string, gchar*, const gchar*) +DEFINE_KF_WRAPPER_PROTO(integer, gint, gint) +DEFINE_KF_WRAPPER_PROTO(boolean, gboolean, gboolean) +DEFINE_KF_WRAPPER_PROTO(value, gchar*, const gchar*) + +/* Misc */ +gchar ** nm_keyfile_plugin_kf_get_keys (GKeyFile *kf, + const char *group, + gsize *out_length, + GError **error); + +gboolean nm_keyfile_plugin_kf_has_key (GKeyFile *kf, + const char *group, + const char *key, + GError **error); + #endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c index 38061a5d..5f3ebe25 100644 --- a/src/settings/plugins/keyfile/writer.c +++ b/src/settings/plugins/keyfile/writer.c @@ -44,8 +44,35 @@ #include "nm-dbus-glib-types.h" #include "nm-glib-compat.h" +#include "nm-logging.h" #include "writer.h" #include "common.h" +#include "utils.h" + +/* Some setting properties also contain setting names, such as + * NMSettingConnection's 'type' property (which specifies the base type of the + * connection, eg ethernet or wifi) or the 802-11-wireless setting's + * 'security' property which specifies whether or not the AP requires + * encrpytion. This function handles translating those properties' values + * from the real setting name to the more-readable alias. + */ +static void +setting_alias_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + const char *str, *alias; + + str = g_value_get_string (value); + alias = nm_keyfile_plugin_get_alias_for_setting_name (str); + nm_keyfile_plugin_kf_set_string (file, + nm_setting_get_name (setting), + key, + alias ? alias : str); +} static gboolean write_array_of_uint (GKeyFile *file, @@ -65,7 +92,7 @@ write_array_of_uint (GKeyFile *file, for (i = 0; i < array->len; i++) tmp_array[i] = g_array_index (array, int, i); - g_key_file_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len); + nm_keyfile_plugin_kf_set_integer_list (file, nm_setting_get_name (setting), key, tmp_array, array->len); g_free (tmp_array); return TRUE; } @@ -91,71 +118,63 @@ ip4_dns_writer (GKeyFile *file, list = g_new0 (char *, array->len + 1); for (i = 0; i < array->len; i++) { - char buf[INET_ADDRSTRLEN + 1]; - struct in_addr addr; - - addr.s_addr = g_array_index (array, guint32, i); - if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) { - g_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); - } else - list[num++] = g_strdup (buf); + char *buf = g_new (char, INET_ADDRSTRLEN); + guint32 addr; + + addr = g_array_index (array, guint32, i); + nm_utils_inet4_ntop (addr, buf); + list[num++] = buf; } - g_key_file_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); + nm_keyfile_plugin_kf_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); g_strfreev (list); } static void write_ip4_values (GKeyFile *file, const char *setting_name, - const char *key, GPtrArray *array, - guint32 tuple_len, - guint32 addr1_pos, - guint32 addr2_pos) + gboolean is_route) { GString *output; - int i, j; + int i; + guint32 addr, gw, plen, metric; + char key_name[30], *key_name_idx; - for (i = 0, j = 0; i < array->len; i++, j++) { - GArray *tuple = g_ptr_array_index (array, i); - gboolean success = TRUE; - char *key_name; - int k; + if (!array->len) + return; - output = g_string_new (""); + strcpy (key_name, is_route ? "route" : "address"); + key_name_idx = key_name + strlen (key_name); - for (k = 0; k < tuple_len; k++) { - if (k == addr1_pos || k == addr2_pos) { - char buf[INET_ADDRSTRLEN + 1]; - struct in_addr addr; - - /* IP addresses */ - addr.s_addr = g_array_index (tuple, guint32, k); - if (!inet_ntop (AF_INET, &addr, buf, sizeof (buf))) { - g_warning ("%s: error converting IP4 address 0x%X", - __func__, ntohl (addr.s_addr)); - success = FALSE; - break; - } else { - g_string_append_printf (output, "%s%s", k == 0 ? "" : ",", buf); - } - } else { - /* prefix, metric */ - g_string_append_printf (output, "%c%d", k == 1 ? '/' : ',', g_array_index (tuple, guint32, k)); - } - } + output = g_string_sized_new (2*INET_ADDRSTRLEN + 10); + for (i = 0; i < array->len; i++) { + GArray *tuple = g_ptr_array_index (array, i); - if (success) { - key_name = g_strdup_printf ("%s%d", key, j + 1); - g_key_file_set_string (file, setting_name, key_name, output->str); - g_free (key_name); + addr = g_array_index (tuple, guint32, 0); + plen = g_array_index (tuple, guint32, 1); + gw = g_array_index (tuple, guint32, 2); + metric = is_route ? g_array_index (tuple, guint32, 3) : 0; + + g_string_set_size (output, 0); + g_string_append_printf (output, "%s/%u", + nm_utils_inet4_ntop (addr, NULL), + (unsigned) plen); + if (metric || gw) { + /* Older versions of the plugin do not support the form + * "a.b.c.d/plen,,metric", so, we always have to write the + * gateway, even if it's 0.0.0.0. + * The current version support reading of the above form. */ + g_string_append_c (output, ','); + g_string_append (output, nm_utils_inet4_ntop (gw, NULL)); + if (metric) + g_string_append_printf (output, ",%lu", (unsigned long) metric); } - g_string_free (output, TRUE); - + sprintf (key_name_idx, "%d", i + 1); + nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); } + g_string_free (output, TRUE); } static void @@ -173,7 +192,18 @@ ip4_addr_writer (GKeyFile *file, array = (GPtrArray *) g_value_get_boxed (value); if (array && array->len) - write_ip4_values (file, setting_name, "address", array, 3, 0, 2); + write_ip4_values (file, setting_name, array, FALSE); +} + +static void +ip4_addr_label_writer (GKeyFile *file, + const char *keyfile_dir, + const char *uuid, + NMSetting *setting, + const char *key, + const GValue *value) +{ + /* skip */ } static void @@ -191,7 +221,7 @@ ip4_route_writer (GKeyFile *file, array = (GPtrArray *) g_value_get_boxed (value); if (array && array->len) - write_ip4_values (file, setting_name, "route", array, 4, 0, 2); + write_ip4_values (file, setting_name, array, TRUE); } static void @@ -216,90 +246,63 @@ ip6_dns_writer (GKeyFile *file, list = g_new0 (char *, array->len + 1); for (i = 0; i < array->len; i++) { - char buf[INET6_ADDRSTRLEN]; + char *buf = g_new (char, INET6_ADDRSTRLEN); byte_array = g_ptr_array_index (array, i); - if (!inet_ntop (AF_INET6, (struct in6_addr *) byte_array->data, buf, sizeof (buf))) { - int j; - GString *ip6_str = g_string_new (NULL); - g_string_append_printf (ip6_str, "%02X", byte_array->data[0]); - for (j = 1; j < 16; j++) - g_string_append_printf (ip6_str, " %02X", byte_array->data[j]); - g_warning ("%s: error converting IP6 address %s", - __func__, ip6_str->str); - g_string_free (ip6_str, TRUE); - } else - list[num++] = g_strdup (buf); + nm_utils_inet6_ntop ((const struct in6_addr *) byte_array->data, buf); + list[num++] = buf; } - g_key_file_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); + nm_keyfile_plugin_kf_set_string_list (file, nm_setting_get_name (setting), key, (const char **) list, num); g_strfreev (list); } -static gboolean +static void ip6_array_to_addr (GValueArray *values, guint32 idx, char *buf, - size_t buflen, - gboolean *out_is_unspec) + struct in6_addr *out_addr) { GByteArray *byte_array; GValue *addr_val; - struct in6_addr *addr; - - g_return_val_if_fail (buflen >= INET6_ADDRSTRLEN, FALSE); + const struct in6_addr *addr; addr_val = g_value_array_get_nth (values, idx); byte_array = g_value_get_boxed (addr_val); - addr = (struct in6_addr *) byte_array->data; + addr = (const struct in6_addr *) byte_array->data; - if (out_is_unspec && IN6_IS_ADDR_UNSPECIFIED (addr)) - *out_is_unspec = TRUE; + nm_utils_inet6_ntop (addr, buf); - errno = 0; - if (!inet_ntop (AF_INET6, addr, buf, buflen)) { - GString *ip6_str = g_string_sized_new (INET6_ADDRSTRLEN + 10); - - /* error converting the address */ - g_string_append_printf (ip6_str, "%02X", byte_array->data[0]); - for (idx = 1; idx < 16; idx++) - g_string_append_printf (ip6_str, " %02X", byte_array->data[idx]); - g_warning ("%s: error %d converting IP6 address %s", - __func__, errno, ip6_str->str); - g_string_free (ip6_str, TRUE); - return FALSE; - } - - return TRUE; + if (out_addr) + *out_addr = *addr; } static char * -ip6_array_to_addr_prefix (GValueArray *values) +ip6_array_to_addr_prefix (GValueArray *values, gboolean force_write_gateway) { GValue *prefix_val; char *ret = NULL; GString *ip6_str; - char buf[INET6_ADDRSTRLEN + 1]; - gboolean is_unspec = FALSE; + char buf[INET6_ADDRSTRLEN]; + struct in6_addr addr; /* address */ - if (ip6_array_to_addr (values, 0, buf, sizeof (buf), NULL)) { - /* Enough space for the address, '/', and the prefix */ - ip6_str = g_string_sized_new ((INET6_ADDRSTRLEN * 2) + 5); - - /* prefix */ - g_string_append (ip6_str, buf); - prefix_val = g_value_array_get_nth (values, 1); - g_string_append_printf (ip6_str, "/%u", g_value_get_uint (prefix_val)); - - if (ip6_array_to_addr (values, 2, buf, sizeof (buf), &is_unspec)) { - if (!is_unspec) - g_string_append_printf (ip6_str, ",%s", buf); - } + ip6_array_to_addr (values, 0, buf, NULL); - ret = ip6_str->str; - g_string_free (ip6_str, FALSE); - } + /* Enough space for the address, '/', and the prefix */ + ip6_str = g_string_sized_new ((INET6_ADDRSTRLEN * 2) + 5); + + /* prefix */ + g_string_append (ip6_str, buf); + prefix_val = g_value_array_get_nth (values, 1); + g_string_append_printf (ip6_str, "/%u", g_value_get_uint (prefix_val)); + + ip6_array_to_addr (values, 2, buf, &addr); + if (force_write_gateway || !IN6_IS_ADDR_UNSPECIFIED (&addr)) + g_string_append_printf (ip6_str, ",%s", buf); + + ret = ip6_str->str; + g_string_free (ip6_str, FALSE); return ret; } @@ -327,20 +330,18 @@ ip6_addr_writer (GKeyFile *file, char *key_name, *ip6_addr; if (values->n_values != 3) { - g_warning ("%s: error writing IP6 address %d (address array length " - "%d is not 3)", - __func__, i, values->n_values); + nm_log_warn (LOGD_SETTINGS, "%s: error writing IP6 address %d (address array " + "length %d is not 3)", __func__, i, values->n_values); continue; } - ip6_addr = ip6_array_to_addr_prefix (values); - if (ip6_addr) { - /* Write it out */ - key_name = g_strdup_printf ("address%d", j++); - g_key_file_set_string (file, setting_name, key_name, ip6_addr); - g_free (key_name); - g_free (ip6_addr); - } + /* we allow omitting the gateway if it's :: */ + ip6_addr = ip6_array_to_addr_prefix (values, FALSE); + /* Write it out */ + key_name = g_strdup_printf ("address%d", j++); + nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, ip6_addr); + g_free (key_name); + g_free (ip6_addr); } } @@ -366,21 +367,35 @@ ip6_route_writer (GKeyFile *file, for (i = 0, j = 1; i < array->len; i++) { GValueArray *values = g_ptr_array_index (array, i); char *key_name; - guint32 int_val; + char *addr_str; + guint metric; output = g_string_new (""); - /* Address, prefix and next hop*/ - g_string_append (output, ip6_array_to_addr_prefix (values)); - /* Metric */ value = g_value_array_get_nth (values, 3); - int_val = g_value_get_uint (value); - g_string_append_printf (output, ",%d", int_val); + metric = g_value_get_uint (value); + + /* Address, prefix and next hop + * We allow omitting the gateway ::, if we also omit the metric + * and force writing of the gateway, if we add a non zero metric. + * The current version of the reader also supports the syntax + * "a:b:c::/plen,,metric" for a gateway ::. + * As older versions of the plugin, cannot read this form, + * we always write the gateway, whenever we also write the metric. + * But if possible, we omit them both (",::,0") or only the metric + * (",0"). + **/ + addr_str = ip6_array_to_addr_prefix (values, metric != 0); + g_string_append (output, addr_str); + g_free (addr_str); + + if (metric != 0) + g_string_append_printf (output, ",%u", metric); /* Write it out */ key_name = g_strdup_printf ("route%d", j++); - g_key_file_set_string (file, setting_name, key_name, output->str); + nm_keyfile_plugin_kf_set_string (file, setting_name, key_name, output->str); g_free (key_name); g_string_free (output, TRUE); @@ -399,23 +414,15 @@ mac_address_writer (GKeyFile *file, GByteArray *array; const char *setting_name = nm_setting_get_name (setting); char *mac; - int type; g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY)); array = (GByteArray *) g_value_get_boxed (value); - if (!array) - return; - - type = nm_utils_hwaddr_type (array->len); - if (type < 0) { - g_warning ("%s: invalid %s / %s MAC address length %d", - __func__, setting_name, key, array->len); + if (!array || !array->len) return; - } - mac = nm_utils_hwaddr_ntoa (array->data, type); - g_key_file_set_string (file, setting_name, key, mac); + mac = nm_utils_hwaddr_ntoa_len (array->data, array->len); + nm_keyfile_plugin_kf_set_string (file, setting_name, key, mac); g_free (mac); } @@ -453,7 +460,7 @@ write_hash_of_string (GKeyFile *file, } if (write_item) - g_key_file_set_string (file, group_name, property, data); + nm_keyfile_plugin_kf_set_string (file, group_name, property, data); } } @@ -505,13 +512,13 @@ ssid_writer (GKeyFile *file, ssid[j++] = array->data[i]; } } - g_key_file_set_string (file, setting_name, key, ssid); + nm_keyfile_plugin_kf_set_string (file, setting_name, key, ssid); g_free (ssid); } else { tmp_array = g_new (gint, array->len); for (i = 0; i < array->len; i++) tmp_array[i] = (int) array->data[i]; - g_key_file_set_integer_list (file, setting_name, key, tmp_array, array->len); + nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, array->len); g_free (tmp_array); } } @@ -537,7 +544,7 @@ password_raw_writer (GKeyFile *file, tmp_array = g_new (gint, array->len); for (i = 0; i < array->len; i++) tmp_array[i] = (int) array->data[i]; - g_key_file_set_integer_list (file, setting_name, key, tmp_array, array->len); + nm_keyfile_plugin_kf_set_integer_list (file, setting_name, key, tmp_array, array->len); g_free (tmp_array); } @@ -686,7 +693,10 @@ cert_writer (GKeyFile *file, break; } } - g_return_if_fail (objtype != NULL); + if (!objtype) { + g_return_if_fail (objtype); + return; + } scheme = objtype->scheme_func (NM_SETTING_802_1X (setting)); if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) { @@ -702,7 +712,7 @@ cert_writer (GKeyFile *file, path++; } - g_key_file_set_string (file, setting_name, key, path); + nm_keyfile_plugin_kf_set_string (file, setting_name, key, path); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { const GByteArray *blob; gboolean success; @@ -732,9 +742,10 @@ cert_writer (GKeyFile *file, success = write_cert_key_file (new_path, blob, &error); if (success) { /* Write the path value to the keyfile */ - g_key_file_set_string (file, setting_name, key, new_path); + nm_keyfile_plugin_kf_set_string (file, setting_name, key, new_path); } else { - g_warning ("Failed to write certificate/key %s: %s", new_path, error->message); + nm_log_warn (LOGD_SETTINGS, "Failed to write certificate/key %s: %s", + new_path, error->message); g_error_free (error); } g_free (new_path); @@ -760,9 +771,18 @@ typedef struct { * in struct in6_addr internally, but as string in keyfiles. */ static KeyWriter key_writers[] = { + { NM_SETTING_CONNECTION_SETTING_NAME, + NM_SETTING_CONNECTION_TYPE, + setting_alias_writer }, + { NM_SETTING_BRIDGE_SETTING_NAME, + NM_SETTING_BRIDGE_MAC_ADDRESS, + mac_address_writer }, { NM_SETTING_IP4_CONFIG_SETTING_NAME, NM_SETTING_IP4_CONFIG_ADDRESSES, ip4_addr_writer }, + { NM_SETTING_IP4_CONFIG_SETTING_NAME, + "address-labels", + ip4_addr_label_writer }, { NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_ADDRESSES, ip6_addr_writer }, @@ -873,7 +893,7 @@ write_setting_value (NMSetting *setting, * the secret flags there are in a third-level hash in the 'secrets' * property. */ - if (pspec->flags & NM_SETTING_PARAM_SECRET && !NM_IS_SETTING_VPN (setting)) { + if (pspec && (pspec->flags & NM_SETTING_PARAM_SECRET) && !NM_IS_SETTING_VPN (setting)) { NMSettingSecretFlags secret_flags = NM_SETTING_SECRET_FLAG_NONE; nm_setting_get_secret_flags (setting, key, &secret_flags, NULL); @@ -895,21 +915,21 @@ write_setting_value (NMSetting *setting, str = g_value_get_string (value); if (str) - g_key_file_set_string (info->keyfile, setting_name, key, str); + nm_keyfile_plugin_kf_set_string (info->keyfile, setting_name, key, str); } else if (type == G_TYPE_UINT) - g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_uint (value)); + nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (int) g_value_get_uint (value)); else if (type == G_TYPE_INT) - g_key_file_set_integer (info->keyfile, setting_name, key, g_value_get_int (value)); + nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, g_value_get_int (value)); else if (type == G_TYPE_UINT64) { char *numstr; numstr = g_strdup_printf ("%" G_GUINT64_FORMAT, g_value_get_uint64 (value)); - g_key_file_set_value (info->keyfile, setting_name, key, numstr); + nm_keyfile_plugin_kf_set_value (info->keyfile, setting_name, key, numstr); g_free (numstr); } else if (type == G_TYPE_BOOLEAN) { - g_key_file_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); + nm_keyfile_plugin_kf_set_boolean (info->keyfile, setting_name, key, g_value_get_boolean (value)); } else if (type == G_TYPE_CHAR) { - g_key_file_set_integer (info->keyfile, setting_name, key, (int) g_value_get_schar (value)); + nm_keyfile_plugin_kf_set_integer (info->keyfile, setting_name, key, (int) g_value_get_schar (value)); } else if (type == DBUS_TYPE_G_UCHAR_ARRAY) { GByteArray *array; @@ -922,7 +942,7 @@ write_setting_value (NMSetting *setting, for (i = 0; i < array->len; i++) tmp_array[i] = (int) array->data[i]; - g_key_file_set_integer_list (info->keyfile, setting_name, key, tmp_array, array->len); + nm_keyfile_plugin_kf_set_integer_list (info->keyfile, setting_name, key, tmp_array, array->len); g_free (tmp_array); } } else if (type == DBUS_TYPE_G_LIST_OF_STRING) { @@ -938,19 +958,19 @@ write_setting_value (NMSetting *setting, for (iter = list; iter; iter = iter->next) array[i++] = iter->data; - g_key_file_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, i); + nm_keyfile_plugin_kf_set_string_list (info->keyfile, setting_name, key, (const gchar **const) array, i); g_free (array); } } else if (type == DBUS_TYPE_G_MAP_OF_STRING) { write_hash_of_string (info->keyfile, setting, key, value); } else if (type == DBUS_TYPE_G_UINT_ARRAY) { if (!write_array_of_uint (info->keyfile, setting, key, value)) { - g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'", - setting_name, key, g_type_name (type)); + nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (write) '%s/%s' : '%s'", + setting_name, key, g_type_name (type)); } } else { - g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'", - setting_name, key, g_type_name (type)); + nm_log_warn (LOGD_SETTINGS, "Unhandled setting property type (write) '%s/%s' : '%s'", + setting_name, key, g_type_name (type)); } } @@ -995,6 +1015,11 @@ _internal_write_connection (NMConnection *connection, if (out_path) g_return_val_if_fail (*out_path == NULL, FALSE); + if (!nm_connection_verify (connection, error)) { + g_return_val_if_reached (FALSE); + return FALSE; + } + id = nm_connection_get_id (connection); if (!id) { g_set_error (error, KEYFILE_PLUGIN_ERROR, 0, |