about summary refs log tree commit diff
path: root/src/settings/plugins/keyfile
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2012-03-24 01:37:02 +0100
committerMichael Biebl <biebl@debian.org>2012-03-24 01:37:02 +0100
commitde06e5715e780baade318f3490ac7a4c9ce84e32 (patch)
tree23fbc3fafc12072476eff98bee60100eb54c29db /src/settings/plugins/keyfile
parentb436a68a20ff3114ded32a7a3d70cdd4954039f9 (diff)
Imported Upstream version 0.9.4.0 upstream/0.9.4.0
Diffstat (limited to 'src/settings/plugins/keyfile')
-rw-r--r--src/settings/plugins/keyfile/Makefile.am4
-rw-r--r--src/settings/plugins/keyfile/Makefile.in13
-rw-r--r--src/settings/plugins/keyfile/plugin.c54
-rw-r--r--src/settings/plugins/keyfile/plugin.h4
-rw-r--r--src/settings/plugins/keyfile/reader.c89
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.am2
-rw-r--r--src/settings/plugins/keyfile/tests/Makefile.in11
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.am3
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Makefile.in12
-rw-r--r--src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection13
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile.c207
-rw-r--r--src/settings/plugins/keyfile/writer.c40
12 files changed, 353 insertions, 99 deletions
diff --git a/src/settings/plugins/keyfile/Makefile.am b/src/settings/plugins/keyfile/Makefile.am
index 3b242142..83031c24 100644
--- a/src/settings/plugins/keyfile/Makefile.am
+++ b/src/settings/plugins/keyfile/Makefile.am
@@ -3,7 +3,9 @@ SUBDIRS=. tests
 INCLUDES = \
 	-I$(top_srcdir)/src/settings \
 	-I$(top_srcdir)/include \
-	-I$(top_srcdir)/libnm-util
+	-I$(top_builddir)/include \
+	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util
 
 noinst_LTLIBRARIES = \
 	libkeyfile-io.la \
diff --git a/src/settings/plugins/keyfile/Makefile.in b/src/settings/plugins/keyfile/Makefile.in
index ae0c9f8e..c766e794 100644
--- a/src/settings/plugins/keyfile/Makefile.in
+++ b/src/settings/plugins/keyfile/Makefile.in
@@ -193,6 +193,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -247,11 +249,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -262,6 +268,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -301,6 +308,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -368,7 +377,9 @@ SUBDIRS = . tests
 INCLUDES = \
 	-I$(top_srcdir)/src/settings \
 	-I$(top_srcdir)/include \
-	-I$(top_srcdir)/libnm-util
+	-I$(top_builddir)/include \
+	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util
 
 noinst_LTLIBRARIES = \
 	libkeyfile-io.la \
diff --git a/src/settings/plugins/keyfile/plugin.c b/src/settings/plugins/keyfile/plugin.c
index af69c200..d53907a9 100644
--- a/src/settings/plugins/keyfile/plugin.c
+++ b/src/settings/plugins/keyfile/plugin.c
@@ -42,9 +42,6 @@
 #include "common.h"
 #include "utils.h"
 
-#define CONF_FILE SYSCONFDIR "/NetworkManager/NetworkManager.conf"
-#define OLD_CONF_FILE SYSCONFDIR "/NetworkManager/nm-system-settings.conf"
-
 static char *plugin_get_hostname (SCPluginKeyfile *plugin);
 static void system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
 
@@ -60,7 +57,7 @@ typedef struct {
 	GFileMonitor *monitor;
 	guint monitor_id;
 
-	const char *conf_file;
+	char *conf_file;
 	GFileMonitor *conf_file_monitor;
 	guint conf_file_monitor_id;
 
@@ -354,13 +351,15 @@ setup_monitoring (NMSystemConfigInterface *config)
 		priv->monitor = monitor;
 	}
 
-	file = g_file_new_for_path (priv->conf_file);
-	monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
-	g_object_unref (file);
+	if (priv->conf_file) {
+		file = g_file_new_for_path (priv->conf_file);
+		monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, NULL);
+		g_object_unref (file);
 
-	if (monitor) {
-		priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
-		priv->conf_file_monitor = monitor;
+		if (monitor) {
+			priv->conf_file_monitor_id = g_signal_connect (monitor, "changed", G_CALLBACK (conf_file_changed), config);
+			priv->conf_file_monitor = monitor;
+		}
 	}
 }
 
