about summary refs log tree commit diff
path: root/src/settings/plugins/keyfile
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-06-28 18:58:14 +0200
committerMichael Biebl <biebl@debian.org>2020-06-28 18:58:14 +0200
commita54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (patch)
tree6a32883bd916c4096357b35298beff6db8bcd0b5 /src/settings/plugins/keyfile
parent45e8e1149027529194982212c804c0468aa01d98 (diff)
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'src/settings/plugins/keyfile')
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-plugin.c44
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-plugin.h2
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-reader.c49
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-reader.h1
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-storage.c8
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-storage.h2
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-writer.c58
-rw-r--r--src/settings/plugins/keyfile/nms-keyfile-writer.h1
-rw-r--r--src/settings/plugins/keyfile/tests/test-keyfile-settings.c1
9 files changed, 116 insertions, 50 deletions
diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c
index 2906b399..c84bd78d 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c
@@ -89,22 +89,33 @@ G_DEFINE_TYPE (NMSKeyfilePlugin, nms_keyfile_plugin, NM_TYPE_SETTINGS_PLUGIN)
 /*****************************************************************************/
 
 static const char *
-_extra_flags_to_string (char *str, gsize str_len, gboolean is_nm_generated, gboolean is_volatile)
+_extra_flags_to_string (char *str, gsize str_len, gboolean is_nm_generated, gboolean is_volatile, gboolean is_external)
 {
 	const char *str0 = str;
 
 	if (   !is_nm_generated
-	    && !is_volatile)
+	    && !is_volatile
+	    && !is_external)
 		nm_utils_strbuf_append_str (&str, &str_len, "");
 	else {
-		nm_utils_strbuf_append_str (&str, &str_len, " (");
+		char ch = '(';
+
+		nm_utils_strbuf_append_c (&str, &str_len, ' ');
 		if (is_nm_generated) {
+			nm_utils_strbuf_append_c (&str, &str_len, ch);
 			nm_utils_strbuf_append_str (&str, &str_len, "nm-generated");
-			if (is_volatile)
-				nm_utils_strbuf_append_c (&str, &str_len, ',');
+			ch = ',';
 		}
-		if (is_volatile)
+		if (is_volatile) {
+			nm_utils_strbuf_append_c (&str, &str_len, ch);
 			nm_utils_strbuf_append_str (&str, &str_len, "volatile");
+			ch = ',';
+		}
+		if (is_external) {
+			nm_utils_strbuf_append_c (&str, &str_len, ch);
+			nm_utils_strbuf_append_str (&str, &str_len, "external");
+			ch = ',';
+		}
 		nm_utils_strbuf_append_c (&str, &str_len, ')');
 	}
 
@@ -202,6 +213,7 @@ _read_from_file (const char *full_filename,
                  struct stat *out_stat,
                  NMTernary *out_is_nm_generated,
                  NMTernary *out_is_volatile,
+                 NMTernary *out_is_external,
                  char **out_shadowed_storage,
                  NMTernary *out_shadowed_owned,
                  GError **error)
@@ -215,6 +227,7 @@ _read_from_file (const char *full_filename,
 	                                           out_stat,
 	                                           out_is_nm_generated,
 	                                           out_is_volatile,
+	                                           out_is_external,
 	                                           out_shadowed_storage,
 	                                           out_shadowed_owned,
 	                                           error);