@@ -410,6 +409,9 @@ get_unmanaged_specs (NMSystemConfigInterface *config)
 	GSList *specs = NULL;
 	GError *error = NULL;
 
+	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;
@@ -460,6 +462,9 @@ plugin_get_hostname (SCPluginKeyfile *plugin)
 	char *hostname = NULL;
 	GError *error = NULL;
 
+	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))
 		hostname = g_key_file_get_value (key_file, "keyfile", "hostname", NULL);
@@ -481,6 +486,11 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
 	GError *error = NULL;
 	gboolean result = FALSE;
 
+	if (!priv->conf_file) {
+		g_warning ("Error saving hostname: no config file");
+		return FALSE;
+	}
+
 	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;
@@ -517,14 +527,6 @@ plugin_set_hostname (SCPluginKeyfile *plugin, const char *hostname)
 static void
 sc_plugin_keyfile_init (SCPluginKeyfile *plugin)
 {
-	SCPluginKeyfilePrivate *priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (plugin);
-
-	if (g_file_test (CONF_FILE, G_FILE_TEST_EXISTS))
-		priv->conf_file = CONF_FILE;
-	else
-		priv->conf_file = OLD_CONF_FILE;
-
-	priv->hostname = plugin_get_hostname (plugin);
 }
 
 static void
@@ -597,6 +599,7 @@ dispose (GObject *object)
 	}
 
 	g_free (priv->hostname);
+	g_free (priv->conf_file);
 
 	if (priv->hash)
 		g_hash_table_destroy (priv->hash);
@@ -642,13 +645,22 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
 }
 
 GObject *
-nm_settings_keyfile_plugin_new (void)
+nm_settings_keyfile_plugin_new (const char *config_file)
 {
 	static SCPluginKeyfile *singleton = NULL;
+	SCPluginKeyfilePrivate *priv;
 
-	if (!singleton)
+	if (!singleton) {
 		singleton = SC_PLUGIN_KEYFILE (g_object_new (SC_TYPE_PLUGIN_KEYFILE, NULL));
-	else
+		if (singleton) {
+			priv = SC_PLUGIN_KEYFILE_GET_PRIVATE (singleton);
+
+			priv->conf_file = g_strdup (config_file);
+
+			/* plugin_set_hostname() has to be called *after* priv->conf_file is set */
+			priv->hostname = plugin_get_hostname (singleton);
+		}
+	} else
 		g_object_ref (singleton);
 
 	return G_OBJECT (singleton);
diff --git a/src/settings/plugins/keyfile/plugin.h b/src/settings/plugins/keyfile/plugin.h
index af5147ef..05d4e2b0 100644
--- a/src/settings/plugins/keyfile/plugin.h
+++ b/src/settings/plugins/keyfile/plugin.h
@@ -16,7 +16,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright (C) 2008 - 2011 Red Hat, Inc.
  */
 
 #ifndef _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 (void);
+GObject *nm_settings_keyfile_plugin_new (const char *config_file);
 
 #endif	/* _PLUGIN_H_ */
diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c
index 4128b9f2..c7889cfc 100644
--- a/src/settings/plugins/keyfile/reader.c
+++ b/src/settings/plugins/keyfile/reader.c
@@ -34,8 +34,10 @@
 #include <nm-setting-wireless.h>
 #include <nm-setting-bluetooth.h>
 #include <nm-setting-8021x.h>
+#include <nm-utils.h>
 #include <arpa/inet.h>
 #include <netinet/ether.h>
+#include <linux/if_infiniband.h>
 #include <string.h>
 #include <ctype.h>
 
@@ -650,12 +652,11 @@ static void
 mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
 {
 	const char *setting_name = nm_setting_get_name (setting);
-	struct ether_addr *eth;
 	char *tmp_string = NULL, *p;
 	gint *tmp_list;
 	GByteArray *array = NULL;
 	gsize length;
-	int i;
+	int i, type;
 
 	p = tmp_string = g_key_file_get_string (keyfile, setting_name, key, NULL);
 	if (tmp_string) {
@@ -666,43 +667,45 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons
 				i++;
 			p++;
 		}
-		if (i == 5) {
-			/* parse as a MAC address */
-			eth = ether_aton (tmp_string);
-			if (eth) {
-				g_free (tmp_string);
-				array = g_byte_array_sized_new (ETH_ALEN);
-				g_byte_array_append (array, eth->ether_addr_octet, ETH_ALEN);
-				goto done;
-			}
-		}
+
+		/* 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);
 	}
 	g_free (tmp_string);
 
-	/* Old format; list of ints */
-	tmp_list = g_key_file_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);
-		} else
-			g_byte_array_append (array, (const unsigned char *) &v, sizeof (v));
+	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) {
+			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);
+					g_byte_array_free (array, TRUE);
+					array = NULL;
+					break;
+				}
+				g_byte_array_append (array, &v, 1);
+			}
+		}
+		g_free (tmp_list);
 	}
-	g_free (tmp_list);
 
-done:
-	if (array->len == ETH_ALEN) {
+	if (array) {
 		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);
 	}
-	g_byte_array_free (array, TRUE);
 }
 
 static void
@@ -825,6 +828,22 @@ ssid_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char
 	}
 }
 
+static void
+password_raw_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
+{
+	const char *setting_name = nm_setting_get_name (setting);
+	GByteArray *array;
+
+	array = get_uchar_array (keyfile, setting_name, key, FALSE, TRUE);
+	if (array) {
+		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);
+	}
+}
+
 static char *
 get_cert_path (const char *keyfile_path, GByteArray *cert_path)
 {
@@ -1019,11 +1038,19 @@ static KeyParser key_parsers[] = {
 	  NM_SETTING_BLUETOOTH_BDADDR,
 	  TRUE,
 	  mac_address_parser },
+	{ NM_SETTING_INFINIBAND_SETTING_NAME,
+	  NM_SETTING_INFINIBAND_MAC_ADDRESS,
+	  TRUE,
+	  mac_address_parser },
 	{ NM_SETTING_WIRELESS_SETTING_NAME,
 	  NM_SETTING_WIRELESS_SSID,
 	  TRUE,
 	  ssid_parser },
 	{ NM_SETTING_802_1X_SETTING_NAME,
+	  NM_SETTING_802_1X_PASSWORD_RAW,
+	  TRUE,
+	  password_raw_parser },
+	{ NM_SETTING_802_1X_SETTING_NAME,
 	  NM_SETTING_802_1X_CA_CERT,
 	  TRUE,
 	  cert_parser },
@@ -1300,7 +1327,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
 	 * the keyfile didn't include it, which can happen when the base
 	 * device type setting is all default values (like ethernet).
 	 */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	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);
@@ -1314,7 +1341,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
 	if (vpn_secrets) {
 		NMSettingVPN *s_vpn;
 
-		s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
+		s_vpn = nm_connection_get_setting_vpn (connection);
 		if (s_vpn)
 			read_vpn_secrets (key_file, s_vpn);
 	}
diff --git a/src/settings/plugins/keyfile/tests/Makefile.am b/src/settings/plugins/keyfile/tests/Makefile.am
index affe8dca..2adbf873 100644
--- a/src/settings/plugins/keyfile/tests/Makefile.am
+++ b/src/settings/plugins/keyfile/tests/Makefile.am
@@ -2,7 +2,9 @@ SUBDIRS=keyfiles
 
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-I$(srcdir)/../
 
diff --git a/src/settings/plugins/keyfile/tests/Makefile.in b/src/settings/plugins/keyfile/tests/Makefile.in
index c1fc662d..ff08e529 100644
--- a/src/settings/plugins/keyfile/tests/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/Makefile.in
@@ -179,6 +179,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -233,11 +235,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -248,6 +254,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -287,6 +294,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -353,7 +362,9 @@ top_srcdir = @top_srcdir@
 SUBDIRS = keyfiles
 INCLUDES = \
 	-I$(top_srcdir)/include \
+	-I$(top_builddir)/include \
 	-I$(top_srcdir)/libnm-util \
+	-I$(top_builddir)/libnm-util \
 	-I$(top_srcdir)/libnm-glib \
 	-I$(srcdir)/../
 
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
index 55dda7ee..f163312e 100644
--- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.am
@@ -13,7 +13,8 @@ KEYFILES = \
 	Test_Wired_TLS_Old \
 	Test_Wired_TLS_New \
 	Test_Wired_TLS_Blob \
-	Test_Wired_TLS_Path_Missing
+	Test_Wired_TLS_Path_Missing \
+	Test_InfiniBand_Connection
 
 CERTS = \
 	test-ca-cert.pem \
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
index 0ea23ebc..cf5b868f 100644
--- a/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Makefile.in
@@ -107,6 +107,8 @@ GIO_LIBS = @GIO_LIBS@
 GLIB_CFLAGS = @GLIB_CFLAGS@
 GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
 GLIB_LIBS = @GLIB_LIBS@