@@ -284,8 +297,9 @@ _load_file (NMSKeyfilePlugin *self,
 {
 	NMSKeyfilePluginPrivate *priv;
 	gs_unref_object NMConnection *connection = NULL;
-	NMTernary is_volatile_opt;
 	NMTernary is_nm_generated_opt;
+	NMTernary is_volatile_opt;
+	NMTernary is_external_opt;
 	NMTernary shadowed_owned_opt;
 	gs_free char *shadowed_storage = NULL;
 	gs_free_error GError *local = NULL;
@@ -350,6 +364,7 @@ _load_file (NMSKeyfilePlugin *self,
 	                              &st,
 	                              &is_nm_generated_opt,
 	                              &is_volatile_opt,
+	                              &is_external_opt,
 	                              &shadowed_storage,
 	                              &shadowed_owned_opt,
 	                              &local);
@@ -367,6 +382,7 @@ _load_file (NMSKeyfilePlugin *self,
 	                                           storage_type,
 	                                           is_nm_generated_opt,
 	                                           is_volatile_opt,
+	                                           is_external_opt,
 	                                           shadowed_storage,
 	                                           shadowed_owned_opt,
 	                                           &st.st_mtim);
@@ -732,6 +748,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
                                    gboolean in_memory,
                                    gboolean is_nm_generated,
                                    gboolean is_volatile,
+                                   gboolean is_external,
                                    const char *shadowed_storage,
                                    gboolean shadowed_owned,
                                    NMSettingsStorage **out_storage,
@@ -756,6 +773,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
 	nm_assert (   in_memory
 	           || (   !is_nm_generated
 	               && !is_volatile
+	               && !is_external
 	               && !shadowed_storage
 	               && !shadowed_owned));
 
@@ -770,6 +788,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
 	if (!nms_keyfile_writer_connection (connection,
 	                                    is_nm_generated,
 	                                    is_volatile,
+	                                    is_external,
 	                                    shadowed_storage,
 	                                    shadowed_owned,
 	                                      storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC
@@ -807,7 +826,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
 	       uuid,
 	       nm_connection_get_id (connection),
 	       full_filename,
-	       _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile),
+	       _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile, is_external),
 	       NM_PRINT_FMT_QUOTED (shadowed_storage, " (shadows \"", shadowed_storage, shadowed_owned ? "\", owned)" : "\")", ""));
 
 	storage = nms_keyfile_storage_new_connection (self,
@@ -816,6 +835,7 @@ nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
 	                                              storage_type,
 	                                              is_nm_generated ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
 	                                              is_volatile ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
+	                                              is_external ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
 	                                              shadowed_storage,
 	                                              shadowed_owned ? NM_TERNARY_TRUE : NM_TERNARY_FALSE,
 	                                              nm_sett_util_stat_mtime (full_filename, FALSE, &mtime));
@@ -840,6 +860,7 @@ add_connection (NMSettingsPlugin *plugin,
 	                                          FALSE,
 	                                          FALSE,
 	                                          FALSE,
+	                                          FALSE,
 	                                          NULL,
 	                                          FALSE,
 	                                          out_storage,
@@ -853,6 +874,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
                                       NMConnection *connection,
                                       gboolean is_nm_generated,
                                       gboolean is_volatile,
+                                      gboolean is_external,
                                       const char *shadowed_storage,
                                       gboolean shadowed_owned,
                                       gboolean force_rename,
@@ -883,6 +905,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
 	nm_assert (   storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN
 	           || (   !is_nm_generated
 	               && !is_volatile
+	               && !is_external
 	               && !shadowed_storage
 	               && !shadowed_owned));
 	nm_assert (!shadowed_owned || shadowed_storage);
@@ -895,6 +918,7 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
 	if (!nms_keyfile_writer_connection (connection,
 	                                    is_nm_generated,
 	                                    is_volatile,
+	                                    is_external,
 	                                    shadowed_storage,
 	                                    shadowed_owned,
 	                                      storage->storage_type == NMS_KEYFILE_STORAGE_TYPE_ETC
@@ -933,11 +957,12 @@ nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
 	       full_filename,
 	       uuid,
 	       nm_connection_get_id (connection),
-	       _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile),
+	       _extra_flags_to_string (strbuf, sizeof (strbuf), is_nm_generated, is_volatile, is_external),
 	       NM_PRINT_FMT_QUOTED (shadowed_storage, shadowed_owned ? " (owns \"" : " (shadows \"", shadowed_storage, "\")", ""));
 
 	storage->u.conn_data.is_nm_generated = is_nm_generated;
 	storage->u.conn_data.is_volatile     = is_volatile;
+	storage->u.conn_data.is_external     = is_external;
 	storage->u.conn_data.stat_mtime      = *nm_sett_util_stat_mtime (full_filename, FALSE, &mtime);
 	storage->u.conn_data.shadowed_owned  = shadowed_owned;
 
@@ -959,6 +984,7 @@ update_connection (NMSettingsPlugin *plugin,
 	                                             connection,
 	                                             FALSE,
 	                                             FALSE,
+	                                             FALSE,
 	                                             NULL,
 	                                             FALSE,
 	                                             FALSE,
diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.h b/src/settings/plugins/keyfile/nms-keyfile-plugin.h
index e885f16c..603f0c26 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-plugin.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.h
@@ -31,6 +31,7 @@ gboolean nms_keyfile_plugin_add_connection (NMSKeyfilePlugin *self,
                                             gboolean in_memory,
                                             gboolean is_nm_generated,
                                             gboolean is_volatile,
+                                            gboolean is_external,
                                             const char *shadowed_storage,
                                             gboolean shadowed_owned,
                                             NMSettingsStorage **out_storage,
@@ -42,6 +43,7 @@ gboolean nms_keyfile_plugin_update_connection (NMSKeyfilePlugin *self,
                                                NMConnection *connection,
                                                gboolean is_nm_generated,
                                                gboolean is_volatile,
+                                               gboolean is_external,
                                                const char *shadowed_storage,
                                                gboolean shadowed_owned,
                                                gboolean force_rename,
diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.c b/src/settings/plugins/keyfile/nms-keyfile-reader.c
index e8c9f9fe..577709d8 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-reader.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-reader.c
@@ -17,11 +17,15 @@
 /*****************************************************************************/
 
 static const char *
-_fmt_warn (const char *group, NMSetting *setting, const char *property_name, const char *message, char **out_message)
+_fmt_warn (const NMKeyfileHandlerData *handler_data, char **out_message)
 {
-	const char *setting_name = setting ? nm_setting_get_name (setting) : NULL;
+	const char *group = handler_data->kf_group_name;
+	const char *message = _nm_keyfile_handler_data_warn_get_message (handler_data);
 
 	if (group) {
+		NMSetting *setting = handler_data->cur_setting;
+		const char *property_name = handler_data->cur_property;
+		const char *setting_name = setting ? nm_setting_get_name (setting) : NULL;
 		char *res;
 
 		if (setting_name) {
@@ -37,30 +41,30 @@ _fmt_warn (const char *group, NMSetting *setting, const char *property_name, con
 			res = g_strdup_printf ("%s: %s", group, message);
 		*out_message = res;
 		return res;
-	} else
-		return message;
+	}
+
+	return message;
 }
 
 typedef struct {
 	bool verbose;
-} HandlerReadData;
+} ReadInfo;
 
 static gboolean
 _handler_read (GKeyFile *keyfile,
                NMConnection *connection,
-               NMKeyfileReadType type,
-               void *type_data,
-               void *user_data,
-               GError **error)
+               NMKeyfileHandlerType handler_type,
+               NMKeyfileHandlerData *handler_data,
+               void *user_data)
 {
-	const HandlerReadData *handler_data = user_data;
+	const ReadInfo *read_info = user_data;
 
-	if (type == NM_KEYFILE_READ_TYPE_WARN) {
-		NMKeyfileReadTypeDataWarn *warn_data = type_data;
+	if (handler_type == NM_KEYFILE_HANDLER_TYPE_WARN) {
+		const NMKeyfileHandlerDataWarn *warn_data = &handler_data->warn;
 		NMLogLevel level;
 		char *message_free = NULL;
 
-		if (!handler_data->verbose)
+		if (!read_info->verbose)
 			return TRUE;
 
 		if (warn_data->severity > NM_KEYFILE_WARN_SEVERITY_WARN)
@@ -72,15 +76,17 @@ _handler_read (GKeyFile *keyfile,
 		else
 			level = LOGL_INFO;
 
-		nm_log (level, LOGD_SETTINGS, NULL,
+		nm_log (level,
+		        LOGD_SETTINGS,
+		        NULL,
 		        nm_connection_get_uuid (connection),
 		        "keyfile: %s",
-		        _fmt_warn (warn_data->group, warn_data->setting,
-		                   warn_data->property_name, warn_data->message,
+		        _fmt_warn (handler_data,
 		                   &message_free));
 		g_free (message_free);
 		return TRUE;
 	}
+
 	return FALSE;
 }
 
@@ -93,7 +99,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file,
                                  GError **error)
 {
 	NMConnection *connection;
-	HandlerReadData data = {
+	ReadInfo read_info = {
 		.verbose = verbose,
 	};
 	gs_free char *base_dir_free = NULL;
@@ -122,7 +128,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file,
 		filename = &s[1];
 	}
 
-	connection = nm_keyfile_read (key_file, base_dir, _handler_read, &data, error);
+	connection = nm_keyfile_read (key_file, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_read, &read_info, error);
 	if (!connection)
 		return NULL;
 
@@ -150,6 +156,7 @@ nms_keyfile_reader_from_file (const char *full_filename,
                               struct stat *out_stat,
                               NMTernary *out_is_nm_generated,
                               NMTernary *out_is_volatile,
+                              NMTernary *out_is_external,
                               char **out_shadowed_storage,
                               NMTernary *out_shadowed_owned,
                               GError **error)
@@ -163,6 +170,7 @@ nms_keyfile_reader_from_file (const char *full_filename,
 
 	NM_SET_OUT (out_is_nm_generated, NM_TERNARY_DEFAULT);
 	NM_SET_OUT (out_is_volatile, NM_TERNARY_DEFAULT);
+	NM_SET_OUT (out_is_external, NM_TERNARY_DEFAULT);
 
 	if (!nms_keyfile_utils_check_file_permissions (NMS_KEYFILE_FILETYPE_KEYFILE,
 	                                               full_filename,
@@ -198,6 +206,11 @@ nms_keyfile_reader_from_file (const char *full_filename,
 	                                                      NM_KEYFILE_KEY_NMMETA_VOLATILE,
 	                                                      NM_TERNARY_DEFAULT));
 
+	NM_SET_OUT (out_is_external, nm_key_file_get_boolean (key_file,
+	                                                      NM_KEYFILE_GROUP_NMMETA,
+	                                                      NM_KEYFILE_KEY_NMMETA_EXTERNAL,
+	                                                      NM_TERNARY_DEFAULT));
+
 	NM_SET_OUT (out_shadowed_storage, g_key_file_get_string (key_file,
 	                                                         NM_KEYFILE_GROUP_NMMETA,
 	                                                         NM_KEYFILE_KEY_NMMETA_SHADOWED_STORAGE,
diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.h b/src/settings/plugins/keyfile/nms-keyfile-reader.h
index 307d6ffe..828715fa 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-reader.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-reader.h
@@ -23,6 +23,7 @@ NMConnection *nms_keyfile_reader_from_file (const char *full_filename,
                                             struct stat *out_stat,
                                             NMTernary *out_is_nm_generated,
                                             NMTernary *out_is_volatile,
+                                            NMTernary *out_is_external,
                                             char **out_shadowed_storage,
                                             NMTernary *out_shadowed_owned,
                                             GError **error);
diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.c b/src/settings/plugins/keyfile/nms-keyfile-storage.c
index bcc06795..15f20295 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-storage.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-storage.c
@@ -155,6 +155,7 @@ nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin,
                                     NMSKeyfileStorageType storage_type,
                                     NMTernary is_nm_generated_opt,
                                     NMTernary is_volatile_opt,
+                                    NMTernary is_external_opt,
                                     const char *shadowed_storage,
                                     NMTernary shadowed_owned_opt,
                                     const struct timespec *stat_mtime)
@@ -181,6 +182,7 @@ nms_keyfile_storage_new_connection (NMSKeyfilePlugin *plugin,
 	if (storage_type == NMS_KEYFILE_STORAGE_TYPE_RUN) {
 		self->u.conn_data.is_nm_generated = (is_nm_generated_opt == NM_TERNARY_TRUE);
 		self->u.conn_data.is_volatile     = (is_volatile_opt == NM_TERNARY_TRUE);
+		self->u.conn_data.is_external     = (is_external_opt == NM_TERNARY_TRUE);
 		self->u.conn_data.shadowed_owned  =    shadowed_storage
 		                                    && (shadowed_owned_opt == NM_TERNARY_TRUE);
 	}
@@ -243,7 +245,8 @@ nm_settings_storage_load_sett_flags (NMSettingsStorage *self,
 
 	*sett_flags = NM_SETTINGS_CONNECTION_INT_FLAGS_NONE;
 	*sett_mask =   NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED
-	             | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE;
+	             | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
+	             | NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL;
 
 	if (!NMS_IS_KEYFILE_STORAGE (self))
 		return;
@@ -260,4 +263,7 @@ nm_settings_storage_load_sett_flags (NMSettingsStorage *self,
 
 	if (s->u.conn_data.is_volatile)
 		*sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE;
+
+	if (s->u.conn_data.is_external)
+		*sett_flags |= NM_SETTINGS_CONNECTION_INT_FLAGS_EXTERNAL;
 }
diff --git a/src/settings/plugins/keyfile/nms-keyfile-storage.h b/src/settings/plugins/keyfile/nms-keyfile-storage.h
index 00a034d4..bd8a4367 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-storage.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-storage.h
@@ -65,6 +65,7 @@ typedef struct {
 			 * That is, it must be tied to the actual keyfile, and not to the UUID. */
 			bool is_nm_generated:1;
 			bool is_volatile:1;
+			bool is_external:1;
 
 			/* if shadowed_storage is set, then this flag indicates whether the file
 			 * is owned. The difference comes into play when deleting the in-memory,
@@ -112,6 +113,7 @@ NMSKeyfileStorage *nms_keyfile_storage_new_connection (struct _NMSKeyfilePlugin
                                                        NMSKeyfileStorageType storage_type,
                                                        NMTernary is_nm_generated_opt,
                                                        NMTernary is_volatile_opt,
+                                                       NMTernary is_external_opt,
                                                        const char *shadowed_storage,
                                                        NMTernary shadowed_owned_opt,
                                                        const struct timespec *stat_mtime);
diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.c b/src/settings/plugins/keyfile/nms-keyfile-writer.c
index 7554becc..feea6065 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-writer.c
+++ b/src/settings/plugins/keyfile/nms-keyfile-writer.c
@@ -28,21 +28,22 @@ typedef struct {
 static void
 cert_writer (NMConnection *connection,
              GKeyFile *file,
-             NMKeyfileWriteTypeDataCert *cert_data,
+             NMSetting8021x *setting,
+             const NMSetting8021xSchemeVtable *vtable,
              WriteInfo *info,
              GError **error)
 {
-	const char *setting_name = nm_setting_get_name (NM_SETTING (cert_data->setting));
+	const char *setting_name = nm_setting_get_name (NM_SETTING (setting));
 	NMSetting8021xCKScheme scheme;
 	NMSetting8021xCKFormat format;
 	const char *path = NULL, *ext = "pem";
 
-	scheme = cert_data->vtable->scheme_func (cert_data->setting);
+	scheme = vtable->scheme_func (setting);
 	if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) {
 		char *tmp = NULL;
 		const char *accepted_path = NULL;
 
-		path = cert_data->vtable->path_func (cert_data->setting);
+		path = vtable->path_func (setting);
 		g_assert (path);
 
 		if (g_str_has_prefix (path, info->keyfile_dir)) {
@@ -78,11 +79,11 @@ cert_writer (NMConnection *connection,
 
 		if (!accepted_path)
 			accepted_path = tmp = g_strconcat (NM_KEYFILE_CERT_SCHEME_PREFIX_PATH, path, NULL);
-		nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, accepted_path);
+		nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, accepted_path);
 		g_free (tmp);
 	} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) {
-		nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key,
-		                                 cert_data->vtable->uri_func (cert_data->setting));
+		nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key,
+		                                 vtable->uri_func (setting));
 	} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
 		GBytes *blob;
 		const guint8 *blob_data;
@@ -91,13 +92,13 @@ cert_writer (NMConnection *connection,
 		GError *local = NULL;
 		char *new_path;
 
-		blob = cert_data->vtable->blob_func (cert_data->setting);
+		blob = vtable->blob_func (setting);
 		g_assert (blob);
 		blob_data = g_bytes_get_data (blob, &blob_len);
 
-		if (cert_data->vtable->format_func) {
+		if (vtable->format_func) {
 			/* Get the extension for a private key */
-			format = cert_data->vtable->format_func (cert_data->setting);
+			format = vtable->format_func (setting);
 			if (format == NM_SETTING_802_1X_CK_FORMAT_PKCS12)
 				ext = "p12";
 		} else {
@@ -110,7 +111,7 @@ cert_writer (NMConnection *connection,
 		 * from now on instead of pushing around the certificate data.
 		 */
 		new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection),
-		                            cert_data->vtable->file_suffix, ext);
+		                            vtable->file_suffix, ext);
 
 		/* FIXME(keyfile-parse-in-memory): writer must not access/write to the file system before
 		 * being sure that the entire profile can be written and all circumstances are good to
@@ -125,10 +126,10 @@ cert_writer (NMConnection *connection,
 		if (success) {
 			/* Write the path value to the keyfile.
 			 * We know, that basename(new_path) starts with a UUID, hence no conflict with "data:;base64,"  */
-			nm_keyfile_plugin_kf_set_string (file, setting_name, cert_data->vtable->setting_key, strrchr (new_path, '/') + 1);
+			nm_keyfile_plugin_kf_set_string (file, setting_name, vtable->setting_key, strrchr (new_path, '/') + 1);
 		} else {
 			nm_log_warn (LOGD_SETTINGS, "keyfile: %s.%s: failed to write certificate to file %s: %s",
-			             setting_name, cert_data->vtable->setting_key, new_path, local->message);
+			             setting_name, vtable->setting_key, new_path, local->message);
 			g_error_free (local);
 		}
 		g_free (new_path);
@@ -146,15 +147,17 @@ cert_writer (NMConnection *connection,
 static gboolean
 _handler_write (NMConnection *connection,
                 GKeyFile *keyfile,
-                NMKeyfileWriteType type,
-                void *type_data,
-                void *user_data,
-                GError **error)
+                NMKeyfileHandlerType type,
+                NMKeyfileHandlerData *type_data,
+                void *user_data)
 {
-	if (type == NM_KEYFILE_WRITE_TYPE_CERT) {
-		cert_writer (connection, keyfile,
-		             (NMKeyfileWriteTypeDataCert *) type_data,
-		             (WriteInfo *) user_data, error);
+	if (type == NM_KEYFILE_HANDLER_TYPE_WRITE_CERT) {
+		cert_writer (connection,
+		             keyfile,
+		             NM_SETTING_802_1X (type_data->cur_setting),
+		             type_data->write_cert.vtable,
+		             user_data,
+		             type_data->p_error);
 		return TRUE;
 	}
 	return FALSE;
@@ -164,6 +167,7 @@ static gboolean
 _internal_write_connection (NMConnection *connection,
                             gboolean is_nm_generated,
                             gboolean is_volatile,
+                            gboolean is_external,
                             const char *shadowed_storage,
                             gboolean shadowed_owned,
                             const char *keyfile_dir,
@@ -211,7 +215,7 @@ _internal_write_connection (NMConnection *connection,
 
 	info.keyfile_dir = keyfile_dir;
 
-	kf_file = nm_keyfile_write (connection, _handler_write, &info, error);
+	kf_file = nm_keyfile_write (connection, NM_KEYFILE_HANDLER_FLAGS_NONE, _handler_write, &info, error);
 	if (!kf_file)
 		return FALSE;
 
@@ -229,6 +233,13 @@ _internal_write_connection (NMConnection *connection,
 		                        TRUE);
 	}
 
+	if (is_external) {
+		g_key_file_set_boolean (kf_file,
+		                        NM_KEYFILE_GROUP_NMMETA,
+		                        NM_KEYFILE_KEY_NMMETA_EXTERNAL,
+		                        TRUE);
+	}
+
 	if (shadowed_storage) {
 		g_key_file_set_string (kf_file,
 		                       NM_KEYFILE_GROUP_NMMETA,
@@ -375,6 +386,7 @@ gboolean
 nms_keyfile_writer_connection (NMConnection *connection,
                                gboolean is_nm_generated,
                                gboolean is_volatile,
+                               gboolean is_external,
                                const char *shadowed_storage,
                                gboolean shadowed_owned,
                                const char *keyfile_dir,
@@ -392,6 +404,7 @@ nms_keyfile_writer_connection (NMConnection *connection,
 	return _internal_write_connection (connection,
 	                                   is_nm_generated,
 	                                   is_volatile,
+	                                   is_external,
 	                                   shadowed_storage,
 	                                   shadowed_owned,
 	                                   keyfile_dir,
@@ -423,6 +436,7 @@ nms_keyfile_writer_test_connection (NMConnection *connection,
 	return _internal_write_connection (connection,
 	                                   FALSE,
 	                                   FALSE,
+	                                   FALSE,
 	                                   NULL,
 	                                   FALSE,
 	                                   keyfile_dir,
diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.h b/src/settings/plugins/keyfile/nms-keyfile-writer.h
index 98ec8a6b..73a2e333 100644
--- a/src/settings/plugins/keyfile/nms-keyfile-writer.h
+++ b/src/settings/plugins/keyfile/nms-keyfile-writer.h
@@ -15,6 +15,7 @@ typedef gboolean (*NMSKeyfileWriterAllowFilenameCb) (const char *check_filename,
 gboolean nms_keyfile_writer_connection (NMConnection *connection,
                                         gboolean is_nm_generated,
                                         gboolean is_volatile,
+                                        gboolean is_external,
                                         const char *shadowed_storage,
                                         gboolean shadowed_owned,
                                         const char *keyfile_dir,
diff --git a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
index d2da09da..1a9482e5 100644
--- a/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
+++ b/src/settings/plugins/keyfile/tests/test-keyfile-settings.c
@@ -63,6 +63,7 @@ check_ip_route (NMSettingIPConfig *config, int idx, const char *destination, int
 	                                            NULL, \
 	                                            NULL, \
 	                                            NULL, \
+	                                            NULL, \
 	                                            (nmtst_get_rand_uint32 () % 2) ? &_error : NULL); \
 	nmtst_assert_success (_connection, _error); \
 	nmtst_assert_connection_verifies_without_normalization (_connection); \