+GLIB_MAKEFILE = @GLIB_MAKEFILE@
+GLIB_MKENUMS = @GLIB_MKENUMS@
 GMODULE_CFLAGS = @GMODULE_CFLAGS@
 GMODULE_LIBS = @GMODULE_LIBS@
 GMSGFMT = @GMSGFMT@
@@ -161,11 +163,15 @@ LIBNL2_LIBS = @LIBNL2_LIBS@
 LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
 LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
+LIBNL_GENL3_CFLAGS = @LIBNL_GENL3_CFLAGS@
+LIBNL_GENL3_LIBS = @LIBNL_GENL3_LIBS@
 LIBNL_LIBS = @LIBNL_LIBS@
 LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
 LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
+LIBSOUP_CFLAGS = @LIBSOUP_CFLAGS@
+LIBSOUP_LIBS = @LIBSOUP_LIBS@
 LIBTOOL = @LIBTOOL@
 LIPO = @LIPO@
 LN_S = @LN_S@
@@ -176,6 +182,7 @@ MAINT = @MAINT@
 MAKEINFO = @MAKEINFO@
 MANIFEST_TOOL = @MANIFEST_TOOL@
 MKDIR_P = @MKDIR_P@
+MOC = @MOC@
 MSGFMT = @MSGFMT@
 MSGFMT_015 = @MSGFMT_015@
 MSGMERGE = @MSGMERGE@
@@ -215,6 +222,8 @@ SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
+SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@
+SYSTEMD_LIBS = @SYSTEMD_LIBS@
 SYSTEM_CA_PATH = @SYSTEM_CA_PATH@
 UDEV_BASE_DIR = @UDEV_BASE_DIR@
 USE_NLS = @USE_NLS@
@@ -293,7 +302,8 @@ KEYFILES = \
 	Test_Wired_TLS_Old \
 	Test_Wired_TLS_New \
 	Test_Wired_TLS_Blob \
-	Test_Wired_TLS_Path_Missing
+	Test_Wired_TLS_Path_Missing \
+	Test_InfiniBand_Connection
 
 CERTS = \
 	test-ca-cert.pem \
diff --git a/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection b/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection
new file mode 100644
index 00000000..3a984b77
--- /dev/null
+++ b/src/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection
@@ -0,0 +1,13 @@
+[connection]
+id=Test InfiniBand Connection
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=infiniband
+
+[infiniband]
+mac-address=00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90
+transport-mode=datagram
+mtu=1400
+
+[ipv4]
+method=auto
+
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c
index 2859cb3e..79fa2f9c 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile.c
@@ -26,6 +26,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
+#include <linux/if_infiniband.h>
 
 #include <nm-utils.h>
 #include <nm-setting-connection.h>
@@ -38,6 +39,7 @@
 #include <nm-setting-ppp.h>
 #include <nm-setting-gsm.h>
 #include <nm-setting-8021x.h>
+#include <nm-setting-infiniband.h>
 
 #include "nm-test-helpers.h"
 
@@ -93,7 +95,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -142,7 +144,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "connection-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -174,7 +176,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "connection-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -297,7 +299,7 @@ test_read_valid_wired_connection (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "connection-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_FILE,
@@ -745,7 +747,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -779,7 +781,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "connection-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -787,7 +789,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "connection-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -809,7 +811,7 @@ test_read_ip6_wired_connection (void)
 
 	/* ===== IPv6 SETTING ===== */
 
-	s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
+	s_ip6 = nm_connection_get_setting_ip6_config (connection);
 	ASSERT (s_ip6 != NULL,
 	        "connection-verify-ip6", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_IP6_FILE,
@@ -1001,7 +1003,7 @@ test_read_wired_mac_case (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_MAC_CASE_FILE,
@@ -1035,7 +1037,7 @@ test_read_wired_mac_case (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+	s_wired = nm_connection_get_setting_wired (connection);
 	ASSERT (s_wired != NULL,
 	        "connection-verify-wired", "failed to verify %s: missing %s setting",
 	        TEST_WIRED_MAC_CASE_FILE,
@@ -1087,7 +1089,7 @@ test_read_valid_wireless_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1136,7 +1138,7 @@ test_read_valid_wireless_connection (void)
 
 	/* ===== WIRED SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "connection-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1162,7 +1164,7 @@ test_read_valid_wireless_connection (void)
 
 	/* ===== IPv4 SETTING ===== */
 
-	s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
+	s_ip4 = nm_connection_get_setting_ip4_config (connection);
 	ASSERT (s_ip4 != NULL,
 	        "connection-verify-ip4", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1315,7 +1317,7 @@ test_read_string_ssid (void)
 
 	/* ===== WIRELESS SETTING ===== */
 
-	s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+	s_wireless = nm_connection_get_setting_wireless (connection);
 	ASSERT (s_wireless != NULL,
 	        "connection-verify-wireless", "failed to verify %s: missing %s setting",
 	        TEST_STRING_SSID_FILE,
@@ -1832,7 +1834,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_BT_DUN_FILE,
@@ -1866,7 +1868,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== BLUETOOTH SETTING ===== */
 
-	s_bluetooth = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+	s_bluetooth = nm_connection_get_setting_bluetooth (connection);
 	ASSERT (s_bluetooth != NULL,
 	        "connection-verify-bt", "failed to verify %s: missing %s setting",
 	        TEST_WIRELESS_FILE,
@@ -1905,7 +1907,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== GSM SETTING ===== */
 
-	s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+	s_gsm = nm_connection_get_setting_gsm (connection);
 	ASSERT (s_gsm != NULL,
 	        "connection-verify-gsm", "failed to verify %s: missing %s setting",
 	        TEST_BT_DUN_FILE,
@@ -1952,7 +1954,7 @@ test_read_bt_dun_connection (void)
 
 	/* ===== SERIAL SETTING ===== */
 
-	s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL));
+	s_serial = nm_connection_get_setting_serial (connection);
 	ASSERT (s_serial != NULL,
 	        "connection-verify-serial", "failed to verify %s: missing %s setting",
 	        TEST_BT_DUN_FILE,
@@ -2081,7 +2083,7 @@ test_read_gsm_connection (void)
 	NMSettingConnection *s_con;
 	NMSettingSerial *s_serial;
 	NMSettingGsm *s_gsm;
-	NMSetting *s_bluetooth;
+	NMSettingBluetooth *s_bluetooth;
 	GError *error = NULL;
 	const char *tmp;
 	const char *expected_id = "AT&T Data Connect";
@@ -2100,7 +2102,7 @@ test_read_gsm_connection (void)
 
 	/* ===== CONNECTION SETTING ===== */
 
-	s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+	s_con = nm_connection_get_setting_connection (connection);
 	ASSERT (s_con != NULL,
 	        "connection-verify-connection", "failed to verify %s: missing %s setting",
 	        TEST_GSM_FILE,
@@ -2134,7 +2136,7 @@ test_read_gsm_connection (void)
 	/* ===== BLUETOOTH SETTING ===== */
 
 	/* Plain GSM, so no BT setting expected */
-	s_bluetooth = nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+	s_bluetooth = nm_connection_get_setting_bluetooth (connection);
 	ASSERT (s_bluetooth == NULL,
 	        "connection-verify-bt", "unexpected %s setting",
 	        TEST_GSM_FILE,
@@ -2142,7 +2144,7 @@ test_read_gsm_connection (void)
 
 	/* ===== GSM SETTING ===== */
 
-	s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+	s_gsm = nm_connection_get_setting_gsm (connection);
 	ASSERT (s_gsm != NULL,
 	        "connection-verify-gsm", "failed to verify %s: missing %s setting",
 	        TEST_GSM_FILE,
@@ -2215,7 +2217,7 @@ test_read_gsm_connection (void)
 
 	/* ===== SERIAL SETTING ===== */
 
-	s_serial = NM_SETTING_SERIAL (nm_connection_get_setting (connection, NM_TYPE_SETTING_SERIAL));
+	s_serial = nm_connection_get_setting_serial (connection);
 	ASSERT (s_serial != NULL,
 	        "connection-verify-serial", "failed to verify %s: missing %s setting",
 	        TEST_GSM_FILE,
@@ -2324,7 +2326,7 @@ static void
 test_read_wired_8021x_tls_blob_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2346,11 +2348,11 @@ test_read_wired_8021x_tls_blob_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2389,7 +2391,7 @@ static void
 test_read_wired_8021x_tls_bad_path_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2411,11 +2413,11 @@ test_read_wired_8021x_tls_bad_path_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2451,7 +2453,7 @@ static void
 test_read_wired_8021x_tls_old_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2472,11 +2474,11 @@ test_read_wired_8021x_tls_old_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2507,7 +2509,7 @@ static void
 test_read_wired_8021x_tls_new_connection (void)
 {
 	NMConnection *connection;
-	NMSetting *s_wired;
+	NMSettingWired *s_wired;
 	NMSetting8021x *s_8021x;
 	GError *error = NULL;
 	const char *tmp;
@@ -2529,11 +2531,11 @@ test_read_wired_8021x_tls_new_connection (void)
 	}
 
 	/* ===== Wired Setting ===== */
-	s_wired = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
+	s_wired = nm_connection_get_setting_wired (connection);
 	g_assert (s_wired != NULL);
 
 	/* ===== 802.1x Setting ===== */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (connection);
 	g_assert (s_8021x != NULL);
 
 	g_assert (nm_setting_802_1x_get_num_eap_methods (s_8021x) == 1);
@@ -2779,7 +2781,7 @@ test_write_wired_8021x_tls_connection_blob (void)
 	g_assert (testfile);
 
 	/* Check that the new certs got written out */
-	s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+	s_con = nm_connection_get_setting_connection (connection);
 	g_assert (s_con);
 	uuid = nm_setting_connection_get_uuid (s_con);
 	g_assert (uuid);
@@ -2805,7 +2807,7 @@ test_write_wired_8021x_tls_connection_blob (void)
 	}
 
 	/* Ensure the re-read connection's certificates use the path scheme */
-	s_8021x = (NMSetting8021x *) nm_connection_get_setting (reread, NM_TYPE_SETTING_802_1X);
+	s_8021x = nm_connection_get_setting_802_1x (reread);
 	g_assert (s_8021x);
 	g_assert (nm_setting_802_1x_get_ca_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
 	g_assert (nm_setting_802_1x_get_client_cert_scheme (s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
@@ -2828,6 +2830,134 @@ test_write_wired_8021x_tls_connection_blob (void)
 	g_object_unref (connection);
 }
 
+#define TEST_INFINIBAND_FILE    TEST_KEYFILES_DIR"/Test_InfiniBand_Connection"
+
+static void
+test_read_infiniband_connection (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingInfiniband *s_ib;
+	GError *error = NULL;
+	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 };
+	const char *expected_id = "Test InfiniBand Connection";
+	const char *expected_uuid = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
+	gboolean success;
+
+	connection = nm_keyfile_plugin_connection_from_file (TEST_INFINIBAND_FILE, &error);
+	g_assert_no_error (error);
+	g_assert (connection);
+	success = nm_connection_verify (connection, &error);
+	g_assert_no_error (error);
+	g_assert (success);
+
+	/* Connection setting */
+	s_con = nm_connection_get_setting_connection (connection);
+	g_assert (s_con);
+	g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, expected_id);
+	g_assert_cmpstr (nm_setting_connection_get_uuid (s_con), ==, expected_uuid);
+
+	/* InfiniBand setting */
+	s_ib = nm_connection_get_setting_infiniband (connection);
+	g_assert (s_ib);
+
+	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_write_infiniband_connection (void)
+{
+	NMConnection *connection;
+	NMSettingConnection *s_con;
+	NMSettingInfiniband *s_ib;
+	NMSettingIP4Config *s_ip4;
+	NMSettingIP6Config *s_ip6;
+	char *uuid;
+	GByteArray *mac;
+	guint8 tmpmac[] = { 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0xab, 0xbc,
+		0xcd, 0xde, 0xef, 0xf0, 0x0a, 0x1b, 0x2c, 0x3d, 0x4e, 0x5f, 0x6f, 0xba
+	};
+	gboolean success;
+	NMConnection *reread;
+	char *testfile = NULL;
+	GError *error = NULL;
+	pid_t owner_grp;
+	uid_t owner_uid;
+
+	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, "Work InfiniBand",
+	              NM_SETTING_CONNECTION_UUID, uuid,
+	              NM_SETTING_CONNECTION_AUTOCONNECT, FALSE,
+	              NM_SETTING_CONNECTION_TYPE, NM_SETTING_INFINIBAND_SETTING_NAME,
+	              NULL);
+	g_free (uuid);
+
+	/* InfiniBand setting */
+	s_ib = (NMSettingInfiniband *) nm_setting_infiniband_new ();
+	g_assert (s_ib);
+	nm_connection_add_setting (connection, NM_SETTING (s_ib));
+
+	mac = g_byte_array_sized_new (sizeof (tmpmac));
+	g_byte_array_append (mac, &tmpmac[0], sizeof (tmpmac));
+	g_object_set (s_ib,
+	              NM_SETTING_INFINIBAND_MAC_ADDRESS, mac,
+	              NM_SETTING_INFINIBAND_MTU, 900,
+	              NM_SETTING_INFINIBAND_TRANSPORT_MODE, "datagram",
+	              NULL);
+	g_byte_array_free (mac, TRUE);
+
+	/* IP4 setting */
+	s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
+	g_assert (s_ip4);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip4));
+	g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+	/* IP6 setting */
+	s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
+	g_assert (s_ip6);
+	nm_connection_add_setting (connection, NM_SETTING (s_ip6));
+	g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, 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));
+
+	unlink (testfile);
+	g_free (testfile);
+
+	g_object_unref (reread);
+	g_object_unref (connection);
+}
+
 int main (int argc, char **argv)
 {
 	GError *error = NULL;
@@ -2876,6 +3006,9 @@ int main (int argc, char **argv)
 	test_write_wired_8021x_tls_connection_path ();
 	test_write_wired_8021x_tls_connection_blob ();
 
+	test_read_infiniband_connection ();
+	test_write_infiniband_connection ();
+
 	base = g_path_get_basename (argv[0]);
 	fprintf (stdout, "%s: SUCCESS\n", base);
 	g_free (base);
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
index 2babe267..bbd6a7c3 100644
--- a/src/settings/plugins/keyfile/writer.c
+++ b/src/settings/plugins/keyfile/writer.c
@@ -416,7 +416,7 @@ mac_address_writer (GKeyFile *file,
 	GByteArray *array;
 	const char *setting_name = nm_setting_get_name (setting);
 	char *mac;
-	struct ether_addr tmp;
+	int type;
 
 	g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY));
 
@@ -424,15 +424,16 @@ mac_address_writer (GKeyFile *file,
 	if (!array)
 		return;
 
-	if (array->len != ETH_ALEN) {
+	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);
 		return;
 	}
 
-	memcpy (tmp.ether_addr_octet, array->data, ETH_ALEN);
-	mac = ether_ntoa (&tmp);
+	mac = nm_utils_hwaddr_ntoa (array->data, type);
 	g_key_file_set_string (file, setting_name, key, mac);
+	g_free (mac);
 }
 
 static void
@@ -532,6 +533,31 @@ ssid_writer (GKeyFile *file,
 	}
 }
 
+static void
+password_raw_writer (GKeyFile *file,
+                     const char *keyfile_dir,
+                     const char *uuid,
+                     NMSetting *setting,
+                     const char *key,
+                     const GValue *value)
+{
+	const char *setting_name = nm_setting_get_name (setting);
+	GByteArray *array;
+	int i, *tmp_array;
+
+	g_return_if_fail (G_VALUE_HOLDS (value, DBUS_TYPE_G_UCHAR_ARRAY));
+
+	array = (GByteArray *) g_value_get_boxed (value);
+	if (!array || !array->len)
+		return;
+
+	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);
+	g_free (tmp_array);
+}
+
 typedef struct ObjectType {
 	const char *key;
 	const char *suffix;
@@ -787,10 +813,16 @@ static KeyWriter key_writers[] = {
 	{ NM_SETTING_BLUETOOTH_SETTING_NAME,
 	  NM_SETTING_BLUETOOTH_BDADDR,
 	  mac_address_writer },
+	{ NM_SETTING_INFINIBAND_SETTING_NAME,
+	  NM_SETTING_INFINIBAND_MAC_ADDRESS,
+	  mac_address_writer },
 	{ NM_SETTING_WIRELESS_SETTING_NAME,
 	  NM_SETTING_WIRELESS_SSID,
 	  ssid_writer },
 	{ NM_SETTING_802_1X_SETTING_NAME,
+	  NM_SETTING_802_1X_PASSWORD_RAW,
+	  password_raw_writer },
+	{ NM_SETTING_802_1X_SETTING_NAME,
 	  NM_SETTING_802_1X_CA_CERT,
 	  cert_writer },
 	{ NM_SETTING_802_1X_SETTING_NAME,